Desplegable de categorías multinivel

27 feb 2011, 06:19:16
Vistas: 15.1K
Votos: 3

Estoy usando WordPress como CMS y me gustaría tener categorías seleccionables desde múltiples opciones, es decir <option>.

Ejemplo visual de desplegable de categoríasEjemplo de selección jerárquica

Como ejemplo de uso: El primer desplegable contendría las categorías padres. Luego, después de seleccionar el padre, aparecería un segundo desplegable con las categorías hijas. Hay algunos plugins disponibles en Wordpress.org pero todos parecen estar rotos o desactualizados. Agradecería cualquier ayuda.

Plugin roto http://wordpress.org/extend/plugins/ajax-category-dropdown/

El código que estoy usando de wordpress.org

<form action="<?php bloginfo('url'); ?>/" method="get">
    <?php
    // Mostrar desplegable de categorías con parámetros específicos
    $select = wp_dropdown_categories('orderby=name&echo=0&depth=0&hierarchical=1&exclude=5,4');
    // Añadir evento onchange al select
    $select = preg_replace("#<select([^>]*)>#", "<select$1 onchange='return this.form.submit()'>", $select);
    echo $select;
    ?>
    <noscript><input type="submit" value="Ver" /></noscript>
</form>
0
Todas las respuestas a la pregunta 2
7
function parent_child_cat_select() { ?>
        <script type="text/javascript">
        /* <![CDATA[ */
            jQuery(document).ready(function() {     
                jQuery('#parent_cat').change(function(){
                    var parentCat=jQuery('#parent_cat').val();
                    // llamada ajax
                    jQuery.ajax({
                        url:"/wp-admin/admin-ajax.php",
                        type:'POST',
                        data:'action=category_select_action&parent_cat_ID=' + parentCat,
                        success:function(results)
                        {
                        jQuery("#sub_cat_div").html(results);
                        }
                     });
                });         
            });     
        /* ]]> */
        </script>

        <form action="<?php bloginfo('url'); ?>/" method="get">

        <div id="parent_cat_div"><?php wp_dropdown_categories("show_option_none=Selecciona categoría padre&orderby=name&depth=1&hierarchical=1&id=parent_cat"); ?></div>

        <div id="sub_cat_div"><select name="sub_cat_disabled" id="sub_cat_disabled" disabled="disabled"><option>¡Primero selecciona una categoría padre!</option></select></div>

        <div id="submit_div"><input type="submit" value="Ver" /></div>

        </form>
<?php }

function implement_ajax() {
    $parent_cat_ID = $_POST['parent_cat_ID'];
    if ( isset($parent_cat_ID) )
    {
        $has_children = get_categories("parent=$parent_cat_ID");
        if ( $has_children ) {
            wp_dropdown_categories("orderby=name&parent=$parent_cat_ID");
        } else {
            ?><select name="sub_cat_disabled" id="sub_cat_disabled" disabled="disabled"><option>¡No hay subcategorías!</option></select><?php
        }
        die();
    } // end if
}
add_action('wp_ajax_category_select_action', 'implement_ajax');
add_action('wp_ajax_nopriv_category_select_action', 'implement_ajax');// para usuarios no logueados

// esto es opcional, solo si no estás usando jQuery  
function load_jquery() {
    wp_enqueue_script('jquery');            
}     
add_action('init', 'load_jquery');

Para mostrar los menús desplegables usa la función parent_child_cat_select().

<?php parent_child_cat_select(); ?>
23 abr 2011 21:42:18
Comentarios

add_action('wp_ajax_category_select_action', 'implement_ajax');//para usuarios que no han iniciado sesión. Debería ser add_action( 'wp_ajax_nopriv_category_select_action', 'implement_ajax' );

Cristian Cristian
24 abr 2011 19:32:10

@Wild Phoenix sí, tienes razón. Lo corregí en mi publicación.

Ján Bočínec Ján Bočínec
24 abr 2011 19:36:06

¡Gracias! Sin embargo, estoy recibiendo un mensaje que indica que no hay categorías hijas cuando en realidad hay varias.

Zach Shallbetter Zach Shallbetter
25 abr 2011 21:54:04

@Zach ¿tienes publicaciones asignadas a estas categorías hijas? También ten en cuenta que esta configuración solo listará subcategorías estrictamente relacionadas.

Ján Bočínec Ján Bočínec
26 abr 2011 01:08:59

@JohnnyPea Sí, cada una tiene varias publicaciones personalizadas. Estoy de acuerdo con que liste solo categorías estrictamente relacionadas. Por ejemplo, Cámara tendría cada una de las categorías a las que he asignado productos. Actualicé la publicación con una captura de cómo se ve mi sección de categorías. Gracias de nuevo por tu ayuda.

