Jump to content

chained selects for WordPress


lional

Recommended Posts

Hi All

I am trying to write chained selects for a WordPress plugin I am busy with. I have been struggling with it for a few days because my ajax is very weak.

This is my file plugin file:

<?php
function js_enqueue_scripts() {
  wp_enqueue_script ("nova-ajax-handle", get_stylesheet_directory_uri() . "js/nova-ajax.js", array('jquery')); 
  //the_ajax_script will use to print admin-ajaxurl in custom ajax.js
  wp_localize_script('nova-ajax-handle', 'nova_ajax_script', array('ajaxurl' =>admin_url('admin-ajax.php')));
} 
add_action("wp_enqueue_scripts", "js_enqueue_scripts");
?>
<select name="drop_bl" id="drop_bl" style="margin-top:0px;margin-left:35px">
    
    <option value="" selected="selected" disabled="disabled">Select a Province</option>
    
    <?php getTierBLOne(); ?>
  
  </select> 
  
  <span id="wait_bl" style="display: none;">
  
  </span>
  <span id="result_bl" style="display: none;"></span>

My Javascript file looks like this:

$(document).ready(function() {
    $('#wait_bl').hide();
    $('#drop_bl').change(function(){
    $('#wait_bl').show();
    $('#result_bl').hide();
        $.ajax({
            url: nova_ajax_script,ajax_url,
            type: get,
            func: "drop_bl",
            drop_var: $('#drop_bl').val()
        }), function(response) {
            $('#result_bl').fadeOut();
            setTimeout("finishAjax('result_bl', '"+escape(response)+"')", 400); 
        }
      
        return false;
    });
});

function finishAjax(id, response) {
  $('#wait_bl').hide();
  $('#'+id).html(unescape(response));
  $('#'+id).fadeIn();
}

When I select my first dropdown, it does not fire up the second one.

This is my very first attempt at WordPress development, so I might be making many errors

Thank you

Link to comment
Share on other sites

Sorry, I have another function page

<?php
//**************************************
//     Page load dropdown results     //
//**************************************
function getTierBLOne()
{
	include 'includes/conn_db.php';
	$result_query = mysqli_query($conn,"SELECT * FROM nova_tp_forex_main_cats ORDER BY forex_name ASC");

	while ($tier = mysqli_fetch_array($result_query))
		{
			echo '<option value="'.$tier['forex_id'].'">'.$tier['forex_name'].'</option>';
		}
}

//**************************************
//     First selection results     //
//**************************************
if (isset($_GET['func'])&& $_GET['func'] == 'drop_bl' ) {
   drop_1($_GET['drop_var']); 
}

function drop_1($drop_var)
{  
    include_once('includes/conn_db.php');
    
    $result_query = mysqli_query($conn,"SELECT * FROM nova_tp_forex_main_cats WHERE forex_main_cat = '$drop_var' ORDER BY forex_subcat_name");
	
	echo '<select name="drop_2" id="drop_2">
	      <option value=" " disabled="disabled" selected="selected">Choose one</option>';

		   while($drop_2 = mysqli_fetch_array($result_query)) 
			{
			  echo '<option value="'.$drop_2['forex_subcat_id'].'">'.$drop_2['forex_subcat_name'].'</option>';
			}
	
	echo '</select> ';
	

    
}


?>

So what effectively happens (or suppose to happen) is the plugin page goes to this page to pull initial drop down data, then on change the ajax calls the next function to populate the second drop down

Link to comment
Share on other sites

Few things here.

  1. I could be wrong, but I think it's too late to call the wp_enqueue_scripts hook after the template is loaded.
  2. In the JavaScript file, your AJAX url value is incorrectly formed - you're using `nova_ajax_url,ajax_url`. You need to use a period between the object and the property, not a comma.
  3. WordPress doesn't know what 'func' means as a parameter passed to the AJAX handlers - it's looking for 'action'.
  4. I don't have the slightest idea what `drop_var` is.
  5. You show a functions file, but there's no AJAX handling in what you've shown. WordPress looks for `wp_ajax_{whatever_your_action_value_is}` and `wp_ajax_nopriv_{whatever_your_action_value_is}` action hooks to handle AJAX functionality.
  6. If you're using setTimeout() to wait for a response to be returned, it's unnecessary - AJAX is asynchronous and the .done() or .fail() chained functions await the promise resolution.
Link to comment
Share on other sites

Thanks for your input, I made some alterations since my post, still not working but I think I am closer.

I moved my functions to the functions.php in my theme. Here are my two functions

