So for example I have a simple HTML form:
<h3>
Login
</h3>
<div id="tabs-login">
<form method="get" action="./dev.html">
<fieldset>
<legend>
Email:
</legend>
<input type="text" class="required email" name="login" />
</fieldset>
<fieldset>
<legend>
Password:
</legend>
<input type="password" class="required" name="pass" />
</fieldset>
<input type="submit" value="Submit" />
</form>
</div>
And I use jQuery to validte it:
<script>
$(document).ready(function() { $("form").validate(); });
</script>
I want on form submition to take user inputed password value and take SHA256 from it via this jQuery plugin and submit email=user-inputed-value and pass=sha-value. How to access validated values via jQuery and change them and send to original form destination?
First -- I want to point out that I don't think this is a good idea. It's generally a bad idea to implement password hashing on the client side. Instead, the pass should be sent in plain text (over HTTPS) to the server, where it is then hashed using your preferred algorithm before storage. This has the added benefit of not advertising to potential attackers which hashing method is used, since that code exists only on the server.
That said: you're going to want to calculate that SHA value prior to form submit.
You could bind an event handler to the password field's blur event to update a hidden field's value with the new hash. Or you could add the update logic to the validation code.
Regardless of where the extra code goes, it will be much easier for you to prepare the hash prior to the form submit than it will be to send a second submission chasing after the first.
E.g.
<!-- add this to the form -->
<input type="hidden" name="sha_pass" value="" />
// add this to the document ready handler
$('[name=pass]').blur(function() {
$('[name=sha_pass]').val($.sha256($(this).val());
});
Related
A Boolean which, if present, specifies that the form-data (inputs) should not be validated when submitted.
Why would you use this?
If it's applied to your form it allows your JavaScript to manage all validation.
If it's applied to your submit input it can be used to allow users to have the ability to leave the form completion and later on continue where they left off without being forced to fix all the validation errors.
Is this statement about formnovalidate true?
A Boolean which, if present, specifies that the form-data (inputs) should not be validated when submitted.
Yes, the statement is true. Basically it's what the documantation says. It's worth mentioning that this HTML5 attribute can be applied to <button> or <input type="submit"> and it overrides default behaviour of the form which validates all inputs before it is submitted. This default behaviour of the form can also be overriden using another HTML5 attribute - novalidate of <form> element.
If it's applied to your form it allows your JavaScript to manage all validation.
You don't apply attribute formnovalidate to a <form> element. Attribute novalidate is used for this purpose - see above. If you apply novalidate to a <form> or formnovalidate to a <button> that caused the form to submit then it effectively disables validation of form's input fields by the browser. You can still use some kind of client-side (JavaScript) validation whether or not browser validation is enabled. Disabling the validation allows the user to submit the form to server where you can also validate the form data by your backend.
If it's applied to your submit input it can be used to allow users to have the ability to leave the form completion and later on continue where they left off without being forced to fix all the validation errors.
That's true, but note that you still have to somehow store and restore the values of inputs by yourself either using local or server-side storage.
See here how combination of novalidate and formnovalidate works in real life:
form + form {
margin-top: 2em;
}
fieldset {
display: inline-block;
}
<form onsubmit="window.alert('submitted'); return false;">
<fieldset>
<legend>This form validates input on submit</legend>
<input type="text" name="some-text" placeholder="enter some non-blank text" required>
<input type="submit" value="Save" />
<input type="submit" value="Save without validation" formnovalidate />
</fieldset>
</form>
<form novalidate onsubmit="window.alert('submitted'); return false;">
<fieldset>
<legend>This form never validates input on submit</legend>
<input type="text" name="some-text" placeholder="enter some non-blank text" required>
<input type="submit" value="Save" />
<input type="submit" value="Save without validation" formnovalidate />
</fieldset>
</form>
I have a form that contains an input field for an email address. The form doesn't have a submit button. Instead it has the Stripe checkout.js script which provides a button that triggers a roundtrip to Stripe (to process a credit card) before submitting the form. The checkout.js script allows an optional variable data-email which makes it possible to pass a preset email address to the Stripe checkout form. I'd like to set the data-email variable with the value of the email address input field on my own form.
Here's the form and the script:
<form role="form" class="new_user" id="new_user" action="/users" method="post">
<label for="user_email">Email</label>
<input class="form-control" type="email" value="" name="user[email]" id="user_email" />
<script src="https://checkout.stripe.com/v2/checkout.js"
class="stripe-button"
data-email=document.getElementById('user_email').value
data-key="stripe_key"
data-description="Product"
data-amount="500">
</script>
</form>
I know I need to use:
data-email=document.getElementById('user_email').value
But the data-email isn't getting set. Do I need to add an onchange property to the input field? What would that look like? Do I need more than that?
If the user is entering his email on the page, you might as well just update the script as they type:
var stripe = document.getElementById("stripe");
document.getElementById("email").onkeypress = function () {
stripe.setAttribute("data-email", this.value);
}
<input id="email">
<script id="stripe"></script>
If you run the snippet and inspect the input element, then type, you'll see the data-email attribute update for the given stripe script tag. You should be able to adapt this to your form.
I'm new to html and JS and I have a form with a few fields that I need posted to a URL.
<form>
<div>
<label style="font-size:16px" for="title">Title:</label>
<input type="text" id="title" maxlength="128"/>
</div>
<div>
<label style="font-size:16px" for="description">Description:</label>
<textarea id="description" maxlength="1999"></textarea>
</div>
<div>
<label style="font-size:16px" for="idnumber">IDNumber:</label>
<input type="number" id="idnumber"/>
</div>
</form>
I need the values entered into this form to be posted to a URL that already knows how to process the input. I'm sure this is easy to do but I'm new and I'm having trouble finding a solution. Apologies for any incorrect terminology. Thanks!
You can use the action attribute:
<form action="some/url" method="post">
<!-- ... -->
<input type="submit" value="Submit" /> <!-- Submit button -->
</form>
You have to add an action to your form tag that points to a server side script.
<form action="myscript.php" method="post">
Alternatively, you can use JavaScript to post it as an AJAX request which submits the request without a page refresh.
I'd say you're on the right track. This would be perfectly easy using basic HTML: Add an action="mySubmitPage.php" to the form element. It sounds like you want to do it without refreshing/changing the page, though (at least, that's how it sounds by "with Javascript")
That will involve an "asynchronous" submit. The fancy term is "AJAX". That part can be a lot easier using some form of Javascript framework, especially if you want to support all browser quirks. Here's an example of doing it using JQuery, for instance:
jQuery - Send a form asynchronously
I am writing a very simple web app with three text inputs. The inputs are used to generate a result, but all the work is done in Javascript, so there is no need to submit a form. I'm trying to find a way to get the browser to store input values for autocomplete as it would if they were in a form that was submitted.
I have tried giving the inputs autocomplete="on" manually, but without a form to submit, the browser has no way of knowing when it should store the values, so this has no effect.
I have also tried wrapping the inputs in a form that has onSubmit="return false;", but preventing the form from actually submitting appears to also prevent the browser from storing its inputs' values.
It is of course possible to manually use localStorage or a cookie to persist inputs and then generate autocomplete hints from those, but I'm hoping to find a solution that taps into native browser behavior instead of duplicating it by hand.
Tested with Chrome, IE and Firefox:
<iframe id="remember" name="remember" class="hidden" src="/content/blank"></iframe>
<form target="remember" method="post" action="/content/blank">
<fieldset>
<label for="username">Username</label>
<input type="text" name="username" id="username" value="">
<label for="password">Password</label>
<input type="password" name="password" id="password" value="">
</fieldset>
<button type="submit" class="hidden"></button>
</form>
In your Javascript trigger the submit, e.g. $("form").submit(); $("#submit_button").click() (updated from comments)
You need to return an empty page at /content/blank for get & post (about:blank didn't work for me but YMMV).
We know that the browser saves its information only when the form is submitted, which means that we can't cancel it with return false or e.preventDefault()
What we can do is make it submit the data to nowhere without reloading a page. We can do that with an iframe
<iframe name="💾" style="display:none" src="about:blank"></iframe>
<form target="💾" action="about:blank">
<input name="user">
<input name="password" type="password">
<input value="Login" type="submit">
</form>
Demo on JSfiddle (tested in IE9, Firefox, Chrome)
Pros over the currently accepted answer:
shorter code;
no jQuery;
no server-side page loaded;
no additional javascript;
no additional classes necessary.
There is no additional javascript. You normally attach an handler to the submit event of the form to send the XHR and don't cancel it.
Javascript example
// for modern browsers with window.fetch
document.forms[0].addEventListener('submit', function (event) {
fetch('login.php', {
method: 'post',
body: new FormData(event.target))
}).then(r => r.text()).then(() => { /* login completed */ })
// no return false!!
});
No-javascript support
Ideally, you should let the form work without javascript too, so remove the target and set the action to a page that will receive your form data.
<form action="login.php">
And then simply add it via javascript when you add the submit event:
formElement.target = '💾';
formElement.action = 'about:blank';
I haven't tested this, but it might work if you submit the form to a hidden iframe (so that the form is actually submitted but the current page is not reloaded).
<iframe name="my_iframe" src="about:blank"></iframe>
<form target="my_iframe" action="about:blank" method="get">...</form>
---WITHOUT IFRAME---
Instead of using iframe, you can use action="javascript:void(0)", this way it doesn't go to another page and autocomplete will store the values.
<form action="javascript:void(0)">
<input type="text" name="firstName" />
<button type="submit">Submit</button>
</form>
Maybe you can use this Twitter Typeahead...is a very complete implementation of a autocomplete, with local and remote prefetch, and this make use of localStorage to persist results and also it show a hint in the input element...the code is easy to understand and if you don't want to use the complete jquery plugin, I think you can take a look of the code to see how to achieve what you want...
You can use jQuery to persist autocomplete data in the localstorage when focusout and when focusin it autocompletes to the value persisted.
i.e.
$(function(){
$('#txtElement').on('focusout',function(){
$(this).data('fldName',$(this).val());
}
$('#txtElement').on('focusin',function(){
$(this).val($(this).data('fldName'));
}
}
You can also bind persistence logic on other events also depending on the your application requirement.
For those who would rather not change their existing form functionality, you can use a second form to receive copies of all the form values and then submit to a blank page before your main form submits. Here is a fully testable HTML document using JQuery Mobile demonstrating the solution.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile.structure-1.4.5.min.css" />
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
</head>
<body>
<form method="post">
<input type="text" name="email" />
<input type="submit" value="GO" onclick="save_autofill(this);" />
</form>
<script>
function save_autofill(o) {
$(':input[name]', $('#hidden_form')).val(function () {
return $(':input[name=' + this.name + ']', $(o.form)).val();
});
$('#hidden_form').find("input[type=submit]").click();
}
</script>
<iframe name="hidden_iframe" style="display:none"></iframe>
<form target="hidden_iframe" id="hidden_form" action="about:blank" style="display:none">
<input type="text" name="email" />
<input type="submit" />
</form>
</body>
</html>
The save_autofill function just needs to be called on your main form submit button. If you have a scripted function that submits your form, place that call after the save_autofill call. You must have a named textbox in your hidden_form for each one in your main form.
If your site uses SSL, then you must change the URL for about:blank with https://about:blank.
From what i searched.. it seems you need to identify the names. Some standard names like 'name', 'email', 'phone', 'address' are automatically saved in most browser.
Well, the problem is, browsers handle these names differenetly. For example, here is chrome's regex:
first name: "first.*name|initials|fname|first$"
email: "e.?mail"
address (line 1): "address.*line|address1|addr1|street"
zipcode: "zip|postal|post.*code|pcode|^1z$"
But chrome also uses autocomplete, so you can customize the name and put an autocomplete type, but i believe this is not for custom fields..
Here is chrome's standard
And it's another thing in IE, Opera, and Mozilla. For now, you can try the iframe solution there, so you can submit it. (Maybe it's something semi-standard)
Well, that's all i can help.
Make sure you're submitting the form via POST. If you're submitting via ajax, do <form autocomplete="on" method="post">, omitting the action attribute.
you can use "." in both iframe src and form action.
<iframe id="remember" name="remember" style="display:none;" src="."></iframe>
<form target="remember" method="post" action=".">
<input type="text" id="path" size='110'>
<button type="submit" onclick="doyouthing();">your button</button>
</form>
I'm working on a simple javascript login for a site, and have come up with this:
<form id="loginwindow">
<strong>Login to view!</strong>
<p><strong>User ID:</strong>
<input type="text" name="text2">
</p>
<p><strong>Password:</strong>
<input type="password" name="text1"><br>
<input type="button" value="Check In" name="Submit" onclick=javascript:validate(text2.value,"username",text1.value,"password") />
</p>
</form>
<script language = "javascript">
function validate(text1,text2,text3,text4)
{
if (text1==text2 && text3==text4)
load('album.html');
else
{
load('failure.html');
}
}
function load(url)
{
location.href=url;
}
</script>
...which works except for one thing: hitting enter to submit the form doesn't do anything. I have a feeling it's cause I've used "onclick" but I'm not sure what to use instead. Thoughts?
Okay yeah so I'm well aware of how flimsy this is security-wise. It's not for anything particularly top secret, so it's not a huge issue, but if you guys could elaborate on your thoughts with code, I'd love to see your ideas. the code i listed is literally all I'm working with at this point, so I can start from scratch if need be.
There are several topics being discussed at once here. Let's try to clarify.
1. Your Immediate Concern:
(Why won't the input button work when ENTER is pressed?)
Use the submit button type.
<input type="submit".../>
..instead of
<input type="button".../>
Your problem doesn't really have anything to do with having used an onclick attribute. Instead, you're not getting the behavior you want because you've used the button input type, which simply doesn't behave the same way that submit buttons do.
In HTML and XHTML, there are default behaviors for certain elements. Input buttons on forms are often of type "submit". In most browsers, "submit" buttons fire by default when ENTER is pressed from a focused element in the same form element. The "button" input type does not. If you'd like to take advantage of that default behavior, you can change your input type to "submit".
For example:
<form action="/post.php" method="post">
<!--
...
-->
<input type="submit" value="go"/>
</form>
2. Security concerns:
#Ady mentioned a security concern. There are a whole bucket of security concerns associated with doing a login in javascript. These are probably outside of the domain of this question, especially since you've indicated that you aren't particularly worried about it, and the fact that your login method was actually just setting the location.href to a new html page (indicating that you probably don't have any real security mechanism in place).
Instead of drudging that up, here are links to related topics on SO, if anyone is interested in those questions directly.
Is there some way I can do a user validation client-side?
Encrypting Ajax calls for authentication in jQuery
3. Other Issues:
Here's a quick cleanup of your code, which just follows some best practices. It doesn't address the security concern that folks have mentioned. Instead, I'm including it simply to illustrate some healthy habits. If you have specific questions about why I've written something a certain way, feel free to ask. Also, browse the stack for related topics (as your question may have already been discussed here).
The main thing to notice is the removal of the event attributes (onclick="", onsubmit="", or onkeypress="") from the HTML. Those belong in javascript, and it's considered a best practice to keep the javascript events out of the markup.
<form action="#" method="post" id="loginwindow">
<h3>Login to view!</h3>
<label>User ID: <input type="text" id="userid"></label>
<label>Password: <input type="password" id="pass"></label>
<input type="submit" value="Check In" />
</form>
<script type="text/javascript">
window.onload = function () {
var loginForm = document.getElementById('loginwindow');
if ( loginwindow ) {
loginwindow.onsubmit = function () {
var userid = document.getElementById('userid');
var pass = document.getElementById('pass');
// Make sure javascript found the nodes:
if (!userid || !pass ) {
return false;
}
// Actually check values, however you'd like this to be done:
if (pass.value !== "secret") {
location.href = 'failure.html';
}
location.href = 'album.html';
return false;
};
}
};
</script>
Put the script directly in your html document. Change the onclick value with the function you want to use. The script in the html will tell the form to submit when the user hits enter or press the submit button.
<form id="Form-v2" action="#">
<input type="text" name="search_field" placeholder="Enter a movie" value=""
id="search_field" title="Enter a movie here" class="blink search-field" />
<input type="submit" onclick="" value="GO!" class="search-button" />
</form>
<script>
//submit the form
$( "#Form-v2" ).submit(function( event ) {
event.preventDefault();
});
</script>
Instead of <input type="button">, use <input type="submit">. You can put your validation code in your form onsubmit handler:
<form id="loginwindow" onsubmit="validate(...)">
it's because it's not a form submitting, so there's no event to be triggered when the user presses enter. An alternative to the above form submit options would be to add an event listener for the input form to detect if the user pressed enter.
<input type="password" name="text1" onkeypress="detectKey(event)">
Maybe you can try this:
<form id="loginwindow" onsubmit='validate(text2.value,"username",text1.value,"password")'>
<strong>Login to view!</strong>
<p><strong>User ID:</strong>
<input type="text" name="text2">
</p>
<p><strong>Password:</strong>
<input type="password" name="text1"><br>
<input type="submit" value="Check In"/>
</p>
</form>
As others have pointed out, there are other problems with your solution. But this should answer your question.
Surely this is too unsecure as everyone can crack it in a second ...
-- only pseudo-secure way to do js-logins are the like:
<form action="http://www.mySite.com/" method="post" onsubmit="this.action+=this.theName.value+this.thePassword.value;">
Name: <input type="text" name="theName"><br>
Password: <input type="password" name="thePassword"><br>
<input type="submit" value="Login now">
</form>
My Thought = Massive security hole. Anyone can view the username and password.
More relevant to your question: - You have two events happening.
User clicks button.
User presses enter.
The enter key submits the form, but does not click the button.
By placing your code in the onsubmit method of the form the code will run when the form is submitted. By changing the input type of the button to submit, the button will submit the form in the same way that the enter button does.
Your code will then run for both events.