Monitor specific fields for pristine/dirty form state - angularjs

I'm trying to make a form that can contain complex "fieldtypes". ie. A group of fields that work together to manipulate the value of a single field.
Each of these fieldtypes contains a single field that will hold the actual "value" of the field.
The fields containing the real data will have ng-model="" attributes attached to them. The PublishController will be monitoring these fields. If there are fields without an ng-model on them, it doesn't care about it.
Is it possible to make a form only consider itself dirty/pristine by the fields with ng-model on them?
I don't mind having to put a class/attribute on all the fields I want it to watch specifically, if thats an option.
Here's an example of the code:
<div ng-controller="PublishController">
<form name="publishForm" ng-submit="save()">
<div class="fieldtype">
<!-- there might be a bunch of form elements in here that a user can manipulate to alter the value that the PublishController is concerned with -->
<input class="helper-field-1" />
<input class="helper-field-2" />
<!-- then the inputs above will perform their own logic, and output their value to this field, which the form *is* concerned with -->
<input type="hidden" name="myfield" ng-model="data.myfield" />
</div>
<div class="fieldtype">...</div>
<div class="fieldtype">...</div>
<!-- one of the goals of this is to only show the submit button when the *actual* values have been modified, not the helper fields -->
<button ng-disabled="publishForm.$pristine">Save</button>
</form>
</div>
Is what I'm describing possible?
Thanks!

Related

How to prevent a input field from `validation`?

I have a scenario to show details in the input field. I am getting the information from one of the drop-down objects.
When the user selects the drop-down objects, from the object, I would like to bring and show the details in the input field as a text, (even read-only).
But when I bring the description details from the drop down objects to input field, always my form goes as $invalid. How to prevent my form to not consider one of the text fields ?
Here is my input field:
I tried using non-bind prop. but I am not getting the description details in the input field.
<div class="form-group__text" ng-if="ctrl.data.productDetails">
<label class="fs-label"> </label>
<input name="itemDescription" class="fs-input-item" type="text" placeholder="Product Description" ng-model="ctrl.itemDesc">
</div>
Add formnovalidate="formnovalidate" to any inputs you don't want validated.
<input name="itemDescription" formnovalidate="formnovalidate" class="fs-input-item" type="text" placeholder="Product Description" ng-model="ctrl.itemDesc">

Validate one element inside an ng-repeat only when dirty

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

Angular js:Dynamic values as string in ng-model within ng-repeat

I am generating a form dynamically in my application. The fields of the forms are the column names in the database table.The user of this application will just pass the name of the table and the skeleton for CRUD application will be prepared dynamically.
In the view part I want to achieve something like this
<div class="form-group" ng-repeat="(key,col) in cols">
<label for="{{::col}}">{{::col | uppercase | replaceUnderscore}}</label>
<input class="form-control" type="text" ng-model="{{::col}}" required />
</div>
In the ng-model I just need the string value that is, if the column name is Username then model value should be something like ng-model="username" and the value should not be displayed in the form field. So I want to achieve kind of one way data binding.
Simply use a JS object, for example $scope.data = {}, and then ng-model="data[col]".

AngularJS - What's the best way to submit only values of "relevant" form fields?

Say I have a form with some fields that are only relevant/displayed under certain condition. What's the best way to prevent these fields from being submitted if they're hidden/irrelevant?
E.g.
<form name="fm">
<div><input name="field1" ng-model="data.field1"/></div>
<div ng-if="data.field1=='1'"><input name="field2" ng-model="data.field2"/></div>
</form>
What's the best way to prevent the value of field2 from being submitted if data.field1='2'?
The only way I can think of is to loop through each and every item in $scope.data and manually remove them if the corresponding field is missing from the dom.

AngularJS ng-model value not initially displayed in input field

I am trying to use ng-repeat to iterate through an array of keys and display the scenario value associated with each key. The view code worked when the key value was hardcoded. Now that ng-repeat provides the key, the input field does not initially display the associated scenario value. I am using AngularJS 1.2.21.
This is the controller code that sets up $scope:
$scope.keys = KEYS; // array of strings
$scope.scenario = scenario; // object containing key: value pairs
This is the view code that generates the input:
<form name="gameSettingsForm" novalidate ng-submit="validateAndSaveSettings()" class="form-horizontal" role="form">
<div class="row">
<div class="col-md-6">
<div class="form-group" ng-repeat="key in keys">
<div class="col-md-3">
<input type="number" required ng-disabled="readOnly" class="form-control"
ng-model="scenario[key]"
id='{{key}}' name='{{key}}'>
<p>input contains {{scenario[key]}}</p>
</div>
</div>
</div>
</div>
</form>
When the page loads, the input field is empty even though the "input contains" text correctly displays the scenario[key] value. How do I get the value to display in the input field when the page loads?
UPDATE:
I had commented out all but one of the KEY array items. After activating them, most of the generated input fields are empty when the page loads. However some of them populate when the page loads. All the "input contains" strings always correctly display their scenario[key] values.
WORK AROUND:
Realized the scenario values that were displayed had been modified via multiplication. Made the problem go away by multiplying all scenario values by 1 before displaying.
The solution is to make sure the model values are numbers for inputs with type "number". I did this via multiplication:
value = value * 1;
I created a stand alone example that demonstrates the issue occurs when model values are not numbers: http://plnkr.co/qnFHafmIOWVW6eWkQsmk

Resources