Question

I have a page that displays a list of records. The user can select the record status using radio buttons, e.g.:

<div id="record_653">
  <label><input type="radio" name="status_653" value="new" checked/>new</label>
  <label><input type="radio" name="status_653" value="skipped" />skipped</label>
  <label><input type="radio" name="status_653" value="downloaded" />downloaded</label>
</div>

I am using JQuery to send the changes made by the user back to the server, where I use them to update the database. This is a simplified version of what I do:

$("#record_653").click( 
function(event) { 
    var url = ...,        
        params = ...;
    post(url,params);                    
});

The problem is that this code will create requests even if the user clicks the same button that was previously checked. What I actually want is the "on change" event, except its behavior in Internet Explorer is not very useful (e.g. here).

So I figure I somehow have to identify if the click event changed the value.

Is the old value stored somewhere (in the DOM? in the event?) so I could compare against it?

If not, how should I store the old value?

Was it helpful?

Solution

The old value is not stored someplace where you can query it, no. You will need to store the value yourself. You could use a javascript variable, a hidden input element, or jQuery's data() function.

EDIT

The jQuery data function provides access to a key-value-pair data structure as a way to store arbitrary data for a given element. The api looks like:

 // store original value for an element
 $(selector).data('key', value);

 // retrieve original value for an element
 var value = $(selector).data('key');

A more developed thought:

$(document).ready(function() {

    // store original values on document ready
    $(selector).each(function() {
        var value = $(this).val();
        $(this).data('original-value', value);
    })

    // later on, you might attach a click handler to the the option
    // and want to determine if the value has actually changed or not.
    $(selector).click(function() {

        var currentValue = $(this).val();
        var originalValue = $(this).data('original-value');
        if (currentValue != originalValue) {

            // do stuff.

            // you might want to update the original value so future changes
            // can be detected:
            $(this).data('original-value', currentValue);
        }

    });

});

OTHER TIPS

$('#record_653 input:radio').each(function() {
    $(this).data('isChecked', $(this).is(':checked'));

    $(this).click(function() {
        if ( $(this).is(':checked') !== $(this).data('isChecked') ) {
            // do changed action
        } else {
          $(this).data('isChecked', !$(this).data('isChecked') );
        }
    })

});

This was complicated to do in my head but I think you want something like this.

As was suggested by meder and Ken Browning, I ended up using JQuery's data() to store the previous value and check against it on every click.

Storing an "is checked" boolean for each input radio is one solution. However you need to maintain this value. So in the click event handler, in addition to changing the "is checked" of the current input, you need to find the input that was previously checked and change its "is checked" data to false.

What I chose to do instead was to store, in the parent element, the currently checked object. So my code looks something like:

$(document).ready(  
    function()  {
        // find the checked input and store it as "currChecked" for the record
        $("#record_653").data("currChecked", 
                             $(this).find("input:radio:checked")[0]);
        // add the click event
        $("#record_653").click( function(event) {
                 if ($(event.target).is("input:radio") && 
                     event.target !== $(this).data("currChecked")) 
                 {
                    $(this).data("currChecked", event.target);
                    handleChangeEvent(event);
                 }
            });

        });
    }
);

Thanks

I had the same problem, but with FF I managed to deal with it using the onchange event rather than the onclick.

This is exactly what I was looking for to deal with IE7. Works like a charm! Thanks for the detailed solution!

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