Cum să filtrezi un al doilea dropdown list în funcție de valoarea selectată în primul

5 feb. 2015, 05:56:23
Vizualizări: 13.9K
Voturi: 0

Am un tabel cu două dropdown liste. Prima reprezintă brand-ul, care este un custom post type WordPress. A doua reprezintă aromele, care este de asemenea un custom post type. Brand-ul este părintele aromelor. Când selectez un brand, trebuie să actualizez a doua listă dropdown cu aromele acelui brand (copiii acestuia).

Am creat shortcode-uri pentru liste și acestea sunt completate corect. Dar nu știu cum să filtrez a doua listă dropdown când prima se schimbă.

Iată tabelul meu:

<table id="fla_inf" width="100%">
<tbody>
<tr>
<th class="tab_header" colspan="6">Arome și Aditivi</th>
</tr>
<tr>
<th class="tab_header_nam">Brand Aromă</th>
<th class="tab_header_nam">Nume Aromă</th>
<th class="tab_header_nam">Tip picurător</th>
<th class="tab_header_nam">Unitate Cantitate</th>
<th class="tab_header_nam">Cantitate</th>
<th class="tab_header_nam">Adaugă/Șterge rând</th>
</tr>
<tr class="flavors">
<td>[brand_list]</td>
<td>[flavor_list]</td>
<td><select id="dropper0" class="dropper">
<option selected="selected" value="type1">tip 1</option>
<option value="type2">tip 2-3</option>
</select></td>
<td><select id="qtyunit0" class="qtyunit">
<option value="ml">ml</option>
<option value="drops">picturi</option>
<option selected="selected" value="perc">%</option>
</select></td>
<td><input id="quantity0" class="quantity" type="number" /></td>
<td><input class="addline" src="http://spitilab.com/wp-content/uploads/2015/01/add.png" type="image" /><input class="remline" src="http://spitilab.com/wp-content/uploads/2015/01/delete.png" type="image" /></td>
</tr>
</tbody>
</table>

Iată shortcode-urile mele:

function GetBrandList() {
    $brands = wp_dropdown_pages(array('id'=>'marque0','post_type' => 'marque-type','echo'=>0));
    return $brands;
} 

function GetFlavorList() {
   $flavors = wp_dropdown_pages(array('id'=>'arome0','post_type'=>'aromes-type','echo'=>0));
   return $flavors;
}   

add_shortcode('brand_list', 'GetBrandList');
add_shortcode('flavor_list', 'GetFlavorList');

Iată actualizarea mea:

Am adăugat următoarele în functions.php

add_action( 'wp_ajax_brand_children', 'GetBrandChildren');
add_action( 'wp_ajax_nopriv_brand_children', 'GetBrandChildren');

function GetBrandChildren($parent_id,$id) {
   $children = wp_dropdown_pages(array('id'=>'arome$id','post_type'=>'aromes-type','child_of'=>$parent_id,'echo'=>0));
   return $children;
}

și iată jQuery-ul meu:

//La schimbarea brand-ului, actualizează lista de arome
$(document).on('change', "select[id^='marque']", function() {
        var $brandid =  $(this).val();
        var $brand_dd_id = $(this).attr('id');
        var $flav_dd_id = $brand_dd_id.substr($brand_dd_id.length-1);
        $("#arome"+$flav_dd_id).empty();

        //Fă cerere AJAX, folosind valoarea selectată ca GET
        $.ajax({data: '{"parent_id":"' + $brandid + '","id":"'+ $flav_dd_id +'","action":"brand_children"}',
                success: function(output) {
                    alert(output);
                    $("#arome"+$flav_dd_id).html(output);
                }
         });
});

Totuși, lista mea dropdown de arome rămâne goală. În output-ul afișat în alert, întreaga pagină HTML pare să fie returnată.

ACTUALIZARE:

add_action( 'wp_ajax_brand_children', 'GetBrandChildren');
add_action( 'wp_ajax_nopriv_brand_children', 'GetBrandChildren');

