How to Manually Trigger Events in JavaScript

by

Occasionally, I find need to be able to manually trigger a predefined JavaScript event from within the context of a web application. Those of you who didn’t understand that first statement may want to stop reading now or risk suffering from extreme boredom, but those who actually have encountered the same challenge in coding, please read on!

Let’s examine a possible scenario that could merit actually taking hold of the reigns on individual event calls. Consider the situation that you have devised a very user friendly data entry form, and in conjunction with specifications, you have a select box that triggers certain fields to be visible based on user selection. Typically, you would have simply attached a listener to the select box’s onchange event that checks the value of the field and performs the necessary showing and hiding. So far, we have done nothing difficult or out of the ordinary.

Now, suppose you also have need to be able to populate the form with a preexisting data set and get your form to behave in the same way. You could always write an onload listener for the body of your page that runs all the field checks and manipulates the fields accordingly, and in most cases, this may not be a poor solution. However, when loading dynamically via AJAX or other method, the onload event may not be triggered, and therefore, neither is your form updated.

To get around this untimely issue, we can set up a sort of reset method that manually triggers all our events within our form, allowing the attached listeners within those fields to run their own checks and manipulate the form as needed. Let’s use a very simplistic example — that of the select box and hidden field mentioned above. In our case, let’s make it extremely easy: our select box will have only a yes and no value that will enable or disable an associated text field.

For sake of argument, let’s say we have a select box that allows a user to select whether or not they have an email address, and our listener will disable our text field for email address entry if the select box is set to no. With our form in place — and fields nicely ID’d for our selecting pleasure — we can easily write a very simplistic listener that will disable or enable the email address field based on what was selected:

document.getElementById('has-email').onchange = function (e)
{
    var el = e.target;
    if (el.options[el.selectedIndex].value == 'yes')
    {
        document.getElementById('email-address').enabled = true;
        return;
    }
    document.getElementById('email-address').enabled = false;
};

So far, we shouldn’t have covered anything ground-breaking in the least. However, let’s assume that we have just executed and AJAX request to populate the fields of our form and the select box has been dynamically set to no. Those of you with any JavaScript experience will know that this does not trigger the onchange event, because no user interaction has taken place with that select box. Instead, to update our UI, we need to trigger that event in order to disable the email address field.

To do so, we simply need to check if our desired event listener has been defined on our object and verify that it is a function that can be executed. This can very easily be done like so:

var el = document.getElementById('has-email');
if ((el.onchange || false) && typeof el.onchange == 'function')
{
    // We have a valid onchange listener declared
}

Now, we simply have to execute this listener manually, keeping in mind that our listener is expecting an event object, complete with a target. Since we have no true event object and we are solely dependent upon the target of the event, we can easily fake the event trigger by adding one line to our code above:

var el = document.getElementById('has-email');
if ((el.onchange || false) && typeof el.onchange == 'function')
{
    // We have a valid onchange listener declared
    el.onchange({target : el});
}

I fully realize that in and of itself, especially in our negligible example, this is not an extremely useful tool; however, in the right contexts, it can save you massive headache. Imagine for a moment that we have a dozen different elements for which we need to manually trigger events. We can set up a single handler that will do our execution for us and save up to dozens of lines of unnecessary code:

// Here is a VERY basic generic trigger method
function triggerEvent(el, type)
{
    if ((el[type] || false) && typeof el[type] == 'function')
    {
        el[type](el);
    }
}

// We could call this on multiple objects at any time
function resetFields()
{
    triggerEvent(document.getElementById('has-email'), 'onchange');
    triggerEvent(document.getElementById('other-field'), 'onclick');
    triggerEvent(document.getEleemntById('another-one'), 'onblur');
}

By writing our trigger handler in such a way as to allow providing both the object and the event we are checking, we could easily execute multiple events on a single object or even pick and choose different events to trigger at a given time. This can quickly become extremely useful on larger dynamic applications.

I hope this makes as much sense in reading as it did when I was writing it, and I hope that the usefulness is not lost in translation. Let me know if this is of some help to you.


4 Comments »

  1. Thanks for the post; this is just exactly what I needed!

    Comment by Rob — 1 Dec 2011 @ 2:03 pm

  2. Um,, in your first lines of code you mean to enable the text box so set it to true. Currently your setting it to be false twice. Typo.

    Comment by Dan — 17 Aug 2012 @ 8:35 am

  3. Dan, thanks for the catch. It’s been quite a while since I looked at this post, but I have updated the content accordingly.

    Comment by obsidian — 17 Aug 2012 @ 9:27 am

  4. Thanks for the post. I faced the same problem and your solution work splendidly. Save me a lot of headache. :)

    Comment by Sue — 31 Mar 2014 @ 1:43 am

RSS feed for comments on this post. TrackBack URL

Leave a comment