I am using the template created via the "dotnet new angular" command.
I have a form which is working fine in all respects, until I add the ng2-date-time-picker control. The control works fine in terms of passing the selected values to a variable on the component when I set it up as explained here: https://www.npmjs.com/package/ng2-date-time-picker.
<input [ngModel]="momentValue | date: 'short'" [dateTimePicker]="momentValue" (dateTimePickerChange)="setMoment($event)" readonly />
However, after that happens:
-- The submit button no longer triggers the (submit) method bound to the form.
-- checkboxes on the form stop firing a (change) event.
It is as if the datepicker control does not return event handling to the main form.
I like this control, but I obviously can't use it if other controls on my form (including the submit button) become nonresponsive. I do note, however, that (click) events continue to fire.
Has anyone else had this problem? Any ideas?
Related
I know a way to stop a form from submitting, but i have a on click event to the submit button and its firing even though the form doesnt pass the HTML validation.
<form id="signupform" class="signupform" onsubmit="(e)=>{e.preventDefault()};return false">
</form>
My goal is to stop the page refresh either way (if it validates or not) but still allow the built in validation to run first.
Any suggestions?
A submit button's job is to trigger the submit event of a form. Therefore, with form elements, you don't set up click events on the submit button, you set up submit event handlers on the form.
Then, to introduce validation into the mix, you can stop the native submit to take place in the handler, only if validation fails. This is done by accessing the event argument that is automatically sent to every DOM event handler* (see next paragraph for caveat). You can use the event.preventDefault() method to stop the native event from taking place.
*One final note, the use of inline HTML event handling attributes such as onsubmit and onclick is to be avoided. This is a 25+ year old technique that we used before we had standards and unfortunately, because they seem easy to use, they get copied by new developers who don't know any better. There are real reasons not to use them and you've stumbled into one. Your e argument to your event handling function is not being populated with a reference to the event like you think it is. That only happens when you use the modern standard way of setting up event callbacks, which is .addEventListener().
// Set up a submit event handler for the form
// not a click event handler for the button because
// clicking a submit button triggers the form's submit event
document.querySelector("form").addEventListener("submit", function(event){
if(document.querySelector("input").value === ""){
// Invalid data! Stop the submit!
event.preventDefault();
alert("Please fill in all fields!");
return;
}
// If the code reaches this point, validation succeeded
console.log("Form submitted");
});
<form action="https://example.com" method="post">
<input>
<button>Submit</button>
</form>
I have some working code that I'm now using in slightly different context. The working part is that I use objects onclick event to bring up a form to send an e-mail. When this in an HTML page, it works fine. I would have a lot of buttons that look like this:
<button id="mail-c1" onclick="initMailFormButton(this.id, 'someone','somedomain.com','a subject')">Someone's Name</button>
The entire form is created in javascript and has its own submit and cancel buttons but is within the button element. In order to be able to enter data into the form, I need to kill the onclick event then restore it after I've submitted or cancelled the e-mail. The onclick handler starts out with:
function initMailFormButton(mailId, eName, eDomain, eSubject) {
myFormLocation = document.getElementById(mailId);
stopFormClick(myFormLocation);
where the stopFormClick function is:
function stopFormClick(myFormLocation) {
saveOnclick = myFormLocation.onclick;
myFormLocation.onclick = null;
}
This has the bug that it doesn't handle someone opening multiple forms at once, but that's not my immediate concern. I'll fix it outside of this discussion.
The submit and cancel buttons in the generated form both restore the onclick event handler so you can open and close the form multiple times quite happily.
My new case is that I'm generating HTML page from a database. I'm using HTML datasets to store the previously hard-coded information like so:
emailButton.setAttribute("data-mailname", emailName);
emailButton.setAttribute("data-maildomain", emailDomain);
emailButton.addEventListener("click", function() { initMailFormButton(this.id, this.dataset.mailname, this.dataset.maildomain, ""); }, false);
The information being retrieved is correct and the form appears in the correct location. However, I can't enter information because the original onclick handler kicks in when I click in the first form field and generates another form...
The only clue I have is that when I look at the value of the onclick event being saved in the static HTML pages, it has the expected value but it is null in the generated pages. I find this confusing because I am passing the (unique) element id to the routine so it should be getting to the correct element.
Can anyone help me on this one. Meanwhile, I'll fix the event handler bug I mentioned above.
OK. So it's that there is a difference between click and onclick. The onclick event handler wasn't set so it is null. I changed setting the click event listener to setting the onclick attribute as:
emailButton.onclick =
function() { initMailFormButton(this.id, this.dataset.mailname, this.dataset.maildomain, ""); };
and everything works nicely.
To handle the limitation I'd noted earlier, I made the saveOnclick variable into an associative array keyed by the button id. Now people can have as many buttons clicked as they want - although wanting to have more than one is probably rare.
I am using a simplified example to describe the issue I am facing.
I have the following HTML markup:
<input ng-model="something" style="margin-top:8px;"/>
And, I have two HTML buttons:
<button id='submit'>Save</button>
<button id='btnGetAnalyzerInput'>Generate Analyzer File </button>
I used jQuery's change event on my input (to track whether any changes have been made to the input - by maintaining a simple JS variable).
When the user clicks "Generate Analyzer file button", what I want to is this:
Look up the JS variable to find out whether any changes have been made.
If yes, then prompt the user to save changes (window.dialog)
However, I find that when the focus is still on the input element, and when the button is clicked, the click event runs before the OnChange event. In all other cases, it is the OnChange event which gets fired before the click event (and so my code works as expected).
Is there any way to ensure that for such a scenario, the click event runs after the onChange event?
I am using Google Chrome to test my application.
Note :
Both events work as expected - the OnChange event gets fired when the textbox loses focus.
I can't use the keypress event since I want to track changes.
You could have the click event call the same function as the OnChange event. Something like this:
function OnChange(){
//Do stuff for on change;
}
function ClickEvent(){
OnChange();
//continue with generate stuff
}
You you may need to set up and pass in arguments to the OnChange function, depending on how you are accessing the data you need. If you need more guidance, post more of your code.
Using Selenium and Scalatest, having tested with Chrome, Firefox, IE9 and the default as values for drivers:
I have a form called form. It has onSubmit = 'return false;'
There is a separate event handler defined in some JavaScript file that gets attached.
I have a field in that form called field, and a button called button.
When I type things in to the field by hand, and click on button, everything works as expected.
When I run this, nothing happens:
click on id ("field")
enter("searchTerm")
submit
It seems that the submission occurs, and field's value is set back to "".
However, the (seperate) jQuery event handler for the form submission does not fire.
I have an <input type=text> with focusout event handler
I have a <button> with click event handler
Focusout checks whether format in input box is correct. It does so by testing input value against a regular expression. If it fails it displays a message (a div fades-in and -out after some time) and refocuses my input by calling
window.setTimout(function() { $(this).focus(); }, 10);
since I can't refocus in focusout event handler. focusout event can't be cancelled either. Just FYI.
Click collects data from input elements and sends it using Ajax.
The problem
When user TABs their way through the form everything is fine. When a certain input box failes formatting check it gets refocused immediately after user presses TAB.
But when user doesn't use TAB but instead clicks on each individual input field everything works fine until they click the button. focusout fires and sets time-out for refocusing. Since time-out is so short focusing happens afterwards and then click event fires and issues an Ajax request.
Question
I have implemented my formatting check as an independent jQuery plugin that I want to keep that way. It uses .live() to attach focusout on all input fields with a particular attribute where format regular expression is defined.
Data submission is also generic and I don't want to make it dependant on formatting plugin. They should both stay independent.
How can I prevent click event from executing without making these two plugins dependant?
Example code I'm fiddling with
After some searching I've seen that all major browser support document.activeElement but I can't make it work in Chrome. FF and IE both report this being the active element, but Chrome always says it's BODY that is active even though click fired on the button element.
Check this code http://jsfiddle.net/Anp4b/1/ and click on the button. Test with Chrome and some other browser and see the difference.
You could use a flag...
Live demo: http://jsfiddle.net/Anp4b/4/
So your question is:
How can I prevent click event from executing without making these two plugins dependent?
Well, you obviously cannot prevent the click event. If the user wants to click the button, he will, and the click event will trigger. There's nothing you can do about that.
So the answer to the above question is: You cannot.
Based on the current conditions, you have to - inside the click handler - retrieve the validation result, and based on that result, decide if form submission should or should not occur.
JS Code:
$("#Name").focusout(function(){
var that = this;
valid = this.value.length ? true : false;
!valid && window.setTimeout(function() {
$(that).focus();
}, 0);
});
$("#Confirm").click(function(e) {
if ( !valid ) { return false; }
e.preventDefault();
alert('AJAX-TIME :)');
});
HTML Code:
<input type="text" id="Name">
<button id="Confirm">OK</button>
Is there are reason you use .focusout instead of .blur?
Using a flag is a good idea, but I would rather use a class on the element. By using classes to determine the state you can also style it accordingly. Here's my example based on your fiddle.
Another solution that hopefully gives the result you are looking for.
1) Create a named click handler:
var clickHandler = function(e){ /** submit form or whatever you want to do**/ };
$("button").click(clickHandler);
2) Add the following to the focusout event when it's failing validation:
$("button").unbind("click", clickHandler).one("click", function(){ button.click(clickHandler); return false;});
You can find an example of this here.