Problem with Accordion Bootstrap plugin

0

Well, I have a page that I'm doing with Bootstrap and AngularJS for the front-end and I generate several accordions on the same page dynamically with a ng-repeat . The problem is that when I click on the names of the tabs to enlarge them, the tab title is hidden and the content is shown ... that is, it does not work as it should, and I have another code that is the same and if it works ... I do not understand why that behavior. I leave the html that I am using and the Angular filter that I use just in case ...

productos.html:

<!DOCTYPE html>
<html lang="es" ng-app="tangoInfinito">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Tango Infinito - Productos</title>
        <link rel="stylesheet" href="css/bootstrap.min.css">
        <link rel="stylesheet" href="css/font-awesome.min.css">
        <link rel="stylesheet" href="css/estilos.css">
        <link rel="stylesheet" href="css/bootstrap-social.css">
        <link href="https://fonts.googleapis.com/css?family=Roboto+Condensed" rel="stylesheet">
        <link href="https://fonts.googleapis.com/css?family=Play:400,700" rel="stylesheet">
        <link rel="icon" type="image/png" href="favicon32x32.png">
        <link rel="shortcut icon" type="image/x-icon" href="favicon32x32.ico">
        <script src="js/angular.min.js"></script>
        <script src="js/angular-route.min.js"></script>
        <script src="js/angular-resource.min.js"></script>
        <script src="js/app.js"></script>
        <script src="js/Controllers/ProductosController.js"></script>
        <script src="js/Services/ProductosService.js"></script>
        <script src="js/Filters/IdFilter.js"></script>

        <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]>
          <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
          <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
        <![endif]-->
    </head>
    <body ng-controller="ProductosController">
        <nav class="navbar" role="navigation">
            <div class="container">
                <div class="navbar-header">
                    <button type="button" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar" class="navbar-toggle collapsed">
                        <span class="sr-only">Toggle navigation</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    <div class="col-xs-2 col-sm-3">
                        <a id="link-logo" class="navbar-brand" href="index.html"><img class="img-responsive" src="logos/logo.png"></a>
                    </div>
                    <div class="col-xs-6 col-sm-9">
                        <h1><a href="index.html"><span id="titulo-logo-1">TANGO INFINITO</span><span id="titulo-logo-2">.com.ar</span></a></h1>
                    </div>
                </div>
                <div id="navbar" class="navbar-collapse collapse">
                    <ul class="nav navbar-nav navbar-right">
                        <li class="active"><a href="index.html"><span class="glyphicon glyphicon-home" aria-hidden="true"></span> Inicio</a></li>
                        <li><a href="http://web.facebook.com/orquestatipicalayumba" target="_blank"><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> Notitango</a></li>
                        <li class="dropdown">
                            <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-list-alt"></span> Productos<span class="caret"></span></a>
                            <ul class="dropdown-menu">
                                <!-- Contenido generado dinámicamente -->
                            </ul>
                        </li>
                        <li><a href="index.html#contact-form"><i class="fa fa-envelope-o"></i> Contacto</a></li>
                    </ul>
                </div>
            </div>
        </nav>

        <!-- Contenido -->
        <div id="main-content" style="padding-top: 80px; font-family: 'Play', sans-serif;">
            <div class="container">
                <div class="row row-content" ng-repeat="r in rubros">
                    <h2 class="col-xs-12 col-lg-3 col-lg-push-5 rubro" id="{{r.rubro | lowercase}}" style="font-weight: 700;">{{r.rubro | uppercase}}</h2>
                    <div class="col-xs-12 wrapper" ng-repeat="t in tipos | filter: {rubro: r.rubro}">
                        <div class="row row-content">
                            <h3 id="{{t.tipo | lowercase}}" class="tipo">{{t.tipo | uppercase}}</h3>
                            <!-- Tabs -->
                            <ul class="nav nav-tabs">
                                <li ng-repeat="prod in productos | filter: {tipo: t.tipo}"><a data-toggle="tab" href="#{{prod.nombre | IdFilter}}">{{prod.nombre}}</a></li>
                            </ul>
                            <!-- Tabs Contenido -->
                            <div class="tab-content">
                                <div class="tab-pane fade" id="{{prod.nombre | IdFilter}}" ng-repeat="prod in productos | filter: {tipo: t.tipo}">
                                    <p style="padding-top: 10px;">{{prod.resenia}}</p>
                                    <h4>INTEGRANTES:</h4>
                                    <!-- Accordion -->
                                    <div id="{{accordionId(prod.nombre)}}" class="panel-group" role="tablist" aria-multiselectable="true">
                                        <div ng-repeat="integrante in prod.integrantes" class="panel panel-default">
                                            <div class="panel-heading" role="tab" id="heading-{{integrante.nombre | IdFilter}}">
                                                <h3 class="panel-title">
                                                   <a role="button" data-toggle="collapse" data-parent="#{{accordionId(prod.nombre)}}" href="#{{integrante.nombre | IdFilter}}" aria-expanded="true" aria-controls="{{integrante.nombre | IdFilter}}">{{integrante.nombre}} {{integrante.apellido}}</a>
                                                </h3>
                                            </div>
                                            <div role="tabpanel" aria-labelledby="heading-{{integrante.nombre | IdFilter}}" id="{{integrante.nombre | IdFilter}}" class="panel-collapse collapse">
                                                <div class="panel-body">
                                                    <p>{{integrante.resenia}}</p>
                                                </div>
                                            </div>
                                        </div>
                                    </div> <!-- Fin Accordion -->
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <footer class="row-footer">
            <div class="container">
                <div class="row">
                    <div class="col-xs-6 col-sm-5">
                        <h5 style="font-weight: bolder;">Contacto</h5>
                        <address>
                          <i class="fa fa-phone"></i>: +54 9 343-5064897<br>
                          <i class="fa fa-envelope"></i>: <a href="mailto:[email protected]">[email protected]</a>
                       </address>
                    </div>
                    <div id="social-icons" class="col-xs-6 col-sm-3 col-sm-push-4">
                        <div class="nav navbar-nav" style="padding: 10px 10px;">
                            <a class="btn btn-social-icon btn-facebbok" href="http://www.facebook.com/orquestatipicalayumba/?ref=bookmarks" target="_blank"><i class="fa fa-facebook"></i></a>
                            <a class="btn btn-social-icon btn-twitter" href="http://twitter.com/PetruccelliFac2" target="_blank"><i class="fa fa-twitter"></i></a>
                            <a class="btn btn-social-icon btn-youtube" href="https://www.youtube.com/channel/UCDz466X5LlESY5SJ_tlLmjA" target="_blank"><i class="fa fa-youtube"></i></a>
                            <a class="btn btn-social-icon" href="mailto:[email protected]"><i class="fa fa-envelope-o"></i></a>
                        </div>
                    </div>
                    <div class="col-xs-12">
                        <p style="text-align: center; font-weight: bolder;">&copy; Copyright 2016 Tango Infinito</p>
                    </div>
                </div>
            </div>
        </footer>

        <script src="js/jquery-3.1.1.min.js"></script>
        <script src="js/bootstrap.min.js"></script>
        <script src="js/carousel.js"></script>
        <script src="js/send-email.js"></script>
        <script src="js/appear-navbar-productos.js"></script>
        <script>
            $(document).ready(function() {
                //Tomo el nodo al que luego le agrego li según correspondan
                //<li class="dropdown-header">Rubro</li> Para los rubros
                //<li><a href="#tipo">Tipo</a></li> 
                var lista = $("ul.dropdown-menu");

                var navbarProductosLista = undefined;

                //Chequea hasta que la variable navbarList de ProductosController esta asignada
                function checkVariable() {
                    //Toma la variable navbarList del scope de ProductosController
                    //para agregar la lista de manera dinámica
                    navbarProductosLista = angular.element($("[ng-controller=ProductosController]")).scope().navbarList;

                    if(navbarProductosLista != undefined) {
                        for(var i = 0; i < navbarProductosLista.length; i++) {
                            if(navbarProductosLista[i].isHeader === true) {
                                var nodo = $("<li><a href='productos.html#" + navbarProductosLista[i].descripcion.toLowerCase() + "'>" +  navbarProductosLista[i].descripcion + "</a></li>");
                                nodo.children().addClass("dropdown-header");
                                lista.append(nodo);
                            }
                            else {
                                var nodo = $("<li><a href='productos.html#" + navbarProductosLista[i].descripcion.toLowerCase() + "'>" +  navbarProductosLista[i].descripcion + "</a></li>");
                                lista.append(nodo);
                            }
                        }

                        clearInterval(id);
                    }

                    $("ul li:first-child")
                    .addClass("active");

                    $(".tab-content div:first-child")
                    .addClass("in active");
                };

                var id = setInterval(checkVariable, 250);
            });
        </script>
    </body>
