My form have two buttons say "Draft" and "Submit", so for draft some validations are applicable and same for submit button. I have one variable cmpnStatus it is initialised with value 1. For draft value of cpmnStatus is 0 and for submit it is 1.
<div class="form-group">
<label>Short Description<span class="red-ast">*</span></label><br/>
<textarea ng-model="shortdesc" ng-change="shortchange(shortdesc)" class="form-control b-rad3" ng-required="cmpnStatus == 0"></textarea>
</div>
<button type="submit" ng-click="campform.$valid && submitDraft(campform)" class="btn btn-draft">Save as draft</button>
<button type="submit" class="btn btn-launch" ng-click="campform.$valid && submitCampaign()">Submit for Approval</button>
Below is the code of submitDraft function.
$scope.submitDraft = function(form){
$scope.cmpnStatus = 0;
if(form.$valid) {
alert("valid");
} else {
alert("invalid");
}
//Then call to save data in db
};
My problem is when I click on draft form shows valid and save data in db and after that it points the required validation because initially value of cpmnStatus is 1 and according to condition required validation condition fails. Again I click on draft button now required validation is working fine because value of cpmnStatus changes from 1 to 0. I want that when user click on draft button and when the value of cpmnStatus changes it should be show me required validation (even in first click) according to condition(ng-required="cmpnStatus == 0"). Is there any other way to do the same ?
1st change the html to be like this :
<button type="submit" ng-disabled="campform.$error" ng-click="submitDraft(campform)" class="btn btn-draft">Save as draft</button>
<button type="submit" class="btn btn-launch" ng-disabled="campform.$error" ng-click="submitCampaign()">Submit for Approval</button>
Disabling button for user when form is invalid is better.
About the cmpnStatusThings i suggest you to use a checkbox or radio button to switch between draft or approval mode :
<input type="checkbox" ng-model="cmpnStatus" ng-true-value="1" ng-false-value="0"/>
Radio sample :
<input type="radio" ng-model="cmpnStatus" ng-value="1"/>
<input type="radio" ng-model="cmpnStatus" ng-value="0" />
Thank you for the clarification. Here is a function I am currently using:
$scope.checkIfSaveAllowed = function() {
var timer = setTimeout(function() {
var validControls = document.getElementsByClassName('has-feedback ng-scope has-success');
var modalSaveBtn = document.getElementById('eventModalSaveBtn');
if (validControls.length >= 3) {
if (validControls.length == 4) {
modalSaveBtn.disabled = false;
}
else if (validControls[0].id != "commentFormGroup" && validControls[1].id != "commentFormGroup" && validControls[2].id != "commentFormGroup") {
modalSaveBtn.disabled = false;
}
}
else {
modalSaveBtn.disabled = true;
}
}, 50);
}
I call this function on every field in the form using an ng-change. That else if in the middle is how I accomplish what you are asking about. The commentFormGroup is not required in my code. I check if (1) there are only three valid fields and (2) none of those valid fields are the optional field, then the button should be enabled.
In your case, you could have two functions called by the ng-change, one for each button or you could specify when one should be disabled and the other enabled.
Alternatively, you could display a customized error message instead of disabling the button. I hope this helps.
Related
Trying to figure out the best way to stay on the same page alerting the user if they have failed to check at least one checkbox.
HTML:
<div class="col3">
<input type="checkbox" ng-model="$parent.value5" ng-true-value="'Togetherness'" ng-false-value="">
<span class="checkboxtext">
Togetherness
</span><br>
<!--<p>We value our people and recognize that <strong>Together</strong> we achieve superior results.</p><br>-->
<div class="col3">
<a ui-sref="form.submit">
<button name="button" ng-click="SaveValue()">Continue</button>
</a>
Back-end angularJS to check if one of the boxes was checked-
$scope.SaveValue = function () {
var valueStatus = [];
if ($scope.value1 === "Methodical")
{
valueStatus.push($scope.value1);
}
if ($scope.value2 === "Relentless")
{
valueStatus.push($scope.value2);
}
if ($scope.value3 === "Togetherness")
{
valueStatus.push($scope.value3)
}
if ($scope.value4 === "Excellent") {
valueStatus.push($scope.value4)
}
if ($scope.value5 === "Ingenious") {
valueStatus.push($scope.value5)
}
return valueStatus
};
Basically I'm wanting to make an array of these values and then return it. However, I want the user to check at least one box. I've tried redirecting back to the page if valueStatus[0] == null. However, I don't think this is the best way to validate and it does not work completely how I think it ought to.
The way I solve this is putting validation on the length of array (valueStatus in your case) with hidden number input. The input will have min validation on. So, if user fails to check at least one, the form is not submitted;
<input type="number" name="valueStatus" ng-model="valueStatus.length" min="1" style="display: none">
Then, you can use normal validation on valueStatus that is available on the form model
myFormName.valueStatus.$valid
This way, most of the logic is put into the template, which is called angularjs way ;)
UPDATE
Forgot to mention:
You need to update the list of checked values on on-change checkbox event
<input type="checkbox" ng-model="checkboxValue1" on-change="updateValueStatus(checkboxValue1)">
<input type="checkbox" ng-model="checkboxValue2" on-change="updateValueStatus(checkboxValue2)">
and in controller
$scope.updateValueStatus = function(value){
var indexOf = $scope.valueStatus.indexOf(value);
if(indexOf < 0) {
$scope.valueStatus.push(value);
} else {
$scope.valueStatus.splice(indexOf, 1);
}
}
Hope it will help people with the same issue
simply just check the valueStatus length is equal to 0 or not
$scope.SaveValue = function () {
var valueStatus = [];
if ($scope.value1 === "Methodical")
{
valueStatus.push($scope.value1);
}
if ($scope.value2 === "Relentless")
{
valueStatus.push($scope.value2);
}
if ($scope.value3 === "Togetherness")
{
valueStatus.push($scope.value3)
}
if ($scope.value4 === "Excellent") {
valueStatus.push($scope.value4)
}
if ($scope.value5 === "Ingenious") {
valueStatus.push($scope.value5)
}
if (valueStatus.length === 0 ) {
console.log('please select atleast one select box')
}
return valueStatus
};
Edited
remove the ui-sref tag and change the state inside your click function
<button name="button" ng-click="SaveValue()">Continue</button>
in the saveValue function add this
if (valueStatus.length === 0 ) {
console.log('please select atleast one select box')
}else{
$state.go('form.submit') // if atleast one selected then the page will change
}
i am using angular.
i have a input box after entered 6 digit i have to click the button.
<input type="tel" ng-model="loginData.otp" id="otp1" placeholder="OTP" >
</label>
<label class="item">
<button class="button button-block button-positive" id="otplogin" type="submit">Login</button>
</label>
i have a input box after entering 6 digit i need to click the button.
how can i call function after entering 6 digit.so that i no need to click the button?
You can use the ng-change attribute, something like ng-change="inputChanged()". In your controller you have
$scope.inputChanged = function() {
// Check value of $scope.loginData.otp here, example:
if(!$scope.loginData.otp || $scope.loginData.otp.length < 5) {
return;
}
// then you continue with your processing
};
Check the documentation for more:
https://docs.angularjs.org/api/ng/directive/ngChange
Update:
The currently accepted answer uses $watch. You should try to minimize using $watch in controllers (just in directives whenever possible, an example of why).
In this question you say you are interested in the value change due to user entry, so, I think it makes sense to use the view's change directive, as it's a user change event.
You can also use $scope.$watch to watch the length of the input.
function TodoCtrl($scope){
$scope.loginData = { otp: '' };
$scope.$watch('loginData.otp.length', function(newValue, oldValue){
if(newValue == 6){
alert('Process to next level');
// put your function here
}
});
}
Check out my answer in http://jsfiddle.net/Zing87/po9rxsLs/1/
Is it possible to show a Validation Summary, a Div on top of the page with all the Validation error messages in angularjs , on form submit ?
I am coming from a .Net background and used to have a validation summary concept,all the examples i have seen in angular shows the error message right next to the control.
I am very new to angularjs , so an example or pointer to the right direction would be appreciated !
Thanks !
Yeah, you can use flags on each of your input fields, which will show a specific error message based on whether that flag is true or false.
For example:
<div ng-controller="signupCtrl">
<input type="text" id="username">
<input type="text" id="password">
<button ng-click="validate()">Sign-up</button>
</div>
Then, the validate function would run several other functions that would set flags. For example:
function signupCtrl($scope) {
$scope.validate = function() {
if( /* username is bad */ ) {
$scope.usernameError = true;
} else if ( /* password is bad */ ) {
$scope.passwordError = true;
} else {
// AJAX call to submit sign-up, or whatever
}
}
}
Your error messages would look like this:
<div class="error" ng-show="usernameError">Your username is bad</div>
<div class="error" ng-show="passwordError">Your password is bad</div>
Or, better yet, you can use a model, and only one error message:
<div class="error" ng-show="error">You {{field}} is bad</div>
But that second option would require some different tweaking of your code.
We're trying to implement a checkbox and list with the following functionality:
Clicking the checkbox will either clear the array if there are items in there, or add a new item if not.
Remove an item from the array when clicking the Remove button, once the last item is removed the checkbox automatically unchecks itself.
The problem I am having is that if you click to remove each array item, then click the checkbox to add a blank entry, I'm expecting the checkbox to be checked again (as per the checked observable), however it is not?
I have the following code:
http://jsfiddle.net/UBsW5/3/
<div>
<input type="checkbox" data-bind="checked: PreviousSurnames().length > 0, click: $root.PreviousSurnames_Click" />Previous Surname(s)?
</div>
<div data-bind="foreach: PreviousSurnames">
<div>
<input type="text" data-bind="value: $data">
<span data-bind="click: $root.removePreviousSurname">Remove</span>
</div>
</div>
var myViewModelExample = function () {
var self = this;
self.PreviousSurnames = ko.observableArray(['SURNAME1', 'SURNAME2', 'SURNAME3']);
self.removePreviousSurname = function (surname) {
self.PreviousSurnames.remove(surname);
};
self.PreviousSurnames_Click = function () {
if (self.PreviousSurnames().length === 0) {
self.PreviousSurnames.push('');
}
else {
self.PreviousSurnames.removeAll();
}
alet(2)
}
}
ko.applyBindings(new myViewModelExample());
If you are using together the click and the checked then you need to return true from your click handler to allow the browser default click action which is in this case checking the checkbox:
self.PreviousSurnames_Click = function () {
if (self.PreviousSurnames().length === 0) {
self.PreviousSurnames.push('');
}
else {
self.PreviousSurnames.removeAll();
}
return true;
}
Demo JSFiddle.
You need to use a computed to monitor the length of the observable array. This way when the length reaches zero you can react to it automatically.
self.surnames = ko.computed(function() {
var checked = true;
if (self.PreviousSurnames().length === 0) {
self.PreviousSurnames.push('');
checked = false;
}
return checked;
});
Now you will have the blank text box when all of the names are cleared. If you update your binding on the checkbox it will function properly as well.
<input type="checkbox" data-bind="checked: surnames, click: PreviousSurnames_Click" />Previous Surname(s)?
FIDDLE
I have a dropdown list in a repeater that should toggle my custom "required" attribute. I tried ng-show but the display="none" attribute is all that was added. My options are:-
1- Add/remove the input field and set bird.Stuff, not just hide it because it is still required.
2- Add/remove 'required' attribute on the input field.
js
$scope.validateParticipants = function (type) {
if (type == "Single") {
this.donation.Participants = "1";
}
else
this.donation.Participants = "";
}
html
<div ng-repeat="bird in animalTest.birds">
#(Html.DropDownList("Type", (IEnumerable<SelectListItem>)ViewBag.BirdList, new { ng_model = "bird.Type", ng_change = "validateRequired(bird.Type)", required = "Type is required" }))
...
<input data-ng-show="bird.Type == 'Endangered'" id="stuff" type="number" data-ng-model="bird.Stuff" required = "Number of Volunteers required"/>
</div>
Thanks for the help in advance!
Use ng-required. This takes an angular expression and adds the required attribute if the expression is true.
<input type="number" data-ng-model="bird.Stuff" ng-required="donation.Participants > 0"/>