Yahoo.Util.Event get fired twice

Hello,
i am trying to inject a simple custom event in editview like this:

var handler = YAHOO.util.Event.addListener('cdz_contracts_mobile_cdz_service_lists_name', 'change', function(e){     
	var name = this.value;
	var id = $('#cdz_contracts_mobile_cdz_service_listscdz_service_lists_ida').val();
	if(id) {
    		alert("You have selected "+name+" with ID: "+id);
    		//e.PreventDefault();
	}
});

It works but it gets fired twice.
During browser dev tools inspection this event is injected twice.

Tried with PreventDefault() but the subsequent event will be, of course, disabled.
What am i doing wrong? What is causing this?
I’ve also tried with jquery .on() but in this case it won’t get fired.
I cannot let it so because in real scenario thos event will call an ajax request.

Many Thanks
Any help highly appreciate

@rainolf

  1. I don’t see any problems with jquery. You should sure that page was loaded only.
jQuery(document).ready(function(){
... //your code
})
  1. About YAHOO.util.Event.addListener I didn’t use it. Look at the file for example:
    jssource/src_files/modules/Meetings/duration_dependency.js

Yes, already done, please see this:

$(document).ready(function() {
    $('#cdz_contracts_mobile_cdz_service_lists_name').on('change', function(){
        alert("Hello");
    });
});

Please note that it is not a simple field but a relate one instead.
So seems that in some way it is triggered twice…
Note also that it must work in both ways, one by popup selection and other with click on autocomplention
Any hint?

Thanks

I recently solved a problem with events firing multiple times with this construct I found on StackOverflow:

     $(document).off('keypress').on('keypress', function(e) {

try it, it just might work

Hi, thanks for the tip.
However it gets fired(once this time) only in autocomplete and not when an item is selected from popup view:

$('#cdz_contracts_mobile_cdz_service_lists_name').off('change').on('change', function(e) {
        alert("CIAO");
    });

Do you know why?
Many Thanks

I don’t know, and I warn you I’m a beginner with JS…

But I would guess that it’s Javascript code writing the value when the popup returns, not a real browser event. So it’s not triggering your code.

I would search for the place where that is happening: which Javascript is running when returning from the pop-up. Then customize that with your code and forget about browser events.

That’s why i used Yahoo.util.Event
In that case it worked both with popup and autocomplete, but get fired twice
See my example above, maybe you can hep me.

Thanks

Try the first technique here

Defining the function once (with a name), instead of defining the function as a parameter.

Also note that you can set a browser breakpoint on an event; this should be a nice way to find two things

  • if your code adding event listener is getting called twice, thus adding two listeners

  • if the listener is getting called twice, what is the difference between the two call stacks? Meaning: where is it getting called from, and why?

I am trying the first solution but seems that Event is still triggered twice

   addIt();

    function addIt() {
      $("#cdz_contracts_mobile_cdz_service_lists_name").addEvent("change", handler);
      alert("Handler");
    }
    
    function handler(e) {
      alert("Hello");
    }

Hi,
this is my working solution.
The key note is to avoid that event will get fired multiple times because, in my case, an ajax request to custom EntryPoint will be sent.

var handler = YAHOO.util.Event.addListener('cdz_contracts_mobile_cdz_service_lists_name', 'change', function(e){
        var name = this.value;
        var id = $('#cdz_contracts_mobile_cdz_service_listscdz_service_lists_ida').val();
        //#!@ # Check if present
        if(id && name) {
            alert("You have selected "+name+" with ID: "+id);
            //do action
            //#!@ # Stopping further default actions, otherwise the change event could be triggered more than one time
            YAHOO.util.Event.preventDefault(e);
        }
    });
    //#!@ # Without this every time you try to digit different values in field will cause double triggering
    //#!@ # We reset those fields on click being sure that further autocomplete selection will start from scratch
    $('#cdz_contracts_mobile_cdz_service_lists_name').on( 'click', function() {
        SUGAR.clearRelateField(this.form, 'cdz_contracts_mobile_cdz_service_lists_name', 'cdz_contracts_mobile_cdz_service_listscdz_service_lists_ida');    
    });

The YAHOO.util.Event.addListener will be used because it works both with autocomplete and popup in relate field.
YAHOO.util.Event.preventDefault(e); is used to stop further triggering, after some test this is the only way
e.PreventDefault() has strange behavior.

Hope is also useful for someone else.

Note:
Now what i am trying to understand is regarding my ajax request.
The question is: “Better call a custom EntryPoint or custom Controller Action?”
My thoughts is about performance and security.

What do you think about?

Many Thanks

That double-triggering when the user is typing sounds a lot like the same problem I mentioned above.

Where exactly are you adding your code? Do you know what additional JS is on the same view?

A possible explanation is that this screen has the same keyboard events issue, which causes multiple events to fire, and your code is working inside those calls and so you need additional checks to avoid duplicating things. But if we could stop this it the root level we would be better off.

About your new question, I think Ajax calls should go through Controller, no reason not to. This way you stay within the intended architecture.

Added in editviewdefs.php of custom module.
No additional js is included:

 'includes' =>
      array(
        0 =>
        array(
          'file' => 'modules/CDZ_Contracts_Mobile/caderize/js/cdz_ContractsMobile.js',
        ),
      ),

What i see now is that if AjaxUI is enabled for this module it is causing “$(document).ready(function()” fired twice, disabling it gets fired only once.
I think, in terms of performance, it is better to keep it enabled.

How to avoid it? Cause it should be the root of all problems, see attached

What I meant about the “additional JS” is that any Edit view will get a lot of stuff included in it by default. That “AjaxUI support” is an example. I am not sure where that is coming from, and I’m afraid I don’t have time to investigate. The browser console is a good place to start looking. A breakpoint on the “document ready” event can also be informative.

But I agree that getting to the root of this problem and avoiding any duplicate events would be valuable. It gets pretty confusing to do any coding in JS when events are out of control…

Thanks.
I found this, maybe pertinent:

Currently no solution i guess

1 Like