I have a form with simple ng-required validation. This works for simple input fields but I don't know what to do with an array inside an ng-repeat. I want the inputs inside the ng-repeat to become invalid only after they lose focus once.
Here is an example of the problem:
https://jsbin.com/kugobiwoxo/1/edit?html,js,output
This works: ng-required="myform.MyName.$touched"
This doesn't: ng-required="myform.contact[{{$index}}].$touched"
Is there some other expression I can use in the second case.
Angularjs does not honor indexed input names or ids. In ng-repeat you need to use ng-form attribute.
The changes I made to your div containing ng-repeat are as follows
<div ng-repeat='contact in model.Contacts' ng-form="innerform">
<label for='name'>Contact {{$index}}:</label>
<input type='text' ng-model='contact.Name'
id='name' name='contact'
ng-required="innerform.contact.$touched" />
<button ng-click='remove($event, $index)'>-</button>
</div>
and it is working as desired as you can see in this JSBin
Related
I have created dynamic form, here I want to send form data to controller. How can do this?
Here is plunker code link https://plnkr.co/edit/xmxDJHTPfJoSFwa2FWCB?p=preview
Issues:
when I change the value then element label also change.
How can I get the form data in product_submit function of controller.
All response appreciated.
Use
<input type="text"
id="module_module"
ng-model="getCol.value"
required="required"
class="form-control col-md-7 col-xs-12"
placeholder="Enter {{getCol.Field}}"
/>
Look here ng-model="getCol.value". You are using filed name as text field model value. Filed name and value are different. That is what you want I suppose.
You can access the values easily from your controller as $scope.getColumn[1].value. Change index or iterate accordingly.
Plunker here
To solve label issues, in your html, I changed ng-model expression to bound into getColumn.Value
In controller, I can read value entered in scope.getColumn[i].Value
I also updated code https://plnkr.co/edit/KlhAb69seMzHsLuhqweR?p=preview
I am creating a AngularJS app to render forms dynamically from a generic for definition data structure. So the form details (including all validation rules, data types etc) are defined in a database and a single AngularController should "draw" the form.
For background - here is the rough structure of the defiintion:
Form
Sections
Fields
It works fine - but I have a problem when adding attributes to the <input> element on the form based on the definition. So for example, lets say field1requires a min and max length validation, but field 2 does not. This is achieved by adding the ng-minlength and ng-maxlength attributes to the input element for field1 and NOT adding these to the input element for field2.
Some googling sugested that the recently removed ng-attr directive might have been a sollution - but since its removed, I am stuck?
<ng-form name="frmTSFApp">
<uib-tabset>
<uib-tab ng-repeat="aSection in tsf3fd.section track by aSection.ukey"
index="aSection.display_order"
heading="{{aSection.display_label}}">
<ng-form name="frmSection{{aSection.display_order}}">
<div ng-repeat="aField in aSection.fields track by aField.ukey"
class="form-group"
ng-class="getFormClass(frmSection{{aSection.display_order}}[aField.data_name],aField)">
<label class="control-label">{{aField.field_label}}</label>
<input ng-required="{{aField.require_kind == 'R'}}"
type="text"
class="form-control"
ng-model="tsf3fd.model[aField.data_name]"
name="{{aField.data_name}}" />
</ng-form>
</uib-tab>
</uib-tabset>
</ng-form>
The above snippet is what we use to render the form - so the ng-required attribute works nicely, since its always there and its value can be resolved from the expression. For each field we "know" all the validations we need to add (ng-minlength or ng-pattern etc etc) but not sure how to do this?
In psuedo code I would like something like this "inside: the input element:
if (aField.validations.minmax)
{
ng-minlength = "{aField.validations.minmax.min}"
ng-maxlength = "{aField.validations.minmax.max}"
}
Hope my explanation makes sense.
I am starting to doubt my approach - it seems a simpler approach is to render the "literal" form markup externally through something like XSLT from the deffinition data. We have done this and it works fine, but I thought working directly from the data would be so "cool" and would simplify the process.
Anyway - any help would be appreciated.
You can just use:
<input
ng-required="{{aField.require_kind == 'R'}}"
ng-minlength="{{aField.validations.minmax ? aField.validations.minmax.min : '' }}"
ng-maxlength="{{aField.validations.minmax ? aField.validations.minmax.max : '' }}"
type="text"
class="form-control"
ng-model="tsf3fd.model[aField.data_name]"
name="{{aField.data_name}}" />
Setting ng-minlength or ng-maxlength to empty string has the same effect as not setting them.
I'm attempting to use Angular directives to create custom input field types. For example, I have a type called "duration" which draws three separate hours, minutes, and seconds fields. I'm trying to use the directive as an attribute of an input element, and the directive replaces the input element.
For example, in the following code:
<input duration>
Would be rendered as a <div> with several inputs inside of it, and the original input would be out of the picture.
I'm running an ngRepeat loop through several form fields of different types, including duration. I'd like to find a way that only requires me to put one input in the HTML, with the duration attribute applied only if the field is supposed to be of duration type. I tried the following:
<div ng-repeat="field in fields">
<input type='{{field}}' ng-attr-duration="field==='duration'">
</div>
The problem with that code is that every element is rendered as duration because ng-attr-duration gets evaluated to duration='false' when the field is not duration, which triggers my directive.
Is there a way for me to apply the directive conditionally without having to define multiple <input>s to reduce redundancy in my code?
Take a look at what the directive docs say about ng-attr:
When using ngAttr, the allOrNothing flag of $interpolate is used, so if any expression in the interpolated string results in undefined, the attribute is removed and not added to the element.
Note that you need to be using curly braces so Angular will interpolate the expression. And, if your expression has an undefined term in it, the attribute won't be added.
How about something like this:
<div ng-repeat="field in fields">
<input type='{{field}}' ng-attr-duration="{{field==='duration' ? true : undefined}}">
</div>
The true in the ternary expression can be whatever you want, just not undefined.
What i can think of you can use condition if-else of ng-switch
<div ng-repeat="field in fields">
<div ng-switch on="field">
<input ng-switch-when="true" type='{{field}}' ng-attr-duration="field==='duration'">
<input ng-switch-default="true" type='{{field}}'>
</div>
</div>
It will also maintain readability of code.
Checkbox is not updating while
<input type="checkbox" ng-repeat="status in statuses"
checklist-model="task.status"
checklist-value="status">
In plunker
Isn't that 2 and 3(in plunker) are similar? Any Idea.
The problem is that you're using ng-repeat on the INPUT tag. You should put INPUT inside the ng-repeat. The checklist-model directive should have a separate scope.
All the official document example to use it within label. And my guess is that, the statement
<input type="checkbox"
checklist-model="task.status"
checklist-value="status">
is an iterating one. And if you add another iteration to it(ng-repeat) to it, it doesn't look logical.
<input type="text" value="{{codes[0].code}}" ng-click="newNumber(0)" />
<input type="text" value="{{codes[1].code}}" ng-click="newNumber({{codes[1].id}})" />
The first ng-click event fires in my controller just fine but the second one does nothing.
I tried concat'ing as well ... is there some other way I should do this?
ng-click
The value of ng-click is already evaluated as an angular expression. As such, you don't need the {{ }}. Read http://docs.angularjs.org/guide/expression for more information. Take a look at the second example, it will help clarify this.
ng-model
Also, ng-model should be used for data-binding. For example, take a look at this jsfiddle: http://jsfiddle.net/bCpW9/8/ and the notes below.
<li ng-repeat="code in codes">
This loops through the codes collection which was defined in the controller. It creates a <li> for each element in the codes collection.
<input ng-model="codes[$index].code" />
Inside each <li>, an <input> for the current code is created. Each input is bound to it's corresponding element in the codes array by setting ng-model to it. For instance, type a new code into the first input field. It automatically updates the corresponding code model with what you typed, as you can see to the right.
I hope that helps.