Problem Statement

We need to bind specific events like click, onchange of one element to another element due to there could be a situation where we cannot access the methods which are calling an event handler of an element which should even be needed for a new element.

 Solution

Before going to know the solution for this, I would like to share some scenario where I was benefited with this approach.

In one of my application, the functionality is, there is a dropdown where I am filling the data from backend data store and binding a Click event with some methods which are private to this scope. Now, in another scenario, I am forced to refresh the panel but shouldn’t reload this dropdown data. So, the only solution is to have a variable holding this dropdown innerHTML and once the panel is refreshed reset this dropdown innerHTML back to it. In this process, we are losing all the events bound dynamically.

So, I thought of having a copy of events before refreshing the panel and again re-bind the same events to the dropdown back.

Before going to the solution, we need to understand about jQuery._data() method. Below is the short explanation about this method.

jQuery keep maintains internally all the events information which is attached or detached for each individual element in the DOM. _data() is the internal (or private) method of jQuery is used to access all the events related data of given DOM element.

Before jQuery 1.8, all the events can access with public jQuery.data() method, but, since jQuery 1.8 they are not allowing to access events information using data() method because to remove the conflicts of having same names for the data variable and event names. Instead, we can access all events by calling _data() method (method starts with ‘_’ symbol represents a private and undocumented method). 

For example, if we want to read the events information from an element id ‘myele‘ as follows 

$._data($("#myele"), "events");

or

jQuery._data($("#myele"), "events");

Hah, now we are good enough to understand the following solution for our problem with information what we learned in the above couple of paragraphs.

In the following generic method, we are trying to push all the specific events (Click event) of given element and returning the same.

var eleEvents  = getEvents("click", $('#divpanel').find('li a')[0]); 

var getEvents = function (eventType, eleSource) { 
            var eleEvents = []; 
            var allEvents = jQuery._data(eleSource, "events"); 
            if (typeof allEvents === "object") { 
                if (typeof allEvents[eventType] === "object") { 

                    for (var i = 0; i < allEvents[eventType].length; i++) { 
                        eleEvents.push(allEvents[eventType][i].handler); 

                    } 
                } 
            } 

            return eleEvents; 
        }

Note: As it will be the same handler for all the elements we took the only first element from the array.

Once, we get all the events in an array we can apply these events to any elements. In our case, I need to re-apply to the same element after refreshing the screen/panel.

//Restoring events again after new filter view 
if (eleEvents.length > 0) { 
    for (var i = 0; i < eleEvents.length; i++) { 

        $('#divpanel').find('li a').bind("click", runSearchItemLinkEvents[i]); 
 } 
}

Now, you will be having the same functionality what you were before refreshing of a panel and no need to maintain a duplicate copy or making already existing private methods to public and disturbing existing functionality.

Hope this article helps you.

 

Happy Coding 🙂

<a href=”https://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=7194459″ rel=”tag” style=”display:none”>CodeProject</a>