¿Acordeón jQuery UI que mantiene abiertas varias secciones?

93

Puede que sea un idiota, pero ¿cómo se mantienen abiertas varias secciones en el acordeón de jQuery UI? Todas las demostraciones tienen solo una abierta a la vez ... Estoy buscando un sistema de tipo de menú plegable.

Caminante
fuente
18
Mire este jsfiddle.net/DkHyd
supersuphot
Bueno, ¡tu complemento es perfecto! ¡Muchas gracias, amigo!
SexyBeast

Respuestas:

94

Esto se discutió originalmente en la documentación de jQuery UI para Accordion :

NOTA: Si desea que se abran varias secciones a la vez, no use un acordeón

Un acordeón no permite que se abra más de un panel de contenido al mismo tiempo, y eso requiere mucho esfuerzo. Si está buscando un widget que permita abrir más de un panel de contenido, no lo use. Por lo general, se puede escribir con unas pocas líneas de jQuery, algo como esto:

jQuery(document).ready(function(){
  $('.accordion .head').click(function() {
      $(this).next().toggle();
      return false;
  }).next().hide();
});

O animado:

jQuery(document).ready(function(){
  $('.accordion .head').click(function() {
      $(this).next().toggle('slow');
      return false;
  }).next().hide();
});

"Puede que sea un idiota": no eres un idiota si no lees la documentación, pero si tienes problemas, generalmente se acelera la búsqueda de una solución.

MvanGeest
fuente
9
Esta solución no hace nada del estilo acordeón.
forresto
12
Además, esta no es una solución a la pregunta en absoluto. El documento de acordeón y la lista de opciones, eventos, etc. es simplemente pobre. Y en lugar de decirle al usuario "si no tenemos las opciones para usted, ¡no las use!" deberían decir "lo siento, no hay una opción para eso todavía, pero damos la bienvenida a cualquier colaborador que agregue funcionalidad a nuestro excelente complemento"
artgrohe
El texto que cité se ha eliminado de la documentación. Agregué un enlace a una versión archivada.
MvanGeest
1
Tenga en cuenta que jQuery UI Accordion hace más que crear el efecto de acordeón real. También agrega mucho marcado de accesibilidad para lectores de pantalla.
Brian
2
Esto no tiene ningún sentido. Un acordeón puede tener todos los pliegues abiertos si los brazos del músico están muy separados, todos los pliegues cerrados si las mitades del instrumento están juntas, o algo intermedio. Si las palabras significan algo, entonces el control de la interfaz de usuario del software de acordeón debería permitir cualquier combinación de paneles abiertos y cerrados.
Birdus
119

Bastante simple:

<script type="text/javascript">
    (function($) {
        $(function() {
            $("#accordion > div").accordion({ header: "h3", collapsible: true });
        })
    })(jQuery);
</script>

<div id="accordion">
    <div>
        <h3><a href="#">First</a></h3>
        <div>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.</div>
    </div>
    <div>
        <h3><a href="#">Second</a></h3>
        <div>Phasellus mattis tincidunt nibh.</div>
    </div>
    <div>
        <h3><a href="#">Third</a></h3>
        <div>Nam dui erat, auctor a, dignissim quis.</div>
    </div>
</div>
2upmedia
fuente
1
Funcionó muy bien. Añadí create: function(event) { $(event.target).accordion( "activate", false ); }para empezar a colapsar.
forresto
2
Increíble. Me alegro que funcionó para usted. :) Me gusta mantener las cosas lo más simples posible.
2upmedia
7
en jquery-ui 1.10, para comenzar a colapsar, en lugar de create: function(event) { $(event.target).accordion( "activate", false ); }establecer la opción:{active: false}
damko
16
(facepalm) acordeón separado para cada bloque.
Paul Annekov
2
Aquí está el jsFiddle que usé para probarlo jsfiddle.net/txo8rx3q/1 También agregué algo de CSS para evitar que una sección de acordeón abierta parezca seleccionada cuando está expandida
Matthew Lock
77

Publiqué esto en un hilo similar, pero pensé que podría ser relevante aquí también.

Lograr esto con una sola instancia de jQuery-UI Accordion