function GetBrandChildren() {
   $parent_id = $_POST['brandid'];
   $id = $_POST['flav_dd_id'];
   echo wp_dropdown_pages(array("id"=>"arome$id",'post_type'=>'aromes-type','child_of'=>$parent_id,'echo'=>0));
  //ob_clean();
  //echo "working";
  wp_die();
}

// sunt necesare aceste două linii pentru a localiza admin-ajax.php în jQuery
wp_enqueue_script( 'my-ajax-request', get_template_directory_uri() . '/js/ajax.js', array( 'jquery' ) );
wp_localize_script( 'my-ajax-request', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );

jQuery:

//La schimbarea brand-ului, actualizează lista de arome
$(document).on('change', "select[id^='marque']", function() {
        var $brandid =  $(this).val();
        var $brand_dd_id = $(this).attr('id');
        var $flav_dd_id = $brand_dd_id.substr($brand_dd_id.length-1);
        $("#arome"+$flav_dd_id).empty();

        //Fă cerere AJAX
        $.ajax({
                url: MyAjax.ajaxurl,
                data: {
                        'parent_id': $brandid,
                        'id': $flav_dd_id,
                        'action': 'brand_children'
                      },
                success: function(output) {
                    console.log(output);
                    $("#arome"+$flav_dd_id).html(output);
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    alert(xhr.status + " "+ thrownError);
        }});
});

acum a doua mea listă dropdown este actualizată.

0
Toate răspunsurile la întrebare 1
10

Vei dori să folosești Ajax pentru a realiza acest lucru, astfel încât al doilea meniu derulant să se încarce după ce primul a fost selectat. Nu sunt sigur despre câteva lucruri pe care le ai acolo, așa că voi scrie codul pentru tine - poate fi necesar să modifici ceva aici sau acolo, voi încerca să îl completez cât mai bine posibil. Primul lucru de făcut este să configurezi o acțiune Ajax. Aceasta ar trebui să fie configurată într-un plugin, ideal. Funcția is_admin() este folosită deoarece atunci când cererea Ajax este trimisă de la pagina cu meniul tău derulant, aceasta va rula sub administrare. Dacă simți că lucrăm invers, este doar o chestiune de ou și găină. Ce a venit mai întâi, cererea sau handler-ul... handler-ul, desigur, motiv pentru care încep de aici.

<?php
if ( is_admin() ) {
    // Adăugăm 2 acțiuni, prima pentru utilizatorii autentificați, a doua pentru vizitatori.
    add_action( 'wp_ajax_dynamic_dropdown', 'dynamic_dropdown_func' );
    add_action( 'wp_ajax_nopriv_dynamic_dropdown', 'dynamic_dropdown_func' );
}

// Aceasta este funcția care va gestiona Cererea/Răspunsul Ajax
function dynamic_dropdown_func () {
    global $wpdb;
    if (isset($_POST['value'])) {
        $selected_option = $_POST['value'];
        // Acesta va fi al doilea meniu derulant, acesta va fi returnat într-o cerere Ajax
        $args = array(
            'show_option_none' => __( 'Alege altul' ),
            'class' => 'dropper',
            'id' => 'dropper0',
            'orderby' => 'ID',
            'order' => 'ASC',
            'hide_empty' => 0,
            'hierarchical' => 1,
            'depth' => 1,
            // Aceasta este ceea ce ne va obține copiii primei opțiuni selectate
            'child_of' => (int)$selected_option,
            'echo' => 0,
            // Asigură-te că înlocuiești această constantă cu taxa ta personalizată
            'taxonomy' => MY_CUSTOM_TAX,
        );

        $my_second_dropdown = wp_dropdown_categories( $args );
        // Dacă dorești să faci vreun preg_replace sau str_replace, fă-o aici înainte de ob_clean() de mai jos         
    }
    // ob_clean este pentru a preveni erori, echiouri sau orice altceva care a fost afișat până în acest punct în instanța Ajax WP care ar putea strica returnarea ta.
    ob_clean();
    return $my_second_dropdown;
    wp_die();
}

