I have encountered an issue with my code, while developing a project. I dynamically add a login form to a certain div in the DOM-Tree. It is all nice and fine, all elements are generated and all attributes are added, but I cannot access either of the fields, let alone submit it. Can somebody please spot the issue within?
loginArea.click((e) => {
e.preventDefault();
loginArea
.empty()
.append(
$(document.createElement('form'))
.attr({id: 'user__loginform'})
.append(
$(document.createElement('p'))
.addClass('user__action')
.text('Please enter your credentials!')
)
.append(
$(document.createElement('input'))
.prop({
type: 'email',
id: 'login_mail',
})
.attr({
placeholder: 'Please enter a valid e-mail adress!',
required: true,
form: 'user__loginform'
})
)
.append(
$(document.createElement('input'))
.prop({
type: 'text',
id: 'login_pw',
})
.attr({
placeholder: 'Please enter a password!',
minglength: 9,
maxlength: 16,
required: true,
form: 'user__loginform'
})
)
.append(
$(document.createElement('input'))
.attr({
form: 'user__loginform',
type: 'submit',
value: 'Login'
})
)
)
});
Thank you a lot in advance
EDIT:
Incorporating the input I have received, I have shortened the function to this, and added .off() at the end. This seems to solve the issue I had, as for now the dynamically generated input can be filled out.
signupArea.click((e) => {
e.preventDefault();
let formTemplate = `
<div id="form-template" class="user__action">
<form id="user__registform">
<p>Please enter your preferred credentials!</p>
<input type="email" id="regist_mail" placeholder="Please enter a valid e-mail!" required="required" form="user__registform">
<input type="text" id="regist_pw" placeholder="Please enter a password!" minglength="9" maxlength="16" required="required" form="user__registform">
<input form="user__registform" type="submit" value="Register" class="user__regist--submit">
</form>
</div>
`;
signupArea.html(formTemplate);
signupArea.off();
});
The issue is because you've bound the click handler to the loginArea element, yet every time you click that element, or importantly an element within it, the event bubbles back up and fires the event again, which clears the content and re-inserts a fresh form element.
To fix this you could add the event which adds the form to an element outside of loginArea, like this:
$('#foo').click((e) => {
e.preventDefault();
$('#loginarea')
.empty()
.append(
$(document.createElement('form'))
.attr({
id: 'user__loginform'
})
.append(
$(document.createElement('p'))
.addClass('user__action')
.text('Please enter your credentials!')
)
.append(
$(document.createElement('input'))
.prop({
type: 'email',
id: 'login_mail',
})
.attr({
placeholder: 'Please enter a valid e-mail adress!',
required: true,
form: 'user__loginform'
})
)
.append(
$(document.createElement('input'))
.prop({
type: 'text',
id: 'login_pw',
})
.attr({
placeholder: 'Please enter a password!',
minglength: 9,
maxlength: 16,
required: true,
form: 'user__loginform'
})
)
.append(
$(document.createElement('input'))
.attr({
form: 'user__loginform',
type: 'submit',
value: 'Login'
})
)
)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="foo">Click me to add form</button>
<div id="loginarea"></div>
You should also note that the logic you're using to create the form is unnecessarily long winded and not a good separation of concerns.
A much better approach is to store a template in your HTML and use it to create the new dynamic content. This way if you need to make a change to the form layout in the future it can be done directly in the HTML. The JS becomes completely agnostic of the UI. Try this:
$('#foo').click((e) => {
e.preventDefault();
let formTemplate = $('#form-template').html();
$('#loginarea').html(formTemplate);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="foo">Click me to add form</button>
<div id="loginarea"></div>
<script type="text/html" id="form-template">
<form id="user__loginform">
<p class="user__action">Please enter your credentials!</p>
<input type="email" id="login_mail" placeholder="Please enter a valid e-mail adress!" required="required" form="user__loginform">
<input type="text" id="login_pw" placeholder="Please enter a password!" minglength="9" maxlength="16" required="required" form="user__loginform">
<input form="user__loginform" type="submit" value="Login">
</form>
</script>
Related
Im trying to use a library called jquery validate which just takes form inputs and returns success or error messages. With materialize I can use the data-error and data-success. I cant get the error working at all. I see it changes in the console but not on the webpage. Until I click off an input the go back to an input i know is wrong then it gives me an error warning
Even then the error is not persistent it disappears when i click onto another input again.
I can see by watching the inspector a valid class appears in the input.
I will post my code below any explanations why this happens would be appreciated:
$(document).ready(function() {
$("#signup_form").validate({
rules: {
first_name: {
required: true,
minlength: 2
},
last_name: {
required: true,
minlength: 2
},
user_name: {
required: true,
maxlength: 3
}
},
//For custom messages
messages: {
first_name: {
required: "Enter your first name",
text: true,
minlength: "Enter at least 2 characters"
},
last_name: {
required: "Enter your second name",
text: true,
minlength: "Enter at least 2 characters"
},
user_name: {
required: "Enter a username",
maxlength: "Enter at least 3 characters"
}
},
errorClass: 'invalid',
validClass: "valid",
errorPlacement: function(error, element) {
$(element)
.closest("form")
.find("label[for='" + element.attr("id") + "']")
.attr('data-error', error.text());
}
});
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.0/css/materialize.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.0/js/materialize.min.js"></script>
<form id="signup_form" class="col s6">
<div class="row">
<div class="input-field col s6">
<input id="user_name" type="text" name="user_name" class="validate">
<label for="user_name" data-error="" data-success="">User Name</label>
</div>
</div>
</form>
Too see the error start typing the click off the input and back on the type another letter its weird
Just incase someone comes across this in the future I wont take it down. Look through your inputs and remove the class 'validate'.
I'm not entirely sure but what I think happens is the validate class is looking at the input and testing for any of the markup contstraints i.e. max, min, step, type etc. This will add the valid class to all inputs regardless of the rules set in validate() because it fulfils the requirements made in markup.
So when we remove the validate class the validate library can act accordingly.
// Register form validation
$('.register-form')
.form({
on: 'blur',
fields: {
registerEmail: {
identifier : 'registerEmail',
rules: [{
type : 'email',
prompt : 'Please enter a valid email address.'
}]
},
registerPassword: {
identifier : 'registerPassword',
rules: [{
type : 'empty',
prompt : 'Please enter a password.'
}]
},
registerPasswordVerify: {
identifier : 'registerPasswordVerify',
rules: [{
type : 'match[registerPassword]',
prompt : 'Your passwords do not match.'
}]
}
},
onSuccess: function() {
$scope.createUser();
console.log("Passed");
},
onFailure: function() {
console.log("Failed");
}
});
Not sure what is wrong here exactly, but I'm simply trying to get the two password fields to match but I keep getting the "Your passwords do not match" error. Here's my HTML as well:
<div class="field">
<label>Password</label>
<input type="password" name="registerPassword" ng-model="password">
</div>
<div class="field">
<label>Verify Password</label>
<input type="password" name="registerPasswordVerify">
</div>
I had the same problem. After trying few options, i realize that registerPassword inside match[registerPassword] is undefined. match is not looking for name of the input, but the id of the input.
So if you put id="registerPassword" in your password input. That should work. I don't know why this is not in the documentation.
you will working just add id name of every input
Password
<div class="field">
<label>Verify Password</label>
<input type="password" name="registerPasswordVerify" id="registerPassword">
</div>
I'm trying to submit my form through Jquery, but the submit part of my code just doesn't work! And I can't see what's wrong with it.
<?php
if(!isset($_SESSION["useridentity"])){
die(header("Location:index.php"));
}
include("actions/connect.php");
$q = "SELECT username FROM users WHERE useridentity = '".$_SESSION["useridentity"]."'";
$r = mysql_query($q,$con);
$f = mysql_fetch_array($r);
?>
<div class="absolutedialog" id="login">
<form class="loginform" id="loginform" name="loginform" method="POST" action="actions/login.php">
<div class="label">
Welcome back, <b><?php echo $f["username"]; ?></b>. Please, type your password to confirm your identity.
</div>
<input class="loginformpassword" id="password" type="password" name="pass" maxlength="32"/>
<div id="passwordfail"></div>
<input class="regularbutton" id="submit" type="button" value="Submit"/>
<button class="grayregularbutton" id="gobacktoconsole" type="button">Go back</button>
</form>
</div>
<div class="blackoverlay"></div>
<script>
$(document).ready(function() {
$('#login').fadeIn(1000);
$('.blackoverlay').fadeIn(500);
//Destroy $_SESSION variables and go back to console
$('#gobacktoconsole').on('click',this, function(e) {
$(".absolutedialog").fadeOut(500);
$(".blackoverlay").fadeOut(1000);
window.setTimeout(
function() {
window.location.href="actions/logout.php";
},
1000
);
});
//Submit validations
$('#submit').on('click',this, function(e){
if($("#password").val() == "")
$("#passwordfail").html("Please, type your password");
else{
$("form#loginform").submit();
$(".absolutedialog").fadeOut(500);
$(".blackoverlay").fadeOut(1000);
}
});
//Clear password message error when something is typed in the password input
$('#password').on('keyup',this, function(e) {
$("#passwordfail").html("");
});
//Prevent default submit on enter, and click #submit button instead in order to execute validations
$('#loginform').bind("keyup keypress", function(e) {
var code = e.keyCode || e.which;
if(code == 13){
e.preventDefault();
$("#submit").click();
}
});
});
</script>
I tried adding return false; below $("form#loginform").submit(); but doesn't works. Am I missing something? Please, help!
Sorry for the lack of details; if you need me to add some more, please ask.
You have this element:
<input class="regularbutton" id="submit" type="button" value="Submit"/>
When you say
$("form#loginform").submit();
THe brpwser is assuming you're calling it, not the submit() method of the form object. Just change the id to something else.
<input class="regularbutton" id="submitButton" type="button" value="Submit"/>
The nastiest thing ever! Hope this helps.
I have seen many times problems about form submitting and form validation and I have found that the best way to do it is by using a simple open source jquery plugin such as jquery.validate.js.
This is an example about preventing default submit and posting data successfully to php file.
First you have to get these open source framework and you can use them whenever you want.
Files are three scripts :
<script src="js/jquery.min.js></script>
<script src="js/bootstrap.min.js"></script> <!-- open source framework twitter bootstrap -->
and one css file :
<link href="bootstrap/bootstrap.min.css" rel="stylesheet" media="screen">
example of code :
<form method="post" action="php/inscriptionAction2.php" class="form-horizontal" name="register" id="register">
// code of site inscription : name , email , password , confirmed password ....
<div class="form-group">
<div class="col-xs-offset-3 col-xs-9">
<div class="form-actions">
<input type="submit" class="btn btn-primary" name="newsubmit" id="newsubmit" value="Submit">
<input type="reset" class="btn btn-default" value="Reset">
</div>
</div>
</div>
</form>
and this is a simple script
$(document).ready(function(){
jQuery.validator.addMethod("lettersonly", function(value, element) {
return this.optional(element) || /^[a-z]+$/i.test(value);
});
$('#loginForm').validate({
rules: {
name: {
minlength: 2,
lettersonly:true,
required: true
},
lname: {
minlength: 2,
lettersonly:true,
required: true
},
username: {
lettersonly:true,
minlength: 2,
required: true
},
email: {
required: true,
email: true,
remote: {
url: '/setup/verify_email/',
cache: false
}
},
password: {
required: true,
minlength: 5,
maxlength: 250
},
password2: {
equalTo: '#password'
},
gender: {
required: true
}
},
messages: {
name: {
required:"Please enter your first name",
minlenght:"Your first name must consist of at least {0} characters",
lettersonly: "Letters only please"
},
lname: {
required:"Please enter your last name",
minlenght:"Your last name must consist of at least {0} characters",
lettersonly: "Letters only please"
},
username: {
lettersonly: "Letters only please",
required: "Please enter a username",
minlength: "Your username must consist of at least {0} characters"
},
email: {
required:"Please enter your email address",
email:"Please enter a valid email adress",
url:"Please enter a valid url",
cache:""
},
password: {
required: "Please provide a password",
minlength: "Your password must be at least {0} characters long",
maxlength: "Your password must be less than {0} characters long"
},
password2: {
equalTo: "Please enter the same passwords"
},
postal_code: "Please enter a valid zip code",
timezones: "Please select a time zone",
mp: "Please enter a valid mobile number. Only numbers please.",
gender: "Please select a gender",
dob: "Please enter a valid Date of Birth in mm/dd/yyyy format."
},
highlight: function (element, errorClass, validClass) {
$(element).closest('.control-group').removeClass('success').addClass('error');
},
unhighlight: function (element, errorClass, validClass) {
$(element).closest('.control-group').removeClass('error').addClass('success');
},
success: function (label) {
$(label).closest('form').find('.valid').removeClass("invalid");
},
errorPlacement: function (error, element) {
element.closest('.control-group').find('.help-block').html(error.text());
}
}).cancelSubmit=true; // to block the submit of this plugin and call submit to php file
By using two powerful frameworks, Twitter Bootstrap and jQuery , you can make your work faster and more professional.
For more details you can have a look at their documentation.
First you should import jquery
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
second change the id value of the button to anything else and will work, you may need to set timeout before submitting in order to delay the submit after the fadeout effect
I'm trying to implement Mesosphere for validation into my meteor app but it seems like Mesosphere isn't picking up on some of the native validations I've listed.
I tried just a single validation for formatting of email and it's required length. For example:
Mesosphere({
name: 'signupForm',
method: 'signupUser',
fields: {
email: {
required: true,
format: 'email',
rules: {
exactLength: 4
},
message: 'Wrong length'
}
},
onFailure: function (errors) {
messages = [];
messages = _.map(errors, function (val, err) {
console.log(val.message);
});
},
onSuccess: function (data) {
alert("Totally worked!")
}
});
The 'onFailure' (and onSuccess) callback seems to work because it is logging something when I submit the form. Which makes me believe I have it set up properly on the form submit event too. There you pass the form object to Mesosphere to create the validationObject if I understand it correctly. For example:
var validationObject = Mesosphere.signupForm.validate(accountData);
Once submitted, it's logging Field Required as the error which is weird because I did type something into the field. It makes no mention of an incorrect length or format. It skips the 'Wrong Length' message and I can't find that message in the object anywhere.
So my question is what am I doing wrong to not be getting the proper message for the incorrect input for that form field? Thanks : )
Also, willing to take recommendations on other validation packages. Mesosphere leverages Meteor's server/client features for validation so it seemed like a good place to start.
Template:
<template name="signup">
<form name="signupForm" id="signup-form" class="panel" action="#">
<div class="form-group">
<label for="email">Email</label>
<input type="text" name="email" id="email" class="form-control" />
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" name="password" id="password" class="form-control" />
</div>
<div class="form-group">
<input type="submit" value="Sign Up" id="create-account" class="btn btn-success pull-right">
</div>
</form> </template>
Which calls this method in the corresponding file:
signupUser: function(accountData) {
var uid = Accounts.createUser(accountData);
}
So basically what I see here is that your rules don't reflect how the form would be validated. You have an email that must match the email format, but then you have a rule that says it has to be exactly 4 characters long.. a better field definition would look like this:
fields: {
email: {
required: true,
format: 'email',
message: 'Please enter a valid email address'
},
password: {
required: true,
rules: {
minLength: 6,
maxLength: 30,
},
message: "Password must be between 6 and 30 characters"
}
}
I created a github repo that you can clone and run to test this out if you would like.
https://github.com/copleykj/meso-test
Hope this helps.
I'm using this jquery validation plugin
<s:textfield cssClass="form-control input-default" name="contest.title" id="title" placeholder="Enter Title"
/>
Validation doesn't work for this, but if I change the name to title - validation works.
I tried searching, but couldn't find a means to validate fields with a . in their name.
Please help
Update
Script
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery("#contestform").validate({
submitHandler: function(form) {
// return false; // block the default submit action
},
rules: {
title: {
required: true
},
link: {
required: true
},
startdt: {
required: true
},
enddt: {
required: true
},
descr: {
required: true
},
},
messages: {
title: "Please enter a title",
link: "Please enter the sponser redirection link",
startdt: "Please select start date",
enddt: "Please select end date",
descr: "Please enter description"
}
});
});
</script>
Part of the form
<form action="" enctype="multipart/form-data" method="post" id="contestform">
<s:hidden name="option" value="option"/>
<s:hidden name="contest.idcontest"/>
<div class="form-group">
<label for="title">Title</label>
<s:textfield cssClass="form-control input-default" name="contest.title" id="title" placeholder="Enter Title"
/>
</div>
You need to put the field names in qoutes. From the plugin documentation
Fields with complex names (brackets, dots)
When you have a name attribute like user[name], make sure to put the
name in quotes. More details in the General Guidelines.
The sample in the linked reference:
$("#myform").validate({
rules: {
// no quoting necessary
name: "required",
// quoting necessary!
"user[email]": "email",
// dots need quoting, too!
"user.address.street": "required"
}
});