Difference between ng-model and data-ng-model - angularjs

I am new with the AngularJs. Can anyone say the difference between ng-model and data-ng-model?
With ng-model
First Name : <input type="text" ng-model="fname" id="fname">
Second Name : <input type="text" ng-model="lname" id="lname">
With data-ng-model
First Name : <input type="text" data-ng-model="fname" id="fname">
Second Name : <input type="text" data-ng-model="lname" id="lname">

while both ng-model and data-ng-model would work, HTML5 expects any custom attribute to be prefixed by data-.
<!-- not HTML5 valid -->
<input type="text" ng-model="name">
<!-- HTML5 valid -->
<input type="text" data-ng-model="name">

They are the same. Angular strips the data- part from the attribute. From the docs:
Angular normalizes an element's tag and attribute name to determine which elements match which directives... The normalization process is as follows:
Strip x- and data- from the front of the element/attributes.
Convert the :, -, or _-delimited name to camelCase.

There is no difference between ng-model and data-ng-model if you see in terms of AngularJs.
Actually, 'data' used as prefix to validate HTML5 validation. So, it is good practice to use data-ng-model, however, you can use ng-model as well. There is no problem in that also.
Both have the same meaning and both have the same output:
With ng-model
First Name : <input type="text" ng-model="fname" id="fname">
Second Name : <input type="text" ng-model="lname" id="lname">
With data-ng-model
First Name : <input type="text" data-ng-model="fname" id="fname">
Second Name : <input type="text" data-ng-model="lname" id="lname">

Best Practice: Prefer using the dash-delimited format (e.g. ng-bind for ngBind). If you want to use an HTML validating tool, you can instead use the data-prefixed version (e.g. data-ng-bind for ngBind). The other forms shown above are accepted for legacy reasons but we advise you to avoid them.

