Let's use a simple little petition form designed to innocently gather billions of passwords:
<form action="/Petition/Sign" method="post">
<input class="form-control password" id="Password" name="Password" type="password">
<button type="submit" class="btn loginBtn">Sign</button>
</form>
I would like to be signaled in JavaScript code (as Angular-esque as possible) within this view when a successful post has taken place for whatever reason, the most obvious the being the 'Sign' button being clicked, but that even is only the beginning of the event I want to catch the end of.
The most simple I can think of is to create and clear a hidden input on the button's ngClick event, then poll for a fixed timeout until the value of that input is a constant one always expected back from POST requests.
NOTE: This is a tiny example of a great horde of such forms and converting then all to use Ajax calls with signaled completions is only on the very remote side of feasible and further from desirable. Unlike in other such questions I f have asked, I have no interest directly measuring the success of the call.
In pure javascript way-
var ele = [Your Form Element];
if(ele.addEventListener){
ele.addEventListener("submit", callback, false); //Modern browsers
}else if(ele.attachEvent){
ele.attachEvent('onsubmit', callback); //Old IE
}
In jquery -
$(element).submit(function(){
console.log('submitted);
});
Whereas in AngularJs-
There is ng-submit directive for this purpose.https://docs.angularjs.org/api/ng/directive/ngSubmit
<form ng-submit="callback()">
in controller
$scope.callback = function(){ /*...*/ };
Have a read here also - How can I listen to the form submit event in javascript?
Related
Or put in tl;dr code:
form.email.$setValidity('conflict', false);
is too sticky for my simple serverside validation flow.
I'm trying to get the form to show good feedback in the event that the user enters an email address already in use by another customer. I'm running AngularJS v1.2 and have this template:
<form name="form">
<input name="email" type="email" ng-model="..." required>
</form>
<div ng-messages="form.email.$error">
<div ng-message="conflict">Email address already in use.</div>
</div>
In my controller, I'll handle the submit event and trigger the validation in my $http.post().error handler like this:
$http.post('api/form/submit/path/here').error(function(resp) {
if (resp.details === 'conflict')
$scope.form.email.$setValidity('conflict', false);
});
The problem is that when the user goes back and changes the value in the input field, the error message doesn't go away. It sticks around until I manually call $scope.form.setValidity();.
The docs say implement a custom directive with an ng-model dependency, but that seems super overkill for my purposes. I've also tried setting $scope.form.email.$valid = false; and $scope.form.email.$invalid = true; but those don't change the appearance of the textbox.
Nothing in your code modifies the conflict validation key, except for when $setValidity('conflict', false) is explicitly called. Since that is the only code setting the state of the conflict validation key and there is nothing else resetting it to true, it's expected behaviour that editing the textbox wouldn't reset its conflict validation state.
To get the behaviour that you want, you need to code for it. One way is to use ng-change.
<input name="email" type="email" ng-model="..." required ng-change="resetConflictState()">
$scope.resetConflictState = function() {
$scope.form.email.$setValidity('conflict', true);
}
I'm using on('submit') to detect when the form was submitted, but it only works when the user clicks on the submit button.
I use a <button> tag so I can put an image inside the button. I know I could use an input with type="submit" and use CSS it with the image, but I'd like to know the alternative jQuery way.
I was thinking doing an or comparison, for example on('submit') OR when user presses enter on any of the input field, but how should I do that?
$('#form').on('submit', function (e) {
e.preventDefault();
var email = $('#email').val();
function validateEmail(email) {
var re = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
});
<form id="form">
<input id="email" maxlength="64" name="EmailEDIT" type="text" width="100">
<button id="submitBtn"><img height="30" src="images/fx_demo_button.png" width="74"></button>
</form>
If the user presses enter in one of the field, the form will submit. It will trigger the same event as the button does. If this does not occur, something's up in your code.
You commented that your code doesnt work, but it does: http://jsfiddle.net/B5pZ4/
All I've added was alert(1); the rest is your code from this topic
You define your function in the eventhandler, might be better to seperate that, just in case you want to use that function again (or alter it a bit and use it in two situations).
If you seperate it in your code, it'll make more sense, I also think this is the problem you're having:
http://jsfiddle.net/B5pZ4/1/
You can actually make your code work with just one line. You create the function in your eventhandler (which, in this case, should be considered bad practice!), but you never call it. Either remove the function declaration, or add this under the function:
return validateEmail( email ); // THIS IS BAD PRACTICE AS FIX!
A tip: if you're working in html5, you can use this and the browser will do validating for you:
<input type="email" />
You need to insert an invisible input type submit for this to work.
I know you can disable the autocomplete on a form by setting autocomplete="off" on the form itself.
The problem I have is, I want to prevent the browser from populating the password field but do not want to disable username or other fields.
The other thing to consider is legacy data. Using autocomplete="off" on the form (or even the field itself) does not prevent existing users with saved passwords from getting a free-pass. Or ones that use web inspector, change the value of autocomplete and submit, allowing themselves to save the password.
I know it is possible to change the password field name attribute to a random/new one on every visit. Regretfully, I am working with a java/spring back-end and I am being told this is NOT easily manageable without a huge refactor/override.
How would you architect this? How would you enforce that the field always starts empty? There is no consistent way for browsers to event notify you of pre-population by a password manager - some may fire an onChange, others may not.
I guess I can move fields around with javascript and build the real form on the fly and submit it but once again, this will have implications with spring security and validations etc. Any other ideas?
you can made a temp variable when onFocus is call to set a variable to true ( like userFocus )
and on the onChange attribut but a short code for reseting "value" to NULL if userFocus== false) kind of overkilling imo but migth work
EDIT
function reset()
{
if (document.getElementById("hidden").value!=" ")
{
document.getElementById("demo").value=" ";
}
else;
}
function getfocus()
{
document.getElementById("hidden").value=" ";
}
else;
}
<input type="password" id="pwd" onchange="reset()" onfocus="getfocus()"/>
<input type="hidden" id="hidden" value="not focus"/>
I had to find this solution for IE 11 (since it ignores the autocomplete attribute). It works fine in other browsers. Really more of a work around, but it works.
https://stackoverflow.com/a/20809203/1248536
I was recently faced with this problem, and with no simple solution since my fields can be prepopulated, I wanted to share an elegant hack I came up with by setting password type in the ready event.
Don't declare your input field as type password when creating it, but add a ready event listener to add it for you:
function createSecretTextInput(name,parent){
var createInput = document.createElement("input");
createInput.setAttribute('name', name);
createInput.setAttribute('class', 'secretText');
createInput.setAttribute('id', name+'SecretText');
createInput.setAttribute('value', 'test1234');
if(parent==null)
document.body.appendChild(createInput);
else
document.getElementById(parent).appendChild(createInput);
$(function(){
document.getElementById(name+'SecretText').setAttribute('type', 'password');
});
};
createSecretTextInput('name', null);
http://jsfiddle.net/N9F4L/
Just what the question title says. I'm using SpringMVC, but that's irrelevant really. I just need to be able to pass the submit button name=value along with the rest of the form parameters for validation and control purposes. Example below for clarification:
The HTML I'm using:
<form action='somepage.htm' method='post'>
<input name='somename' value='bob' />
<input type='submit' name='mybutton' value='click me' />
</form>
The JavaScript (with jQuery) I'm using:
$('form').submit(function() {
$('input[type="submit"]', this).attr('disabled','disabled');
return true;
}
And so the HTTP POST request looks like this without the JavaScript event binding:
somepage.htm?somename=bob&mybutton=click%20me
And with the bound event, it excludes the button parameter as such:
somepage.htm?somename=bob
I need to be able to disable the buttons and still send the button value to the server for processing.
Thanks!
SOLUTION:
The code I actually used to solve this problem is:
$(document).ready(function() {
$('input[type="submit"]').click(function() {
var clone = $(this).clone();
$(clone).attr("type","hidden");
$(this).attr('disabled','disabled');
$(clone).appendTo($(this).parents('form')[0]);
return true;
});
});
And in case anyone was wondering, pressing Enter on a field in the form does in fact trigger the click event on the first submit button in the form!
Disabled inputs cannot be submitted.
http://www.w3.org/TR/html4/interact/forms.html#h-17.12
So maybe the way to go is to add a hidden element <input type='hidden' value='foo' name='bar'/> to stimulate the validation methods on the other end.
I think, if the submit button is clicked, then it's values will also be submitted, like rest of the form.
I need to clear the default values from input fields using js, but all of my attempts so far have failed to target and clear the fields. I was hoping to use onSubmit to excute a function to clear all default values (if the user has not changed them) before the form is submitted.
<form method='get' class='custom_search widget custom_search_custom_fields__search' onSubmit='clearDefaults' action='http://www.example.com' >
<input name='cs-Price-2' id='cs-Price-2' class='short_form' value='Min. Price' />
<input name='cs-Price-3' id='cs-Price-3' class='short_form' value='Max Price' />
<input type='submit' name='search' class='formbutton' value=''/>
</form>
How would you accomplish this?
Read the ids+values of all your fields when the page first loads (using something like jquery to get all "textarea", "input" and "select" tags for example)
On submit, compare the now contained values to what you stored on loading the page
Replace the ones that have not changed with empty values
If it's still unclear, describe where you're getting stuck and I'll describe more in depth.
Edit: Adding some code, using jQuery. It's only for the textarea-tag and it doesn't respond to the actual events, but hopefully it explains the idea further:
// Keep default values here
var defaults = {};
// Run something like this on load
$('textarea').each(function(i, e) {
defaults[$(e).attr('id')] = $(e).text();
});
// Run something like this before submit
$('textarea').each(function(i, e){
if (defaults[$(e).attr('id')] === $(e).text())
$(e).text('');
})
Edit: Adding some more code for more detailed help. This should be somewhat complete code (with a quality disclaimer since I'm by no means a jQuery expert) and just requires to be included on your page. Nothing else has to be done, except giving all your input tags unique ids and type="text" (but they should have that anyway):
$(document).ready(function(){
// Default values will live here
var defaults = {};
// This reads and stores all text input defaults for later use
$('input[type=text]').each(function(){
defaults[$(this).attr('id')] = $(this).text();
});
// For each of your submit buttons,
// add an event handler for the submit event
// that finds all text inputs and clears the ones not changed
$('input[type=submit]').each(function(){
$(this).submit(function(){
$('input[type=text]').each(function(){
if (defaults[$(this).attr('id')] === $(this).text())
$(this).text('');
});
});
});
});
If this still doesn't make any sense, you should read some tutorials about jQuery and/or javascript.
Note: This is currently only supported in Google Chrome and Safari. I do not expect this to be a satisfactory answer to your problem, but I think it should be noted how this problem can be tackled in HTML 5.
HTML 5 introduced the placeholder attribute, which does not get submitted unless it was replaced:
<form>
<input name="q" placeholder="Search Bookmarks and History">
<input type="submit" value="Search">
</form>
Further reading:
DiveintoHTML5.ep.io: Live Example... And checking if the placeholder tag is supported
DiveintoHTML5.ep.io: Placeholder text
1) Instead of checking for changes on the client side you can check for the changes on the client side.
In the Page_Init function you will have values stored in the viewstate & the values in the text fields or whichever controls you are using.
You can compare the values and if they are not equal then set the Text to blank.
2) May I ask, what functionality are you trying to achieve ?
U can achieve it by using this in your submit function
function clearDefaults()
{
if(document.getElementById('cs-Price-2').value=="Min. Price")
{
document.getElementById('cs-Price-2').value='';
}
}