</html>

ProductosController.js:

(function(){

    var module = angular.module("tangoInfinito");

    var ProductosController = function($scope, ProductosService) {

        function idAsignado(lista, producto) {
            var listaLength = lista.length;
            for (var i = 0; i < listaLength; i++) {
                if (lista[i].producto === producto) {
                    return true;
                }
            }
            return false;
        };

        var listaIdAccordions = [];
        var accordionNumber = 1;
        $scope.accordionId = function(prodNombre) {
            if(!idAsignado(listaIdAccordions, prodNombre)) {
                var accId = "accordion" + accordionNumber;
                accordionNumber++;
                listaIdAccordions.push({
                    producto: prodNombre,
                    id: accId
                });
                //console.log(listaIdAccordions);
                //console.log("Nuevo id asignado");
                return accId;
            }
            else {
                var largo = listaIdAccordions.length;
                for(var i = 0; i < largo; i++) {
                    if(listaIdAccordions[i].producto === prodNombre) {
                        //console.log(listaIdAccordions);
                        //console.log("Id devuelto");
                        return listaIdAccordions[i].id;
                    }
                }
            }
        };

        var armarLista = function($rubros, $tipos) {
            var lista = [];
            var rubrosTemp = $rubros.slice(0);
            var tiposTemp = $tipos.slice(0);

            for(var i = 0; i < rubrosTemp.length; i++) {

                var rubro = rubrosTemp[i].rubro.toUpperCase();

                lista.push( {descripcion: rubro, isHeader: true} ); 
                for(var j = 0; j < tiposTemp.length; j++) {
                    if(tiposTemp[j].rubro === rubrosTemp[i].rubro) {
                        lista.push( {descripcion: tiposTemp[j].tipo, isHeader: false} );
                    }
                }
            }

            return lista;
        };

        var getDatosFromService = function() {
            ProductosService.getDatos().success(function(response) {

                //Lista para armar el menu desplegable (menu productos) de la barra de navegación
                //Esta lista es tomada por index.html y productos.html 
                //(en un script al final de la página) para armar el menu dinamicamente
                $scope.navbarList = armarLista(response["rubros"], response["tipos"]);
                $scope.productos = response["productos"];
                $scope.rubros = response["rubros"];
                $scope.tipos = response["tipos"];
            });
        }

        getDatosFromService();
    };

    module.controller("ProductosController", ProductosController);

})();

