0

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.

reallyJim
  • 1,336
  • 2
  • 16
  • 32

2 Answers2

1

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 );
    });
Esailija
  • 138,174
  • 23
  • 272
  • 326
  • *this* is why I need to improve my writing skills--so I don't leave stuff out! "from various places of the code" should actually mean that various pages/forms throughout the entire application. This is the kind of idea I was looking for. – reallyJim Oct 17 '11 at 17:22
  • Oh, no problem! Just realized I wasn't fully clear. (also the reason developers shouldn't write documentation, in my opinion) – reallyJim Oct 17 '11 at 17:54
0

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.

John Hartsock
  • 85,422
  • 23
  • 131
  • 146
  • The thing is, this logic could be enabled anywhere--was looking for a way to not add it to every "add new line" method in the application--I'll add that to my question – reallyJim Oct 17 '11 at 16:51
  • the code for making it work with every add new line would be simplistic and not repetitive if you are using jQuery. See my update – John Hartsock Oct 17 '11 at 16:53
  • Ok, SO was acting weird there for a moment--I saw your comment without seeing the update to the answer (for several minutes). I see what you're getting at, but was really trying to find a way (magic unicorn, maybe) to not be modifying the "add new line item" code to deal with this--thinking I can use it all across the app without much difficulty. – reallyJim Oct 17 '11 at 17:07
  • @reallyJim.... Not sure I see your "magic unicorn".... You would need to bind to the addbutton anyways to insert the new elements into the DOM. So why is not adding one simple line to your code to update the global reference of IDs and Values. – John Hartsock Oct 17 '11 at 18:55
  • magic unicorn--"there isn't a way". Since there are many data entry pages in the application, my goal was to avoid repeating a call to this routine in each "add new line here" method--as those are unique to the type of page that the user is on. at this point, I'm leaning hard toward adding LiveQuery anyway, as it does work--but at some point, the plugins are going to overwhelm the rest of the app. – reallyJim Oct 17 '11 at 19:15