Title: Nested Select Menu
Last modified: August 21, 2016

---

# Nested Select Menu

 *  Resolved [A31](https://wordpress.org/support/users/a31/)
 * (@a31)
 * [12 years, 3 months ago](https://wordpress.org/support/topic/nested-select-menu/)
 * Hi,
    I am really struggling to get a second dropdown / select box to be automatically
   populated and I hope someone here can help me find my mistake.
 * Before moving to WordPress, I have been using the example by W3Schools but now
   in wordpress, I can’t seem to get it working.
 * My Code is as follows:
 *     ```
       <script type="text/javascript">
       function showUser(str)
       {
       if (str=="")
         {
         document.getElementById("txtHint").innerHTML="";
         return;
         }
       if (window.XMLHttpRequest)
         {// code for IE7+, Firefox, Chrome, Opera, Safari
         xmlhttp=new XMLHttpRequest();
         }
       else
         {// code for IE6, IE5
         xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
         }
       xmlhttp.onreadystatechange=function()
         {
         if (xmlhttp.readyState==4 && xmlhttp.status==200)
           {
           document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
           }
         }
       xmlhttp.open("GET","Fin_GetAllocation.php?q="+str,true);
       xmlhttp.send();
       }
       </script>
       <form>
       	<select name="sel_CostCentre" id="sel_CostCentre" onchange="showUser(this.value)">
       		<option value=0>Please Select Cost Centre: <?php echo $CostCentreDescriptionOptions; ?>
       	</select>
           <select name="Sel" id="txtHint"></select>
       </form>
       ```
   
 * then the code in the file “Fin_GetAllocation.php” is as follows:
 *     ```
       <?php
       	global $wpdb;
   
       	$q=$_GET["q"];
   
       	$SQL_Query01 = ("SELECT * FROM wp_allocations_tbl WHERE CostCentreDescription = '$q'");
       	$SQL_Results01 = $wpdb->get_results($SQL_Query01);
   
       	foreach($SQL_Results01 as $myResult01)
       		{
       			$AccountDescription = $myResult01->AccountDescription; //Field in DB
       			$AccountDescriptionOptions.="<option value='$AccountDescription'>" . $AccountDescription . "</option>";
       		}
       ```
   
 * So my first dropdown / select box works perfectly, but I can’t seem to get the
   second box to populate.
 * Can you please help?

Viewing 15 replies - 1 through 15 (of 21 total)

1 [2](https://wordpress.org/support/topic/nested-select-menu/page/2/?output_format=md)
[→](https://wordpress.org/support/topic/nested-select-menu/page/2/?output_format=md)

 *  Moderator [bcworkz](https://wordpress.org/support/users/bcworkz/)
 * (@bcworkz)
 * [12 years, 3 months ago](https://wordpress.org/support/topic/nested-select-menu/#post-4430753)
 * AJAX in WordPress is handled differently than as is done with other webpages.
   See [AJAX_in_Plugins](http://codex.wordpress.org/AJAX_in_Plugins). Another reference
   still being developed is [http://make.wordpress.org/docs/plugin-developer-handbook/plugin-components/improve-ux-with-ajax/](http://make.wordpress.org/docs/plugin-developer-handbook/plugin-components/improve-ux-with-ajax/).
 * If you can suggest any way to improve the second document, or if certain parts
   do not make sense to you, your feedback is appreciated. You can leave comments
   on the page once you register for “Make”. Besides this forum, I’m involved with
   the Developer Handbooks effort.
 *  Thread Starter [A31](https://wordpress.org/support/users/a31/)
 * (@a31)
 * [12 years, 3 months ago](https://wordpress.org/support/topic/nested-select-menu/#post-4430817)
 * Thank you very much!
 * I think your new documentation is clear and well written, and I already picked
   up on some of the mistakes I’ve made. However, this is my first attempt to really
   using Ajax (the above code I understood as Javascript), and well… I don’t really
   understand how to implement this to a nested / multi-leveled dropdown list box.
 * Is there perhaps any possibility that you could teach me how to do that or maybe
   even include such an example in your documentation?
 * Thank you very much for your help so far!
 *  Thread Starter [A31](https://wordpress.org/support/users/a31/)
 * (@a31)
 * [12 years, 3 months ago](https://wordpress.org/support/topic/nested-select-menu/#post-4430833)
 * Ok I have tried a number of different methods and I am now so confused… most 
   of these methods are so much more code than my origional code as well…
 * So I tried to simplify as much as i could and went back to what I knew worked.
   I tested it outside of WordPress and it works 100%, inside WordPress… not at 
   all.
 * I understand that WP manages all these things differently, can you please teach
   me how to put this simplified code of mine into a working WordPress format?
 * Form.php
 *     ```
       <?php
       	global $wpdb;
       ?>
       <form>
       	<select name="sel_CostCentre" id="sel_CostCentre" onchange="showUser(this.value)">
       		<option selected="selected">Please Select...</option>
       	    <option value="Expense">Expense</option>
       	    <option value="Income">Income</option>
       	</select>
           <select name="Sel" id="txtHint"></select>
       </form>
   
       <script type="text/javascript">
       function showUser(str)
       {
       if (str=="")
         {
         document.getElementById("txtHint").innerHTML="";
         return;
         }
       if (window.XMLHttpRequest)
         {// code for IE7+, Firefox, Chrome, Opera, Safari
         xmlhttp=new XMLHttpRequest();
         }
       else
         {// code for IE6, IE5
         xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
         }
       xmlhttp.onreadystatechange=function()
         {
         if (xmlhttp.readyState==4 && xmlhttp.status==200)
           {
           document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
           }
         }
       xmlhttp.open("GET","GetData.php?q="+str,true);
       xmlhttp.send();
       }
       </script>
       ```
   
 * GetData.php
 *     ```
       <?php
   
       $q=$_GET["q"];
   
       $i = 0;
       while ($i < 5)
       {
       	return "<option value='$i'>$q $i</option>";
       	$i++;
       }
       ```
   
 * If i can just get this simple code to return the value through wordpress, it 
   will surely help me to resolve this problem.
 * Can you please show me how to convert this code into WordPress Format?
 * Thank you again for all your help!!!
 *  Moderator [bcworkz](https://wordpress.org/support/users/bcworkz/)
 * (@bcworkz)
 * [12 years, 3 months ago](https://wordpress.org/support/topic/nested-select-menu/#post-4430852)
 * The main reason conventional AJAX does not work with WP is all requests MUST 
   be channeled through wp-admin/admin-ajax.php. All other sites of course do not
   have such a page. Also, all requests MUST have an ‘action’ parameter passed because
   it is used in part to form the action tag your PHP code must hook into.
 * I’m not entirely sure how to pass an ‘action’ in your pure javascript code, I
   always use jQuery because it is part of the WP installation and it is much easier.
   You could probably append it to the URL `admin-ajax.php?action=my-ajax-request`,
   or learn to use jQuery 🙂
 * The final WP thing you need to do is execute your PHP code by hooking into the
   appropriate action. Both the references show you how to do that, it is not optional.
   Also, for data to be sent to the browser as a response to a request, it must 
   be echoed, not returned. Rather than getting your code to work with WP, I would
   suggest you implement one of the examples in the references and see that it works
   in your installation.
 * Once that works, then alter it to work with a single value of your code. Once
   you get a single value communicated, work on a single nested value. After that
   it should be a matter of just adding data in loops.
 * If you can get a basic communication established, incrementally making changes
   to working code is much more reliable than coding everything then ironing out
   bugs one by one.
 * I can’t (OK, won’t 😉 ) write a custom tutorial for you. You are going have to
   do your own work in large part. I will try to keep you from going too far astray
   though. As I suggested, first get one of the examples working, that can be more
   challenging than it seems. Then start altering the example to meet your needs,
   a little at a time, constantly testing all is as expected after each small change.
 * Check back in here when you get stuck and we’ll see what we can do to get you
   back on track. Good luck!
 *  Thread Starter [A31](https://wordpress.org/support/users/a31/)
 * (@a31)
 * [12 years, 3 months ago](https://wordpress.org/support/topic/nested-select-menu/#post-4430897)
 * Hi there,
 * Thank you very much for your help so far, I fully understand that you wish me
   to figure this out on my own. I am however very confused 🙁
    I do not know which
   part of code goes where and how that applies to the front-end because from what
   I understand from the many many articles is that it differs.
 * Also I am a bit unsure, do I have to put it in a separate .js file?
 * I am sorry that I am so clueless, but am trying to learn.
 * What I have done is taken the most basic AJAX jQuery example i could find that
   is in the general direction of what I am looking for and tested it without WP.
   All it does is it posts info from a form to a seperate data file and gives an
   alert box with the data.
 * the php file:
 *     ```
       <?php
       	global $wpdb;
   
       	// Get Page Links
       	$MyData_PageTitle = 'MyData';
       	$MyData_page = get_page_by_title($MyData_PageTitle);
       	$MyData_myID = $MyData_page->ID;
       	$MyData_Link = get_page_link($MyData_myID);	
   
       	echo $MyData_Link;
       ?>
       	<script type="text/javascript">
       		$(function(){
       			$('#ff').form({
       				success:function(data){
       					$.messager.alert('Info', data, 'info');
       					//$.document.write('Info', data, 'info');
       				}
       			});
       		});
       	</script>
       		<form id="ff" action="<?php echo $MyData_Link; ?>" method="post">
       			<table>
       				<tr>
       					<td>Name:</td>
       					<td><input name="name" type="text"></input></td>
       				</tr>
       				<tr>
       					<td>Email:</td>
       					<td><input name="email" type="text"></input></td>
       				</tr>
       				<tr>
       					<td>Phone:</td>
       					<td><input name="phone" type="text"></input></td>
       				</tr>
       				<tr>
       					<td></td>
       					<td><input type="submit" value="Submit"></input></td>
       				</tr>
       			</table>
       		</form>
       ```
   
 * then the MyData.php file:
 *     ```
       <?php
   
       $name = $_POST['name'];
       $email = $_POST['email'];
       $phone = $_POST['phone'];
   
       echo "Your Name: $name <br/> Your Email: $email <br/> Your Phone: $phone";
   
       ?>
       ```
   
 * but Alas, it is not working 🙁 I am terribly confused.
 * Can you please help?
 *  Moderator [bcworkz](https://wordpress.org/support/users/bcworkz/)
 * (@bcworkz)
 * [12 years, 3 months ago](https://wordpress.org/support/topic/nested-select-menu/#post-4430910)
 * Don’t get too distressed because something doesn’t work, it happens to the best
   of us. It’s often just a silly mistake. Of course when you don’t yet understand
   what’s going on, finding that silly mistake can be overwhelming. Don’t stress,
   we’ll get it worked out eventually. Learning to debug is an essential skill. 
   What better way to learn than make mistakes?
 * The problem here is you’ve introduced yet another element you’ve yet to adequately
   learn… jQuery. I applaud the effort, it will pay off eventually. What your simple
   example’s source had apparently omitted to inform you, assuming everyone using
   jQuery would know this, is you need to reference the jQuery library in the page’s
   head section. Without that, it will fail no matter what. I’m not going to get
   into how to do this in your trial script because once again, how it is done in
   WP is different.
 * You _really_ need to start with a simple _WordPress_ AJAX example. Even though
   such examples appear more complicated, you’re adding needless confusion by learning
   one way and then needing to relearn the WP way.
 * As I believe you realized, whether to use an external js file or inline script
   is a fundamental decision one must make. Either way works, inline makes more 
   sense for simple, short scripts, the external file makes more sense for larger
   scripts or projects where separation of various components is organizationally
   cleaner.
 * I personally use external js files for even basic scripts because it works for
   any project of any size. I have a single setup I use, it works for everything
   of any size. I’m less confused by doing things the same way every time.
 * I’m sure others will argue that it’s stupid to generate another file request 
   for a dozen lines of code, inline script is more efficient. They’re right. But
   I don’t care, my clients have low volume sites, it’s not a big deal, and it keeps
   me organized. I’m set if their script needs grow.
 * The other thing to decide is where to put this stuff. Your choices are [child theme](http://codex.wordpress.org/Child_Themes)
   or plugin. For customizations to your own site, I would suggest a child theme
   makes the most sense. You might eventually find some admin thing you need to 
   customize requires a plugin, but virtually anything can be done from a child 
   theme. Child themes make it easy to utilize the best way to introduce custom 
   code pages into WP, the [custom page template](http://codex.wordpress.org/Page_Templates#Custom_Page_Template).
 * The page template contains the front end form. If your form is for the admin 
   area, then perhaps a plugin makes more sense. Then your form is introduced using
   the Settings API and maybe the Administration Menus API. Let’s keep things simpler
   and focus on a front end page template. Any PHP page can be made into a template
   by adding the following comment as the very first thing on a page:
 *     ```
       <?php
       /*
       Template Name: My AJAX Form
       */
       ```
   
 * Place the file in your child theme folder, name it anything meaningful with a.
   php extension. Add a new page to WP using the Add New Page admin screen, assigning
   a title and basing it on your custom template. This gives you a permalink with
   which to access the page. Unless you build in a provision to do something with
   content, there is no reason to add content when creating a page based on your
   custom template.
 * Submitting an entire form via AJAX is not illustrating its best use. Let’s do
   a check on the email to confirm it’s a valid format as soon as the user enters
   it (on the “change” event). You could do this with javascript alone, but let’s
   let the server do it. Add an ID attribute to the email field: `id="ffemail"` 
   to make it simple to reference the email field. jQuery has a rich set of selectors(
   its best feature IMO) where such IDs are not required, but an ID simplifies things.
 * Here is minimal jQuery to submit the email via AJAX and display the result in
   an alert box. Take some time to ensure you understand every line. Place it in
   a file called myscript.js and place it in your child theme folder.
 *     ```
       jQuery(document).ready(function($) { //no conflict wrapper
          $("#ffemail").change(function() {
             var email = $(this).val();  //'this' is out of scope in .post() data array
             $.post("http://example.com/wp-admin/admin-ajax.php",
             { action: "myajax",   // define data array
       	addr:    email
               /* add localized nonce later */
             },
             function(data) {  // handle server response
                alert(data);
             });
          });
       });
       ```
   
 * Edit the .post() URL to be your actual URL for your site. This should normally
   be a localized value, but we will skip that part for now. A [nonce](http://codex.wordpress.org/WordPress_Nonces)
   is another localized value we will skip over, though it is an important security
   measure.
 * The PHP to reference or “enqueue” your script and to actually handle the AJAX
   request can go on your child theme’s functions.php:
 *     ```
       add_action('wp_enqueue_scripts', 'my_queue');
       function my_queue() {
          //we eventually will only enqueue for the one page
          wp_enqueue_script( 'my-script',
             get_stylesheet_directory_uri().'/myscript.js',
             array('jquery')  // causes the jQuery library to be loaded
          );
          //add localize script stuff here later
       }
   
       add_action('wp_ajax_myajax', 'ck_emailfake');
       add_action('wp_ajax_nopriv_myajax', 'ck_emailfake');
       function ck_emailfake() {
          //add nonce and capability checks later
          echo $_POST['addr'].' email not checked!';
          die;   //all AJAX handlers must die!
       }
       ```
   
 * This code should work for you unchanged except for your site URL. I did test 
   it. But don’t be surprised if it doesn’t work at first. It’s just the nature 
   of coding that something will go wrong. I’ve added a few hints as comments and
   noted where important stuff should be added later. Again, take the time to understand
   every line. This knowledge is essential for being able to track down bugs and
   find mistakes.
 * Note that we are not really checking the email format, we are just passing the
   entered value back and forth to demonstrate round trip data communication.
 * I’ll give you one more thing because it’s a little obscure. The reason the AJAX
   handler is added to two different actions is the page could be accessed by someone
   logged in or not. Each state requires a different action hook. You’re on your
   own to learn the rest 🙂
 * Once you’ve figured out this basic code, building on that to reach your original
   goal of nested dropdown forms is closer than you think. Good luck, and try to
   have fun.
 *  Thread Starter [A31](https://wordpress.org/support/users/a31/)
 * (@a31)
 * [12 years, 2 months ago](https://wordpress.org/support/topic/nested-select-menu/#post-4430964)
 * Hi there bcworkz,
 * Hope you have a wonderful 2014!
 * Thank you very much for your help and your advice above, in some way pointed 
   me into the right direction. Although I did not make use of the child-theme setup,
   I applied some of this information to a custom plugin.
 * What I have managed to accomplish is the following:
 * I can now run jquery from a wordpress plugin, which was one of the biggest goals!!
   🙂 yay!
 * One example would be:
 * in my form.php file:
    at the top i have: ` <div id=”responsecontainer”></div>`
   then in the form section i have: ` <input name=”ItemCost” id=”ItemCost” type=”
   text”/> ` then in my ajax.js file:
 *     ```
       jQuery(document).ready(function () {
       $("#ItemCost").change(function()
       	{
                   $("#responsecontainer").html($("#ItemCost").val());
       	});
       });
       ```
   
 * the moment my ItemCost value changes, it works beautifully, and returns the value
   to the response div.
 * All is not solved yet though 🙁
    This is what I ultimately want to achieve…
 * What I have currently in my form is a select box:
 *     ```
       <select name="MySel" id="MySel">
       <option value="">Please Select... </option>
       <option value="1">Option 1</option>
       <option value="2">Option 2</option>
       </select>
       ```
   
 * my jquery in my ajax.js file looks like:
 *     ```
       jQuery(document).ready(function () {
       $("#MySel").change(function() {
   
       	$.ajax({
               type:"POST",
               url: "GetData.php",
               datatype: "json",
               success: function(data, textStatus, xhr) {
               data = JSON.parse(xhr.responseText);
   
               $("#responsecontainer").html(data);
            }
   
            });
       });
       });
       ```
   
 * my GetData.php file contains the following:
 *     ```
       $ReturnedValue = "Returned Data";
   
       echo json_encode($ReturnedValue);
       ```
   
 * very simple I realise, but only to test.
    So really at this stage it does not
   matter what the user chooses in the select box, I just want to return the data
   from the GetData.php file to the response <div>.
 * Up to now however, I can’t seem to get the data back from the GetData.php file,
   can you please help me in returning the data to the form?
 * You really do help me!
    Thank you so much for all your help!!
 *  Moderator [bcworkz](https://wordpress.org/support/users/bcworkz/)
 * (@bcworkz)
 * [12 years, 2 months ago](https://wordpress.org/support/topic/nested-select-menu/#post-4430965)
 * Hello, a great new year for you too!
 * It’s really cool once you get something working, isn’t it? 🙂
 * AFAICT, the only issue with your jQuery code is you forgot to pass the ‘$’ shortcut
   character in your wrapper function.
    `jQuery(document).ready(function ($) {`
 * If that does not fix it, you probably placed GetData.php in the wrong folder.
   You can check your access logs to see where the request was actually sent, or
   just specify a complete URL to the file.
 * The only other thing that could be wrong is jQuery was not loaded properly, but
   since ItemCost is working, assuming it’s on the same page, that cannot be an 
   issue.
 * I’m sure you’ll get this fixed in short order. Is your form currently a WP page
   or a generic HTML page? If not a WP page, that should be your next challenge:
   Make a custom page template with working jQuery that is loaded through `wp_enqueue_script()`.
 * If you have that already, the next step is get your same PHP code working by 
   POSTing the AJAX request through wp-admin/admin-ajax.php instead of directly 
   to a PHP file. This will give you access to WP functions and the DB.
 * Have fun! 🙂
 *  Thread Starter [A31](https://wordpress.org/support/users/a31/)
 * (@a31)
 * [12 years, 2 months ago](https://wordpress.org/support/topic/nested-select-menu/#post-4430966)
 * Hi,
 * That fixed it! Thank you very much!
 * As to how my pages are created, all my files are currently created when the plugin
   is activated, so I have full wpdb functionality on all files.
 * I am puzzled though, in my GetData.php file, if I hardcode a variable:
 *     ```
       $Value = 'Returned Data';
       ```
   
 * and return it with
 *     ```
       echo json_encode($Value);
       ```
   
 * it returns the data perfectly, which is exactly what I want, BUT….
 * the moment I run a wpdb query, it does not return it any more.
 * for Example:
 *     ```
       global $wpdb;
   
       	$current_user = wp_get_current_user();
       	$UID = $current_user->ID;
   
          echo json_encode($UID);
       ```
   
 * so if i view my GetData.php file on its own, I get the UID returned and displayed,
   however, the moment I want to pass it like I did with the hardcoded ($Value =‘
   Returned Data’;), it does not show a value.
 * Can you perhaps help where I might be missing something?
 * Again thank you for your help! It is a great feeling to get something right and
   to know at least there are people I can ask to help me learn and get these things
   figured out.
 * Kind Regards
 *  Moderator [bcworkz](https://wordpress.org/support/users/bcworkz/)
 * (@bcworkz)
 * [12 years, 2 months ago](https://wordpress.org/support/topic/nested-select-menu/#post-4430971)
 * Yes, you’ve run into what I’ve been trying to say about access to `$wpdb` and
   other WP resources. I’m not sure how to explain this, I hope it makes sense. 
   Sorry about the length. (You should be expecting that from me by now 😉 )
 * You are correct in that your plugin code has access to WP resources. You kind
   of need to understand how WP page requests work to grasp the concept. First let’s
   look at a normal permalink like `example.com/accounts-summary/`. The server executes.
   htaccess directives which tell it if there’s no file matching the request, rewrite
   the request to `example.com/index.php`. This invokes a chain of require statements
   that completely load the WP environment. This includes loading your main plugin
   file and any files required or included by the plugin main page.
 * Because the WP code base loaded your plugin file, it becomes part of the WP namespace.
   WP can access your functions and your functions can access WP resources. A lot
   more happens after plugins load, but it doesn’t matter here. The point is WP 
   called your plugin, so it becomes part of WP.
 * Now let’s look at your AJAX request. The PHP page is requested directly. Since
   this page exists on the server, the request is not rewritten to index.php and
   that chain of requires for loading WP does not occur. Being a PHP page, the server
   sends any HTML found back to the browser and executes any PHP found. In the case
   of your version that is not using `$wpdb`, all is fine. An assignment is made
   and JSON data is sent back to the browser.
 * Now let’s look at the `$wpdb` version. The global bit is fine, but it is only
   establishing a global place holder variable. No code was executed defining $wpdb.
   It’s empty. Then there’s your call `get_current user()`. This _is_ a problem.
   No code encountered since the request has defined this function. If it happens
   to be on your page, no problem, the PHP interpreter will find it and use it. 
   But there is no such thing. No function definition is encountered. The only code
   executed on this request was `global $wpdb;`.
 * With no definition, PHP doesn’t know how to call the function, so it throws an
   error and dies. The default error handler catches the error and does the default
   thing, which is usually logging the error to a file and then dying.
 * Your AJAX query never gets a response back. After a certain period of waiting
   for a response, it to quietly dies. So the whole process dies without any kind
   of warning on the initiating page.
 * You see, it’s doesn’t matter if WP loads your plugin which then loads your AJAX
   handler file, because WP is not loaded when you call the page directly. All PHP
   can know about on any given request is the code it encounters on the immediate
   page or any pages required or included from that page. Since no WP pages were
   included or required, no WP resources are available.
 * You can’t send your AJAX request to index.php either. It is expecting a certain
   permalink to parse. An AJAX request will just confuse it and cause a WP 404 error.
   I can imagine your brain’s thiinking “gears” spinning right now: “Oh, oh! I can
   _include_ index.php on my page and cause WP to load!”
 * You would be very close, but index.php will still expect a permalink and get 
   confused, resulting in a 404. What you _could_ do is include wp-load.php. This
   bypasses the permalink expectation and loads the WP environment. This _will actually
   work_ on your own installation once you figure out the correct relative reference
   from your plugin file to WP root where wp-load.php resides.
 * The big problem with including wp-load.php is you cannot know the correct relative
   reference to it for any random WP installation. It’s possible to completely move
   the plugins folder elsewhere in the file structure. So you cannot expect your
   plugin to work on other installations. In fact, relative references to wp-load.
   php alone is cause for rejection of applications for plugins to be placed on 
   the WP repository.
 * If that is not your goal, go ahead and use a relative reference if you like. 
   For the sake of knowledge though, I encourage you to learn the “right” way to
   do things for future reference, even if you have no use for it right now. There
   are some advantages.
 * The “right” way is what I’ve been going on about with using `wp_enqueue_script()`
   and requesting through wp-admin/admin-ajax.php. `wp_enqueue_script()` is good
   to use because it resolves all dependencies for you and ensures a compatible 
   version of jQuery is loaded. This method will continue to work through indefinite
   upgrades without concern for conflicts.
 * The reason for going through wp-admin/admin-ajax.php is it loads the WP environment
   for you without concern for where the plugin folder is relative to wp-load.php.
   It too will reliably work through indefinite upgrades without concern for conflicts.
 * Future stability can only be relied on if you use the intended methods. Taking
   cheap shortcuts will not be worth it in the long run. Sooner or later they will
   break.
 * I hope this whole AJAX thing in WP is starting to make sense now. Once you understand
   how to access WP resources through AJAX and establish a working data exchange,
   the rest will start falling into place. It should all be mostly downhill from
   here! There’s bound to be a few humps along the way though 🙂
 *  Thread Starter [A31](https://wordpress.org/support/users/a31/)
 * (@a31)
 * [12 years, 2 months ago](https://wordpress.org/support/topic/nested-select-menu/#post-4430977)
 * Hi there,
 * I have been trying to figure this out thos past few days but I am somewhere not
   understanding something,
 * I am using the enqueue_scripts to access the admin-ajax.php
 * wp_enqueue_script(‘custom-script1’, plugin_dir_url(__FILE__) . ‘js/ajax.js’, 
   array(‘jquery’));
    wp_localize_script(‘custom-script1’, ‘custom-script_vars1’,
   array(‘ajaxurl’ => admin_url(‘admin-ajax.php’)));
 * Am I missing something completely?
 * Kind Regards
 *  Moderator [bcworkz](https://wordpress.org/support/users/bcworkz/)
 * (@bcworkz)
 * [12 years, 2 months ago](https://wordpress.org/support/topic/nested-select-menu/#post-4430981)
 * That bit looks totally fine. It’s OK as is, but I would suggest changing ‘ajaxurl’
   to something slightly different, as there is a global javascript variable of 
   the exact same name. They are referenced differently, so there’s nothing technically
   wrong. It’s just that it can lead to confusion.
 * Maybe you’ve done this, the code does need to be inside a declared function. 
   That function must be added as a callback to the correct action. The action depends
   on where your form is presented. Use ‘wp_enqueue_scripts’ for front end forms,‘
   admin_enqueue_scripts’ for backend, and ‘login_enqueue_scripts’ for the login
   form.
 * You can confirm it is working by finding the link tag referring to your JS file
   in the head section when viewing page source. The localized data shows up in 
   a `<![CDATA[ ]]>` section.
 * There’s two other places where things can go wrong if your AJAX is not working.
   One is the jQuery. Are you referencing `custom-script_vars1.ajaxurl` correctly?
   Providing an `action` value in the POST request? Check your error console for
   stray syntax errors.
 * The other is the PHP AJAX handler. Have you hooked the correct action? Which 
   one depends if the user is logged in or not. Typically front end scripts must
   hook both if the form is available publicly, since a logged in user could be 
   using it just as a non-logged in user would.
 * Getting the bugs ironed out of virgin script can be a challenge. Once you’ve 
   gotten it working, it makes a good foundation to build upon and should give you
   little trouble in the future. Hang in there!
 *  Thread Starter [A31](https://wordpress.org/support/users/a31/)
 * (@a31)
 * [12 years, 2 months ago](https://wordpress.org/support/topic/nested-select-menu/#post-4430982)
 * Hi,
 * Ok, Im going to paste ALL the code for all the files (I appologize for so much
   code, but i dont know what else), maybe you can spot my mistake 🙁
 * Plugin main FILE – AJAXTest.php
 *     ```
       <?php
       /*
       Plugin Name: Ajax Test
       Plugin URI: http://www.example.co.za/
       Description: Testing Ajax
       Author: Adrian Beyers
       Version: 1.0
       Author URI: http://www.example.co.za/
       */
   
       /***************************
       * GLOBAL VARIABLES
       ***************************/
   
       if (!isset($wpdb)) $wpdb = $GLOBALS['wpdb'];
       global $wpdb;
   
       /***************************
       * INCLUDES
       ***************************/
       include ("inc/setup_addPages.php");
       include ("inc/setup_shortcodes.php");
   
       /***************************
       * SETUP
       ***************************/
   
       register_activation_hook(__FILE__,'AT_Func_addTestPage');
       register_deactivation_hook(__FILE__,'AT_Func_removeTestPage');
   
       register_activation_hook(__FILE__,'AT_Func_addMyData');
       register_deactivation_hook(__FILE__,'AT_Func_removeMyData');
   
       /***************************
       * SCRIPTS
       ***************************/
   
       function AT_load_scripts() {
       	wp_enqueue_script('custom-script1', plugin_dir_url(__FILE__) . 'js/ajax.js', array('jquery'));
       	wp_enqueue_script('custom-script2', plugin_dir_url(__FILE__) . 'js/jquery.validate.js', array('jquery'));
       	wp_enqueue_script('custom-script3', plugin_dir_url(__FILE__) . 'js/jquery-1.9.1.js', array('jquery'));
       	wp_enqueue_script('custom-script4', plugin_dir_url(__FILE__) . 'js/jquery.min.js', array('jquery'));
       	wp_enqueue_script('custom-script5', plugin_dir_url(__FILE__) . 'js/jquery.validate.min.js', array('jquery'));
       	wp_enqueue_script('custom-script6', plugin_dir_url(__FILE__) . 'js/additional-methods.js', array('jquery'));
   
       	wp_enqueue_script('jquery');
   
       	wp_localize_script('custom-script1', 'custom-script_vars1', array('ajaxurl' =>  admin_url('admin-ajax.php')));
       	wp_localize_script('custom-script2', 'custom-script_vars2', array('ajaxurl' =>  admin_url('admin-ajax.php')));
       	wp_localize_script('custom-script3', 'custom-script_vars3', array('ajaxurl' =>  admin_url('admin-ajax.php')));
       	wp_localize_script('custom-script4', 'custom-script_vars4', array('ajaxurl' =>  admin_url('admin-ajax.php')));
       	wp_localize_script('custom-script5', 'custom-script_vars5', array('ajaxurl' =>  admin_url('admin-ajax.php')));
       	wp_localize_script('custom-script6', 'custom-script_vars6', array('ajaxurl' =>  admin_url('admin-ajax.php')));
   
       }
       add_action('wp_enqueue_scripts', 'AT_load_scripts');
       ```
   
 * FILE setup_addPages.php:
 *     ```
       <?php
       global $wpdb;
   
       /***************************
       * SETUP PAGES
       ***************************/
   
       function AT_Func_addTestPage()
       {
       	$PageTitle = 'AJAX Test';
       	$PageContent = '[AT_TestPage]';
       	$PageStatus = 'publish';
       	$PostType = 'page';
       	$PostAuthor = 1;
       	$CommentStatus = 'closed';
   
       	$myPage = array(
       	'post_title' => $PageTitle,
       	'post_content' => $PageContent,
       	'post_status' => $PageStatus,
       	'post_type' => $PostType,
       	'post_author' => $PostAuthor,
       	'comment_status' => $CommentStatus
       	);
   
       	$post_id = wp_insert_post($myPage);
       }
   
       function AT_Func_removeTestPage()
       {
       	global $wpdb;
       	$post_tbl = $wpdb->prefix . "posts";
       	$postmeta_tbl = $wpdb->prefix . "postmeta";
       	$PageTitle = 'AJAX Test';
       	$page = get_page_by_title($PageTitle);
       	$myID = $page->ID;
   
       	$myMetaID = $wpdb->get_var($wpdb->prepare("SELECT post_id FROM em_postmeta WHERE meta_value = ".$myID.""));
   
       	$deletePost = "DELETE FROM " . $post_tbl . " WHERE ID = ".$myID."";
       	$deletePostSubs = "DELETE FROM " . $post_tbl . " WHERE post_parent = ".$myID."";
       	$deletePostMetaLink = "DELETE FROM " . $post_tbl . " WHERE ID = ".$myMetaID."";
       	$deletePostMeta = "DELETE FROM " . $postmeta_tbl . " WHERE post_id = ".$myMetaID."";
   
       	$wpdb->query($deletePost);
       	$wpdb->query($deletePostSubs);
       	$wpdb->query($deletePostMetaLink);
       	$wpdb->query($deletePostMeta);
   
       }
   
       /************************************************************************************************************/
       /************************************************************************************************************/
       /************************************************************************************************************/
       /************************************************************************************************************/
       /************************************************************************************************************/
       function AT_Func_addMyData()
       {
       	$PageTitle = 'MyData';
       	$PageContent = '[AT_MyData]';
       	$PageStatus = 'publish';
       	$PostType = 'page';
       	$PostAuthor = 1;
       	$CommentStatus = 'closed';
   
       	$myPage = array(
       	'post_title' => $PageTitle,
       	'post_content' => $PageContent,
       	'post_status' => $PageStatus,
       	'post_type' => $PostType,
       	'post_author' => $PostAuthor,
       	'comment_status' => $CommentStatus
       	);
   
       	$post_id = wp_insert_post($myPage);
       }
   
       function AT_Func_removeMyData()
       {
       	global $wpdb;
       	$post_tbl = $wpdb->prefix . "posts";
       	$postmeta_tbl = $wpdb->prefix . "postmeta";
       	$PageTitle = 'MyData';
       	$page = get_page_by_title($PageTitle);
       	$myID = $page->ID;
   
       	$myMetaID = $wpdb->get_var($wpdb->prepare("SELECT post_id FROM em_postmeta WHERE meta_value = ".$myID.""));
   
       	$deletePost = "DELETE FROM " . $post_tbl . " WHERE ID = ".$myID."";
       	$deletePostSubs = "DELETE FROM " . $post_tbl . " WHERE post_parent = ".$myID."";
       	$deletePostMetaLink = "DELETE FROM " . $post_tbl . " WHERE ID = ".$myMetaID."";
       	$deletePostMeta = "DELETE FROM " . $postmeta_tbl . " WHERE post_id = ".$myMetaID."";
   
       	$wpdb->query($deletePost);
       	$wpdb->query($deletePostSubs);
       	$wpdb->query($deletePostMetaLink);
       	$wpdb->query($deletePostMeta);
   
       }
   
       /************************************************************************************************************/
       /************************************************************************************************************/
       /************************************************************************************************************/
       /************************************************************************************************************/
       /************************************************************************************************************/
       ```
   
 * FILE setup_shortcodes.php:
 *     ```
       <?php
   
       global $wpdb;
   
       /***************************
       * SETUP FRONT-END SHORTCODES
       ***************************/
   
       add_shortcode("AT_TestPage","AT_TestPage_Shortcode");
   
       function AT_TestPage_Shortcode($atts)
       {
       	  include ('TestPage.php');
       }
   
       add_shortcode("AT_MyData","AT_MyData_Shortcode");
   
       function AT_MyData_Shortcode($atts)
       {
       	  include ('MyData.php');
       }
       ```
   
 * FILE TestPage.php:
 *     ```
       <div id="responsecontainer"></div>
   
       <form id="MyForm" method="post" action="" novalidate="novalidate" enctype="multipart/form-data">
   
           		<div class="FormLabel">Description</div>
                           <textarea name="Description" id="Description" width="300px"/></textarea>
   
                           <br /><br />
   
                       <div class="FormLabel">Item Cost</div>
                           <input name="ItemCost" id="ItemCost" type="text"/>
                       <div class="FormLabel">Available Budget: Rxxxx.xx (Not yet available)</div>
                       <br /><br /><br /><br />
   
                       <div class="FormLabel">Select Cost Center</div>
                           <select name="Sel_CostCentre" id="Sel_CostCentre">
                               <option value="">Please Select... </option>
                               <option value="29 Degrees">29 Degrees</option>
                               <option value="J-Zone">J-Zone</option>
                           </select>
                           <br /><br />                
   
                       <div class="FormLabel">Select Allocation Account</div>
                           <select name="txtHint" id="txtHint" required="required"></select>
                           <br /><br />                   
   
           <input type="submit" name="submit" value="Submit" />
       </form>
   
       <div id="returneddata"></div>
       ```
   
 * FILE ajax.js:
 *     ```
       jQuery(document).ready(function ($) {
   
       	$("#Sel_CostCentre").change(function() {
   
       		var SendData = document.getElementById('Sel_CostCentre').value;
       		var Usernaam = "Adrian";
   
       		$.ajax({
                      type:"POST",
                       url: "http://localhost/WPTest/wp-content/plugins/AJAXTest/inc/MyData.php",
       				//data:"SentData="+SendData,
       				data: { SentData: SendData, userid: Usernaam },
                      datatype: "json",
                       success: function(data, textStatus, xhr) {
                          data = JSON.parse(xhr.responseText);
                          // do something with data
       				   $("#responsecontainer").html(data);
       				}
                   });
   
       	//$("#responsecontainer").html($("#Sel_CostCentre").val());
   
       	});
   
       	$("#ItemCost").change(function()
       	{
       		$("#responsecontainer").html($("#ItemCost").val());
       	});
   
           $('#MyForm').validate({ // initialize the plugin
               rules:
       		{
                   Description: {
                       required: true
                   },
                   ItemCost: {
                       required: true
                   }
               },
       		messages:
       			{
       				Description: "Please enter a description",
       				ItemCost: "Please enter a description"
       			}
           });
   
       });
   
       	function checkValue(element)
       		{
           		if(element.value >= 2500)
       				{
               			alert ('More than 2500');
           			}
       			else if (element.value < 2500)
       				{
       					alert ('Less than 2500');
       				}
       		}
       ```
   
 * FILE MyData.php:
 *     ```
       <?php
   
       	global $wpdb;
   
       	$SentData = $_POST['SentData'];
       	$userid = $_POST['userid'];
   
       	//echo json_encode($userid . " sent the following data: " . $SentData);
   
       	$Returned = $wpdb->get_var( "SELECT meta_value FROM wp_usermeta WHERE meta_key = 'ActiveEntity'" );
       	echo json_encode($Returned);
       ```
   
 * Ok I think thats everything….
 * As mentioned in my previous posts, I realise that there are some very simple 
   queries in the MyData.php file, and that I have not added Nonces, etc. but for
   now I just need to get my main issue working, then I will add all the rest in
   my main plugin.
 * The ultimate goal, is that when the user selected the value from the first select
   box, it should populate the second selectbox with options from a database.
 * Although my code does not request that at this moment, it is supposed to return
   the basic query, the meta_value for a unique key from the table into a div container
   named “responsecontainer”.
 * Hopefully you can help 🙁 I am getting a bit discouraged after a month of trying
   to get this working 🙁
 * Thank you so much for all your help!! I really do appreciate it so much!
 *  Moderator [bcworkz](https://wordpress.org/support/users/bcworkz/)
 * (@bcworkz)
 * [12 years, 2 months ago](https://wordpress.org/support/topic/nested-select-menu/#post-4430983)
 * One problem may be a script conflict. You are loading jquery-1.9.1.js with the
   WP default 1.10.2 as a dependency. There’s no need to specifically enqueue the
   actual jQuery file. Simply specifying it as a dependency is all you need to do.
   If you must use a specific version for some reason, the WP version must be deregistered.
   You don’t want to go down that path unless you know what you’re doing.
 * You may not need to enqueue some of the other library files either. Check against
   [this list](http://codex.wordpress.org/Function_Reference/wp_register_script#Handles_and_Their_Script_Paths_Registered_by_WordPress).
   If there’s a match, simply specify the handle as a dependency of your script 
   file that’s using the library. If you need the .js file on the list and it’s 
   not a dependent, simply enqueue by the handle alone: `wp_enqueue_script('colorpicker');`
 * In general, all of this introduces potential for difficult to find conflicts.
   You need to develop a working AJAX exchange in isolation. Not only to obtain 
   your own specific functional template for future use, but for study so you can
   truly understand what’s going on and are not merely cutting and pasting code.
 * For your own sanity please set this aside and focus on a very basic AJAX exchange
   through WP. Once you understand how this really works, then you can import it
   into your main project. It’s the only way you can be sure the reason it is not
   working is a conflict and not a simple coding error. You’ve done this with non-
   WP AJAX, but I’ve not seen any functional WP AJAX exchange from you yet.
 * The other things I’m seeing wrong is, one, your AJAX request is not being sent
   to the URL using the localized variable. The request must include an ‘action’
   value to use in constructing an action hook tag.
 * I’m also not seeing any handler function hooked to this tag. It can’t work without
   an ‘action’ value, but I don’t even see an attempt to hook something. None of
   this is optional, it must be part of a successful WP AJAX exchange. I must admit,
   I didn’t study everything really closely, so I may have simply missed this.
 * I’m sorry this is such a struggle for you. All I can offer is this is an important
   technique to master. It will continue to be a very useful skill in your future
   projects.
 * BTW, if you need to post a lot of code, use pastebin.com and simply provide a
   link here. If you select the appropriate syntax highlighting when you post the
   code, it makes the code MUCH easier to read. It helps me help you 🙂
 *  Thread Starter [A31](https://wordpress.org/support/users/a31/)
 * (@a31)
 * [12 years, 2 months ago](https://wordpress.org/support/topic/nested-select-menu/#post-4430984)
 * Hi there,
 * Thank you very much for your feedback. I have a couple of questions on what you
   mentioned though.
    You mention that my AJAX request is not being sent to the 
   URL using the localized variable, is this not what you are referring to:
 *     ```
       wp_localize_script('custom-script1', 'custom-script_vars1', array('ajaxurl' =>  admin_url('admin-ajax.php')));
       ```
   
 * then you also mention that you do not see any handler function hooked, I thought
   that my AT_load_scripts() function with
    add_action(‘wp_enqueue_scripts’, ‘AT_load_scripts’);
   was actually that, if not, can you please explain?
 * Thank you very much for helping me figure this out.
 * Kind Regards

Viewing 15 replies - 1 through 15 (of 21 total)

1 [2](https://wordpress.org/support/topic/nested-select-menu/page/2/?output_format=md)
[→](https://wordpress.org/support/topic/nested-select-menu/page/2/?output_format=md)

The topic ‘Nested Select Menu’ is closed to new replies.

## Tags

 * [automatically](https://wordpress.org/support/topic-tag/automatically/)
 * [box](https://wordpress.org/support/topic-tag/box/)
 * [dropdown](https://wordpress.org/support/topic-tag/dropdown/)
 * [nested](https://wordpress.org/support/topic-tag/nested/)
 * [populate](https://wordpress.org/support/topic-tag/populate/)
 * [select](https://wordpress.org/support/topic-tag/select/)
 * [selectbox](https://wordpress.org/support/topic-tag/selectbox/)

 * In: [Hacks](https://wordpress.org/support/forum/plugins-and-hacks/hacks/)
 * 21 replies
 * 2 participants
 * Last reply from: [bcworkz](https://wordpress.org/support/users/bcworkz/)
 * Last activity: [12 years ago](https://wordpress.org/support/topic/nested-select-menu/page/2/#post-4431029)
 * Status: resolved

## Topics

### Topics with no replies

### Non-support topics

### Resolved topics

### Unresolved topics

### All topics
