0

PHP, JavaScript combo. I have a site with 4 dropdowns. The dropdowns are updated in sequence based on previous dropdown. It works fine when I manually select options, but not when i fill in default values from MySQL records. Codesnip with 2 dropdowns where dropdown 2 is based on dropdown 1 selection, see comments in first three lines:

jQuery('#ClassLevelID').val(data["ClassMin"]); //First dropdown
ClassLevelOnChange(); // Calls DB and gets new values. One value is "4" (i checked that)
jQuery('#CatID').val(4); // Trying to update dropdown 2 to value "4" but nothing happens THIS is what doesn't work properly.
// The #CatID dropdown is filled with values correctly, i see them all. But jQuery does not change from option value 0 to 4 as i want it to.



function ClassLevelOnChange(){

  jQuery('#CatID').find('option').remove();
  jQuery('#CatID').append('<option value="0">Choose option</option>');

  var SelectedClassLevel = document.getElementById("ClassLevelID").value;

  jQuery.ajax({
        type: 'POST',
        url: 'includes/db_GetCategory.php',
        data: {"SelectedClassLevel":SelectedClassLevel},
        success: function(result){

            var result=jQuery.parseJSON(result);
            var x = 0;

            jQuery.each(result.class_id, function(index, value){
              ClassName = result.class_text[x];
              jQuery('#CatID').append('<option value="' + value + '">' + ClassName + '</option>');
              x = x + 1;
            });
        }
        });

}

I tried some refresh but no results.

Emil Olsen
  • 332
  • 1
  • 9
  • 25
  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – freedomn-m May 17 '21 at 08:01
  • Hi, did you tried adding that line inside success function of ajax ? – Swati May 17 '21 at 08:02
  • Time to review what the "a" in "ajax" means - you're trying to set `.val(4)` before the ajax completes , so doesn't exist yet. When you "see them all" it's after the ajax has completed. A few `console.log`s in your code (before/after classlevelonchange and in the success) will show you what's going on. – freedomn-m May 17 '21 at 08:02
  • @freedomn-m No, it doesnt. Because the ajax works fine. The second list IS filled with options. I just can not select the options with jQuery. I can select the option with the mouse... I also suspect that ajax is not done before it continues. Is there a way to wait for ajax? I tried making it sleep 1 second between ajax call and jQuery insert, but no luck. – Emil Olsen May 17 '21 at 09:08
  • @Swati Woops, that did help. So it is an asynchronous problem. The thing is that i need it to run in blocks/sequences. I will see if i can rearrange the code. But is there no smarter way to wait for ajax? So i dont need to put all code inside the ajax success? – Emil Olsen May 17 '21 at 09:11
  • The code *you've provided* does this: (1) set val on #ClassLevelID (2) call ClassLevelOnChange (3) ClassLevelOnChange resets CatID with 1 (=0) option then (4) *starts* an ajax post (5) immediately returns (6) your code then does `jQuery('#CatID').val(4)` which doesn't yet exist (7) *then* (**and only then**), does your ajax complete and add the new options. You can select with the mouse because that's *after* the ajax has completed. You *need to* wait for the ajax to complete and you either do that in `success:` or your `return $.ajax(...` and do it in `.done()` – freedomn-m May 17 '21 at 09:16
  • `ClassLevelOnChange().done(() => jQuery('#CatID').val(4));` and `function ClassLevelOnChange() { ... return $.ajax(...` – freedomn-m May 17 '21 at 09:18
  • *I also suspect that ajax is not done before it continues* - now you're getting what *asynchronous* means... – freedomn-m May 17 '21 at 09:19
  • Okay, cool, i see the issue. But in the example i provided is only 2 dropdowns. I have 4 here, which then means that it gets quite complicated as dropdown 2 depends on 1, dropdown 3 depends on 2, dropdown 4 depends on 3. For now, i just added the next sequential function to the success criteria. It works fine - it loads all 4 options correctly. But when i change eg. option 2 manually, then it calls option 3 and 4 unintentionally, as they are not yet set manually. I can probably fix it with an if, it just doesnt feel right. – Emil Olsen May 17 '21 at 09:29
  • @freedomn-m I did not use the return $.ajax before as i recall. What should i return? Tried return jQuery.ajax(''); as i just need the .done() signal, but it didnt work – Emil Olsen May 17 '21 at 09:37
  • Change your existing code of `jQuery.ajax({ type: 'POST', url: ...` to `return jQuery.ajax({ type: 'POST', url: ...`. Then the return of ClassLevelOnChange will be a jquery promise that you can call `.done(...` on – freedomn-m May 17 '21 at 09:40
  • Nice, it worked for the option 2. I tried including option 3 nested inside. What is the documentation for "=>" ? Here is my guess, but doesnt do the trick. Basically, once ajax is done, it should run the next ajax which is based on the first, two more times. ClassLevelOnChange().done(() => jQuery('#CatID').val(data["org_cat"]), SubCatOnChange().done(() => jQuery('#SubCatID').val(data["org_subcat"]))); – Emil Olsen May 17 '21 at 09:51
  • I know its just a syntax thing, but i cant find the docs for the metod with .done(() => something + something_else); – Emil Olsen May 17 '21 at 10:03
  • @freedomn-m I found the docs for the arrow short, and now it works in sequence. Thanks a lot! Add on question if you have the time: Everything that comes after the ajax in the function is not executed when using return jQuery.ajax. I just moved it up above. But again, seems odd to me that it doesnt run it, even when the function is called manually. – Emil Olsen May 17 '21 at 13:39
  • Your code as `jquery.Ajax({` as the last line. If it's not the last line, then you need to store it in a variable: `var result = jquery.Ajax({... ; your_other_code(); return result;` See [`return`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return) *ends function execution and specifies a value to be returned*. Note, `your_other_code()` will also run *before* the ajax returns / before `success:` / before `.done()` – freedomn-m May 17 '21 at 15:02
  • @freedomn-m Thank you so much. I also layed in bed thinking that the return of course would end it. Thanks for elaborating on it. Means a lot. Web is not my prime language, as i am an engineer and not a web developer. – Emil Olsen May 18 '21 at 06:16
  • No worries - we all had to start somewhere and some of these concepts aren't the most obvious. – freedomn-m May 18 '21 at 07:45

0 Answers0