I have a form with which I am using Smarty Streets Live Address validation. In general it works well. In the case where a user has begun entering address information, though, the Live Address validation can get in the way. The most specific problem encountered is in the case where address information has been entered but the user chooses to cancel the form. The Live Address validation takes precedence of operation and blocks attempts to deactivate the validation and clear the form.
A fiddle example of the issue can be found here.
<form>
<input type="text" id="street" name="street" placeholder="street"><br>
<input type="text" id="city" name="city" placeholder="city"><br>
<input type="text" id="state" name="state" placeholder="city"><br>
<input type="text" id="ZIP" name="ZIP" placeholder="ZIP"><br>
<button id="btnCancel">Cancel</button>
</form>
<script>
var ss = jQuery.LiveAddress({ key: '5640108848289556771', debug: true })
$(function () {
$("#btnCancel").click(function (e) {
e.preventDefault();
alert("click");
ss.deactivate();
});
});
</script>
When no data has been entered the click event works as desired, but once address information has been entered the Live Address validation prevents the event handler from firing.
On the click of the cancel button the form should be cleared or returned to the previous page, but instead the Live Address validation takes over and blocks all other actions.
How can the Live Address validation be deactivated on the button click event?
Your cancel button is mapped as the "submit" button on the plugin side. This means that the plugin recognizes that button to invoke verification when clicked. Verification will happen before actually performing any other actions which is what you are seeing. There are two solutions to working around this.
Add another button to your form. The plugin looks for the submit button with this selector "[type=submit], [type=image], [type=button]:last, button:last"
Line 48. If you add another button then your cancel button will be free and verification will not be invoked when clicked.
When you configure the plugin, set submitVerify to false. See the documentation here. This will disable verification for all buttons on your form. Verification will only happen when you click the plugin checkmark bubble.
Note: I work for SmartyStreets
It wasn't working if the last element was a button (even if I used event.stopPropagation();, so I used an A link.
To do this, I mapped the address fields, assigned an address ID and then used the activate() & deactivate() functions. This enabled me to allow an admin user to bypass the validation and post the form without entering anything. It checks for the visibility of the .smarty-tag checkmark to determine if it should activate or deactivate the validation.
<script type="text/javascript">
var liveaddress = jQuery.LiveAddress({
key: "key",
debug: true,
addresses: [{
id: 'AddressID',
street: '#Address',
street2: '#Address2',
city: '#City',
state: '#State',
zipcode: '#Zip',
country: '#Country'
}]
});
$(function(){
/* If re-editing and address is pre-populated, don't revalidate */
liveaddress.on("MapInitialized", function(event, data, previousHandler){
if ($('#Address').val().length !== 0){
liveaddress.deactivate('AddressID');
}
});
$('#toggleSS').click(function(e){
e.preventDefault();
if ($('.smarty-tag:visible').length){
liveaddress.deactivate('AddressID');
} else {
liveaddress.activate('AddressID');
}
});
/* If editing address, auto-enable verification */
$('#Address').keyup(function(){
if (!$('.smarty-tag:visible').length){
liveaddress.activate('AddressID');
}
});
});
</script>
<input type="submit" value="Save"> Toggle Verification
Related
I've implement localization in my application, all this stuff is saved inside a php file. So I can easy do this:
<input class="form-control" type="text" required="" placeholder="username" oninvalid="this.setCustomValidity('<?php echo $this->lang->line('field_required'); ?>')"></input>
Now if I doesn't enter any text I can see the custom message, but if I fill the input I see again the popup as the form can't get the text inside.
It's a bug of Bootstrap?
EXAMPLE
https://jsfiddle.net/DTcHh/23662/
Using the onvalid won't work in some browsers like Safari or IE below 10. Use a custom event notifier for attaching the function.
Note: As you mentioned in the comment you can print the message from the data-invalid-message attribute from php and catch it using jQuery by .data('invalidMessage').
SEE WORKING EXAMPLE:
var myobj = jQuery('input.form-control');
myobj.on('keyup keypress blur change input', function() {
var messg = ($(this).data('invalidMessage'));
if (this.validity.typeMismatch) {
this.setCustomValidity(messg);
} else {
this.setCustomValidity('');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<form>
<input class="form-control" type="email" required placeholder="username" data-invalid-message="custom message from php here">
<button type="submit">
go
</button>
</form>
a workaround that I've found is:
onkeyup="this.setCustomValidity('');
the bug will be gone now.
TL&DR
Check element.validity.typeMismatch and then element.setCustomValidity('custom error msg') or element.setCustomValidity('') if there's no mismatch. You should listen on both keyup and blur events.
Explanation in Mozilla Developer documentation about setCustomValidity: https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Forms/Data_form_validation#Customized_error_messages.
But just keyup won't work properly if focus is not inside the input box we're modyfing.
Our previous example won't transfer the current state of the input box
if the user mouses away and clicks elsewhere on the page. We update
the component's values property only when the user presses Enter while
the focus is inside the input box.
Let's fix that by listening to the input box's blur event as well.
Above is from Angular 2 docs: User Input, paragraph "On blur" https://angular.io/docs/ts/latest/guide/user-input.html.
Simplified example
Below is example from Mozilla documentation with added blur keyEvent listener. Yup, refactoring needed, but mine version in Angular 2 looks vastly different and so probably will yours.
<form>
<label for="mail">I would like you to provide me an e-mail</label>
<input type="email" id="mail" name="mail">
<button>Submit</button>
</form>
And then
var email = document.getElementById("mail");
email.addEventListener("keyup", function (event) {
if (email.validity.typeMismatch) {
email.setCustomValidity("I expect an e-mail, darling!");
} else {
email.setCustomValidity("");
}
});
email.addEventListener("blur", function (event) {
if (email.validity.typeMismatch) {
email.setCustomValidity("I expect an e-mail, darling!");
} else {
email.setCustomValidity("");
}
});
Is it possible after processing any login Form to prevent the browser from offering the option to remember the password?
I know it's been asked and answered here but none of the answers have worked so far, even one of them suggested using:
autocomplete="off"
But that also didn't worked.
I'm using AngularJS and Jade as templating engine (not sure if relevant or not anyhow), is there any way to do this?
if a site sets autocomplete="off" for a form, and the form includes username and password input fields, then the browser will still offer to remember this login, and if the user agrees, the browser will autofill those fields the next time the user visits this page.
https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion
You should also set autocomplete="off" on your input as well as your form.
Google Chrome release notes:
The Google Chrome UI for auto-complete request varies, depending on whether autocomplete is set to off on input elements as well as their form. Specifically, when a form has autocomplete set to off and its input element's autocomplete field is not set, then if the user asks for autofill suggestions for the input element, Chrome might display a message saying "autocomplete has been disabled for this form." On the other hand, if both the form and the input element have autocomplete set to off, the browser will not display that message. For this reason, you should set autocomplete to off for each input that has custom auto-completion.
I would suggest using Javascript to create a random number. Pass that random number to your Server Action using a hidden field, then incorporate that random number into the names of the "login" and "password" fields.
E.g. (psuedo code, the exact syntax depends on whether you use PHP, jQuery, pure Javascript, etc.)
<script>
var number = Math.random();
var login_name = 'name_'+number;
var pass_word = 'pass_'+number;
</script>
<input name='number' value="number" type='hidden'>
<input name="login_name" type='text'>
<input name="pass_word" type='password'>
Your server reads the "number" field, then uses that to read "name_"number value and "pass_"number value.
It won't matter whether or not the user saves their password in the browser, since every time the user logs in, the name and password fields will be different.
Since you're using AngularJS, you can leave the field unnamed, and access the data it contains through the model :
Login: <input ng-model="login" type="text" />
Password: <input ng-model="password" type="password" autocomplete="off" />
and in your javascript file :
$scope.doLogin = function() {
var dataObj = {
login: $scope.login,
password: $scope.password
};
var res = $http.post('/login', dataObj);
}
Tested in IE10 and Chrome 54
This post is little bit old now, but sincce I found a solution that works for me (at least with Chrome version 56), I'll share it here.
If you remove name and password attributes on your input, then Chrome won't ask to save the password. Then you just have to add the missing attributes by code just before submitting the form:
<!-- Do not set "id" and "name" attributes -->
Login: <input type="text">
Password: <input type="password">
<!-- Handle submit action -->
<input type="submit" onclick="login(this)">
Then in Javascript:
function login(submitButton) {
var form = submitButton.form;
// fill input names by code before submitting
var inputs = $(form).find('input');
$(inputs[0]).attr('name', 'userName');
$(inputs[1]).attr('name', 'password');
form.submit();
}
I hope this will help. Tested on Chrome 56 only.
The problem I have is that while I understand the 'annoyance' to a user in not being able to have their browser remember their password and I don't want to 'disable' that feature completely, there are times when I want to disable it for just a certain password field. Example for me being a 'reset your password' dialogue box.
I want to force them to have to re-enter their old password and then of course type the new one twice.
It's been my experience that no matter what I name that 'old' password input, it is auto-filled with the 'remembered' password (in Firefox 49.0.1 anyway). Maybe this is where I'm getting this wrong, but it just fills it no matter the fact that this input's name is different from saying the login input field.
The behavior I see is basically that the browser seems to say "This user has remembered a password for this site, so now just fill every input type='password' box with that password no matter the name. It seems to me that this should be based on the name attribute, but for me (on multiple sites I've worked on) this just does not seem to be the case.
My solution:
Color this password field to the same color as the background of your input so the 'password dots' is essentially invisible on page load.
onload, onblur, after a timeout, or however you want to do it, use JQuery or JS to set the value of that password field to nothing (blank), then set the color of the field to whatever it is supposed to be.
$("#old_password").val('').css('color','black);
I've discovered that Firefox 52.0.2 is incredibly determined to remember the autocompletion values. I tried almost everything suggested above, including changing the name attributes to random values. The only thing that is working for me is setting the values to "" with Javascript after the browser has had its way with the form.
My use case is lucky in that I do not have to resort to CSS tricks to prevent a confusing and/or annoying flash of autocompleted form values (as proposed by #MinnesotaSlim above) because my form is hidden until they click a button; then it's displayed via a Bootstrap modal. Hence (with jQuery),
$('#my-button').on("click",function(){
$('#form-login input').val("");
});
// this also works nicely
$('#my-modal').on("show.bs.modal",function(){
$('#form-login input').val("");
})
And I imagine you might be able to get the same effect by having your form initially hidden, and in your document load event, manually override the browser and then display the form.
For me, the only solution that reliably worked was to empty username and password input element just before submitting form combined with replacing submit button for the regular button with onclick handler.
NOTE: We use Microsoft MVC so we needed to populate ViewModel with entered credentials. Therefore we created hidden input elements bound to model and copied credential values to them before emptying visible inputs.
<form>
<input id="UserName" name="UserName" type="hidden" value="">
<input id="Password" name="Password" type="hidden" value="">
</form>
<input id="boxUsr" name="boxUsr" type="text" value="" autocomplete="off">
<input id="boxPsw" name="boxPsw" type="password" autocomplete="off">
<input type="submit" value="Login" onclick="javascript:submitformforlogin()">
function submitformforlogin() {
$("[name='boxPsw'],[name='boxUsr']").attr('readonly','true');
var psw = document.getElementsByName('boxPsw')[0];
var usr = document.getElementsByName('boxUsr')[0];
if (psw.value != "false") {
$('#Password').val(psw.value);
$('#UserName').val(usr.value);
psw.value = "";
usr.value = "";
$("form").submit();
} else
window.alert("Error!");
}
I'm fairly new to JS so I'm a bit confused as in why this is not working.
Basically I'm using the geocomplete jQuery plugin to populate a form with the coordinates and address. Then, once a user selects the destination, I want to sumbit the form.
<form action="search.php" method="post" id="searchForm">
<input id="geocomplete" type="text" placeholder="Where are you going to?" size="35" />
<input name="lat" type="hidden" value="">
<input name="lng" type="hidden" value="">
<input name="formatted_address" type="hidden" value="" id="address">
</form>
and this would be the scripts I call to initiate the form plugin (which works), and the script to submit the form once the value of the address has been changed by the plugin:
<script type="text/javascript">
window.onload= function () {
if(window.addEventListener) {
document.getElementById('address').addEventListener('change', doIt, false);
} else if (window.attachEvent){
document.getElementById('address').attachEvent("onchange", doIt);
}
function doIt(){
document.getElementById("searchForm").submit();
}
}
$("input").geocomplete({ details: "form" });
</script>
I don't see why this won't work since the value does get changed. Many thanks!
A change event fires only when the change occurs by direct user input, not when a script changes the input value.
Use the events provided by that plugin as described on the page you already linked to.
Here is another solution uing jquery. This forces a submit when an autopopulated address is clicked on or the user selects it with the arrow keys and hits enter. There is a delay of 1.5 seconds to allow the geocoding library to populate hidden fields. This required delay is why 'onchange="this.form.submit()" didn't work for me.
/*
submit form when user clicks or hits enter on auto suggest
must sleep for 2 seconds to allow the geocoding library to update the hidden fields
*/
$(document).ready(function(){
$('#geocomplete').change(function(){
setTimeout(function() {
$('#find').click()
}, 1500);
});
});
$(document).ready(function(){
$('#geocomplete').keydown(function(event){
if (event.keyCode == 13) {
setTimeout(function() {
$('#find').click()
}, 1500);
return false;
}
});
});
$(function(){
$(".geocomplete")
.geocomplete({details:"form"})
.bind("geocode:result", function(event, result){$(".searchForm").submit();
});
});
I need some help with sequencing (not sure if this is the right term) two jQuery functions so that both can co-exist together.
What I am trying to do is to add a new functionality that makes a field uneditable to the users, like disabled="disabled". Catch is that if I only apply disabled="disabled" to the filed the form will not send its value with the form submit.
Therefore, I have written some JS code, which enables the fields prior submitting and permits that their values are sent when form is submitted.
All works fine once the page is loaded.
Problem is when the user leaves one of the mandatory fields blank and tries to submit the form. Then there is another jQuery that fires - to validate the field contents.
This second validation function triggers the enable field function and all fields become editable again.
Need some help on how to prevent the second function to override the enable one.
Here is the code - the enable function is placed right before the form like this:
<script>
jQuery(function($) {
$('form').bind('submit', function() {
$(this).find(':input').removeAttr('disabled');
});
});
</script>
<form name="RegFrm" id="RegFrm" action="" method="post">
<select class="validate[required] text-input" disabled="disabled">
<option value="">Please Select</option>
</select>
<input name="sbtFrm" type="submit" value="Submit" />
</form>
And here is the second field validation function that is placed on a separate file. It is being invoked from files_include.php every time the page loads:
var genVar = jQuery.noConflict();
genVar(document).ready(function(){
genVar("#RegFrm").validationEngine();
});
How can I prevent the second function triggers the first one?
Thank you?
Thank you all for the comments. Although, no solution proposed you guys gave me an idea how to fix it.
I basically decided to check on form submit if form validates and only if true, then the enable function triggers.
This is the code:
jQuery(function($) {
$('form').bind('submit', function() {
if($("#RegFrm").validationEngine('validate')){
$(this).find(':input').removeAttr('disabled');
};
});
});
Interesting bug here that seems to be limited to IE and Webkit.
I have a basic form setup:
<div id="output">Form output is displayed here</div>
<form id="myForm" action="#" method="post">
<input type="text" name="username" id="usernameInput" />
<input type="submit" value="Submit" />
</form>
Now if I just submit the form through a normal page refresh, the next time I go to type text into the input field, I will get the browser's default auto-suggest dropdown (this is the intended behavior). However, if I highjack the form submission behavior in order to do an AJAX submit:
$('#myForm').submit(function () {
$('#output').text($('usernameInput').val());
return false;
});
Now when I submit the form, the output div updates, but the previous values that I input into the form aren't stored and no suggestions will be made when you type.
Does anyone have any creative solutions to this problem? Maybe an (gulp) iframe?
IE and WebKit only remember values that were submitted normally, and since you are submitting it through AJAX, those engines do not remember the values. Instead of an iframe, I would use a jQuery plugin for the autocomplete, like this one. Of course, with that solution, you will need to maintain a listing of what a user has typed in the past, which shouldn't be too hard.
test with these modifications in controlling submit:
$('#myForm').submit(function (e) {
e.stopPropagation();
$('#output').html($("#usernameInput").val() + "<br />");
});