CodeMirror going into infinite loop when implementing on change function - javascript

I need to track change in CodeMirror editor. So I implemented:
CodeMirrorInstance.on("change", function(CodeMirrorInstance){
$scope.onChangeFunc(CodeMirrorInstance);
} );
In onChangeFunc I do insert based on condition new value using
CodeMirrorInstance.setValue(newCode);
Apparently it leads to infinite loop. How to break this vicious circle?

setValue will always trigger another "change" event (it changes the content, after all). You'll have to make your change handler clever enough to not cause additional changes for changes you yourself caused. Looking at the origin property of the second argument passed to the "change" event handler might work -- it contains a sting that identifies the source of the change, which will be "setValue" when setValue was called.

Related

What is acctually .val().trigger('change') doing?

I'm confused by this line in my project:
This id: categories-product belong to <select> and I've seen in project someone wrote this: And I'm wondering what this basically means ?
$('#categories-product').val(product.category.id).trigger('change');
Please could anyone explain me this?
Thanks
Most jQuery methods provide chaining by returning this (which is the jQuery set you called the method on). This is an absolutely key part of the jQuery API. val is one of those methods. So that code is doing this:
$('#categories-product').val(product.category.id);
$('#categories-product').trigger('change');
...but without having to look up the element a second time.
So it's setting the value of the select, and then triggering the change event on it (presumably so handlers for that event do something).
trigger('change') will actually allow the javascript runtime to execute the change event for the element. If you have associated any change event to that element then this will allow to explicitly trigger that change event.
Actually, the work of trigger() is to just execute all handlers and behaviours attached to the matched elements for the given event type. And specifying the event name as a parameter will only trigger that event. Like,
trigger('change') //triggers the change event listener only
trigger('click') //triggers the click event listener only
So, your code
('#categories-product').val(product.category.id).trigger('change');
Will set the value of the #categories-product and then this will explicitly trigger the change event so that the change action that is associated with this element is executed.
To understand it better you can break this line in 2 statements
$('#categories-product').val(product.category.id);
$('#categories-product').trigger('change');
Now, it is clear that the first line sets the value and second line triggers the change event. The above is just a shorthand way of clubbing the statements into one statement.
There must be a drop down i-e select tag in your DOM with id as categories-product.
And
$('#categories-product').val(product.category.id).trigger('change');
is setting some value as selected value and then triggering a change event so that if there is any listener added for change event on that selector, the callback should be executed
It is called Chaining in Jquery, find more details at Jquery Chaining. It is equivalent to
$('#categories-product').val(product.category.id);
$('#categories-product')..trigger('change');

set event on dynamically changed data in field via jquery

I have several field
$("#a1").change(function(){
console.log('fire'); });
but when value change not user event not work
form[0].val = 100;
event not work
how can i catch this change data ?
ps data changes from different places not my code suggestions like trigger('change') not good idea
I do not think that events will fire when you set the value in that fashion.
Does it work when you set the value of the element in the browser?
What you can do is call form[0].change(), and it should work.
Changing the value property will not fire the change event.
In fact, your code should be changing value and not val.
You could call it explicitly after updating it.
form[0].value = 100;
form.change();
But you mention that is not an option.
The only other way is to poll for changes.
You could define a way of working with the controls inside your form. Create a javascript function that external developers can call to set the value of a given field and make them use that method. Then you can fire change or do whatever you want to your hearts content.

Recursive issues

When I have two text fields which listen to change event from one to another, it causes me an error saying too much recursion. Anyone has good solution?
well you can hold a flag that holds the identity of the true event dispatcher. and break the event triggering if it matches.
You added an onchange event listener on both text fields; problem is, changing one text will trigger a change one the other field, which would trigger the onchange result for the first one, etc., resulting in an infinite loop.

How to know when a textbox changes (without waiting for blur)?

I have an <input> textbox.
I wish to call a function when it has been modified. The default behavior of the change event is to only trigger on blur, but I need to call my function as soon as the textbox's text changes and can't wait for blur.
I'm not sure the best way to do this. I thought of maybe handling keydown and then testing the value of the keyCode for a key that would modify the value. So... ignore arrow keys, etc. But that seems awkward and I don't think I can figure out the test to make it work.
I also thought about recording the inital value and comparing to this value but then I wouldn't be notified in the case when the value changes back to the original.
Maybe there's a better way?
I'd appreciate any suggestions.
a combination of focus and keyup is probably your best bet. record the initial value in the focus handler, and check against the current value in the keyup handler. (the new input value, if any, is available when keyup fires).
You can use the keypress function.
You can use the change() function

How to stop onChange in JavaScript

In one of my selection boxes, I have an onChange="..." specified...
because I want to change some other form value after any selection changes.
However, in the same page, some weird case I have to manually set the value.
So I have to use some JavaScript to set the value of the selection combobox, but in this case, I don't want that onChange event to be fired.
How can I walk around it?
Forgot to mention that I am actually using dijit.form.comboBox.
For normal HTML form comboBox, it won't cause any issue.
Only I use the dijit comboBox, and I try to set the value to some other value, dojo will trigger the onChange.
If you are using Dijit, then you can pass an additional false flag at the end of the set() method that will prevent the widget from firing the onChange event.
For example:
dijit.byId(myComboBox).set("value","Choose an option...",false);
Found this answer from Paul Christopher at http://dojo-toolkit.33424.n3.nabble.com/onchange-event-firing-when-setting-value-of-a-Select-programmatically-td3985692.html. It worked perfectly!
myDigit._lastValueReported = myValue;
myDigit.set('value', myValue);
You don't need to do anything. Setting the value with Javascript will not fire your onchange event handler.
In general, setting the value with JavaScript won't fire onchange. If you're dealing with a strange browser that does fire it, you could remove the onChange (element.onchange = null), change the value, then add it back (element.onchange = functionname) afterwards.
FYI, this answer is not fully correct. It is true that simply setting the value does not trigger the onChange event, BUT as soon as the control loses focus, the change will be detected and onChange will be fired.
So delaying onChange is not really the same as preventing onChange - which is what I need to do!
I could temporarily remove the event, blur and refocus the field, and then restore the event, but this is an ugly hack. It is complicated by dynamicaly added events like jQuery. so really what I'd like is to set the 'focus value' to the 'new value', but haven't been able to find this. I could try setting the defaultValue, but this would prevent a correct form.reset().

Categories