Como han señalado otros, el Accordionwidget no tiene una opción API para hacer esto directamente. Sin embargo, si por alguna razón debe usar el widget (por ejemplo, está manteniendo un sistema existente), es posible lograrlo usando la beforeActivateopción del controlador de eventos para subvertir y emular el comportamiento predeterminado del widget.

Por ejemplo:

$('#accordion').accordion({
    collapsible:true,

    beforeActivate: function(event, ui) {
         // The accordion believes a panel is being opened
        if (ui.newHeader[0]) {
            var currHeader  = ui.newHeader;
            var currContent = currHeader.next('.ui-accordion-content');
         // The accordion believes a panel is being closed
        } else {
            var currHeader  = ui.oldHeader;
            var currContent = currHeader.next('.ui-accordion-content');
        }
         // Since we've changed the default behavior, this detects the actual status
        var isPanelSelected = currHeader.attr('aria-selected') == 'true';

         // Toggle the panel's header
        currHeader.toggleClass('ui-corner-all',isPanelSelected).toggleClass('accordion-header-active ui-state-active ui-corner-top',!isPanelSelected).attr('aria-selected',((!isPanelSelected).toString()));

        // Toggle the panel's icon
        currHeader.children('.ui-icon').toggleClass('ui-icon-triangle-1-e',isPanelSelected).toggleClass('ui-icon-triangle-1-s',!isPanelSelected);

         // Toggle the panel's content
        currContent.toggleClass('accordion-content-active',!isPanelSelected)    
        if (isPanelSelected) { currContent.slideUp(); }  else { currContent.slideDown(); }

        return false; // Cancels the default action
    }
});

Ver una demostración de jsFiddle

Booz
fuente
6
¡Gracias! Esta es la mejor solución ya que no necesita ningún cambio en todo su entorno existente.
artgrohe
Requiere jQuery UI 1.9.0+ (Drupal 7 está bloqueado con 1.8.7)
Capi Etheriel
1
Creo que la clase activa ha cambiadoui-accordion-header-active
Tim Vermaelen
funcionó muy bien para mí, una cantidad mínima de refactorización :-)
Darkloki
buena solución, el único problema es que esta solución no acepta la opción de icono :-)
Tachyons
20

¿O incluso más simple?

<div class="accordion">
    <h3><a href="#">First</a></h3>
    <div>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.</div>
</div>    
<div class="accordion">
    <h3><a href="#">Second</a></h3>
    <div>Phasellus mattis tincidunt nibh.</div>
</div>         
<div class="accordion">
    <h3><a href="#">Third</a></h3>
    <div>Nam dui erat, auctor a, dignissim quis.</div>
</div>
<script type="text/javascript">
    $(".accordion").accordion({ collapsible: true, active: false });
</script>
Roman Gudkov
fuente
Esto es bueno en mi humilde opinión. Solución fácil y resolvió los problemas que tenía con el rendimiento de grandes conjuntos de elementos de acordeón. Sorprendentemente, la inicialización de un gran conjunto de acordeones funciona bien. ¡Gracias!
Code Noviciate
14

He hecho un complemento de jQuery que tiene el mismo aspecto de jQuery UI Accordion y puede mantener todas las pestañas \ secciones abiertas

Lo puedes encontrar aquí

http://anasnakawa.wordpress.com/2011/01/25/jquery-ui-multi-open-accordion/

funciona con el mismo marcado

<div id="multiOpenAccordion">
        <h3><a href="#">tab 1</a></h3>
        <div>Lorem ipsum dolor sit amet</div>
        <h3><a href="#">tab 2</a></h3>
        <div>Lorem ipsum dolor sit amet</div>
</div>

Código javascript

$(function(){
        $('#multiOpenAccordion').multiAccordion();
       // you can use a number or an array with active option to specify which tabs to be opened by default:
       $('#multiOpenAccordion').multiAccordion({ active: 1 });
       // OR
       $('#multiOpenAccordion').multiAccordion({ active: [1, 2, 3] });

       $('#multiOpenAccordion').multiAccordion({ active: false }); // no opened tabs
});

ACTUALIZACIÓN: el complemento se ha actualizado para admitir la opción de pestañas activas predeterminadas

ACTUALIZACIÓN: este complemento ahora está en desuso.

Anas Nakawa
fuente
Gran solución.
Trimantra Software Solution
6

En realidad, estuve buscando en Internet una solución a esto durante un tiempo. Y la respuesta aceptada da la buena respuesta "según el libro". Pero no quería aceptar eso, así que seguí buscando y encontré esto:

http://jsbin.com/eqape/1601/edit - Ejemplo en vivo

Este ejemplo extrae los estilos adecuados y agrega la funcionalidad solicitada al mismo tiempo, con espacio para escribir agregue su propia funcionalidad en cada clic del encabezado. También permite que haya varios divs entre los "h3".

 $("#notaccordion").addClass("ui-accordion ui-accordion-icons ui-widget ui-helper-reset")
  .find("h3")
    .addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-top ui-corner-bottom")
    .hover(function() { $(this).toggleClass("ui-state-hover"); })
    .prepend('<span class="ui-icon ui-icon-triangle-1-e"></span>')
    .click(function() {
      $(this).find("> .ui-icon").toggleClass("ui-icon-triangle-1-e ui-icon-triangle-1-s").end()


        .next().toggleClass("ui-accordion-content-active").slideToggle();
        return false;
    })
    .next()
      .addClass("ui-accordion-content  ui-helper-reset ui-widget-content ui-corner-bottom")
      .hide();

Código HTML:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Toggle Panels (not accordion) using ui-accordion  styles</title>

<!-- jQuery UI  |  http://jquery.com/  http://jqueryui.com/  http://jqueryui.com/docs/Theming  -->
<style type="text/css">body{font:62.5% Verdana,Arial,sans-serif}</style>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/jquery-ui.min.js"></script>


</head>
<body>

<h1>Toggle Panels</h1>
<div id="notaccordion">
  <h3><a href="#">Section 1</a></h3>
  <div class="content">
    Mauris mauris  ante, blandit et, ultrices a, suscipit eget, quam. Integer
    ut neque. Vivamus  nisi metus, molestie vel, gravida in, condimentum sit
    amet, nunc. Nam a  nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut
    odio. Curabitur  malesuada. Vestibulum a velit eu ante scelerisque vulputate.
  </div>
  <h3><a href="#">Section 2</a></h3>
  <div>
    Sed non urna. Donec et ante. Phasellus eu ligula.  Vestibulum sit amet
    purus. Vivamus hendrerit, dolor at aliquet laoreet,  mauris turpis porttitor
    velit, faucibus interdum tellus libero ac justo.  Vivamus non quam. In
    suscipit faucibus urna.
  </div>
  <h3><a href="#">Section 3</a></h3>
  <div class="top">
  Top top top top
  </div>
  <div class="content">
    Nam enim risus, molestie et, porta ac, aliquam ac,  risus. Quisque lobortis.
    Phasellus pellentesque purus in massa. Aenean in pede.  Phasellus ac libero
    ac tellus pellentesque semper. Sed ac felis. Sed  commodo, magna quis
    lacinia ornare, quam ante aliquam nisi, eu iaculis leo  purus venenatis dui.
    <ul>
      <li>List item one</li>
      <li>List item two</li>
      <li>List item  three</li>
    </ul>
  </div>
  <div class="bottom">
  Bottom bottom bottom bottom
  </div>
  <h3><a href="#">Section 4</a></h3>
  <div>
    Cras dictum. Pellentesque habitant morbi tristique  senectus et netus
    et malesuada fames ac turpis egestas. Vestibulum ante  ipsum primis in
    faucibus orci luctus et ultrices posuere cubilia Curae;  Aenean lacinia
    mauris vel est.
    Suspendisse eu nisl. Nullam ut libero. Integer  dignissim consequat lectus.
    Class aptent taciti sociosqu ad litora torquent per  conubia nostra, per
    inceptos himenaeos.
  </div>
</div>

