3

I am trying to do go through the following scenario:

  1. User selects an employee (option) on a select element.
  2. User double clicks the option / clicks on a button that calls a function with a POST request to the server.
  3. The POST returns a string with JSON (containing a piece of HTML with the structure for a new select element).
  4. The POST callback executes two functions: one that loads an array with the JSON content and another that replaces the old select (containing a list of employees) with the new select brought by the POST.

Until this point everything works perfectly fine.

  1. The new select is filled with the options that are stored in an array (containing the data brought by the POST as JSON data).

I need to automate this. I can already make it work by using a click event on a new button that is generated, but my intent is to load the new select with its content loaded.

I don't want to generate the new select containing its content already because as the user interacts with the content will be changed. There's no need to duplicate the code to fill the select both in the jQuery and in the PHP. It's much simpler just to use jQuery all the time to generate the options for the select.

I tried the parameter "complete" but it still doesn't work.

EDIT: I created an js fiddle: https://jsfiddle.net/bmv35vwz/

My code:

function load_edituser(){
    iduser = $("select.showallusers option:selected").val();
    name = $("select.showallusers option:selected").text();
    $.ajax({'url': base_url+'/ManageUser/open_edituser',
            'type': 'POST',
            'data':{'iduser': iduser, 'name': name},
            'success' : function(data){
                var container = $('.usermanagement-canvas');
                if(data)
                {
                    get_user_apps(); //it loads the array with the JSON data, it's another POST function.
                    container.html(data);
                }
                else
                    alert('Error!!');
            },
            'complete': function()
            {
                display_user_apps(); //This is the function that fills the select with options, not being called here.
            }
    });     
}


function get_user_apps(){   

    //alert("it works! name: "+name+" id: "+iduser);

    $.ajax({'url': base_url+'/ManageUser/get_json_user_apps',
            'type': 'POST',
            'data':{'iduser': iduser, 'name': name},
            'success' : function(data){
                //alert("Hell yes");
                //var container = $('.usermanagement-canvas');
                if(data)
                {
                    appsinfo = JSON.parse(data);
                }
                else
                    alert('Error!!');
            }   
    });     
}

function display_user_apps()
{
    //alert(appsinfo.currentapps.length);

    //alert("Shut up");

    var i;
    for (i = 0; i < appsinfo.currentapps.length; i++)
    {
        var id = appsinfo.currentapps[i].idApplication;
        var appName = appsinfo.currentapps[i].appName;

        currentlist += "<option value="+id+">"+appName+"</option>";         
    }
    $("select.left-current").html(currentlist);

    for(i=0; i < appsinfo.excludedapps.length; i++)
    {
        var id = appsinfo.excludedapps[i].idApplication;
        var appName = appsinfo.excludedapps[i].appName;

        notallowedlist += "<option value="+id+">"+appName+"</option>";  
    }
    $("select.right-excluded").html(notallowedlist);
}

EDIT

I am aware of delegating events. I am using that for the button work:

$(".usermanagement-canvas").on("click","button.testbutton",display_user_apps);

However, I DON'T want to use a button. I want to the trigger the function automatically right after the AJAX changes the div's html. In this case, I'd need some sort of event that detects the HTML being changed.

Leandro
  • 367
  • 4
  • 20
  • 3
    jQuery is only aware of the elements in the page at the time that it runs, so new elements added to the DOM are unrecognized by jQuery. To combat that use [event delegation](http://learn.jquery.com/events/event-delegation/), bubbling events from newly added items up to a point in the DOM that was there when jQuery ran on page load. Many people use `document` as the place to catch the bubbled event, but it isn't necessary to go that high up the DOM tree. Ideally [you should delegate to the nearest parent that exists at the time of page load.](http://stackoverflow.com/a/12824698/1011527) – Jay Blanchard Jun 23 '15 at 13:49
  • I am doing this to make the button work: $(".usermanagement-canvas").on("click","button.testbutton",display_user_apps); However, I don't want to use the button. In this case I would need some kind of event that detects when the HTML is changed by the AJAX. Can you see that? – Leandro Jun 23 '15 at 13:55
  • 1
    Can you give us a js fiddle? – John Chrysostom Jun 23 '15 at 13:58
  • Have you considered `.on('change'....` – Jay Blanchard Jun 23 '15 at 13:58
  • 1
    Might be a good opportunity to look at jQuery's promise API (which `$.ajax` implements). You could chain these tasks in a way that makes sense for work-flow. Alternatively, you could attach to [`$.ajaxComplete`](http://api.jquery.com/ajaxComplete/), but you'd have to distill it down to determine if it's the ajax call you want to target. – Brad Christie Jun 23 '15 at 13:59
  • Yes, I considered .on('change') but it only works for INPUT elements and only if their .val() is changed. It doesn't work for HTML being changed in a div. – Leandro Jun 23 '15 at 14:00
  • its hard to understand exactly what you are asking for. Can you create a fiddle with an example of your problem? – CodeGodie Jun 23 '15 at 14:00
  • @JohnChrysostom Sorry, I don't know how to do that yet. – Leandro Jun 23 '15 at 14:02
  • Its very simple. Just go to this site: https://jsfiddle.net/, Save your work, and share your link with us. – CodeGodie Jun 23 '15 at 14:05
  • i believe your problem has something to do with Synchronous and Asynchronous conflicts. Do you know what this means? – CodeGodie Jun 23 '15 at 14:10
  • @CodeGodie Not really. I've read about that many times but I still don't understand. I am trying to put my code on jsfiddle. It's a pain to work with AJAX there... – Leandro Jun 23 '15 at 14:18
  • I've created the js fiddle. Not sure if it is clear enough since I couldn't manage to make the AJAX work: https://jsfiddle.net/bmv35vwz/ @JohnChrysostom – Leandro Jun 23 '15 at 14:27

1 Answers1

2

I would suggest this:

Trigger a custom event as soon as the data are appended into the desired element

'success' : function(data){
     var container = $('.usermanagement-canvas');
     if(data)
        {
          get_user_apps(); 
          container.html(data);
          $(document).trigger('htmlAppended');
        }
          else {
              alert('Error!!');
        }
     },

And then listen to the custom event:

$(document).on('htmlAppended', function() {
   get_user_apps();
});
kapantzak
  • 11,610
  • 4
  • 39
  • 61