OK, acum vom face partea de front-end a codului. Aceasta este partea pe care o va vedea utilizatorul. Când vor declanșa Cererea Ajax, la răspuns, al doilea meniu derulant ar trebui să se încarce. În mod normal, ai localiza un fișier JavaScript cu variabila pentru ajax_url și orice alte valori PHP de care avem nevoie în JS pentru a trimite cereri Ajax către WP. Vom trișa puțin și vom afișa scriptul direct pe pagină și vom obține același rezultat. Doar asigură-te că afișezi acest script la sfârșitul body-ului, ideal, altfel va trebui să adaugi o funcție document ready, nu ar strica oricum.

function my_frontend_javascript () {
    $ajax_url = admin_url( 'admin-ajax.php' );
    $javascript = "
        <script>
            var ajaxUrl = {$ajax_url},
            // Acum să luăm meniurile noastre derulante
                dropdownArome   = jQuery('#arome0'),
                dropdownDropper = jQuery('#dropper0');

            if (dropdownArome.length && dropdownDropper.length) {
                // Bun, elementele noastre există
                dropdownArome.on('change', function (e) {
                    var value = e.target.selectedOptions[0].value,
                        success,
                        data;
                    if (!!value) {
                        // În regulă, să trimitem acea valoare către scriptul nostru Ajax, observă că acțiunea este aceeași cu hook-ul de acțiune Ajax pe care l-am folosit mai devreme
                        data = {
                            'my_value' : value,
                            'action'   : 'dynamic_dropdown'
                        };
                        success = function ( response ) {
                            // Acest răspuns va conține <option>-urile noastre
                            dropdownDropper.html( response );
                        };
                        jQuery.post( ajaxUrl, data, success );
                    }
                });
            }
        </script>";
    return $javascript;
}

/** Aici construim site-ul/formularul/meniurile derulante */

$args = array(
    'show_option_none' => __( 'Alege unul' ),
    'class' => 'arome',
    'id' => 'arome0"',
    'orderby' => 'ID',
    'order' => 'ASC',
    'hide_empty' => 0,
    'hierarchical' => 1,
    'depth' => 1,
    'echo' => 0,
    // Asigură-te că înlocuiești această constantă
    'taxonomy' => MY_CUSTOM_TAX,
);

$my_first_dropdown = wp_dropdown_categories( $args );

// În regulă, acum afișăm cele 2 meniuri derulante, apoi JavaScript-ul din funcția pe care am scris-o mai sus
echo $my_first_dropdown;
echo '<br /><div id="dropper0-container"></div><br />';
echo my_frontend_javascript();

/** Asta ar trebui să fie tot! Cum am spus, va trebui să ajustezi unele opțiuni pentru a se potrivi site-ului tău și implementării tale. */

Deci, așa ai putea face ceea ce încerci să realizezi, într-unul dintre cele mai simple moduri posibile. Spun simplu pentru că nu am făcut nicio validare, nonce, am presupus practic că totul a mers bine. Aș sugera să citești mai multe despre Ajax în WP, chiar dacă știi deja câteva lucruri, nu strică niciodată să știi mai mult. Sper că acest cod îți va funcționa bine cu unele ajustări.

http://codex.wordpress.org/AJAX_in_Plugins

http://www.smashingmagazine.com/2011/10/18/how-to-use-ajax-in-wordpress/

5 feb. 2015 07:37:12
Comentarii

Salut oneThingSimple,

Nu mă așteptam la un răspuns atât de complet, îți mulțumesc foarte mult că ți-ai luat timp să mi-l explici. Sunt foarte nou în ajax, aceasta este de fapt prima dată când am nevoie să-l folosesc. Voi încerca să adaptez răspunsul tău la ceea ce am nevoie, chiar mă ajută foarte mult.

Mulțumesc din nou.

Cyrille

user3515709 user3515709
5 feb. 2015 17:10:40

@user3515709 În regulă, nicio problemă. Ajax poate fi puțin complicat la început. Ar fi bine să te familiarizezi cu modul în care funcționează Obiectul Ajax din jQuery. Acesta este obiectul pe care îl folosim în principal în WP pentru a trimite cereri asincrone. Ca developer, aș spune că jQuery merită singur doar pentru Obiectul Ajax. Dacă ai nevoie de ajutor, poți să mă contactezi, voi încerca să te ajut să treci mai ușor peste această etapă, deoarece va fi complex până când vei înțelege întregul proces, apoi va deveni ca orice altceva. Deci dacă te frustrezi, dă-mi de știre.

