I have started to get into Angular JS validation....
I have this step:
<step title="Let's begin with some information about your business">
<form name="myForm" ng-submit="submitForm(myForm.$valid)" novalidate>
<table>
<tr>
<td><label>Your Name</label></td><td><input class="form-control" type="text" ng-model="user.name" required /></td>
</tr>
</table>
</form>
</step>
and I have this button outside of the steps...outside of the wizard:
<a class="btn btn-default" ng-click="gotoNextStep()" ng-show="showNextButton()">Next</a>
and in my js file, I have this function called on ng-click:
$scope.gotoNextStep = function () {
if ($scope.currentStepIndex == (3)) {
$scope.submitForm = function (isValid) {
if (isValid) {
toggleSteps($scope.currentStepIndex + 1);
}
};
} else {
toggleSteps($scope.currentStepIndex + 1);
}
}
what I am trying to do is prevent the user from going to the next step until the required field is filled.
just before my step ends and after the form ends I added this <p>{{myForm.$invalid}}</p> and it appears as true, if I change it to valid it returns false. So it seems like this is kinda working except I cant provent my user from going to the next page.
Currently with this code, the button does not goto the next step even if the required field is filled in or not. Please Help.
I should also note that $scope.submitForm is saying its undefined :(
Another note.. {{myForm.$valid}} returns false but when I fill out the required field it returns true....how would I use myForm.$valid in the js file for the $scope.gotoNextStep function
Could you use ng-disabled in your button? Like this:
<a ng-disabled="myForm.$pristine || myForm.$invalid" class="btn btn-default" ng-click="gotoNextStep()" ng-show="showNextButton()">Next</a>
And then get rid of the ng-submit in the form tag. I also just noticed you have novalidate on your form. You should remove that too.
Related
I posted a question on how to make 2 errors work here: Multipile forms with input and submit button with the same action with Javascript
I needed 2 errors, 1 error if the input if less than 15 digits, the second error is if the input begins with 9900 (if it does, there is an error and then it redirects to a different page).
It worked for a while, although suddenly it stopped giving the second error (if input starts with 9900), the page is: http://www.unlocker.co.il/shop/sim-unlock-htc-mobile-device/
Each form has it's own id: unlock1, unlock2, unlock3 etc.
the JS files include:
jQuery(function($){
$('form#unlock1').on('submit', function (e){
if($('form#unlock1 > input.the_imei').val().length == 15){
if($(this).val().indexOf('9900') === 0){
alert('לפי המספר IMEI, ברשותכם מכשיר CDMA, אנא ראו מידע נוסף בעמוד פתיחת מכשירי CDMA');
window.location = 'http://www.unlocker.co.il/sim-unlock-cdma-mobile-device';
e.preventDefault();
}
return;
}
alert('אנא מלאו מספר IMEI בעל 15 ספרות');
e.preventDefault();
});
})
and the Forms are:
<form id="unlock1" class="cart" enctype="multipart/form-data" method="post" name="unlock"> <input class="the_imei" style="width: 80%; border-radius: 15px;" name="the_imei" type="text" value="" placeholder="מספר סידורי IMEI של המכשיר (חייג #06#*)" /> <input class="add-to-cart" name="add-to-cart" type="hidden" value="39" /> <button class="unlockButton" type="submit" value="submit">פתח לכל הרשתות בישראל </button> </form>
Each form has a different id (example Unlock1) and on it's own JS file the id like listed in 2 places.
I can't figure out why the "minimum 15 digits" error works, but the "if input begins with 9900" error does not work anymore.
Thanks!
This is how I would do this. Try to avoid using too many nested if statments. Instead create the escape clauses with return statements when the user enters the incorrect value first.
$('form#unlock1').on('submit', function(){
var $el = $('form#unlock1 > input.the_imei');
if($el.val().length<15){
//Not enough characters
return false;
}
if($el.val().substring(0,4)=='9900') {
//Value begins with 9900
return false;
}
//User has entered a correct imei
});
I made a input checkbox that contains array values. so it generates plenty of rows in a table.
But it needs for me to check it all to submit.
It doesn't allow me to check only few not all.
<form>
<table>
<td>
<input required="required" type="checkbox" name="id[]" id="id" value="<?php echo $result2["id"]; ?>"/>
</td>
<input type="submit" name="submit" value="submit"/>
</table>
</form>
How can i make the required field able to check atleast one and able to submit even if not all are checked?
I dont know if I understand you,
but maybee you need something like this:
Online demo
Main part with notes:
$('#frm').bind('submit', function(e) { // set this function for submit for your formular
validForm = true; // default value is that form is correct, you can chcange it as you wish
var n = $( "input:checked" ).length; // count of checked inputs detected by jQuery
if (n != 1) { validForm=false; } // only if you checked 1 checkbox, form is evaluated as valid
if (!validForm) { // if result of validation is: invalid
e.preventDefault(); // stop processing form and disable submitting
}
else {
$('#echo').html("OK, submited"); // ok, submit form
}
});
You can use any number of comboboxes under any tag and get count of selected by jQuery, then use any rule for validate form.
Using the TokenInput plugin and using AngularJS built-in formController validation.
Right now I'm trying to check if the field contains text, and then set field to valid if it does. The issue with using the plugin is it creates it's own input and then a ul+li for stlying.
I have access to addItem (formname) and my capablities in the controller, I just need to set it to $valid.
Markup.
<form class="form-horizontal add-inventory-item" name="addItem">
<input id="capabilities" name="capabilities" token-input data-ng-model="inventoryCapabilitiesAutoComplete" data-on-add="addCapability()" data-on-delete="removeCapability()" required>
<div class="required" data-ng-show="addItem.capabilities.$error.required" title="Please enter capability."></div>
</form>
JS.
$scope.capabilityValidation = function (capability) {
if (capability.name !== "") {
addItem.capabilities.$valid = true;
addItem.capabilities.$error.required = false;
} else {
addItem.capabilities.$valid = false;
addItem.capabilities.$error.required = true;
}
};
I'm running the capabilityValidation function when TokenInput has something entered and passing in the object.
EDIT:
Found out ng-model on my input does stuff and gets the autocomplete results, which is why I can't get ng-valid to work since it's based on the model.
$scope.inventoryCapabilitiesAutoComplete = {
options: {
tokenLimit: null
},
source: urlHelper.getAutoComplete('capability')
};
I didn't write this autocomplete implementation, is there another way to do this where I would have access to the ng-model attr and move the model function somewhere else?
You cannot directly change a form's validity. If all the descendant inputs are valid, the form is valid, if not, then it is not.
What you should do is to set the validity of the input element. Like so;
addItem.capabilities.$setValidity("youAreFat", false);
Now the input (and so the form) is invalid.
You can also see which error causes invalidation.
addItem.capabilities.errors.youAreFat == true;
The answers above didn't help me solve my problem. After a long search I bumped into this partial solution.
I've finally solved my problem with this code to set the input field manually to ng-invalid (to set to ng-valid set it to 'true'):
$scope.myForm.inputName.$setValidity('required', false);
I came across this post w/a similar issue.
My fix was to add a hidden field to hold my invalid state for me.
<input type="hidden" ng-model="vm.application.isValid" required="" />
In my case I had a nullable bool which a person had to select one of two different buttons. if they answer yes, an entity is added to the collection and the state of the button changes. Until all of the questions get answered, (one of the buttons in each of the pairs has a click) the form is not valid.
vm.hasHighSchool = function (attended) {
vm.application.hasHighSchool = attended;
applicationSvc.addSchool(attended, 1, vm.application);
}
<input type="hidden" ng-model="vm.application.hasHighSchool" required="" />
<div class="row">
<div class="col-lg-3"><label>Did You Attend High School?</label><label class="required" ng-hide="vm.application.hasHighSchool != undefined">*</label></div>
<div class="col-lg-2">
<button value="Yes" title="Yes" ng-click="vm.hasHighSchool(true)" class="btn btn-default" ng-class="{'btn-success': vm.application.hasHighSchool == true}">Yes</button>
<button value="No" title="No" ng-click="vm.hasHighSchool(false)" class="btn btn-default" ng-class="{'btn-success': vm.application.hasHighSchool == false}">No</button>
</div>
</div>
It is very simple. For example :
in you JS controller use this:
$scope.inputngmodel.$valid = false;
or
$scope.inputngmodel.$invalid = true;
or
$scope.formname.inputngmodel.$valid = false;
or
$scope.formname.inputngmodel.$invalid = true;
All works for me for different requirement. Hit up if this solve your problem.
to get this working for a date error I had to delete the error first before calling $setValidity for the form to be marked valid.
delete currentmodal.form.$error.date;
currentmodal.form.$setValidity('myDate', true);
How to simulate submit plus validation on a form whose button is outside of it?
It can be done with this:
HTML:
<div ng-controller="MyCtrl">
<form ng-submit="onSubmitted()">
Header inputs:
<input type="name" ng-model="sample" required/>
<input type="name" ng-model="sampleX" required/>
<div style="visibility: hidden">
<input type="submit" id="clcikMe" value="This submit triggers validation. But I wanted to put this button at the end of the page"/>
</div>
</form>
<hr/>
Some other form here. Think line items
<hr />
<a class="btn" linked="clcikMe">Wanted this submit button to trigger the validation+submit on the form in which this button doesn't belong</a>
</div>
Javascript:
var app = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.onSubmitted = function() {
alert('submitted!');
};
}
app.directive("linked",function(){
return function (scope, element, attrs) {
var id = attrs["linked"];
element.on("click",function(){
document.getElementById(id).click();
});
};
});
But I wanted to stay away from that approach, it's very kludgy, it triggers a validation+submit by simulating a submit on first form by clicking its hidden submit button
Is there an API on AngularJS (or even plain javascript) that will let me achieve my objective? I.e. without using any hidden submit button
You're not thinking very Angular here. No one is forcing you to work with form ng-submit. Just use 2 buttons each with their own ng-click="runThisFunction()" or simply use the same function and pass along a parameter. i.e:
<button ng-click="submitForm(true)">Validate + Submit</button>
and
<button ng-click="submitForm(false)">Only Validate</button>
Then in your controller:
$scope.submitForm = function(shouldSubmit) {
//run validation here.
//either using $scope.form.name.$valid or ng-model $scope variable
var dataGood = false;
if ($scope.sample === "goodData" && $scope.sample === "alsoGoodData" ) {
//data is good
dataGood = true;
//alert user that data is good!
alert('good job, your data is great!');
}
else {
//data is bad
alert (' data bad, dear padowan');
}
if (!shouldSubmit) return;
//perform $http request to server, or navigate to a different page or whatever
if (dataGood) {
//submit data to server and let the party begin
$http.post('/api/rocknroll/submit', { sample: $scope.sample, sampleX: $scope.sampleX}).then( $scope.handleResponse);
}
}
This will work whether or not you're in the scope of the form, but you need to be in the scope of the controller.
I've got a form that has multiple submit buttons. One for changing data in a database, one for adding, and one for deleting. It looks like this:
<form action="addform.php" method="post" id="addform" onSubmit="return validate(this)">
<select name="listings" id="listings" size="1" onChange="javascript:updateForm()">
<!-- Here I have a php code that produces the listing menu based on a database query-->
</select>
<br />
Price: <input type="text" name="price" id="price" value="0"/><br />
Remarks: <textarea name="remarks" wrap="soft" id="remarks"></textarea><br />
<input type="submit" value="Update Database Listing" name="upbtn" id="upbtn" disabled="disabled"/>
<input type="submit" value="Delete Database Listing" name="delbtn" id="delbtn" disabled="disabled"/>
<br />
<input type="submit" value="Add Listing to Database" name="dbbtn" id="dbbtn"/>
<input type="button" value="Update Craigslist Output" name="clbtn" id="clbtn" onClick="javascript:updatePreview();"/>
</form>
There are actually more elements in the form, but that doesn't matter. What I want to know is, for my validation method, how can I check which submit button has been clicked?
I want it to do the following:
function validate(form){
if (the 'add new listing' or 'update listing' button was clicked'){
var valid = "Are you sure the following information is correct?" + '\\n';
valid += "\\nPrice: $";
valid += form.price.value;
valid += "\\nRemarks: ";
valid += form.remarks.value;
return confirm(valid);}
else {
return confirm("are you sure you want to delete that listing");
}
}
I assume there must be some way to do this relatively easily?
Why don't you set a global variable specifying which button was last clicked? Then you can check this variable in your validate method. Something like:
var clicked;
$("#upbtn").click(function() {clicked = 'update'});
// $("#delbtn").click(function() {clicked = 'delete'});
// ...
function validate(form) {
switch(clicked) {
case 'update':
break;
// more cases here ...
}
}
You can, for example, attach a click event to every submit button that will save a pointer to it in a variable or mark it with a specific attribute / class (it that case you will have to remove that marker from all other submit buttons in the event handler) and then in the submit callback you will know which one was clicked
I think it's easier to just use a click event on each button and handle it individually.
$(function() {
$('input[name=someName]').click(someFunc);
});
function someFunc() {
// Your validation code here
// return false if you want to stop the form submission
}
You could have a hidden field on a form and set the value of that field on clicking the button and then pick it up in your validation routine. You can use jquery to achieve this, let me know if you require an example.
You can use ajax submission with jQuery, you can try something like this:
$('form#addform input[type="submit"]').on('click',function(e){
e.preventDefault();
var current = $(this); //You got here the current clicked button
var form = current.parents('form');
$.ajax({
url:form.attr('action'),
type:form.attr('method'),
data:form.serialize(),
success:function(resp){
//Do crazy stuff here
}
});
});