griegs
griegs

Reputation: 22760

jQuery detect programatic change to field

I have a hidden field called #myHiddenField say.

The content of this field is programatically changed at various places.

I'd like a method that detects that change. The change event won't fire unless I type into the field but this is impossible.

Is there a jQuery way to detect programatic content change in a field?

Upvotes: 33

Views: 16806

Answers (5)

Protector one
Protector one

Reputation: 7271

I couldn't get the change event to fire when the field changed by Blazor of the .NET framework, but alternatively you could redefine the value property of the input field:

Object.defineProperty($('#myHiddenField')[0], 'value', {
    get() { debugger; return "1"; },
    set(value) { debugger; }
})

Upvotes: 0

Md. Zubaer Ahammed
Md. Zubaer Ahammed

Reputation: 981

Case 1: You want to change the value programmatically yourself and just want to dispatch an event when the value is changed.

$('#myfield').text('New value');
//$('#myfield').val('New value');
$('#myfield').trigger('change');

Case 2:

Suppose, you want to detect the programmatic change to a field which is not written by you. So, there is no way you can trigger 'change' event.

In this case, Use 'DOMSubtreeModified' to detect programmatic changes to descendant elements of a parent element.

Example:

<div id="product-addons-total">
    <div id="total_price">200</div>
</div>

$(document).ready(function() {

    jQuery('#product-addons-total').on("DOMSubtreeModified",function(){
        console.log('content changed');
        //tamp_price_change_handler();
    });
});

Now, if the value of the "total_price" changes somehow programmatically, it will fire "DOMSubtreeModified" event. Example:

jQuery('#total_price').text('300');

Caution for Case 2: DOMSubtreeModified can create an infinite loop and greatly degrade performance. Instead, it is encouraged to use MutationObserver.

Example with MutationObserver:

// create an observer instance
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    console.log(mutation.type);        
  });    
});

// Let's configure the observer
var config = { childList: true, subtree:true, attributes: true, characterData: true,
    characterDataOldValue: true, attributeOldValue: true };
//Let's get a node.
var target = jQuery('#product-addons-total').get(0); 
// Let's pass the target and configuration to the observe function.
observer.observe(target, config); 

Case 3:

The above ways can detect a change in the DOM. But if you want to change the value of an input field programmatically, then these events won't fire. In that case, the only way is to trigger an event manually. So, first change the value of an input field and then trigger an event manually.

$('#inputfield').val(456465).trigger('change');

//Now the change event will fire.
$('#inputfield').on('change', function() {  
    console.log('input filed has been changed');
});

Upvotes: 6

Arne H. Bitubekk
Arne H. Bitubekk

Reputation: 3043

Setting the value using .val() in jQuery doesn't trigger a change event so you'll have to use .change() or .trigger('change') to trigger an change event. You can choose to use either .change(function() { ... }) or .on('change', function() { ... } to detect the change event to the field.

$('#myHiddenField').change(function() {
    alert('content changed to: ' + $('#myHiddenField').val());
});

$('#btnChange').click(function() {
    $('#myHiddenField').val("new content");
    $('#myHiddenField').change();
});

https://jsfiddle.net/qeg5of2a/1/

or

$('#myHiddenField').on('change', function() {
    alert('content changed to: ' + $('#myHiddenField').val());
});

$('#btnChange').click(function() {
    $('#myHiddenField').val("new content");
    $('#myHiddenField').trigger('change');
});

https://jsfiddle.net/qeg5of2a/2/

.change is just shortcut for .on('change', handler) and .trigger('change') so either is fine

Upvotes: 0

pinkfloydx33
pinkfloydx33

Reputation: 12769

The DOM cannot detect the programmatic raising of events. I actually ran into this yesterday. I don't remember where I read it, but the solution was to actually call .trigger() on the jQuery element. jQuery Doc

Upvotes: 7

prodigitalson
prodigitalson

Reputation: 60403

You should be able to trigger the change event with:

$('#myHiddenField').change();

OR

$('#myHiddenField').trigger('change');

Of course this will require the block of code responsible for updating the filed to make one of those calls after it has done its work.

Upvotes: 35

Related Questions