I can't seem to find out what (input) does in Angular. Here's the code sample:
<input class="form-control" placeholder="person" (input)="filterPersons($event.target.value, 'Hair Colour')">
I have placed a log inside the filterPersons method to see when it is executed but nothing gets outputted at all when I click/unclick the checkbox or submit the form. What functionality does (input) actually provide?
Worth noting that there are no errors and the codebase works fine and in fact there are multiple examples of this throughout the codebase so I know it's not a simple typing error but I cannot see what effect it has.
It seems like what you want is this:
https://developer.mozilla.org/de/docs/Web/HTML/Element/Input/checkbox
as the input type and then you can listen for changes via the change event instead of input (There is no input on checkbox):
<input type="checkbox" class="form-control" placeholder="person" (change)="filterPersons($event.target.value, 'Hair Colour')">
As on getting triggered on the form submit, you would have to do that programmatically or store the state when the input changes.
Try providing type="text" / type="number" and I'm sure you will see your method being executed. The (input) event fires on every key press and can be used if you want immediate validation of an input (The (change) event fires when you leave the control.)
I don't know why could not able to find what (input) actually does. In your code
<input class="form-control" placeholder="person" (input)="filterPersons($event.target.value, 'Hair Colour')">
(input) call filterPersons method with 2 parameters.
Please check the stackblitz link and see the console.log value. It changes on every single input.
StackBlitz Demo Link.
Related
I am having an html duration picker inside my code like below. I can either type in the time or change the time by clicking the up/down arrows.
I am binding its value to a variable using ngModel
<input type="text" id="mTime" [class] = "'html-duration-picker'" [(ngModel)]="manufacturingTime">
I also have another text field which shows the result of the time duration divided by another value. So, when the time duration is changed, this field needs to be updated on the fly.
<input name="assemblyTime" class="form-control right" [disabled] = true [ngModel]="(manufacturingTime/numberOfWorkers)">
All these functionalities were working fine. Recently, I moved from angular version 11 to V 13. Since then,when the time is changed by clicking the up/down arrows, it is not updating the ngModel, whereas if the time is typed in, the ngModel is updated. I tried adding code on (change), (ngChange), also tried using changeDetection. But it seems, angular doesn't recognize the value change when it is done using up/down arrows. So these events are not fired. I can access the duration using ViewChild to save the duration to database. But the second textbox which shows the divided value cannot be updated on the fly. Can someone suggest a way to fix this?
The duration picker is a third party tool developed in Javascript.
https://nadchif.github.io/html-duration-picker.js/
So I cannot control the events on arrow clicks.
I suspect that this may work, as it could cause the expression to be evaluated more often.
In your component class, add a getter that calculates the divided value like so:
public get dividedValue(): number {
return this.manufacturingTime / this.numberOfWorkers;
}
Then assign that value to the second input:
<input name="assemblyTime" class="form-control right" [disabled] = true [ngModel]="dividedValue">
Again, this is just a wild guess, because I have no code to run.
If you provide a runnable Stackblitz example, I would be happy to help you debug it.
If you take a look at the html-duration-picker code, in the function definition for changing values using arrow keys changeValueByArrowKeys; the last line:
insertFormatted(inputBox, constrainedValue, false);
has third argument false which is passed to the function insertFormatted. This function insertFormatted creates the (change) or (input) events.
In the above image you can see that any event be it (change) or (input) is only triggered if the dispatchSynethicEvents is not equal to false.
To handle this you can create a fork the library, make changes to it, store a local copy and use that instead of the library. Alternatively you could raise a PR and ask the author to consider your change.
To solve it you need to basically remove that if condition. It will then emit (input) event no matter what.
I am currently working on a project, that requires me to implement the following:
I've got 2 input fields - a regular text field, and a checkbox.
What I want to do is - if the user fills in the text field, the checkbox should be automatically disabled. If the checkbox is checked instead, the text field should be disabled.
What I've come up with so far is:
<input type="text" name="num-input1" id="dis_rm" value=""
onblur="document.getElementById('dis_per').disabled = (''!=this.value);" >
<input type="checkbox" name="num-input2" id="dis_per" value=""
onblur="document.getElementById('dis_rm').disabled = (''!=this.value);" >
If I fill in the text field, the checkbox is successfully disabled. However, if I tick the checkbox, the text field remains available.
What am I missing?
If I were you I would:
Move my JS code out of the HTML and into a separate file or at least into a script element.
Use document.getElementById to find an item in the DOM. See https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById
Once you have the element from the DOM, add an event listener for the blur events like this myElement.addEventListener('blur', myCallbackMethod). See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener for more info.
Inside your callback method you can use event.target.checked to see if the element you've added the event listener to is checked.
Here is a little snippet to get you going:
const
textInput = document.getElementById('element-ID-here'),
checkbox = document.getElementById('element-ID-here');
function onTextInputBlurHandler(event) {
// if textinput value is empty then
// set disabled for checkbox to false
// else
// set disabled for chexbox to true
}
textInput.addEventListenet('blur', onTextInputBlurHandler);
<input type="text" name="num-input1" id="dis_rm" value=""/>
<input type="checkbox" name="num-input2" id="dis_per" value=""/>
With this info you should be able to get (a little) further. When you do, update your question with your JavaScript code and I am sure people will be happy to help you further.
People are bringing up great suggestions in the comments and answers for better code design and quality, but from a purely functional point of view, there are two core things that you should do to get the functionality that you are describing:
1) As mentioned by Paul S. use the checked property for your checkbox logic. Right now, you are checking to see if the checkbox value is not an empty string, but it will always be an empty string, because that's the value that you've assigned to the element:
<input type="checkbox" name="num-input2" id="dis_per" value="" <----- *here*
Nothing else in your code is changing that, so it will always fail the logic check.
However, the checked property automatically switches between true and false as you check and uncheck the input. To do the logic check that you are looking for using that, do this for your JavaScript!
document.getElementById('dis_rm').disabled = this.checked;
2) Switch the event that you are binding for (at least) the checkbox to the "change" event instead of "blur". For checkboxes, the "change" event will trigger when you click on the checkbox (or hit space bar), but the element still maintains its focus. The blur event Will only fire once the user moves the focus to another element of the page.
I'd also recommend using "change" for the text field (there's no point in running the check, if the value is the same when you leave the field as it was when you entered it), but it's not as important since, from a timing point of view, when the "change" event fires, it happens immediately after the "blur" event, so, from the user's point-of-view, the behavior would be the same.
When it's all said and done, if you made no other changes to your code to improve the code design/quality (Thijs made some great suggestions, BTW), this is the minimum change that you would need to get the functionality that you want:
<input type="text" name="num-input1" id="dis_rm" value=""
onblur="document.getElementById('dis_per').disabled = (''!=this.value);" >
<input type="checkbox" name="num-input2" id="dis_per" value=""
onchange="document.getElementById('dis_rm').disabled = (this.checked);" >
I'm having a small issue dealing with number inputs on forms, specifically when trying to call a validation js function when the user modifies them.
<input type="number" name="somenumber" onkeyup="validateForm()" />
This method only calls if the user types a number in the box and is ignored when the user uses the up/down buttons supplied by the browser. So it isn't fully effective.
<input type="number" name="somenumber" onchange="validateForm()" />
This method works great for users using the up/down buttons, but if they type a number into box, it won't execute until they move to another element or click outside the box. It's not the end of the world, but I'd like users to be able to type in the box and immediately be able to click the currently disabled submit button, rather than having to click elsewhere to enable the button.
<input type="number" name="somenumber" onchange="validateForm()" onkeyup="validateForm()" />
So to get the best possible user experience, I'm doing this. The problem is that the function often gets called twice. It works fine I guess. The users don't even notice it's running twice. Still, it seems like I'm missing something and there must be some "right" way to deal with this.
Is there? Or is this just one of those things we have to work around?
You could use the oninput event.
function validateForm() {
console.log('changed');
}
<input type="number" name="somenumber" oninput="validateForm()" />
Please note: I do not want to use jQuery for this (otherwise I like it)
Problem: I have come to situation where I need to do some javascript function after an user changes an input field (e.g. input type="text"). So I said to myself - I remember an onchange event - BUT onchange event runs AFTER user leaves the field, but I need the function to be called for example every time user types a character to that field. Wowhead shows nice example of what I am trying to achieve this (field with placeholder "Search within results...")
Summary: I am looking for a SIMPLE way of detecting REAL onchange event(not the classic HTML one)and through that call a JS function while not using jQuery?
Use onkeyup instead of onchange then.
Following is a simple way of invoking each type of Key Press on field.
input type="text" onkeypress="myFunction()
Get Example here
http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_onkeypress
Enjoy..
you can also use onkeyup and onkeydown instead of onkeypress.
Tried onkeypress="myFunction()" or onkeyup="myFunction()"?
There are also events for onfocus and onblur for entering and leaving a textfield :)
You should use "input" event. keyup and keypress don't work if a user modified the value only by a mouse.
I have already implemented a version of the code below on my development system.
function validateTextBox(textBoxId) {
var textBox = document.getElementById(textBoxId);
if(document.activeElement.id != textBox.id) {
do validation
}
}
The HTML is similar to:
<input type="text" id="ValidateMe" onChange="validateTextBox('ValidateMe');"/>
The idea is that validation takes place only after the user has completed editing the textbox and that, unlike an onBlur event, validation only fires when the value of the textbox has actually changed.
It seems to work I'm just leery of using it without some review and feedback. I haven't seen any similar code examples. So please give me your thoughts on the implementation and any alternate ideas you may have.
Thanks
This is a fine solution. Do keep in mind that the onchange event will typically only fire when the focus changes (ie. onblur)
If you want to do validation while the user is typing you can use onkeydown/onkeyup/onkeypress but that's quite a ways harder.
Additionally you can use this so you don't have to assign an id to each field and remember to pass it to the validate function:
function validate(input_element) {
alert(input_element.value)
}
<input type="text" name="name" onchange="validate(this);"/>