javascriptjquerydom-eventsjquery-trigger

How can I pass a parameter/argument to the onchange listener that is programmatically triggered by a call to click


In my form in one set of repeating rows (created dynamically) there is a button on each row that allows the user to upload a file which will then be linked/tied to the data in that row.

head   head    upload
----   ----    --------
x      y       <button>
a      b       <button>
m      n       <button>

When any of those buttons are clicked I can obviously easily determine what row I am in. Let's say I am in the row with id="row_2". I have that in the function called from the button click.

Now I call $("#fileUploader").click() in order to initiate the file choice dialog. When the user chooses a file and clicks OK the OnFileUploaderChange() function is automatically called. Within that function I obtain the file and now I need to know that the initial button was from row_2 so I can link/associate it with the correct row.

Summary: OnButtonClick() triggers OnFileUploaderClick() which causes OnFileUploaderChange() to be automatically triggered. I have a value in OnButtonClick() which I need to have available in OnFileUploaderChange().

How can I do that?! How can I take a value that I know in the OnButtonClick() function and make it available within (pass it to) the OnFileUploaderChange() function when the OnFileUploaderClick() function is being called in between.

I have figured out how to pass parameters to the OnFileUploaderClick() function by changing $("#fileUploader").click() to $("#fileUploader").trigger('click', [ 2 ]). But that parameter is then available only within OnFileUploaderClick() and I need it in OnFileUploaderChange().

It is possible that the user would initiate uploading a large file and (while that is still uploading) would initiate uploading another smaller file so that multiple threads were uploading at the same time. So using globals in any way doesn't work - it's gotta be a parameter/argument to avoid race conditions and timing issues.

Here's a fiddle to help explain: https://jsfiddle.net/ho819tu0/1/


EDIT WITH SOLUTION:

Based on @vincent-d's comments and answer below (now marked as correct) I have fixed my code and here's another fiddle showing how it works: https://jsfiddle.net/sm2L9kt8/


Solution

  • The prolem is that any dom object and event created outside the initial bubble, will not be called and no parameters nor global variable will be set by those events/functions

    To solve this problem, jQuery have made a very nice function that take care of creating a fresh call on these live created objects

    The left-hand assignement have to be an object that contains the future "live created" objects and the right-hand is a selector that referes to these objects

    var colors=['green','yellow','blue'];
    $('.add').click(function(){
      let num=Math.floor(Math.random() * 3);
      var newHtml='<td>line 1 <button class="clicker">click to set to <span>'+colors[num]+'</span></button></td>'
      $('table tr').append(newHtml);
    });
    
    // click on add, it will set a new button, click on that button it will pass to this function because of the live event call
    
    function colo(colorvar){
      $('td').css('color',colorvar);
    }
    
    //this is the call, notice the body as left-hand, and .clicker button as right-hand
    
    $('body').on('click','.clicker',function(){
    // this refer to the element in the right-hand that is clicked (it can be a child, check at event target for more infos
      colo($('span',this).text());
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <button class='add'>ADD</button>
    <table>
    <tr>
    <td>line 1 <button class='clicker'>click to set to <span>red</span></button></td>
    </tr>
    </table>