I have the following form structure, how can I validate this form except for last item in ng-repeat ? it is a kind of dynamic list of inputs and last input is an empty slot, and as the user types in the input, another empty input field is added to items collection and so on, how can I tell parentForm to ignore the last item?
<div ng-form="parentForm">
<div ng-repeat="item in items" ng-form="itemForm">
<input type="text" ng-model="item.name" required/>
</div>
<input type="submit" ng-disabled="parentForm.$invalid" />
</div>
I would use special ngRepeat property $last with combination with ngRequired:
<div ng-form="parentForm">
<div ng-repeat="item in items" ng-form="itemForm">
<input type="text" ng-model="item.name" ng-required="!$last" />
</div>
<input type="submit" ng-disabled="parentForm.$invalid" />
</div>
Related
I'm new in AngulsrJS and I've got following code:
<form ng-if="editorCtrl.edit" class="form-horizontal" role="form" ng-submit="editorCtrl.saveEntry()">
<div class="form-group">
<div class="col-md-6" ng-repeat="(key,field) in editorCtrl.editEntry">
<label>{{key}}</label>
<input type="text" class="form-control" value={{field}} />
</div>
</div>
<!-- ng-model="editorCtrl.toSave[key]" ng-value="{{field}}" that part was in input attributes -->
<div class="form-group">
<div style="padding-left:110px">
<input type="submit" value="Update selected entry" ng-disabled="form.$invalid" class="btn btn-primary"/>
</div>
</div>
</form>
Now I need to obtain values from input fields. I tried to use ng-model="editorCtrl.toSave[key], but it's not working in a correct way.
Any suggestions how to resolve this situation ?
if you can consider no necesary the "toSave" object maybe you can use the 2-way data binding properly only using editEntry Object :
<input type="text" class="form-control" value={{field}} ng-model="editorCtrl.editEntry[key]"/>
In this way after a submit you will get editEntry with the fields modifieds (or not), here is an example
https://jsfiddle.net/pv8qrwty/1/
run the example and if you modified the fields after you press the submit button it will be displayed in your browser console
hope this help ! and sorry for my english !
This seems to be very common, yet the solutions for it seem complex.
I've got a section of my form that is optional. If enabled, then its fields are required.
<!-- begin optional section -->
<label>
<h4>Trailer </h4>
<span>( optional </span>
<input class="input-inline" ng-model="hasTrailer" type="checkbox"/>
<span>)</span>
<h4 style="display: inline"> :</h4>
</label>
<div class="form-group">
<label for="trailerNumber"> Number:</label>
<div>
<input
type="text"
name="trailerNumber"
ng-disabled="!hasTrailer"
ng-model="vm.Manifest.Trailer.number"
required />
</div>
<div>
<div
class="error-message"
ng-show="hasTrailer && form.trailerNumber.$invalid && form.trailerNumber.$touched || form.submitted">
<span> Trailer Number is required.</span >
</div>
</div>
</div>
<!-- end optional section -->
So, at the top of the section there is a checkbox, whose model is 'trailer'.
If checked, the fields are required.
What I really want is ideally:
<input type="text" required="hasTrailer">
or maybe
<input type="text" ng-attr({'required':hasTrailer})
i.e. if hasTrailer===true then required=true
You could use ng-required directive which will conditionally make input required when provided expression becomes true.
<input type="text" ng-required="hasTrailer">
You can achieve that by using ngRequired. You can read about it here
It is basically used like this in the html element
<input type="text" ng-required="hasTrailer">
hasTrailer should be a boolean property in the scope.
I was about to go with this option, which does the same thing, but additionally makes the whole section disappear.
<div ng-if="hasTrailer">
<!-- all my optional fields-->
</div>
I'm new to AngularJS and am trying to hide a div when a button is clicked. What I'm doing works fine until I put the button in the div I'm trying to hide (the button is using a different controller). The button works as expected when taken out of the controller so I assume it's an issue with scope. Any help would be appreciated.
<form action="" name="signUpForm" class="heroForm" >
<div ng-hide="signUpB">
<span id="signUpFormA">
<input required type="email" />
<input required type="password"/>
<span ng-controller="checkEmailCtrl">
<input type="button" ng-click="signUpB=true">
</span>
</span>
</div>
<div ng-show="signUpB">
<span id="signUpFormB">
<input required type="text">
<input required type="text">
<input type="submit">
<span>
</div>
</form>
Yes, you are setting signUpB=true on the scope of checkEmailCtrl. You can do something like this:
<form action="" name="signUpForm" class="heroForm" ng-init="signUpB={value:false}">
<div ng-hide="signUpB.value">
<span id="signUpFormA">
<input required type="email" />
<input required type="password"/>
<span ng-controller="checkEmailCtrl">
<input type="button" ng-click="signUpB.value=true">
</span>
</span>
</div>
<div ng-show="signUpB.value">
<span id="signUpFormB">
<input required type="text">
<input required type="text">
<input type="submit">
<span>
</div>
</form>
By wrapping the signUpB in an object, the signUpB.value=true statement will look up the signUpB object in the outer scope, and set it's value property to true, no modification will be made on checkEmailCtrl's scope.
ng-controller creates its own scope. So, within ng-click="signUpB=true", you are modifying the signUpB in this new scope.
You can fix this by using a object to hold the state of signUpB. Basically, replace all signUpB occurrences with state.signUpB. And, define state object in your outer controller's scope.
$scope.state = {signUpB: false // defaults to false}
Even better approach would be to use controllerAs syntax. Let's say your outer controller is OuterController. You define it as
ng-controller="OuterController as outerCtrl"
and,
replace all occurrences of signUpB with outerCtrl.signUpB to ensure you are using/modifying outerCtrl's model.
I have a form with input texts that are looped in a ng-repeat.
For every input field there is a switch with which the user sets "Use default value" to YES/NO.
Every row of input fields are basically two fields, with one hidden one at a time, whether you want to show the default value (switch: YES, input text = disabled) or set a custom value (switch: NO)
I need each element to have a unique identifier to be able to save it on submit, for example **id="title_{{spec.id}}".
The switches work so that the switch-variable is used to create 2way binding, but it is the value of the checkbox within the Switch-DIV that will be saved to the database.
What I think I need to do is apply the spec.id value to the switch-variable="useDefaultValue_{{spec.id}}" and set the same value to the ng-show="useDefaultValue_{{spec.id}}" and ng-hide, but I don't know how to.
HTML:
<div class="row form-group" ng-repeat="spec in specsList">
<div class="col-xs-6 col-md-6">
<label for="specification_">{{spec.title}} <span ng-show="spec.unit.length">({{spec.unit}})</span></label>
<input class="form-control" type="text" name="title_{{spec.id}}" id="title_{{spec.id}}" placeholder="Not visible" ng-model="spec.value" ng-hide="useDefaultValue">
<input class="form-control" type="text" ng-model="spec.defaultValue" ng-show="useDefaultValue" disabled>
</div>
<div class="col-xs-6 col-md-6">
<label for="useDefaultValue_">Use default value</label> - {{spec.useDefaultValue}}<br />
<div class="switch" init-switch switch-variable="useDefaultValue">
<input type="checkbox" id="useDefaultValue_{{spec.id}}" name="useDefaultValue_{{spec.id}}" ng-model="spec.useDefaultValue">
</div>
</div>
</div>
Since your checkbox is backed by the row-dependent spec.defaultValue, you can come up with a simpler solution and don't need the switch. Just reference spec.useDefaultValue instead of your current useDefaultValue to directly access it.
<div class="row form-group" ng-repeat="spec in specsList">
<div class="col-xs-6 col-md-6">
<label for="specification_">{{spec.title}} <span ng-show="spec.unit.length">({{spec.unit}})</span></label>
<input class="form-control" type="text" name="title_{{spec.id}}" id="title_{{spec.id}}" placeholder="Not visible" ng-model="spec.value" ng-hide="spec.useDefaultValue">
<input class="form-control" type="text" name="title_{{spec.id}}" id="title_{{spec.id}}" ng-model="spec.defaultValue" ng-show="spec.useDefaultValue" disabled>
</div>
<div class="col-xs-6 col-md-6">
<label for="useDefaultValue_">Use default value</label> - {{spec.useDefaultValue}}<br />
<input type="checkbox" ng-model="spec.useDefaultValue">
</div>
</div>
As an aside, I would also use ng-if instead of ng-show and ng-hide to lighten the page and make the transitions smoother.
EDIT Submit function :
$scope.submit = function() {
angular.forEach(specsList, function(spec, index) {
if (spec.useDefaultValue) {
$scope.user[spec.title] = spec.defaultValue;
}
else {
$scope.user[spec.title] = spec.value;
}
});
User.save(user).$promise.then(function(persisted) {
// do some post-save cleanup
});
};
Of course, this is assuming you save spec values on the user. They could be stored somewhere else.
I have a page where multiple forms are created based on ng-repeat. Everything works fine until write something into the input and everything gets duplicated on all the other repeated forms input elements. I have used ng-model="Notify.message" which is nothing but object which takes the value from the input and sends to control on button submit and hence rest of the logic.
I am looking for when if one form is been filled, other forms should keep quite and shouldn't duplicate the values written in input text of form 1.
Here is the code:
<div data-ng-show="alluserposts.length > 0">
<div id="b{{userpost.id}}" data-ng-repeat="userpost in alluserposts" >
<div class="row" style="margin-left: -5px">
<form class="text-center" role="form" id=f1{{userpost.id}} name="userForm"
ng-submit="notify(userForm.$valid, userpost, apiMe)" novalidate>
<div class="row">
<div class="col-xs-8 col-md-4">
<div class="form-group">
<input data-container="body" data-toggle="popover" data-placement="top"
data-content="Any message which you would like to convey to post owner"
type="text" ng-model="Notify.message" data-ng-init="Notify.message=''"
id="u{{userpost.id}}"
placeholder="Enter a Message or Phone number" class="form-control"
required>
<p ng-show="userForm.name.$invalid && !userForm.name.$pristine" class="help-block">It is
required.</p>
<script>$(function () {
$("[data-toggle='popover']").popover();
});
</script>
<input type="hidden" ng-model="Notify.loggedInEmail"
ng-init="Notify.loggedInEmail = result.email"/>
<input type="hidden" ng-model="Notify.postId" ng-init="Notify.postId = userpost.id"/>
<input type="hidden" ng-model="Notify.destEmail"
ng-init="Notify.destEmail = userpost.userEmail"/>
</div>
</div>
<div ng-show="loginStatus.status == 'connected'" class="col-xs-4 col-md-2">
<button class="btn btn-primary" ng-disabled="userForm.$invalid || !userForm.$dirty"
type="submit">
Notify Post Owner
</button>
</div>
</div>
</form>
</p>
</div>
</div>
</div>
</div>
Issue fiddle - jsfiddle
Here you can when something is written in one input, other gets filled too :( . Also Notify is a Java mapped object and message is a variable inside it. Pls let me know how can this can be segragated!
You bind all of your inputs to same variable on $scope.
You must bind every text box to a distinct variable on $scope:
View:
<ul ng-repeat="post in posts">
<li>{{$index}}
<input type="text" ng-model="emails[$index]"/>
</li>
</ul>
Controller:
$scope.emails = [];
I am also at the starting phase of angularjs.
I have faced the same issue few days ago and resolved it by providing dynamic model name in ng-model like
<input type="text" ng-model="Notify[post.userEmail]" ng-init="Notify[post.userEmail] = post.userEmail" />
Working fiddle: Fiddle