sylewester's answer is correct and can be read in the AngularJS Directive Documentation found at https://docs.angularjs.org/guide/directive
(this helped me understand sylwester's answer, so i figured it might help others too.)

sylewester's answer is correct and can be read in the AngularJS Directive Documentation found at https://docs.angularjs.org/guide/directive. Below is an excerpt from that page.
AngularJS normalizes an element's tag and attribute name to determine which elements match which directives. We typically refer to directives by their case-sensitive camelCase normalized name (e.g. ngModel). However, since HTML is case-insensitive, we refer to directives in the DOM by lower-case forms, typically using dash-delimited attributes on DOM elements (e.g. ng-model).
The normalization process is as follows:
Strip x- and data- from the front of the element/attributes.
Convert the :, -, or _-delimited name to camelCase.
For example, the following forms are all equivalent and match the ngBind directive:
(this helped me understand sylwester's answer, so i figured it might help others too.)

Related

Starting with Number and Ending with Character in Angular JS

I just started learning AngularJs So sorry for dump question. I have requirement to validate the field which will start with number and end with 'M' character eg:- 10M, 5M, 200M etc. please any one help me how to do it in angular js.
You can use ng-pattern in your input field e.g.
<input type="text" ng-model="model" id="input" name="input" ng-pattern="regex" />
and in your controller define regex as
$scope.regex = '\\d+M';
And you can check in your html, if input is valid or not like this:
input valid? = <code>{{form.input.$valid}}</code>
This will work well with ng-messages directive for form validation.
Read More.
You can use the ngPattern directive to validate by matching a regular expression:
Angular docs: ngPattern directive
The pattern you need is \d+M (a sequence of 1..n digits, followed by an 'M'), you can try it out on the page I linked.
AngularJS provide a usefull directive ng-pattern that you can apply on an input.
For your problem, you can use this code :
<input type="text" ng-pattern="/^\d+[M]$/" ng-model="model" id="input" />
Explanation
/d means digits only
+ means at least one
[M] means M characters only

AngularJS Conditional attributes from data

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.

AngularJS ng-required better implement from controller?

I'm thinking of a good way to implement ng-required.
Let's say I have a bunch of inputs with ng-required in my app.
<input type="text" id="one" />
<input type="date" id="two" />
<input type="radio" id="three" />
<input type="checkbox" id="four" />
I would like to do something in a controller, where I could pass an array of required fields. I'm thinking that if I made an array of elements such as:
var myEl = angular.element( document.querySelector( '#some-id' ) );
and some how set the required property that way.
I write a directive which would decide from an array if the field is required, if it does not exist in the array, it's not required if it does, it's required.
Ultimately, I would like to have an array that allows passing of fields in such a way:
var reqArray = ('#id', ('#id1' || 'id2')) etc.
Works the same as conditional logic operators:
#id is required
#id1 || #id2 is required, but not both.
Not sure where to begin, or if it's feasible in Angular.
This would make it easier to modify required fields in large applications without having to modify the actual html.
It can be done, but angular already provides its own ways to validate forms. Some brief details:
The form tag must have a novalidate attribute in order to prevent HTML5 validation. <form name="myForm" novalidate>
With that, now angular can take charge of the validation by adding a "required" attribute to your inputs <input ng-model="myModel" type="text" required>
By this point, angular has taken control of your validation, it can also validate other HTML5 attributes like pattern. <input pattern="[0-9][A-Z]{3}" type="text" title="Single digit followed by three uppercase letters."/>
I suggest you take look at this official guide (also take a look at the directives guide on that same site, I wanted to link it but I don't yet have the rep).
That being said, what you are trying to accomplish is also possible, but rather redundant since you would have to add an attribute to your inputs anyway (the directive, and angular is able to validate already) and also require ngModel in the directive.
I made this plunkr to show you how to do it, but take notice of the extra work needed in order to validate something that angular already does natively, I'd leave this kind of work for expanding on validations, like comparing items or models.
Also, querying a selector directly like in your suggestion is not considered "the angular way". A better way would be to add the directive to your form element and access the element through the 'element' parameter in the directive.
Hope this helps.

validate input with name containing brackets in AngularJS

I have a form input with names containing brackets, e.g.:
<form name="my_form">
<input type="text" name="my_form[email]" ng-model="email" ng-class="'mycssclass': my_form.my_form[email].$invalid">
</form>
So, the problem is that Angular is not applying that css class because of the name of my input (my_form[email]), is that the correct notation to reference my input in Angular.
Here's is a plunk:
http://plnkr.co/edit/t7PEilV9maNYGnVYnTDc?p=preview
The way to reference an input with a name containing brackets is using brackets notation, like this:
my_form['my_form[email]'].$invalid
You need to use the ng-model attribute in your input. It bind the content of a field with a value in the $scope. You also need to pass a Javascript Object to the ng-class directive. In your example it would be :
<form name="my_form">
<input type="text" ng-model="my_form.email" ng-class="{'mycssclass': my_form.email.$invalid}">
</form>
Don't hesitate to look at the examples in the ng-model and ng-class directive documentation.

What is the difference between required and ng-required?

What is the difference between required and ng-required (form validation)?
AngularJS form elements look for the required attribute to perform validation functions. ng-required allows you to set the required attribute depending on a boolean test (for instance, only require field B - say, a student number - if the field A has a certain value - if you selected "student" as a choice)
As an example, <input required> and <input ng-required="true"> are essentially the same thing
If you are wondering why this is this way, (and not just make <input required="true"> or <input required="false">), it is due to the limitations of HTML - the required attribute has no associated value - its mere presence means (as per HTML standards) that the element is required - so angular needs a way to set/unset required value (required="false" would be invalid HTML)
I would like to make a addon for tiago's answer:
Suppose you're hiding element using ng-show and adding a required attribute on the same:
<div ng-show="false">
<input required name="something" ng-model="name"/>
</div>
will throw an error something like :
An invalid form control with name='' is not focusable
This is because you just cannot impose required validation on hidden elements. Using ng-required makes it easier to conditionally apply required validation which is just awesome!!
The HTML attribute required="required" is a statement telling the browser that this field is required in order for the form to be valid. (required="required" is the XHTML form, just using required is equivalent)
The Angular attribute ng-required="yourCondition" means 'isRequired(yourCondition)' and sets the HTML attribute dynamically for you depending on your condition.
Also note that the HTML version is confusing, it is not possible to write something conditional like required="true" or required="false", only the presence of the attribute matters (present means true) ! This is where Angular helps you out with ng-required.

Resources