IdFilter.js:

(function() {

    var module = angular.module("tangoInfinito");

    var IdFilter = function() {
        return function(item) {
            var id = "";
            id = item.toLowerCase();
            id = id.replace(/\s/g, "-");
            return id;
        };
    };

    module.filter("IdFilter", IdFilter);

})();

And the behavior of which I speak:

EDIT: I was seeing that for some reason when I click on a title, the class panel-heading has the class collapse , but not the in , so the property display becomes none , and a style="height: 20px;" is also added, which I assume should be through JavaScript , since at the beginning the element does not have it. But I can not tell from where these changes come ...

    
asked by Augusto Herbel 09.12.2016 в 08:30
source

2 answers

0

Well, I found the reason for the error ... The reason is a script I did at the bottom of the page to do the dropdown-list of the navigation bar and to put the classes active in to the first tabs of each item but it turns out that it also adds the active in classes to the div with the panel-heading class causing the plugin to behave erroneously. The solution was to get the class active-in from the div with the class panel-heading with the method removeClass of jQuery . I leave the solution:

    <script>
        $(document).ready(function() {
            //Tomo el nodo al que luego le agrego li según correspondan
            //<li class="dropdown-header">Rubro</li> Para los rubros
            //<li><a href="#tipo">Tipo</a></li> 
            var lista = $("ul.dropdown-menu");

            var navbarProductosLista = undefined;

            //Chequea hasta que la variable navbarList de ProductosController esta asignada
            function checkVariable() {
                //Toma la variable navbarList del scope de ProductosController
                //para agregar la lista de manera dinámica
                navbarProductosLista = angular.element($("[ng-controller=ProductosController]")).scope().navbarList;

                if(navbarProductosLista != undefined) {
                    for(var i = 0; i < navbarProductosLista.length; i++) {
                        if(navbarProductosLista[i].isHeader === true) {
                            var nodo = $("<li><a href='productos.html#" + navbarProductosLista[i].descripcion.toLowerCase() + "'>" +  navbarProductosLista[i].descripcion + "</a></li>");
                            nodo.children().addClass("dropdown-header");
                            lista.append(nodo);
                        }
                        else {
                            var nodo = $("<li><a href='productos.html#" + navbarProductosLista[i].descripcion.toLowerCase() + "'>" +  navbarProductosLista[i].descripcion + "</a></li>");
                            lista.append(nodo);
                        }
                    }
                    clearInterval(id);
                }

                $("ul li:first-child")
                .addClass("active");

                //Esta es la linea que causa el error
                $(".tab-content div:first-child")
                .addClass("in active");

                //Y esta es la linea que lo soluciona
                $(".panel-heading")
                .removeClass("in active");
            };

            var id = setInterval(checkVariable, 250);
        });
    </script>
    
