Input 'touched' in angular validation is blocking method execution - javascript

I noticed when using this kind of validation:
<label>Password</label>
<input type="password" formControlName="password" class="form-control" [ngClass]="{ 'is-invalid': f.password.touched && f.password.errors }" />
<div *ngIf="f.password.touched && f.password.errors" class="invalid-feedback">
<div *ngIf="f.password.errors.required">Password is required</div>
<div *ngIf="f.password.errors.minlength">Password must be at least 6 characters</div>
</div>
<div class="form-group">
<button class="btn btn-primary" (click)="alertX()">sdf</button>
</div>
When I focused the input and then click the button, the method 'alertX()' is not executed I think it is because the state for the input changes to touched=true before the alertX(), (this happens sometimes not always but is kinda annoying for UX) any advice how to avoid this behaviour would be appreciated...
Example of method not executed when input was focused the button was clicked

According to MDN Docs:
click fires after both the mousedown and mouseup events have fired, in
that order.
In your example, clicking on the button causes the mousedown. This fires the validation immediately and there is an error under the input.
This moves the button a little lower and the mouseup is no longer on the button! So the click event doesn't fire since you didn't mouseup on the button.
Workaround:
<button class="btn btn-primary" id="btnSubmit" (mousedown)="alertX()">Register</button>
Register a EventListener on mouse down rather than a 'click' event to fire.
Working Demo on Stackblitz

Related

I need a clarification of targeting an element from the markup

I am following a class online and the tutor target a <button> document in which I don't really understand how he did it because he used a document.querySelector to target the parent and that's all.
<div class="row">
<form id="task-form" action="index.php">
<div class="input-field col s12">
<input type="text" name="task" id="task" value="">
<label for="task">New Task</label>
</div>
</div>
<button id="add" class="btn">Add</button>
</form>
he then wrote :
document.querySelector('form').addEventListener('submit', function(event) { /* ... */ })
to me what I understand is that the querySelector will only select the firstChild in this case.
The code just targets the <form> and adds a listener for the submit event.
It is not targeting any <button>.
He actually doesn't add listeners to any button. What you confused was the <form> having an onsubmit event listener. Since there is only one button in the form, its type attribute is automatically set to submit, making it trigger the form.onsubmit event every time.
Also, the code is a bit wrong. You open a div, a form, and before closing the form, you close the div. If that was made by the person who runs the course, I would recommend to stop watching that course in general, since it can confuse a lot...

angular div (clickOutside) is called when clicking input inside of div

I am using (clickOutside) directive with div, and it is called when I click input element inside div.
<div class="col-4 align-self-center" (click)="setMethod(true)"
(clickOutside)="setMethod(false)" >
<button type="button" mat-raised-button color="accent" >
<input type="text"
class="form-control"
*ngIf="activeTitle"
[(ngModel)]="title" />
</button>
</div>
You can bind to the (blur) event instead of using (clickOutside). Maybe that would do the trick for you?
Note that the blur event fires when the component loses focus. This means that in order for blur to fire, the HTML element needs to be focused in the first place. E.g. the user has to have clicked on it with the mouse. You can call the focus() method on that element when your user clicks anywhere inside it, thereby ensuring that blur will be fired when the element loses focus.
E.g.:
<div
class="col-4 align-self-center"
(click)="setMethod(true)"
(blur)="setMethod(false)"
>
<button
type="button"
mat-raised-button color="accent"
>
<input
type="text"
class="form-control"
*ngIf="activeTitle"
[(ngModel)]="title"
/>
</button>
</div>

How does onchange and onkeyup work in javascript?

