New to Angular so apologies if this question has been asked before.
I've got field validation working well with ng-messages (great tutorial here if anyones interested).
However what I've read/learnt so far does validation whenever fields are touched.
<div ng-messages="{ required: !main.o1ToAdd || !main.o2ToAdd }"
ng-if="myForm.o1.$touched || myForm.o2.$touched">
<span ng-message="required">you need to specify at least 2</span>
</div>
and on the inputs
<input name="o1" ng-model="main.o1ToAdd" type="text" placeholder="Yes" required
ng-class="{ 'invalidInputField': myForm.o1.$touched && myForm.o1.$invalid }"/>
However I dont really want an error to appear if a user clicks on a field.
Instead I have a post button - so if thats click on then should all verification across the form be made. What I'm unsure of is I already have a ng-click on that button - how do i make it do the verification first and then if successful, proceed with the actual post function. (and ideally I dont want to disable the button i.e. have it greyed out).
<button class="button" ng-click="home.post()">Post</button>
Any help would be appreciated.
Thanks.
May be help you.
angular.module("test", []).controller("TestCtrl", function($scope) {
$scope.onSubmit = false;
$scope.submit = function() {
if(!$scope.theForm.$valid)
$scope.onSubmit = true;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test" ng-controller="TestCtrl">
<form name="theForm">
<input type="text" required name="foo" ng-model="foo" />
<p ng-show="onSubmit && (theForm.foo.$touched || !theForm.foo.$valid)">error at foo input</p>
<input type="text" required name="bar" ng-model="bar" />
<p ng-show="onSubmit && (theForm.bar.$touched || !theForm.bar.$valid)">error at bar input</p>
<button ng-click="submit()" type="button">Submit</button>
</form>
</div>
Related
I am trying to check whether after I submit, login form without username / password, I will receive an error message below the certain field, and i done a simple test scenario for that:
it('password input should display required message', async() => {
component.validateForm.controls['password'].setValue('');
const submitBtn = el.querySelector("[data-test='submit']") as HTMLElement;
const control = el.querySelector("[data-test='password-control']") as HTMLElement;
submitBtn.click();
fixture.detectChanges();
expect(control.innerText).toContain('Please input your Password!');
});
html code:
<form nz-form [formGroup]="validateForm" class="login-form" (ngSubmit)="submitForm()" data-test="form">
<nz-form-item >
<nz-form-control nzErrorTip="Please input your username!" data-test="username-control">
<nz-input-group nzPrefixIcon="user" >
<input type="text" nz-input formControlName="username" placeholder="Username"/>
</nz-input-group>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control nzErrorTip="Please input your Password!" data-test="password-control">
<nz-input-group nzPrefixIcon="lock">
<input type="password" nz-input formControlName="password" placeholder="Password" />
</nz-input-group>
</nz-form-control>
</nz-form-item>
<div nz-row class="login-form-margin">
<div nz-col [nzSpan]="12">
<label nz-checkbox formControlName="remember">
<span>Remember me</span>
</label>
</div>
<div nz-col [nzSpan]="12">
<a class="login-form-forgot">Forgot password</a>
</div>
</div>
<button nz-button class="login-form-button login-form-margin" [nzType]="'primary'" data-test="submit">Log in</button>
Or
<a>register now!</a>
</form>
and when I tried this in browser by running in dev tools after submiting form without typing anything in password input
document.querySelector("[data-test='password-control']").includes('Please input your Password!') it returns true, I also tried adding to code above tick(1000), before expect statement to make sure, there is enough time to make it appear before the check, but it hasn't changed anything, the test result is negative with message Expected '' to contain 'Please input your Password!'..
Will be happy with any suggestions to solve that issue :)
i am making a database programm where the user has to submit some of his contact information.
<form action="add_action.php" method="POST">
<div class="modal-body">
Name: <br>
<input type="text" name="name" placeholder="Name" required><br>
Telefon Nr. <br>
<input type="text" name="telNr" placeholder="Telefon Nr."><br>
Handy Nr. <br>
<input type="text" name="handyNr" placeholder="Handy Nr."><br>
Skype ID <br>
<input type="text" name="skypeId" placeholder="Skype ID"><br>
<div class="modal-footer">
<input type="submit" class="btn btn-default" value="Hinzufügen">
</div>
</form>
i have been researching a while now, but i cant seem to figure out how i can set the form so at least 1 out of "Telefon Nr.", "Handy Nr." and "Skype ID" is required. if you have any sugestions of what i should do i would apreciate your input.
Consider reading this. I'll be showing, only, how to check for the presence of the field named name alongside at least one field from the others.
Sever side verification:
Ps: you didn't give the submit button a name, i'll give it a name="submit", for example, to make checking for form submission possible within php.
if{isset($_POST["submit"])
// don't rely on HTML required attribute, a user with a bit of knowledge can remove/bypass it, I mean check for the presence of the name either
$name = trim($_POST["name"]);
$telNr = trim($_POST["telNr"]);
$handyNr = trim($_POST["handyNr"]);
$skypeId = trim($_POST["skypeId"]);
if(isset($name[0]) && (isset($telNr[0]) || isset($handyNr[0]) || isset($skypeId[0]))) {
echo "At least one field is present alongside with the name";
} else {
echo "The name and/or the other fields are empty";
}
}
Client side verification:
Ps: let me give an ID to the form tag, let's say id="my-form".
var myForm = document.getElementById("my-form");
myForm.addEventListener("submit", function(event){
// get all the fields values, and trim them on the fly
var name = document.getElementsByName("name")[0].value().trim(),
telNr = document.getElementsByName("telNr")[0].value().trim(),
handyNr = document.getElementsByName("handyNr")[0].value().trim(),
skypeId = document.getElementsByName("skypeId")[0].value().trim();
// we want the name and at least one other field to be filled
if(name !== "" && (telNr !== "" || handyNr !== "" || skypeId !== "" )) {
alert("we're good to go, the name is provided alongside with at least another field");
} else {
event.preventDefault(); // we cancel form submission as the name and/or the other fields are empty using the Event argument
alert("Cancelled, please fill in the name and at least one other field");
}
});
Hope I pushed you further to more understand how things work
Ps: that's a really basic example, don't rely on this in production phase as the code I provided may be vulnerable to some attacks(such as XSS aka Cross-Site-Scripting, SQL injection...).
You'd need to use some javascript to do this. The only thing you can do with HTML is add the "required" attribute as you've done with the name already.
This is the way i created it in a form i made a while back. I have edited it for you so place it in and should work off the bat.
<script>
function validateForm() {
var a,b,c,d = document.forms["form"]["name","telNr","handyNr","skypeId"].value;
if (a,b,c,d==null || a,b,c,d=="")
{
alert("Please complete all Required Fields *");
return false;
}
}
</script>
<body>
<form name="form" action="add_action.php" onsubmit="return validateForm()" method="POST">
<div class="modal-body">
Name: <br>
<input type="text" name="name" placeholder="Name"><br>
Telefon Nr. <br>
<input type="text" name="telNr" placeholder="Telefon Nr."><br>
Handy Nr. <br>
<input type="text" name="handyNr" placeholder="Handy Nr."><br>
Skype ID <br>
<input type="text" name="skypeId" placeholder="Skype ID"><br>
<div class="modal-footer">
<button type="submit" class="btn btn-default" value="Hinzufügen" >Sign In</button>
</div>
</form>
I have worked on AngularJs and now working on Angular2. Whenever I searched for form validation in angular I always found the submit button like below:
In AnglarJs
<input type="submit"
ng-disabled="myForm.user.$dirty && myForm.user.$invalid ||
myForm.email.$dirty && myForm.email.$invalid">
In Angular2
<button type="submit" class="btn btn-default"
[disabled]="!heroForm.form.valid">Submit</button>
But I wanted the submit button should be enable and whenver user click on that we prompt the error below the text fields. There is no exact solution mentioned for this purpose.
I found some of that some of the users directly clicks on submit button and they wanted to fill only required fileds.
This is my observation only may be some of you also experienced the same while development.
For AngularJs 1 I am using custom-submit directive from here
https://gist.github.com/maikeldaloo/5133963
So please suggest me any solution to provide custom-submit in angular2 also.
---- Sample Login Form (Angular2) ---
<form class="ui large form" (ngSubmit)="onUserLogin(loginForm.form.valid)" #loginForm="ngForm" method="post" novalidate>
<sm-loader [complete]="!formSubmited" class="inverted" text="Loading..."></sm-loader>
<div class="field">
<input type="email" name="email" placeholder="Email" [(ngModel)]="login.email" #email="ngModel" required />
<div [hidden]="email.valid || email.pristine" class="error text-left">
Email is required
</div>
</div>
<div class="field">
<input type="password" name="password" placeholder="Password" [(ngModel)]="login.password" #password="ngModel" required />
<div [hidden]="password.valid || password.pristine" class="error text-left">
Password is required
</div>
</div>
<button class="fluid yellow large ui button" type="submit">Login</button>
</form>
Please check what custom-submit directive are doing. Please give me answers the based on that. I know I can check the form valid status on controller level, but why this way I can say only form is not valid, I can not say which field is empty (we can also check this which field is valid, but don't know how to enable the error divs from controllers)
Please refer this...
https://gist.github.com/maikeldaloo/5133963
Thanks,
Just set a state and show/hide the errors depending on the state:
onSubmit() {
if(hasErrors()) {
this.hasErrors = true;
return false; // preventDefault
}
this.postData(); // process submit event
}
<div *ngIf="hasError">
... error info here
</div>
This way we actually validate whether you have entered the correct values or not. If any of the value fails then submit button gets disabled otherwise enabled.
For ex: E-mail : If email id doesn't have # and ., then it will be considered as dirty, which wouldn't lead to enable the submit button.
Edited:
To display the message you can do one thing:
<input type="submit" ng-click="done(heroForm.form.valid)" />
And in controller you can do this way.
$scope.done = function(valid){
if(valid) {
// Form content is valid, process it
} else {
// show error and do nothing.
}
}
I have two methods ngMake and ngUpdate. I have one form, PostForm. I want to reuse the same form, but add different functionality depending on the url.
I gain information about the url using
Controller
if ($location.path() === '/makepost') {
$scope.FormTitle = 'Make a Post';
$scope.FormAction = 'server/blog/makepost.php';
$scope.FormMethod = 'POST';
$scope.FormSubmit = "ngMake()"
};
if ($location.path().indexOf('update') !== -1) {
$scope.FormTitle = 'Update a Post';
$scope.FormAction = null;
$scope.FormMethod = 'POST';
$scope.FormSubmit = "ngUpdate()";
};
HTML Form
<div ng-controller="BlogController as blog">
<h3 class="text-center">{{FormTitle}}</h3>
<form ng-show='user != null' ng-submit="{{FormSubmit}}" role="form" class="form-group" name="PostForm">
<label>Title: </label>
<div ng-class="(PostForm.Title.$dirty && PostForm.Title.$invalid) ? 'has-warning' : 'has-success'" class="form-group has-feedback">
<input data-ng-model="post.Title" data-ng-minlength="3" data-ng-maxlength="255" name="Title" type="text" class="form-control" placeholder="Title" required/>
<span ng-class="(PostForm.Title.$dirty && PostForm.Title.$invalid) ? 'glyphicon-warning-sign' : 'glyphicon-ok'" class="glyphicon form-control-feedback"></span>
</div>
<label>Content: </label>
<div ng-class="(PostForm.Content.$dirty && PostForm.Content.$invalid) ? 'has-warning' : 'has-success'" class="form-group has-feedback">
<textarea data-ng-model="post.Content" rows="8" name="Content" type="text" class="form-control" placeholder="Content" required></textarea>
<span ng-class="(PostForm.Content.$dirty && PostForm.Content.$invalid) ? 'glyphicon-warning-sign' : 'glyphicon-ok'" class="glyphicon form-control-feedback"></span>
</div>
<div ng-controller="AuthController as auth">
<input class="ng-hide" type="number" data-ng-model="post.UserID" name="UserID" value="{{user.ID}}">
</div>
<br>
<input type="submit" ng-class="(PostForm.$valid) ? 'btn-success' : 'disabled'" class="btn btn-block btn-default">
</form>
<p ng-show='user == null' class="text-center">You must be logged in in order to {{FormTitle | lowercase}}</p>
Explination
The {{FormSubmit}} template variable probably executes afterwards and causes a problem which doesn't permit the form to execute. I am open to suggestions, I want to reuse the same form. I read that ngSubmit requires a type="submit" button or input element contained within the form tags, I have that. I do not have any ng-clicks which might hinder the form.
I am open to suggestions
If there are any other problems with the form or the entire project please let me know, even if it is just a "bette practice".
The full project
https://github.com/AquaSolid/RAMA_Angular_PHP
Basically, I wised up. I contained the logic in the back-end. I created a function to choose which function to use. Meanwhile the the form contains the attribute ng-submit="chooseSubmit()". That's about it..
$scope.chooseSubmit = function() {
if ($scope.FormSubmit) {
if ($scope.FormSubmit === 'ngMake()') {
$scope.ngMake();
} else {
$scope.ngUpdate();
};
}
};
I have this Javascript datastore which is part of a TiddlyWiki (fyi) for storing product by SKU. However I'm not sure how to make a form to update it. I want the form to retrieve the amount of the product in ID that is available using GetAmount. The user is given the option to add to, subtract from, or update the value, and then it saves it using the Update function. The new amount should also be displayed in the amount field. This seems like it should be simple, but I don't know enough about HTML forms to know how to do it.
Here is a fiddle with what I have so far. http://jsfiddle.net/Arlen22/pCDx3/
Forget about using html forms to submit your data. Your datasource is connected directy to your javascript so you can skip the postback and codebehind stuff. I would use jQuery for simplicity but you could do it with native javascript as well. jQuery is well documented if you decide to learn and use it, and worth the time to learn if you ask me.
This example should help to get you started, feel free to edit and comment on it as needed:
Html
<fieldset class="stock-control">
<legend>Edit Stock Amount</legend>
<label>ID:</label>
<input type="text" id="txt-id">
<label>Amount:</label>
<input type="text" id="txt-change"><br />
<input type="button" id="btn-add" value="Add">
<input type="button" id="btn-sub" value="Subtract">
<input type="button" id="btn-set" value="Set">
<br />
<label>In stock: </label><span id="lbl-total"></span>
</fieldset>
<fieldset class="stock-control">
<legend>Edit Stock Amount</legend>
<label>ID:</label>
<input type="text" class="txt-id">
<label>Amount:</label>
<input type="text" class="txt-change"><br />
<input type="button" class="btn-add" value="Add">
<input type="button" class="btn-sub" value="Subtract">
<input type="button" class="btn-set" value="Set">
<br />
<label>In stock: </label><span class="lbl-total"></span>
</fieldset>
Javascript
// Your code
$(function () {
$('.stock-control').each(function () {
var $control = $(this);
var $id = $control.find('.txt-id');
var $amount = $control.find('.txt-amount');
var $total = $control.find('.lbl-total');
function RenderAmount() {
$total.text(StockRecorder.GetAmount($id.val()));
};
$('.btn-add').click(function () {
var stock = parseInt($total.text()) + parseInt($amount.val());
StockRecorder.Update($id.val(), stock);
RenderAmount();
});
$('.btn-sub').click(function () {
var stock = parseInt($total.text()) - parseInt($amount.val());
StockRecorder.Update($id.val(), stock);
RenderAmount();
});
$('.btn-set').click(function () {
StockRecorder.Update($id.val(), parseInt($amount.val()));
RenderAmount();
});
// Initialize
RenderAmount();
});
});
NOTE: You would want a button or an event that calls the RenderAmount() functions when an id has been entered/changed in the id textbox. In my example i pretended it was already filled in.
By the way, seems like a fun project you have gotten your hands on. Enjoy it! :)