answered by 17.12.2016 / 04:27
source
1

To make a div (in this case a tab) have unique hidden content must have something in common. What I mean is that if a producto has integrantes these integrantes have to have something in common with that product.

Create the following example:

$scope.productos = [
{ 
    nombre: "Producto 1", 
    id: 1, 
    integrantes: [
        { nombre: "Integrante 1", edad: 17, correo: "[email protected]" }, 
        { nombre: "Integrante 2", edad: 40, correo: "[email protected]" }, 
        { nombre: "Integrante 3", edad: 22, correo: "[email protected]" }
    ] 
},
{   nombre: "Producto 2", 
    id: 2, 
    integrantes: [
        { nombre: "Integrante 4", edad: 20, correo: "[email protected]" }, 
        { nombre: "Integrante 5", edad: 35, correo: "[email protected]" }, 
        { nombre: "Integrante 6", edad: 60, correo: "[email protected]" }
    ] 
},
{   nombre: "Producto 3", 
    id: 3, 
    integrantes: [
        { nombre: "Integrante 7", edad: 80, correo: "[email protected]" }, 
        { nombre: "Integrante 8", edad: 18, correo: "[email protected]" }, 
        { nombre: "Integrante 9", edad: 45, correo: "[email protected]" }
    ] 
}];

As you can see, each product has its arrangement of members.

Also create a function called $scope.mostrarHijos and% $scope.isHijoShow

$scope.mostrarHijos = function(integrante) {
    if ($scope.isHijosShow(integrante)) {
        $scope.shownHijos = null;
    } else {
        $scope.shownHijos = integrante;
    }
};
$scope.isHijosShow = function(integrante) {
    return $scope.shownHijos === integrante;
};

In the visual part simply:

<div ng-repeat="producto in productos">
   <h2>{{producto.nombre}}</h2>
   <div ng-repeat="integrante in producto.integrantes" ng-click="mostrarHijos(integrante)">
       <p>{{integrante.nombre}}</p>
       <div ng-show="isHijosShow(integrante)" style="margin-left:40px;">
         <p> Edad : {{integrante.edad}}</p>
         <p> Correo : {{integrante.correo}}</p>
       </div>
   </div>  
</div>

I leave you a codepen of this code running codepen

    
answered by 09.12.2016 в 15:15