function getTierBLOne()
{
	global $wpdb;
	
	$maincats = $wpdb->get_results( "SELECT * FROM nova_tp_forex_main_cats ORDER BY forex_name ASC" );
	//$result_query = mysqli_query($conn,"SELECT * FROM nova_tp_forex_main_cats ORDER BY forex_name ASC");

	//while ($tier = mysqli_fetch_array($result_query))
	foreach($maincats as $maincat) {

	
			echo '<option value="' . $maincat->forex_id .'">'.$maincat->forex_name.'</option>';
	}
}
if (isset($_GET['func'])&& $_GET['func'] == 'drop_bl' ) {
	drop_bl($_GET['drop_var']); 
 }
 
 function drop_bl($drop_var)
 {  
	global $wpdb;
	
	$subcats = $wpdb->get_results( "SELECT * FROM nova_tp_forex_main_subcats WHERE forex_main_cat = '$drop_var' ORDER BY forex_subcat_name");
	 
	 echo '<select name="drop_2" id="drop_2">
		   <option value=" " disabled="disabled" selected="selected">Choose one</option>';
 
		   foreach($subcats as $subcat) 
			 {
			   echo '<option value="'.$subcat->forex_subcat_id.'">'.$subcat->forex_subcat_name.'</option>';
			 }
	 
	 echo '</select> ';
 }

Here is the latest version of my js file

jQuery(document).ready(function() {
    jQuery('#wait_bl').hide();
    jQuery('#drop_bl').change(function(){
        alert( "Handler for .change() called." );
        jQuery('#wait_bl').show();
        jQuery('#result_bl').hide();
        jQuery.post(
            nova_ajax_script.ajax_url,
     {  action: "drop_bl",
        drop_var: jQuery('#drop_bl').val()
     }, function(response) {
        $('#result_bl').fadeOut();
        setTimeout("finishAjax('result_bl', '"+escape(response)+"')", 400); 
        },
     )}
     );
});

function finishAjax(id, response) {
    jQuery('#wait_bl').hide();
    jQuery('#'+id).html(unescape(response));
    jQuery('#'+id).fadeIn();
}

And here is my final plugin file

<?php

function js_enqueue_scripts() {
  wp_register_script('nova_ajax_script', plugins_url('js/nova-ajax.js', __FILE__), array('jquery'), null, true);
  wp_localize_script( 'nova-script', 'nova_ajax_script', array( 'ajax_url' => admin_url('admin-ajax.php')) );
  } 
  add_action( 'wp_enqueue_scripts', 'js_enqueue_scripts' );


function nova_options_page()
{
// Add top level admin menu
add_menu_page('Nova Trade Signal', 'Nova Trade Signal', 'manage_options', 'nova', 'add_nova_trade_signal_html', plugins_url('Nova-Trade-Signals/images/icon_admin.jpg'));
add_submenu_page('nova', 'Add Trade Signal', 'Add Trade Signal', 'manage_options', 'add_nova_trade_signal', 'add_nova_trade_signal_html');
add_submenu_page('nova', 'Update Trade Signal', 'Update Trade Signal', 'manage_options', 'update_nova_trade_signal', 'update_nova_trade_signal_html');
}
/**
 * register our tv_options_page to the admin_menu action hook
 */
add_action('admin_menu', 'nova_options_page');
/**
*function page for output of adding trade signal
*/

function add_nova_trade_signal_html()
{
?>
    <select name="drop_bl" id="drop_bl" style="margin-top:0px;margin-left:35px">
    
    <option value="" selected="selected" disabled="disabled">Select a Province</option>
    
    <?php getTierBLOne(); ?>
  
  </select> 
  
  <span id="wait_bl" style="display: none;">
  
  </span>
  <span id="result_bl" style="display: none;"></span>
  
<?php
    } 
    add_action('wp_ajax_drop_bl', 'drop_2');
    add_action('wp_ajax_no_priv_drop_bl', 'drop_2'); 
?>

 

Link to comment
Share on other sites

You don't have a function named 'drop_2'. Check the documentation - the second parameter of add_action() is the function to be run. So instead of randomly having this:

if (isset($_GET['func'])&& $_GET['func'] == 'drop_bl' ) {
    drop_bl($_GET['drop_var']); 
}

in your functions file, change the 'action' parameter of your AJAX call to 'drop_bl'. Then don't expect to pass a parameter to the function, just check $_POST directly. Which brings up another point, you're checking $_GET but using jQuery's post() method, which is basically a shortcut for using jQuery's ajax() function with method $_POST.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.