Is it right to place an event inside an event?

I have a script in which I am going to add the XLS file, as soon as I check the file format, I close bootstrap modal and open another modal file, which is a confirmation window, to find out if the user is sure to download this file.

There is a confirmation button in this confirmation window, after I clicked, I want me to execute a function that will run AJAX in order to fulfill a request to the server.

However, because of this, I had the following doubts:

  • Which of the two ways is best (and the most correct) to run the code, and why?
  • Why is the click event of the first input file executed if there was no change in the event? I mean, I am adding a file and the event is being changed, and I can make clicks as many times as I want, is it not supposed that I have to add another file in order to run the function again inside?
  • Place an event inside an event, does it have a name?

$(document).ready(function(){ //First input file $(document).on('change','#file', function(){ let file = $(this); let nameFile = file[0].files[0].name; let button = '<button type="button">Clic input 1</button>'; $('#button').html(button); $('#button').click(function(){ console.log('CLICK IN FIRST INPUT FILE!'); }); }); //Second input file $(document).on('change','#file2', function(){ let file = $(this); let nameFile = file[0].files[0].name; let button = '<button type="button">Clic input 2</button>'; $('#button2').html(button); }); $('#button2').click(function(){ console.log('CLICK IN SECOND INPUT FILE!'); }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input type="file" id="file" name="file" /> <div id="button"></div> <div style="margin-top:20px"></div> <input type="file" id="file2" name="file2"/> <div id="button2"></div> 
+8
javascript jquery
source share
5 answers

Places an event inside an event, does it have a name?

He has a name. Bad idea . Let me run away. What happens when you execute the following code.

 $('#button').click(function(){ console.log('CLICK IN FIRST INPUT FILE!'); }); 

A click event is registered on a button. Once an event is registered, it will fire every time, no matter how many times you click.

When you put this code inside another event handler, as in the first example, it runs every time the input files are changed and a new event handler is registered. Therefore, when you select a file, and then decide to change it, changes to the file are entered twice, and you register 2 registered events. Now press the button, you will get 2 new console logs printed with one click !!! Give it a try.

Why is the click event of the first input file executed if there is no event change?

Because, as the event handler works, you register once, after that they are launched every time after that.

Which of the two methods is better (and the most correct) for running the code, and why?

Obviously not the first, because it is a bad idea, not the second. In the case of the second, you attach the event to the division, which will contain the button. Thus, you do not need to click on the button, just click on any right side of the button, the event will be fired !!!

So, if none of them are right, what can we do?

  • Do not create a button / any html javascript element for such simple tasks. Do it with HTML, simple and simple.
  • Do not embed an event handler in another. Put one event handler inside another, this will complicate the situation. Just put all the event handlers directly inside the document.ready jQuery event. document.ready only fires once.
  • When you need to control user action, then show / hide your button or other html element using javascript based on the required conditions.

My suggestion is doing something like this.

 $(document).ready(function(){ // Hide the button at first $('#button').hide(); // When File-input changes $('#file').change(function(){ if(**the file-input has a file selected**){ $('#button').show(); } else{ $('#button').hide(); } }); // When Button Clicked $('#button').click(function(){ // Do the action }); }); 
+11
source share

Which of the two methods is better (and the most correct) for running the code, and why?

I think this is better:

 //Second input file $(document).on('change','#file2', function(){ let file = $(this); let nameFile = file[0].files[0].name; let button = '<button type="button">Clic input 2</button>'; $('#button2').html(button); }); $('#button2').click(function(){ console.log('CLICK IN SECOND INPUT FILE!'); }); 

Mostly because it is more readable and easy to follow. There is no need to set the button press event AFTER the input has been changed. It’s better to change the state of the button as you do it. It would be even better to hide / show the button, for example:

 $('#button2').show(); 

And first he hides:

 <div id="button2" style="display: none">Click me</div> 

Why is the click event of the first input file executed if there was no change in the event?

In my test, all this worked correctly.

What is this called?

Change events should be raised only when a file is pressed and assigned to the input.

+2
source share

you bind the same event several times to the same button object. binding of the same event to the same object in another event, which can be repeated, will lead to its re-binding (stacks events and fires them, in this case β€œit” several times). the binding of an action to an event should occur only once per object. and I see that you are attaching a click event to a div instead of a button. you might need to consider dynamic linking with .on() like this

 $(document).ready(function(){ //first file change event $(document).on('change','#file', function(){ let file = $(this); //handling empty selection if(file[0].files.length == 0){ $('#button').html(""); return; } let nameFile = file[0].files[0].name; let button = '<button type="button">Clic input 1</button>'; $('#button').html(button); }); //second file change event $(document).on('change','#file2', function(){ let file = $(this); //handling empty selection if(file[0].files.length == 0){ $('#button2').html(""); return; } let nameFile = file[0].files[0].name; let button = '<button type="button">Clic input 2</button>'; $('#button2').html(button); }); //first button dynamic event (doesn't stack) $('#button').on('click','button', function(){ console.log('CLICK IN FIRST INPUT FILE!'); }); //second button dynamic event (doesn't stack) $('#button2').on('click','button', function(){ console.log('CLICK IN SECOND INPUT FILE!'); }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input type="file" id="file" name="file" /> <div id="button"></div> <div style="margin-top:20px"></div> <input type="file" id="file2" name="file2"/> <div id="button2"></div> 

note that you need to handle not file selection (for example, the number of files is 0), as in my code

+1
source share

Places an event inside an event, does it have a name?

He has a name. It was called a chain daisy, and this is not a good idea.

0
source share

not enough comments for comments

I had a reason to do it. I had an unpleasant task - to thin out after 2 years a code written by one person with little maintenance or code discipline. I wanted to keep the code structure intact, so I clicked chain-bound events to make some improvements.

To avoid some of the problems mentioned in the better answers above, just forget to call $(selector).off("click") before binding the next event.

0
source share

All Articles