KeyDown event can't use edited state value - javascript

I made contentEditable div to implement ChatFooter component like this(Code Sandbox).
but when i called sendMessage function via onKeyDown event, message value is still empty even i edited.
Weird thing is message value is working well on onChange(actually onInput) and when i called sendMessage directly with onClick event.
Code Sandbox : https://codesandbox.io/s/p56466rxvq
P.S. it was same when i used react-contenteditable lib instead of mine.
Thanks.

First thing I saw in your code is that you are returning onKeyDown event from all keys except enter and shift. Also you are not setting the message property of state. You are sending empty message.

Related

Angular- Adding event listener "input" and prevent user from spamming a key

I'm using Angular, Javascript and Typescript and Ionic.
I have a function createDropdown(inputField, arrayOfItems) which will attach a dropdown to the input field being passed populating the dropdown with the array provided.
This will work as a "autocomplete" dropdown, that's why I need a add an event listener "input" so it will look something like this:
createDropdown(inputField, arrayOfItems){
inputField.addEventListener("input",()=>{
//Logic to create dropdown
});
}
The problem is that, after adding the event listener to the input field, if the user spams a key "A" for instance from the keyboard, then this creates lag or delay and eventually the app crashes. Is there a way to prevent this from happening? I have tried "keyup", and it fixes it. However, with this, pressing any key from the keyboard will trigger the createDropdown function, for example: pressing "Control" or "Alt".
The end result should be, having the user typing in an input field, then the results that match should be displayed in the dropdown so the user can select from it. The more they type, the more accurate the results become.
You could use for example setTimeout() + implementation of a spinner.
Here an example for what I mean
https://stackblitz.com/edit/how-to-trigger-an-event-in-input-text-after-i-stop-typingwritin
What you're looking for is called "debouncing input". Take a look here: https://stackoverflow.com/a/36849347/4088472

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');

CodeMirror going into infinite loop when implementing on change function

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.

onchange wont fire after programmatically changing html select dropdown

I have a select inside HTML
<select id="league" name="league">
which I'm listening for changes inside my javascript.
var league = dojo.byId("league");
dojo.connect(league, "onchange", function (evt) { //do stuff }
Which works fine.
However I have a link that I can click which updates the select:
League
The link works as it updates the selected value of the select with the following function.
function updateSelection(NewLeague){
dojo.byId('league').value = NewLeague; // works
dojo.byId('league').onChange; //this isnt working
//dojo.byId('league').onChange(); //this throws: TypeError: dojo.byId("league").onChange is not a function
}
My problem, as I've read through other stack posts is that programmatically updating the value wont trigger onChange, thus I need to call onchange in the code (shown above). As per the comments inline, the onChange isn't being triggered or throws an error. My first thought that it has something to do with the dojo.Connect which listens for onChange, but I havent found any information that says I cant do this, nor any explanation how to get around it.
Any ideas?
Select onchange doesn't fire for programattic changes, you need to fire it yourself with league.onchange();
As noted by #Greg, the call should be lowercase.
Additionally, I don't know if dojo has a trigger method, but in jQuery this would be done as jQuery('#league').trigger('change').
Depending on your version of dojo you may also want to check: http://dojotoolkit.org/reference-guide/1.8/dojo/connect.html
Have you tried just calling the select by it's id using normal js?
document.getElementById('league').onchange.call();
As others have said, you need to trigger the event yourself, just setting the value does not do that. See the code on How to trigger event in JavaScript? to see how in a cross-browser way.

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