Zach Shallbetter Zach Shallbetter
26 abr 2011 01:13:36

@Zach ¿Usas algún plugin de caché? ¿Lo probaste en otro navegador de internet? (intenta limpiar tu caché) ¿Copiaste mi código tal cual estaba? (prueba a copiar el código nuevamente) ¿No tienes algún plugin o funciones del tema que podrían interactuar con las categorías o filtrarlas de alguna manera? - puedes intentar desactivar todos los plugins y configurar el tema por defecto para ver si funciona...a mí me funciona sin plugins activos y con el tema por defecto TwentyTen

Ján Bočínec Ján Bočínec
26 abr 2011 02:01:03

No, nunca lo he instalado aquí. Sí, lo probé en tres navegadores diferentes. Desactivé todos los plugins de mi sitio. Lo probaré en otro sitio para ver si puedo identificar el problema. Gracias.

Zach Shallbetter Zach Shallbetter
26 abr 2011 02:22:10
Mostrar los 2 comentarios restantes
22
<form action="<?php echo remove_query_arg(array('mycat_go', 'cat')); ?>" method="get">
    <?php
    // obtener categoría seleccionada y hacer algunas inicializaciones
    if (isset($_REQUEST['cat'])) $_REQUEST['mycat_go'] = $_REQUEST['cat'];
    $selected = $_REQUEST['mycat_go'];
    $selects = array();
    $last = 0;
    $top = false;
    $i = 0;
    // básicamente, estamos iterando desde la selección hacia arriba a través de los padres
    // hasta que no haya más padres.
    while (!$top) {
        // preparar consulta para generar campo que contenga todas las categorías hijas
        // de la seleccionada
        $args = array(
            'name' => 'mycat_'.$i,
            'orderby' => 'name',
            'echo' => 0,
            'hierarchical' => 1,
            'exclude' => '4,5',
            'child_of' => $selected,
            'depth' => 1,
            'show_option_none' => '--seleccionar--',
            'hide_if_empty' => true,
        );
        if(!empty($last)) $args['selected'] = $last;
        // preparar siguiente iteración del bucle o detenerse si estamos mostrando hijos de 0
        if (!empty($selected)) {
            $last = $selected;
            $category = get_category($selected);
            $selected = $category->parent;
        } else {
            $top = true;
        }
        // generar salida y almacenar en orden inverso ya que vamos de abajo hacia arriba
        $select = wp_dropdown_categories($args);
        $select = preg_replace("#<option([^>]*)>#", "<option$1 onclick=\"this.parentNode.name = 'mycat_go';return this.form.submit()\">", $select);
        array_unshift($selects, $select);
        $i++;
    }
    // imprimir en pantalla
    foreach ($selects as $select) {
        echo $select;
    }
    ?>
</form>
<form action="<?php remove_query_arg(array('mycat_go', 'cat')); ?>" method="get">
    <input type="hidden" name="cat" value="<?php echo $_REQUEST['mycat_go']; ?>" />
    <input type="submit" value="Ir allí" />
</form>

Podría usar algunos ajustes, pero debería funcionar.

27 feb 2011 23:56:39
Comentarios

jaja, eso fue bastante impresionante y tiene mucho sentido! Sin embargo hay un error en la línea 15 if(!empty($last) $args['selected'] = $last; No estoy seguro de qué lo está causando.

Zach Shallbetter Zach Shallbetter
28 feb 2011 18:43:56

@Zach Shallbetter: Vaya, eso es un error tipográfico... falta el paréntesis de cierre. Lo he editado.

wyrfel wyrfel
28 feb 2011 19:23:08

Así que seguí adelante y lo agregué a la página y devolvió una lista incontable de select boxes. También tuvo un tiempo de carga enorme. Pensé que podría ser yo, así que eliminé algunas categorías y borré todo el otro código de la plantilla. No pareció resolver el problema.

Zach Shallbetter Zach Shallbetter
28 feb 2011 20:15:29

@Zach Shallbetter: Parece que la condición del bucle no se activa y sigue en bucle. Ok... hice otra edición que debería evitar que el bucle sea infinito cuando no se hace una selección inicial.

wyrfel wyrfel
28 feb 2011 20:18:41

Parece que solo muestra una única caja de selección con los valores secundarios. Además, cuando seleccionas un elemento no realiza ninguna acción.

Zach Shallbetter Zach Shallbetter
28 feb 2011 20:33:46

@Zach Shallbetter: Lo siento, mi condición original del bucle venía de un enfoque inicial diferente y luego no lo pensé bien. Edité nuevamente y añadí algunos comentarios, espero que funcione mejor.

wyrfel wyrfel
28 feb 2011 20:35:55

@Zach Shallbetter: El problema con JS debería estar resuelto ahora también.

wyrfel wyrfel
28 feb 2011 20:54:54

Me disculpo por hacerte dar vueltas. El resultado que obtengo es el mismo que tenía originalmente cuando usé el código del codex. Agrego información a la categoría y la categoría aparece en el select. La selecciono y me lleva a la página. Creo que el problema puede estar en que el menú desplegable no muestra categorías vacías.

Zach Shallbetter Zach Shallbetter
28 feb 2011 21:16:52

Además, no importa si el hijo tiene un padre, todo lo que aparecerá en el select es el hijo.

Zach Shallbetter Zach Shallbetter
28 feb 2011 21:20:32

Agregué 'hide_empty' => 0 al array y eso me permitió ver todas las categorías incluyendo las vacías. Sin embargo, no muestra un segundo select al elegir una categoría padre, simplemente va directamente a esa página.

Zach Shallbetter Zach Shallbetter
28 feb 2011 21:27:09

@Zach Shallbetter: Sí, no había pensado en eso, claro que lo haría, ya que está analizando el parámetro 'cat' en la URL. Hice otra edición que debería (con suerte) evitar eso... perdón por hacerte dar vueltas. ;-)

