I have an input field in form that I dont want to send. Even though i removed the name on input field it stills get sent probably due to angular magic.
To prevent this I thought if I could remove this item from post request it'd be the solution.
<input type='radio' ng-model='birthday' ng-value='true'>
when form submits POST has field called birthday despite input not having a name attribute. So how do i prevent it from showing up.
Form is html template, and controller is called on ng-submit
I think that you may be looking for the disabled property:
<input type='radio' ng-model='birthday' ng-value='true' disabled="true">
Edited
Here is an example of how you could use the disabled property for not sending undesired information with the form on submit:
<html>
<body>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
var TestApp = angular.module("TestApp", []);
TestApp.controller('TestCtrl', function($scope) {
$scope.needsBirthdayDisabled = false;
$scope.needsBirthday = false;
$scope.sendForm = function(form) {
$scope.needsBirthdayDisabled = true; //if you comment this line, the "yep"'s input value will be sent with the form
form.$submitted = true;
};
});
</script>
<div ng-app="TestApp" ng-controller="TestCtrl">
<!-- the method is set to GET for test purpose (so we can easily see the sent values on the URL) -->
<form action="" method="GET" name="myForm" ng-submit="sendForm(this)">
<div>
<label for="name">Name</label>
<input type="text" name="name" ng-model="name"/>
</div>
<div ng-show="needsBirthday">
<label for="birthday">Birthday</label>
<input type="text" name="birthday" ng-model="birthday"/>
</div>
<div>
<label>Needs Birthday</label>
Yep <input type='radio' name="yep" ng-model='needsBirthday' ng-value='true' ng-disabled="needsBirthdayDisabled">
</div>
<input type="submit" value="Go!"/>
</form>
</div>
</body>
</html>
Related
I have a form which asks user to give some input values. For some initial inputs i am doing custom validation using javascript. At the end of form one field is validated using "html required attribute". But when user clicks on submit button, input box which have required attribute shows message first instead of giving chance to previous ones i.e. not following order of error display. Below i added code and image , instead of showing that name is empty it directly jumps to location input box. This just confuses the end user. Why this problem occurs and how to resolve it?
<html>
<head>
<script>
function validate(){
var name = document.forms['something']['name'].value.replace(/ /g,"");
if(name.length<6){
document.getElementById('message').innerHTML="Enter correct name";
return false;
}
}
</script>
</head>
<body>
<form name="something" action="somewhere" method="post" onsubmit="return validate()">
<div id="message"></div>
Enter Name : <input type="text" name="name" /> <br/> <br/>
Enter Location : <input type="text" name="location" required="required" /> <br/> <br/><br/> <br/>
<input type="submit" name="submit" />
</form>
</body>
</html>
This is probably just the HTML5 form validation triggered because of the required attribute in the location input.
So one option is to also set the required attribute on the name. And or disable the HTML5 validation with a novalidate attribute. See here for more information: https://stackoverflow.com/a/3094185/2008111
Update
So the simpler way is to add the required attribute also on the name. Just in case someone submits the form before he/she entered anything. Cause HTML5 validation will be triggered before anything else. The other way around this is to remove the required attribute everywhere. So something like this. Now the javascript validation will be triggered as soon as the name input looses focus say onblur.
var nameElement = document.forms['something']['name'];
nameElement.onblur = function(){
var messageElement = document.getElementById('message');
var string = nameElement.value.replace(/ /g,"");
if(string.length<6){
messageElement.innerHTML="Enter correct name";
} else {
messageElement.innerHTML="";
}
};
<form name="something" action="somewhere" method="post">
<div id="message"></div>
Enter Name : <input type="text" name="name" required="required" /> <br/> <br/>
Enter Location : <input type="text" name="location" required="required" /> <br/> <br/><br/> <br/>
<input type="submit" name="submit" />
</form>
Now the above works fine I guess. But imagine you might need that function on multiple places which is kind of the same except of the element to observe and the error message. Of course there can be more like where to display the message etc. This is just to give you an idea how you could set up for more scenarios using the same function:
var nameElement = document.forms['something']['name'];
nameElement.onblur = function(){
validate(nameElement, "Enter correct name");
};
function validate(element, errorMessage) {
var messageElement = document.getElementById('message');
var string = element.value.replace(/ /g,"");
if(string.length < 6){
messageElement.innerHTML= errorMessage;
} else {
messageElement.innerHTML="";
}
}
<form name="something" action="somewhere" method="post">
<div id="message"></div>
Enter Name : <input type="text" name="name" required="required" /> <br/> <br/>
Enter Location : <input type="text" name="location" required="required" /> <br/> <br/><br/> <br/>
<input type="submit" name="submit" />
</form>
With AngularJS, how can I show an error message for a checkbox after a click on submit button if the checkbox isn't checked?
I tried this :
<form action="/" method="post" name="myForm" novalidate>
<label>
<input type="checkbox" name="myCheckbox" ng-model="myCheckbox" value="1" required>
</label>
<p class="error" ng-show="myForm.$submitted && myForm.myCheckbox.$error.required">Error message</p>
<button type="submit" ng-disabled="myForm.$invalid">Submit</button>
</form>
But it didn't work. When I click on submit button, nothing is happening. If I remove "novalidate" on form tag or "ng-disabled" on submit button, the form is submitted even if the checkbox is not checked.
Can you help me please ?
You have ng-disabled="myForm.$invalid" in your submit button, so the submit event never is fired (because the button is disabled when the form is invalid) and thus the condition ng-show="myForm.$submitted && myForm.myCheckbox.$error.required" never is fulfilled because myForm.$submitted is false.
Edit:
As some other users here have suggested, I think your best bet would be if you change the way you are doing things right now. I can think in tow solutions (very similar), but they includes sending the request "the angular way"
Solution 1:
Handle you form submission with angular like this:
Put in your form something like this (note that I deleted the action="/" method="post" part:
<form ng-submit="onSubmit(myForm)" name="myForm" novalidate>
and remove the ng-disabled="myForm.$invalid" from your submit button. Then it would be like this <button type="submit">Submit</button>
... and in the controller
$scope.onSubmit = function(form){
if(form.$invalid){
//... do your call to backend here as you like since the call directly from the form was removed
}
}
Solution 2:
As well change form like this: <form name="myForm" novalidate>
... change your submit button like this: <button type="submit" ng-click="onSubmit(myForm)">Submit</button>
... and use the same function declared in the controller
$scope.onSubmit = function(form){
if(form.$invalid){
//... do your call to backend here as you like since the call directly from the form was removed
}
}
Otherwise you have to change your condition like this
ng-show="myForm.myCheckbox.$error.required"
but this will show the message before the form is submitted
Remove myForm.$submitted because it is never fulfilled (As Asiel Leal mentioned) and also you have put ng-disabled on submit button, so safe to use.
<form action="/" method="post" name="myForm" novalidate>
<label>
<input type="checkbox" name="myCheckbox" ng-model="myCheckbox" value="1" required>
</label>
<p class="error" ng-show="myForm.$dirty && myForm.myCheckbox.$error.required">Error message</p>
<button type="submit" ng-disabled="myForm.$invalid">Submit</button>
</form>
Try this working example :
var app = angular.module('myApp',[]);
app.controller('myController',function( $scope ) {
$scope.validate = function() {
alert('submitting..');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app= "myApp" ng-controller="myController">
<form name="myForm" ng-submit="myForm.$valid && validate()" novalidate>
<input type="checkbox" name="checkb" ng-model="formData.checkb" required/>
<span ng-show="submitted == true && myForm.checkb.$error.required">Please select the checkbox to proceed.</span>
<input type="submit" value="Submit" ng-click="submitted = true"/>
</form>
</div>
In form I have controls with name,id and class attribute. I cant add any costom attribute in html input element.
In this case how can I apply validation.
Can I write directive on element name or id?
HTML
<form class="form-horizontal text-center" role="form" name="DTOstep1" ng-submit="onSubmit(DTOstep1)" novalidate>
<input name="userinput1" id="userinput1" class="" />
<input name="userinput2" id="userinput2" class="" />
<input name="saveDto" type="submit" class="btn btn-success btn-lg" value="Continue" />
</form>
directive code
(function () {
"use strict";
angular
.module("autoQuote")
.directive('userinput1', [userinput1])
....
Or is there any other way to do form validation. I wan to apply some custom validation to each form field.
The angular way requires the ng-model attribute to each field, in order to bind it with a model property.
function TestCtrl($scope) {
$scope.fields = {
"userinput1" : "Initial Value",
"userinput2" : ""
}
$scope.onSubmit = function onFormSubmit($event, form) {
if(form.$invalid) {
console.log("invalid", form);
event.preventDefault();
return;
}
console.log('valid', form);
//send here
};
}
angular
.module('test', [])
.controller("TestCtrl", ["$scope", TestCtrl])
;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<section ng-app="test">
<article ng-controller="TestCtrl">
<form name="DTOstep1" ng-submit="onSubmit($event, DTOstep1)">
<input name="userinput1" ng-model="fields.userinput1" required/>
<input name="userinput2" ng-model="fields.userinput2" required />
<input name="saveDto" type="submit" ng-disabled="DTOstep1.$pristine || DTOstep1.$invalid" />
</form>
</article>
</section>
by the way, if you can't edit the view in order to create an angular-form, you need to control the form via dom queries, such as vanilla javascript... using document.querySelector() and checking value property.
UPDATE
Many basic check could be made using simple procedural approach, if you want apply a minlength to the userinput1 field, on each onSubmit you need to check $scope.fields.userinput1.length > ..., et cetera...
A more clean and suggested way is to use html5 validation attributes,
angular decorates them and recognize thei rules, so, you can use min/max/min-length/max-length/required/pattern/disabled etc.
if you want to provide a reusable way, you should have a look at FormController.$addControl or how build a custom directive via attributes that requires ngModelController and so on...
Add required to those fields on which you want to add validation -
'use strict';
var app = angular.module("demo", [], function($httpProvider) {
});
app.controller("demoCtrl", function($scope) {
$scope.onSubmit = function(){
alert('form valid');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="demo">
<div ng-controller="demoCtrl">
<form name="form" id="form" class="form-horizontal text-center" role="form" >
<input ng-required="true" ng-model="userinput1" name="userinput1" id="userinput1" class="" /><br>
Check it to make userinput 2 required: <input type="checkbox" ng-model="check" />
<input ng-required="check" ng-model="userinput2" name="userinput2" id="userinput2" class="" />
<br><input ng-click="onSubmit(DTOstep1)" ng-disabled="form.$invalid" name="saveDto" type="submit" class="btn btn-success btn-lg" value="Continue" /><br>
</form>
</div>
</body>
you can also use ng-model inside ng-required to toggle the ng-required true and false.
angular automatically adds classed to each ng-model
This should help
https://docs.angularjs.org/guide/forms
Adding a fiddle as an example
https://jsfiddle.net/x0f6czfk/
<body ng-app="app">
<form ng-controller="mainCtrl">
<input ng-model="name" type="text">
<input ng-model="email" type="text">
<input type="button" ng-click="validateForm()" value="Save">
</form>
</body>
(function(window,document,undefined){
var app = angular.module('app',[]);
app.controller('mainCtrl',function($scope){
var self = this;
$scope.validateForm = function(){
//custom validation
if($scope.name === 'test'){
console.log('wrong name');
return;
}
//custom validation
if($scope.email === 'test#demo.com'){
console.log('wrong email');
return;
}
else{
//if no validation error, submit data;
console.log('valid form');
}
}
});
})(window,document)
I was trying to check whenever my form is being edited by writing some fields of it. I read $dirty should work for that task but I can't figure out what I'm missing here:
<!DOCTYPE html>
<html lang="en">
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="formCtrl">
<form name = "myForm" novalidate>
First Name:<br>
<input type="text" ng-model="user.firstName"><br>
Last Name:<br>
<input type="text" ng-model="user.lastName">
<br><br>
<button ng-click="reset()">RESET</button>
</form>
<p> is Form dirty? {{isDirty}}<p>
<p>form = {{user }}</p>
<p>master = {{master}}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('formCtrl', function($scope) {
$scope.master = {firstName:"John", lastName:"Doe"};
$scope.reset = function() {
$scope.user = angular.copy($scope.master);
};
$scope.reset();
$scope.isDirty = $scope.myForm.$dirty;
});
</script>
</body>
</html>
I'm trying to make the flag isDirty to true whenever the user modifies the form. Thanks
You are missing name attributes in your form fields which are not enabling form validation for those field. You need to add unique name for each field so that it will get add those field in myForm object
Markup
<form name="myForm" novalidate>
First Name:<br>
<input type="text" name="firstName" ng-model="user.firstName"><br>
Last Name:<br>
<input type="text" name="lastName" ng-model="user.lastName">
<br><br>
<button ng-click="reset()">RESET</button>
</form>
Also you are accessing myForm object which is nothing but form object, I won't be available until DOM get rendered, $scope.myForm will be simply undefined at the time of controller initilization, If you really want to access $scope.myForm from controller then you need to put that code in $timeout that will run $timeout function code in next digest cycle.
$timeout(function(){
$scope.isDirty = $scope.myForm.$dirty;
});
Update
There is no need to maintain a separate isDirty flag (this would require to change the separate isDirty flag to reflect any changes in myForm.$dirty flag.) Instead I suggest you use $scope.myForm.$dirty directly as a flag. So use the expression myForm.$dirty, and this flag will change as form gets dirty.
Working Plunkr
I'm trying to do a simple JQM AJAX form post to a server - but for some reason, my form input values are always empty. (Even in the DOM inspector)
This is the 2nd page in my HTML - and the only form on the page. The console always prints out "[]"
<div data-role="page" id="login">
<div data-role="content">
<h2>
Login
</h2>
<form id="loginform" data-ajax="false">
<fieldset>
<input name="" id="userId" name="userId" placeholder="login" type="number">
<input name="" id="password" name="password" placeholder="password" type="password">
<input type="button" id="login_submit" data-theme="b" value="Submit">
</fieldset>
</form>
</div>
<script language="JavaScript" >
$(document).on('pagebeforeshow', "#login", function(){
$(document).on('click', '#login_submit', function() {
console.debug($('#loginform').serializeArray());
});
});
</script>
</div>
And the answer is obvious once it's posted into SO.
There's duplicate name attributes on the input fields - note the original issue was probably that the name attributes were set as "" - which would drop them from the form submission.
Try:
$(document).on('submit', '#loginform', function() {
console.debug($('#loginform').serializeArray());
});