</body>
</html>`
Donovan
fuente
5

Encontré una solución complicada. Llamemos a la misma función dos veces pero con ID diferente.

Código JQuery

$(function() {
    $( "#accordion1" ).accordion({
        collapsible: true, active: false, heightStyle: "content"
    });
    $( "#accordion2" ).accordion({
        collapsible: true, active: false, heightStyle: "content"
    });
});

código HTML

<div id="accordion1">
    <h3>Section 1</h3>
    <div>Section one Text</div>
</div>
<div id="accordion2">   
    <h3>Section 2</h3>
    <div>Section two Text</div>
</div>
SpritsDrácula
fuente
2
Es mejor ir con un solo selector basado en lo classsugerido por otros, esto significa que no se repite ( DRY )
Scotty.NET
4

Simple, cree múltiples div accordian cada uno representando una etiqueta de ancla como:

<div>
<div class="accordion">
<a href = "#">First heading</a>
</div>
<div class="accordion">
<a href = "#">First heading</a>
</div>
</div>

Agrega algo de marcado. Pero funciona como un profesional ...

Azeem
fuente
4

Simple: active el acordeón a una clase y luego cree divs con esto, como múltiples instancias de acordeón.

Me gusta esto:

JS

$(function() {
    $( ".accordion" ).accordion({
        collapsible: true,
        clearStyle: true,
        active: false,
    })
});

HTML

<div class="accordion">
    <h3>Title</h3>
    <p>lorem</p>
</div>
<div class="accordion">
    <h3>Title</h3>
    <p>lorem</p>
</div>
<div class="accordion">
    <h3>Title</h3>
    <p>lorem</p>
</div>

https://jsfiddle.net/sparhawk_odin/pm91whz3/

Giovan Cruz
fuente
1
Probé todas las respuestas en el hilo y esto funciona mejor. Con las últimas jquery y jqueryUI, ahora hay muchos problemas de estilo con otras soluciones. Aquí está la actualización de 2017 jsfiddle.net/rambutan2000/eqbbgb7g
Geordie
@Geordie Me alegro de que haya ayudado.
Giovan Cruz
2

Simplemente llame a cada sección del acordeón como su propio acordeón. activo: n será 0 para el primero (por lo que se mostrará) y 1, 2, 3, 4, etc. para el resto. Como cada uno es su propio acordeón, todos tendrán solo una sección, y el resto se colapsará para comenzar.

$('.accordian').each(function(n, el) {
  $(el).accordion({
    heightStyle: 'content',
    collapsible: true,
    active: n
  });
});
Funkodebat
fuente
Tenga en cuenta que esto ya se ha sugerido en la respuesta de 2upmedia a continuación
Boaz
2

Aún más simple, póngalo etiquetado en el atributo de clase de cada etiqueta li y haga que jquery recorra cada li para inicializar el acordeón.

Mikey
fuente
1

Sin el acordeón jQuery-UI, uno puede simplemente hacer esto:

<div class="section">
  <div class="section-title">
    Section 1
  </div>
  <div class="section-content">
    Section 1 Content: Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.
  </div>
</div>

<div class="section">
  <div class="section-title">
    Section 2
  </div>
  <div class="section-content">
    Section 2 Content: Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.
  </div>
</div>

Y js

$( ".section-title" ).click(function() {
    $(this).parent().find( ".section-content" ).slideToggle();
});

https://jsfiddle.net/gayan_dasanayake/6ogxL7nm/

Gayan Dasanayake
fuente
0

abrir jquery-ui - *. js

encontrar $.widget( "ui.accordion", {

encontrar _eventHandler: function( event ) {dentro

cambio

var options = this.options,             active = this.active,           clicked = $( event.currentTarget ),             clickedIsActive = clicked[ 0 ] === active[ 0 ],             collapsing = clickedIsActive && options.collapsible,            toShow = collapsing ? $() : clicked.next(),             toHide = active.next(),             eventData = {
                oldHeader: active,
                oldPanel: toHide,
                newHeader: collapsing ? $() : clicked,
                newPanel: toShow            };

a

var options = this.options,
    clicked = $( event.currentTarget),
    clickedIsActive = clicked.next().attr('aria-expanded') == 'true',
    collapsing = clickedIsActive && options.collapsible;

    if (clickedIsActive == true) {
        var toShow = $();
        var toHide = clicked.next();
    } else {
        var toShow = clicked.next();
        var toHide = $();

    }
    eventData = {
        oldHeader: $(),
        oldPanel: toHide,
        newHeader: clicked,
        newPanel: toShow
    };

antes de active.removeClass( "ui-accordion-header-active ui-state-active" );

agregar if (typeof(active) !== 'undefined') {y cerrar}

disfrutar

alex
fuente
-1

Solo usa jquery each () función;

$(function() {
    $( ".selector_class_name" ).each(function(){
        $( this ).accordion({
          collapsible: true, 
          active:false,
          heightStyle: "content"
        });
    });
});
Mamba negro
fuente