I was trying to validate a password field when I found the javascript code on the net. Can someone please explain when is the "onchange" fired and why does the code not work when I replace onkeyup with onchange (last 2 lines in javascript code)
function validatePassword(){
if(password.value != confirm_password.value) {
confirm_password.setCustomValidity("Passwords Don't Match");
} else {
confirm_password.setCustomValidity('');
}
}
password.onchange = validatePassword;
confirm_password.onkeyup = validatePassword;
<div class="password" id="password-fields" style="display:none">
Password: <input type="password" name="password" class="password" id="password"><br>
Confirm Password: <input type="password" name="password" class="password" id="confirm-password">
</div>
<div> <input type="submit" name="submit"> </div>
</form>
The change event occurs when you leave an input field after having changed its value. It doesn't fire immediately as the user changes the value, only when they've finished, which is detected by them using the keyboard or mouse to select a different element on the page.
The keyup event occurs after every keystroke. This allows you to take action while the user is typing.
The onChange event occurs when the value is assigned to the field, which is usually when the field loses focus.
The onKey events are bound to the keypress, meaning, they are triggered by the key itself and not related to the value assignment of the field.
The onKeyUp event will only fire when the user physically stops pressing the key (when the key goes "up").
You can test the behavior here.

jQuery Enter keyup function needs to be hit twice before function is called

I have an event listener that looks for the keyup of the enter key in an input box. There is also a button that is next to the submission box that the user can click which submits the data and triggers a function. On the keyup, I am directly calling the function.
The issue is that the function only works when I press enter the second time. Example: I enter a number and hit enter, the page goes into a loading modal like it should, but nothing gets displayed on the page. If I click on the input box again (not changing the number I inputted) and hit enter again, it goes into the loading modal and then it displays the charts that I have.
I am unsure on why it works the second time but not the first? I have seen multiple posts on pressing once triggering multiple function calls, but can't find anything that you need to do an event twice just to get one function call.
Here is the jQuery for enter key
document.getElementById('SN').addEventListener("keyup", function (event) {
if (event.keyCode === 13) {
self.getInformation();
}
});
Here is the input box.
<div class="col-md-3">
<label class="control-label" for="SN">Serial Number</label>
<input class="form-control text-box single-line" id="SN" name="SN" type="number" data-bind="value: SN" />
</div>
Here is the button that works when the user actually clicks it instead of hitting enter in the input box.
<div class="col-md-offset-6 col-md-3 col-md-push-3">
<label></label>
<button id="getInformationBtn" class="btn btn-success btn-block" data-bind="click: getInformation">Get Information</button>
</div>

Javascript turn div into form on button click

I am trying to turn a password row into an input field when the 'change password' button is clicked. I am kind of halfway there already using Jquery. So I have made it so that when you click 'change password' the input field gets added. Also when they click 'back' the original state is shown. If you look on the codepen, you'll notice that after clicking 'back', you can't then click 'change password' again, the jquery doesn't work. Is there a solution to this?
Also I have used jquery 'replaceWidth', is there a better way to do this? I am putting a lot of html into my Jquery and not sure if that's the best way to do it.
Please take a look!
https://codepen.io/liamdthompson/pen/WYwXeK
$("#change").click(function () {
$("#container").replaceWith('<input class="form-control" id="zing" required="required" type="text" value="Change password" id="website_name">');
$(this).replaceWith('<button type="button" id="yeet" class="btn btn-light lighter">back</button>');
$("#yeet").click(function () {
$(this).replaceWith('<button type="button" id="change" class="btn btn-light lighter">Change password</button>');
$("#zing").replaceWith('<div class="" id="container">*********</div>');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="accountmain" style="padding-top:25px;">
<div class="row">
</div>
<div class="row">
<div class="col">
<h6> Password</h6>
</div>
<div class="col" id="container">
*********
</div>
</div>
<button type="button" id="change" class="btn btn-light lighter">Change password</button>
</div>
This is because your #change on click event is bound to the dom element when the page loads.
To bind events to dynamically created elements, bind to the document using the .on feature, like this.
You have to re-attach the event listener again when you insert the button back in.
Otherwise another solution is to use the derived event on the parent class ie.
$('body').on('click', '#change', function(){});
This will affect any element with Id change that has body in its line of ancestors.

Categories

Resources