wyrfel wyrfel
28 feb 2011 21:30:04

Ojalá esto me permitiera publicar imágenes, jeje. Así que seleccionar un elemento ahora muestra absolutamente todas las publicaciones. Tampoco muestra un segundo select cuando agrego 'hide_empty' => 0 para ver las categorías padre y seleccionar una de esas. Aún no he visto el segundo select. El problema con usar 'hide_empty' => 0 es que muestra todas las categorías en lugar de solo las padres (si eso tiene sentido).

Zach Shallbetter Zach Shallbetter
28 feb 2011 21:39:38

@Zach Shallbetter: Jaja...bueno, para variar, finalmente lo probé localmente, configuré algunas categorías y demás. Ahora...funciona, más o menos. Hay algunos problemas. No sé qué tan bien se comporta con hide_empty, pero lo básico funciona.

wyrfel wyrfel
28 feb 2011 22:10:18

Todavía no hay selección secundaria, ¿hay algo de mi parte que podría causar esto?

Zach Shallbetter Zach Shallbetter
28 feb 2011 23:32:09

Sí, cuando selecciono la categoría en el menú desplegable me lleva a la lista completa de entradas que pertenecen a ella.

Zach Shallbetter Zach Shallbetter
28 feb 2011 23:41:46

@Zach Shallbetter: ¡Argh, hoy no es mi día en absoluto... algo salió mal al pegar el código de vuelta. Asegúrate de que sean 2 formularios separados (faltaba el último fragmento).

wyrfel wyrfel
1 mar 2011 00:17:49

También considera que esto es más bien una solución rápida para inspirarse. Debería hacerse de mejor manera, como recargar solo esa parte del formulario con AJAX en lugar de recargar toda la página y cuando haya una sola entrada debería seleccionarse automáticamente, etc.

wyrfel wyrfel
1 mar 2011 00:20:10

Si reemplazas todo tu fragmento de código con el fragmento de código completo de arriba, ya no debería redirigir a la página de categorías.

wyrfel wyrfel
1 mar 2011 00:22:04

Dios, simplemente no sé qué estoy haciendo mal aquí. He creado una página completamente básica. Agrego una copia exacta del código anterior. Cuando selecciono "modelos" del menú desplegable (tiene 4 subcategorías). Inmediatamente salta a /?mycat_go=112 sin mostrar una selección secundaria. Gracias de nuevo por toda tu ayuda wyrfel.

Zach Shallbetter Zach Shallbetter
1 mar 2011 18:13:12

Quizás hay un malentendido...se supone que debe recargar la página con ese parámetro. Así es como funciona. No está impulsado por AJAX o JS. Simplemente recarga la página con la categoría seleccionada como parámetro y luego se redibuja al cargar la página.

wyrfel wyrfel
1 mar 2011 21:05:35

Ahh, creo que lo entiendo...debe ser el parámetro action en los formularios...mira la edición.

wyrfel wyrfel
1 mar 2011 21:07:00

Sí, lamentablemente lo he intentado un par de veces y no he conseguido que funcione correctamente. Cuando selecciono una categoría del menú desplegable, se queda colgado y no se actualiza mostrando la selección secundaria.

Zach Shallbetter Zach Shallbetter
3 mar 2011 00:03:03
Mostrar los 17 comentarios restantes