I'm creating a Shopify website, and I'm currently working on the customer registration form. I need to make a Confirm Password field. Does anybody know how to do this in Shopify?
Just Got it working on my register page:
The two password fields:
<div id="create_password_container">
<label for="password">Your Password<em>*</em></label>
<input type="password" value="" name="customer[password]" id="create_password" {% if form.errors contains "password" %} class="error"{% endif %}>
</div>
<div id="password_confirm_container">
<label for="password_confirmation">Password Confirmation</label> <span class="password-match">PASSWORDS DO NOT MATCH</span>
<input type="password" value="" name="customer[password_confirmation]" id="password_confirm" />
</div>
Javascript:
$('form#create_customer').submit(function(e) {
if ( $('#create_password').val() === $('#password_confirm').val()) {
//alert('Password Good!!');
} else {
$('.password-match').fadeIn("slow");
e.preventDefault(); // stops our form from submitting
}
});
The CSS for the password not-matching message:
.password-match {font-size: 12px; color: #f1152f; display:none;}
When customers receive the link to their activation they are prompted for both a password and a password confirmation. Failing that - you can add an extra input (password confirmation) and then do a simple comparison with javascript. Something like:
.... <label for="password" class="login">{{ 'customer.register.password' | t }}</label>
<input type="password" value="" name="customer[password]" id="password" class="large password" size="30" />
<label for="password-confirm" class="login">{{ 'customer.register.password' | t }}</label>
<input type="password" value="" name="customer[password-confirm]" id="password-confirm" class="large password" size="30" /> ....
and then with jquery - something like
$('form').submit(function(e) {
e.preventDefault(); // stops our form from submitting
if ( $('#password').val() === $('#password-confirm').val()) {
$('form').submit();
}
});
That was done off the top of my head - so not tested. It should compare the two password strings - and if they match, allow the form to submit. Of course - you'll probably want to do stuff like show a pop up... alert or message to say your passwords don't match etc. In which case:
$('form').submit(function(e) {
e.preventDefault(); // stops our form from submitting
if ( $('#password').val() === $('#password-confirm').val()) {
$('form').submit();
} else {
// put your validation message in here - this could be showing an element... or showing an alert etc
alert("Your passwords don't match dummy!")
}
});
You could just as easily do
$( ".errorMessage" ).fadeIn( "slow", function() {
// Animation complete
$(this).hide();
});
instead of the alert - but you'd need to make sure you have a div with a class of .errorMessage that contains your error message :)
Related
I have a registration page for my app. In order to be able to click the button the username and email input fields must have content inside of them. The password input field has a list of parameters: between 8-30 characters long and contain atleast one: uppercase letter, lowercase letter, special character, & number. and the confirm password input field should match the password input field exactly. I used regex to test the password input field and I used the triple equal operator to test if the passwords matched. I'm using oninput events for both of those cases. Where I'm having trouble is finding the best event to trigger the styles associated with my button depending on it being enabled or disabled. I can tie the styling and element attribute to the same functions I'm using for the password stuff but its not exactly full proof.
JS:
function pwValidation() {
let str = document.getElementById('password').value;
let message = document.getElementById('passwordError');
if (!str.match(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[#$#!%&*?])[A-Za-z\d#$#!%&*?]{8,30}$/)) {
message.innerText = 'Passwords must be between 8-30 characters long and contain atleast one: uppercase letter, lowercase letter, special character, & number.';
document.getElementById('signUp-btn').style.color = "rgba(255, 255, 255, 0.38)"
document.getElementById('signUp-btn').style.backgroundColor = "rgba(14, 16, 27, 0.38)"
} else {
message.innerText = '';
}
};
function pwMatch() {
if(document.getElementById('password').value !== document.getElementById('password2').value){
document.getElementById('passwordMatch').innerText = 'Passwords must match.';
} else {
document.getElementById('passwordMatch').innerText = '';
document.getElementById('signUp-btn').style.color = "rgb(255, 255, 255)"
document.getElementById('signUp-btn').style.backgroundColor = "rgb(14, 16, 27)"
}
}
HTML:
<form action="/register/createUser" method="POST">
<fieldset>
<input
type="text"
id="text"
name="username"
class="form-control"
placeholder="Username"
oninput="inputDisable()"
/>
<input
type="email"
id="email"
name="email"
class="form-control"
placeholder="Email"
oninput="inputDisable()"
/>
<div class="password-container">
<input
type="password"
id="password"
name="password"
class="form-control"
placeholder="Password"
oninput="pwValidation()"
/>
<div id="passwordError"></div>
<i class="fa-regular fa-eye-slash" id="togglePassword"></i>
</div>
<div class="password-container">
<input
type="password"
id="password2"
name="password2"
class="form-control"
placeholder="Confirm Password"
oninput="pwMatch()"
/>
<div id="passwordMatch"></div>
<i class="fa-regular fa-eye-slash" id="togglePassword2"></i>
</div>
<button type="submit" id="signUp-btn">Sign Up</button>
</fieldset>
</form>
My logic with the functions isn't full proof and you can easily get the button to display. I need some better logic in my functions or a need a better eventlistener but I lack context as I'm new.
Controller : User.php
public function index()
{
log_message('debug', ' Index User');
die("should never get here");
}
public function login()
{
log_message('debug', ' Login Entered');
echo '<pre> Printing Login data:';
print_r($_POST);
echo "</pre>";
$data['pageHeader'] = "Login";
$data['message'] = 'temporary message - This will be the login stuff';
$this->session->set_flashdata('flashInfo', 'Login form will go here');
$this->form_validation->set_rules('username', 'Username', 'trim|required');
$this->form_validation->set_rules('password', 'Password', 'required');
if ($this->form_validation->run() === FALSE)
{
log_message('debug', ' validation run FALSE');
$this->load->helper('form');
$this->render_page('user/login', 'public_header', 'footer', $data);
}
else
{
log_message('debug', ' validation run TRUE');
$remember = (bool) $this->input->post('remember');
if ($this->ion_auth->login($this->input->post('username'), $this->input->post('password'), $remember))
{
log_message('debug', ' redirect Dashboard');
redirect('dashboard');
}
else
{
$_SESSION['auth_message'] = $this->ion_auth->errors();
$this->session->mark_as_flash('auth_message');
log_message('debug', ' redirect user login');
redirect('user/login');
}
}
}
Known from log:
function login entered,
$_POST always 'empty',
form validation-> always FALSE thus debug message is logged and form redisplayed
Form user/login.php
<?php defined('BASEPATH') OR exit('No direct script access allowed');?>
<div class="container">
<?php echo $message;?>
<h1>Login</h1>
<form action="#" method="post">
<div class="imgcontainer">
<img src="http://www.hdkumdo.com/smen/assets/crow2.png" alt="Swordsmen Martial Arts">
</div>
<div class="container">
<label for="username"><b>Username</b></label>
<input type="text" placeholder="Enter Username" name="username" id="username" required autofocus>
<label for="password"><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="password" id="password" required>
<button type="submit" name="login" id="login" value"login" >Login</button>
<label>
<input type="checkbox" checked="checked" name="remember" id="remember"> Remember me
</label>
</div>
<div class="container" style="background-color:#f1f1f1">
<button type="button" class="cancelbtn">Cancel</button>
<span class="psw">Forgot password?</span>
</div>
</form>
</div>
Copied an example from https://www.codeigniter.com/user_guide/libraries/form_validation.html
and form posts data but if I change function index to login it does not work.
Menu link : Login works fine.
Everything seems to be connected...login form displays, Controller function login is entered but it seems like there is no POST data so the form is simply redisplayed. I have 2 simple validation rules so it seems that validation->run should return true if I just enter any data into the fields.
I am sure it's something simple but for the life of me I can't see what.
First of all make sure you have loaded form validation library
$this->load->library('form_validation');
//set field validation
$this->form_validation->set_rules('fieldname','Field Name','required');
if($this->form_validation->run())
{
//then process form
//redirect
}
else {
//load view
}
I am new to Angular 2.
I have created a simple template which has two text field, I want to required field validate those two fields.
Login Form
<form #loginForm="ngForm" (ngSubmit)="onSubmit(loginForm)" novalidate>
<div class="container">
<div class="form-group">
ooooo <label><b>Username</b></label>
<input type="text" placeholder="Enter Username" name="uname" required [(ngModel)]="UserData.uname" #uname="ngModel">
<div *ngIf="loginForm.invalid" class="alert alert-danger">
<div [hidden]="!uname.errors.required"> Name is required </div>
</div>
</div>
<div class="form-group">
<label><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="pwd" required [(ngModel)]="UserData.pwd" #pwd="ngModel">
<div *ngIf="UserData.pwd.errors && (UserData.pwd.dirty || UserData.pwd.touched)" class="alert alert-danger">
<div [hidden]="!UserData.pwd.errors.required">Password is required </div>
</div>
<button type="submit" >Login</button>
</div>
</div>
</form>
My Component
import { Component } from "#angular/core"
import { User } from "./UserModel"
#Component({
selector: 'my-login',
templateUrl:"app/Login/login.html"
})
export class LoginComponent
{
//alert: any("hello");
UserData: User = new User("", "");
submitted = false;
onSubmit(form: any) {
alert("dfsdfsd" + form);
if (!form.invalid) {
alert(this.UserData.uname);
alert(this.UserData.pwd);
this.submitted = true;
}
}
}
What i want to implement is-
When the form loads no validation message should appear?
When user clicks on the submit button then the required message should appear?
In both the textbox i have applied different type of checks to show the message that is inconsistent? so there should be a consistent way to solve this.
Many thanks for the help.
Maybe make use of the submitted variable, and use that in template, to not show message, until submitted is true, which we set it as in the submit function.
Also you wouldn't really need the two-way-binding here, since the object your form produces is directly assignable to your UserData.
The validation messages I'd just set then simply like this, where we are targeting the username:
<div *ngIf="uname.errors?.required && submitted"> Name is required </div>
in your submit function I'd pass loginForm.value as parameter instead of just loginForm. This way you get the form object ready to be used :)
And in your function you can assign the object to your UserData variable.
onSubmit(form: any) {
this.submitted = true;
this.UserData = form;
}
If you do want to keep the two-way-binding, it's of course totally possible! :)
DEMO
I have a template based form in my Angular2 app for user registration. There, I am passing the form instance to the Submit function and I reset the from once the async call to the server is done.
Following are some important part from the form.
<form class="form-horizontal" #f="ngForm" novalidate (ngSubmit)="onSignUpFormSubmit(f.value, f.valid, newUserCreateForm, $event)" #newUserCreateForm="ngForm">
<div class="form-group">
<label class="control-label col-sm-3" for="first-name">First Name:</label>
<div class="col-sm-9">
<input type="text" class="form-control" placeholder="Your First Name" name="firstName" [(ngModel)]="_userCreateForm.firstName"
#firstName="ngModel" required>
<small [hidden]="firstName.valid || (firstName.pristine && !f.submitted)" class="text-danger">
First Name is required !
</small>
</div>
</div>
.......
.......
<div class="form-group">
<div class="col-sm-offset-3 col-sm-12">
<button type="submit" class="btn btn-default">Submit</button>
<button type="reset" class="btn btn-link">Reset</button>
</div>
</div>
</form>
In my component file, I have written following function.
onSignUpFormSubmit(model: UserCreateForm, isValid: boolean, form: FormGroup, event:Event) {
event.preventDefault();
if (isValid) {
this._userEmail = model.email;
this._authService.signUp(this._userCreateForm).subscribe(
res => {
console.log("In component res status = "+res.status);
if(res.status == 201){
//user creation sucess, Go home or Login
console.log("res status = 201");
this._status = 201;
}else if(res.status == 409){
//there is a user for given email. conflict, Try again with a different email or reset password if you cannot remember
this._status = 409;
}else{
//some thing has gone wrong, pls try again
this._serverError = true;
console.log("status code in server error = "+res.status);
}
form.reset();
alert("async call done");
}
);
}
}
If I submit an empty form, I get all validations working correctly. But, when I submit a valid form, Once the form submission and the async call to the server is done, I get all the fields of the form invalid again.
See the following screen captures.
I cannot understand why this is happening. If I comment out form.reset(), I do not get the issue. But form contains old data i submitted.
How can I fix this issue?
I solved this By adding these lines:
function Submit(){
....
....
// after submit to db
// reset the form
this.userForm.reset();
// reset the errors of all the controls
for (let name in this.userForm.controls) {
this.userForm.controls[name].setErrors(null);
}
}
You can just initialize a new model to the property the form is bound to and set submitted = false like:
public onSignUpFormSubmit() {
...
this.submitted = false;
this._userCreateForm = new UserCreateForm();
}
You need to change the button type submit to button as following.
<div class="form-group">
<div class="col-sm-offset-3 col-sm-12">
<button type="button" class="btn btn-default">Submit</button>
<button type="reset" class="btn btn-link">Reset</button>
</div>
</div>
Reseting the form in simple javascript is the solution for now.
var form : HTMLFormElement =
<HTMLFormElement>document.getElementById('id');
form.reset();
this is how finally I had achieved this. I am using Angular5.
I have created a form group named ="firstFormGrop".
If you are not using form groups you can name the form as follow:
<form #myNgForm="ngForm">
In the html doc:
<form [formGroup]="firstFormGroup">
<button mat-button (click)='$event.preventDefault();this.clearForm();'>
<span class="font-medium">Create New</span>
</button>
</form>
In the .ts file:
this.model = new MyModel();
this.firstFormGroup.reset();
if you where using #myNgForm="ngForm then use instead:
myNgForm.reset();
// or this.myNgForm.reset()
This is a very common issue that after clicking the reset button we created the validators are not reset to its initial state, and it looks ugly.
To avoid that we have two options,the button is outside the form, or we prevent the submission when the button is tagged inside the form.
To prevent this default behaviour we need to call $event.preventDefault() before whatever method we are choosing to clear the form.
$event.preventDefault() is the key point.
The solution:
TEMPLATE:
<form
action=""
[formGroup]="representativeForm"
(submit)="register(myform)"
#myform="ngForm"
>
*ngIf="registrationForm.get('companyName').errors?.required && myform.submitted"
COMPONENT:
register(form) {
form.submitted = false;
}
Try changing the button type from "submit" to "button", e.g. :
<button type="button">Submit</button>
And move the submit method to click event of the button. Worked for me!
I have the following form in an Angular partial:
<form name="submit_entry_form" id="submit_entry_form" ng-submit="submit()" ng-controller="SubmitEntryFormCtrl" novalidate >
<input type="text" name="first_name" ng-model="first_name" placeholder="First Name" required/><br />
<input type="text" name="last_name" ng-model="last_name" placeholder="Last Name" required/><br />
<input type="text" name="email" ng-model="email" placeholder="Email Address" required/><br />
<input type="text" name="confirm_email" ng-model="confirm_email" placeholder="Confirm Email Address" required/><br />
<span ng-show="submit_entry_form.$invalid">Error!</span>
<input type="submit" id="submit" value="Submit" />
</form>
The trouble I'm having is with the span at the bottom that says "Error!". I want this to show ONLY if one of the inputs is both "ng-dirty" and "ng-invalid". As it is above, the error will show until the form is completely valid. The long solution would be to do something like:
<span ng-show="submit_entry_form.first_name.$dirty && submit_entry_form.first_name.$invalid || submit_entry_form.last_name.$dirty && submit_entry_form.last_name.$invalid || submit_entry_form.email.$dirty && submit_entry_form.email.$invalid || submit_entry_form.confirm_email.$dirty && submit_entry_form.confirm_email.$invalid">Error!</span>
Which is UGLY. Any better way to do this?
Method 1: Use a function on $scope set up by your controller.
So with a better understanding of your problem, you wanted to show a message if any field on your form was both $invalid and $dirty...
Add a controller method:
app.controller('MainCtrl', function($scope) {
$scope.anyDirtyAndInvalid = function (form){
for(var prop in form) {
if(form.hasOwnProperty(prop)) {
if(form[prop].$dirty && form[prop].$invalid) {
return true;
}
}
}
return false;
};
});
and in your HTML:
<span ng-show="anyDirtyAndInvalid(submit_entry_form);">Error!</span>
Here is a plunker to demo it
Now all of that said, if someone has entered data in your form, and it's not complete, the form itself is invalid. So I'm not sure this is the best usability. But it should work.
Method 2: Use a Filter! (recommended)
I now recommend a filter for this sort of thing...
The following filter does the same as the above, but it's better practice for Angular, IMO. Also a plunk.
app.filter('anyInvalidDirtyFields', function () {
return function(form) {
for(var prop in form) {
if(form.hasOwnProperty(prop)) {
if(form[prop].$invalid && form[prop].$dirty) {
return true;
}
}
}
return false;
};
});
<span ng-show="submit_entry_form | anyInvalidDirtyFields">Error!</span>