Question

I have a document with a dynamic UI--users can add rows to an existing data entry form as needed to provide more information.

I'm using a simple array to track what items are on the screen so I can prompt for save, but I'm having trouble figuring out how to add the ID of the new item to my array. The logic that works for existing items is

$(document).ready(function () {
   $('.monitor').each(function () {
        monitorIds.push($(this).attr('id'));
        monitorValues.push($(this).val());
    });
});

I was hoping to be able to do something along these lines, but can't find a suitable way to do it: (I'm aware that this doesn't work, as the 'live' method isn't defined with an event)

$('.monitor').live(function () {
    monitorIds.push($(this).attr('id'));
    monitorValues.push($(this).val());
});

I've seen the LiveQuery plug in, but as I'm already deep into plugin hell, was hoping to avoid adding yet another one. Is there a better way?

EDIT: I wasn't clear about one point--I'm trying to keep this in a separate script, and do it dynamically, rather than update each script that might add elements to also call a function to add the element(s) to the monitoring array. Just trying to keep the work of the team to a minimum to implement this, even after they've written scripts to do the UI work.

Was it helpful?

Solution

Due to NodeList being a live collection, we can listen to element additions/removals like this:

(function(){
var a = document.getElementsByTagName("*"), elmCount = a.length;

    window.setInterval( 
        function(){
        var curCount = a.length;

            if(curCount !== elmCount ) {
            jQuery( document ).trigger( "DOMChange" );
            elmCount = curCount;
            }
        },
    200 );


})();

jQuery( document ).bind( "DOMChange",
    function(e){
    console.log("domchange");
    }
);

Downside is that if the DOM changes without the element count changing, it won't trigger. Tested on google chrome 14 on this very page.

Also, it should be slightly more efficient to do this instead of creating new jQuery objects:

$('.monitor').each(function () {
        monitorIds.push( this.id );
        monitorValues.push this.value );
    });

OTHER TIPS

Why not just write a function called getMonitorData and call it when needed

function getMonitorData() {
  var monitorData = { monitorIds: [], monitorValues: [] };

  $('.monitor').each(function () {
        monitorData.monitorIds.push($(this).attr('id'));
        monitorData.monitorValues.push($(this).val());
  });
  return monitorData;
}

For adding to every Add New Button

var globalMonitorData;

$(document).ready(function () {
  $(".myAddNewButton").click(function () {

    // add your new stuff to the DOM HERE

    globalMonitorData = getMonitorData();
  });
});

But by separating the getMonitorData() from the click handler you can also use it when form is submitted or other operations.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top