OnethingSimple OnethingSimple
5 feb. 2015 18:36:14

Am actualizat codul meu, am o problemă cu output-ul. Probabil ceva am greșit.

user3515709 user3515709
5 feb. 2015 18:45:59

@user3515709 Voi termina cu munca în 4 ore. Apoi, dacă vrei să mă uit la cod, pot să fac asta cu tine. Încerc să te ajut să-l faci funcțional. Fie în camera de chat de aici de pe stackexchange, fie poți să-mi trimiți un e-mail la mike@stayshine.com și putem discuta în afara forumului. Mult succes.

OnethingSimple OnethingSimple
5 feb. 2015 19:36:13

Încă nu am reușit să rezolv. Cred că există o problemă cu codul meu, dar și cu funcția wp_dropdown_pages, deoarece am creat un shortcode pentru a afișa copiii unui părinte specific și meniul derulant afișează: "Pagina principală (fără părinte)"

user3515709 user3515709
6 feb. 2015 01:18:27

Cu funcția ta function GetBrandChildren($parent_id,$id), nu preiei efectiv datele trimise în cererea Ajax ca argumente. Trebuie să obții acele valori din array-ul $_POST. Nu este nevoie să încerci să transformi manual obiectul de date în string. Folosește pur și simplu un obiect JavaScript obișnuit. jQuery se va ocupa de serializarea argumentelor. De asemenea, nu uita să afișezi Children, nu să-l returnezi. După ce îl afișezi, folosește wp_die(), astfel încât pagina să fie completă și să fie trimisă, fără a mai adăuga alte elemente.

OnethingSimple OnethingSimple
6 feb. 2015 01:59:30

mulțumesc pentru sugestii, am modificat codul conform recomandărilor tale. Există vreo modalitate de a verifica dacă returnarea output-ului este corectă? Când afișez output-ul într-un alert, pare că întreaga pagină este returnată

user3515709 user3515709
6 feb. 2015 03:25:34

1 Nu ai URL în obiectul tău ajax, așa că nu va trimite datele nicăieri. În primul rând, ar trebui să încerci să folosești console.log(msg) în loc de alert(msg), nu doar pentru liniștea ta, dar și pentru că logarea în consolă îți oferă acces mai bun la orice ai nevoie să inspectezi, alert blochează și este doar text. O modalitate ușoară de a te asigura că handler-ele de acțiune ajax sunt apelate corect este să scrii simplu în interiorul funcției handler ob_clean();echo "I WORK!";wp_die(); Aceasta va curăța orice output generat de alte funcții și va returna doar "I WORK" la succesul $.ajax dacă întreaga cerere este configurată corect.

OnethingSimple OnethingSimple
6 feb. 2015 03:37:30

funcționează, acum dropdown-ul merge, problema rămasă este wp_dropdown_pages care nu este filtrat cu id-ul părintelui.

user3515709 user3515709
6 feb. 2015 05:32:10

@user3515709 Ar trebui să convertești $parent_id la Integer. Deci ar trebui să arate astfel 'child_of' => (int)$parent_id, Prefer să păstrez argumentele mele $args într-o variabilă decât direct în apelul funcției, astfel încât în momentele de depanare să pot folosi var_dump(), print_r(), var_export(). Acum că ai funcționalitatea AJAX, acestea vor fi returnate în răspuns, astfel încât să poți face depanarea. Eu plec pentru astăzi. Dacă reușești să o faci să funcționeze, te rog să verifici răspunsul meu. Dacă mai ai nevoie de ajutor, poți să-mi trimiți un email la adresa pe care am lăsat-o în comentarii sau putem continua discuția mâine într-un chat. Succes!

OnethingSimple OnethingSimple
6 feb. 2015 05:52:32
Arată celelalte 5 comentarii