AngularJS with JQuery response content inside div - angularjs

I use JQuery post to communicate with server, and show the response inside a div. The response is an AngularJS script, like
<div ng-app="" ng-controller="formController" class="ng-scope">
<form novalidate="" class="ng-valid ng-dirty">
First Name:<br>
<input type="text" ng-model="user.firstName.x" class="ng-valid ng-dirty"><br>
<input type="text" ng-model="user.firstName.y" class="ng-pristine ng-valid"><br>
Last Name:<br>
<input type="text" ng-model="user.lastName" class="ng-pristine ng-valid">
<br><br>
</form>
<p class="ng-binding">form = {{user}}</p>
</div>
But it does not work. Can anyone help me figure out the problem?

When I ran it, it worked except:
You have double quotes after app. They're not necessary for the code to run.
User firstname is entered twice, which will create two text boxes, one under the other. Syntactically, you may want to re-name the second variable (user middle name?) since not many people have two first names.
You're printing form=user with the quote after binding. Take it out and form=user will stop printing itself on your screen. At least it did when I tried it.

Related

Protractor: How to test an element built with ngTagsInput?

I currently has a simple form that I am trying to test with Protractor. While it seems to work fine with basic input types, it does not seem to work with ngTagsInput the way I have it set up. I was wondering if there was a particular way of setting this up without triggering the error below.
Failed: unknown error: cannot focus element
(Session info: ...)
(Driver info: ...)
...
Currently my form, has 4 elements. A name (standard input), a type (radio buttons), targets (the tag inputs), and a submit button. In HTML, it appears something like this.
<div class="form-group">
<input class="form-control" placeholder="Enter name here..." ng-model="name">
</div>
<div class="form-group">
<div id="t1" class="radio">
<input name="radioType" id="a" value="A" checked="" type="radio" ng-model="type">
</div>
<div id="t2" class="radio">
<input name="radioType" id="b" value="B" type="radio" ng-model="type">
</div>
<div id="t3" class="radio">
<input name="radioType" id="c" value="C" type="radio" ng-model="type">
</div>
</div>
<div class="form-group">
<tags-input class="btags" name="targets" min-length=1 placeholder="Enter your targets here..." min-tags=1 add-on-blur="true" ng-model="targets">
</div>
<div class="form-group">
<button id="submit" type="button" class="btn btn-primary" ng-click="submitThing()"></button>
</div>
Lastly, the one Protractor test I have written looks like this.
it('should submit a valid thing',function(){
//Sets a name for the object
element(by.model('name')).sendKeys('user');
//Sets a type for the object
element(by.id('t1')).click();
/*Inputting tags (the functions below) seem to not work and throw an error*/
//Clicks (or focuses on) the tag input box
element(by.model('targets')).click();
//Types in the elements within it
element(by.model('targets')).sendKeys('target1');
//Presses Enter to submit that particular target
browser.actions().sendKeys(protractor.Key.ENTER).perform();
//Repeat for more
element(by.model('targets')).sendKeys('target2');
browser.actions().sendKeys(protractor.Key.ENTER).perform();
element(by.model('targets')).sendKeys('target3');
browser.actions().sendKeys(protractor.Key.ENTER).perform();
element(by.id('submit')).click();
}
The managed to find a solution thanks to MBielski's comment. It turns out that you need to look at the HTML that is rendered and focus on one of those elements since it is a custom element. Using Google Chrome's developer tools, I managed to find some of the inner code for the make up of the tags. In short, it appears as:
<input class="input" ng-model="newTag.text">
There is much more information in this inner element, but I left what was relevant. So, you add information into the tags inbox I've defined in the question asked, you would simply focus on the model called "newTag.text", like this.
it('should submit a valid thing',function(){
//Sets a name for the object
element(by.model('name')).sendKeys('user');
//Sets a type for the object
element(by.id('t1')).click();
//Clicks (or focuses on) the tag input box // This may not be needed
element(by.model('newTag.text')).click();
//Types in the elements within it
element(by.model('newTag.text')).sendKeys('target1');
//Presses Enter to submit that particular target
browser.actions().sendKeys(protractor.Key.ENTER).perform();
//Repeat for more
element(by.model('newTag.text')).sendKeys('target2');
browser.actions().sendKeys(protractor.Key.ENTER).perform();
element(by.model('newTag.text')).sendKeys('target3');
browser.actions().sendKeys(protractor.Key.ENTER).perform();
element(by.id('submit')).click();
}
This solved the problem for me. Hopefully it also does for others.

label hiding input text field value in md-input-container when retrieving with ng-value

When using angularjs to retrieve a value for a text input field with ng-value, the label the overlays the field doesn't transition above the field after the value is retrieved. I can only see the value in the input field after clicking on that field.
I'm using material's md-input-container:
<md-input-container>
<label>Name</label>
<input type="text" ng-value="profileInfo.name" ng-model="savedProfileInfo.name" class="provider-name" id="providerName" name="providerName" />
</md-input-container>
Here's the Inspect Element code:
<md-input-container class="">
<label for="providerName">Name</label>
<input type="text" ng-value="profileInfo.name" ng-model="savedProfileInfo.name" class="provider-name ng-pristine ng-untouched ng-valid md-input" id="providerName" name="providerName" aria-invalid="false" value="a"><div class="md-errors-spacer"></div>
</md-input-container>
You can clearly see that value="a" which was pulled after the page loaded using ng-value. But, the field still looks like this:
Only after I click on the field does it look how I would expect:
Is this a bug? Am I missing something? I though AngularJS and Material were supposed to play nice.
Available plunker here
In a roundabout way troig's comment helped me figure this out.
This form is used to display and update a user's profile information. I was using ng-model to update the user's profile and ng-value to display any existing user profile info from the database.
ng-value spits back the value="" attribute which does not play nice with md-input-container. To get this to work properly, I removed ng-value, replaced ng-model's value with profileInfo.name, and modified my controller to allow me to save profileInfo.name instead of savedProfileInfo.name.
Code translation:
<form ng-submit="saveProfile(profileInfo)">
<md-input-container>
<label>Name</label>
<input type="text" ng-model="profileInfo.name" class="provider-name" id="providerName" name="providerName" />
</md-input-container>
Moral of the story, ng-value does not play nice with md-input-container and form labels.

ng-repeat radio button 2-way binding issue, only last item set correctly

I am using angularjs to repeat radio button groups with the following code.
<div class="row observation-point"
ng-repeat="observationPoint in question.observationPointList">
<div class="col-md-6 col-sm-6">
<small>{{observationPoint.text}}</small>
</div>
<div class="col-md-4 col-sm-4 col-md-offset-2 col-sm-offset-2">
<label class="radio-inline">
<input type="radio" ng-disabled="observation.status != 'Open'"
name="{{domain.id}}-{{question.id}}-{{observationPoint.id}}"
id="{{domain.id}}-{{question.id}}-{{observationPoint.id}}-1" ng-value="true"
ng-model="observationPoint.observed">{{'observation-domain.html.yes' | translate}} {{observationPoint.observed}}
</label>
<label class="radio-inline">
<input type="radio" ng-disabled="observation.status != 'Open'"
name="{{domain.id}}-{{question.id}}-{{observationPoint.id}}"
id="{{domain.id}}-{{question.id}}-{{observationPoint.id}}-0" ng-value="false"
ng-model="observationPoint.observer">{{'observation-domain.html.no' | translate}}
</label>
</div>
</div>
With angular 1.2.28 this worked fine, however we've recently upgraded to 1.4.2 and now the result is as in the picture below.
The model values are correctly saved and restored (see the true and false values in the image) in the variables, but only the last radio button in the ng-repeat is selected after reloading the page.
Why is this happening, because I really don't understand what the problem is and how to fix this.
nb. observationPoint.observer contains a boolean value not a string
EDIT: i've created a simplified plunker and of course this works as intended :S
http://plnkr.co/edit/tWjizHB8I5FNZVOgdq6J?p=preview
Which would suggest something is wrong with the naming or id's.
However when I check with the developer tools id and name seem fine
I've found a solution, if I change the dynamic names from
name="{{domain.id}}-{{question.id}}-{{observationPoint.id}}"
to
name="observationPoint_{{observationPoint.id}}"
it works without a hitch. I presume there is some sort of loading/timing issue going on. The variables are probably not unique at the moment the UI is rendered and causes only the last item to be set.

angularjs: ng-message always showing

I'm using angular-messages to display form validation errors on my angular app.
As per the documentation, I have built the following code
<form name="loginForm">
<label class="item item-input">
<input type="email" placeholder="Email" ng-model="data.email" name="email" required>
</label>
<div ng-messages="loginForm.email.$error" style="color:maroon">
<div ng-message="required">Please input a valid e-mail address</div>
<div ng-message="email">You did not enter your email address correctly...</div>
</div>
</form>
I have included the ngMessages directive in my javascript as well as imported the angular-messages.js file.
Unfortunately, these two messages are showing perpetually. Regardless of what I type in the input field, be it a valid email or not. Both messages are always showing. If I try to only include one ng-message, the result is the same.
What could I be doing wrong?
edit: In case my description isn't very clear, this is a print of the result
https://s9.postimg.cc/du9230tdb/Screen_Shot_2015_06_26_at_17_09_24.png
You gotta make sure you are actually including ngMessage to your module.
var app = angular.module('app', [
'ngMessages'
])
... and that you included the library to your project
<script src="/scripts/vendors/angular-messages/angular-messages.js"></script>
Everything seems to be fine in the code you're sharing.
<form name="loginForm">
<label class="item item-input">
<input type="email" placeholder="Email" ng-model="data.email" name="email" required>
</label>
<div ng-messages="loginForm.email.$error" style="color:maroon">
<div ng-message="required">Please input a valid e-mail address</div>
<div ng-message="email">You did not enter your email address correctly...</div>
</div>
</form>
Here is a working copy on Plunker I'm using your piece of code.
From Angularjs documentation.
By default, ngMessages will only display one error at a time. However, if you wish to display all messages then the ng-messages-multiple attribute flag can be used on the element containing the ngMessages directive to make this happen.
If you want to show the errors after the field is dirty, please visit this link.
Make sure you are including ngMessage module and the library as well. Please see Carlos's answer.
Thanks
Check with
<div ng-messages="loginForm.email.$error" ng-show="loginForm.email.$invalid && loginForm.email.$touched">
...
</div>
This trick saved my day.

angularjs ng-minlength validation is not working, form still being submitted

I am trying to submit the form on only successful validation.
validation is working for required but not working for ng-minlength
form input is invalid but form is still being submitted.
<form name="myForm" ng-submit="count = count + 1" ng-init="count=0" ng-app>
<div class="control-group" ng-class="{error: myForm.mobile.$invalid}">
<label class="control-label" for="mobile">Mobile</label>
<div class="controls">
<input type="text" name="mobile" placeholder="07XXXXXXXXX" ng-model="mobile" ng-minlength="11" required />
<span ng-show="myForm.mobile.$error.required" class="help-inline">Required</span>
<span ng-show="myForm.mobile.$error.minlength" class="help-inline">Mobile number should be minimum 11 character starting from 07</span>
</div>
</div>
<div class="control-group">
<div class="controls">
<input class="btn" type="submit" value ="submit" />
</div>
count: {{count}}<br />
<tt>myForm.$invalid = {{myForm.$invalid}}</tt><br/>
</div>
</form>
http://jsfiddle.net/pMMke/9/
what am I doing wrong.
I don't want to use submit button disable method.
This is what you are doing wrong: you are mixing two concepts, Angular validators and
HTML5 validators.
The required HTML5 validators, for instance, states that:
When present, it specifies that an input field must be filled out before submitting the form.
So, if you try to submit a form that has an input with this attribute, it will show a message explaining this to the user, and it will prevent the form from being sent. This is the behavior you want. Why isn't working for ng-minlength? Because ng-minlength is an Angular validator (you can tell because it begins with ng-), and it doesn't add any special behavior to the form. It simply set the input where it is located to invalid (and hence, the form), and let you decide what to do with it.
You have an option: you can use the pattern HTML5 validator, to specify the field requires at least 11 characters. It would like this:
<input type="text" pattern=".{11,}">
So when you submit a form containing this input, it will no be sent if the user has enter less than 11 characters.
But since we are it, and you are already using the pattern validator, you could use the regular expression in its full potential, and define something like:
<input type="text" pattern="07[0-9]{9}" />
Which will only admit values of 11 characters, that start by "07" and that contains only digits. I have modified your fiddle to show you how it would work: http://jsfiddle.net/helara/w35SQ/
I mistakenly used ngMaxlength="12" ngMinlength="6" instead of ng-minlength="6" ng-maxlength="12", it's working fine now.
Both ng-minlength & mg-maxlength works in AngularJS.
I've tested this in AngularJS version 1.3.
Make sure to use novalidate with <form> to disable browser's native validation.
This should work:
To enter mobile number
ng-show="myForm.mobile.$touched && myForm.mobile.$error.required"
For minimum length
ng-show="myForm.mobile.$touched && myForm.mobile.$error.minlength"
For maximum length
ng-show="myForm.mobile.$touched && myForm.mobile.$error.maxlength"
This work for me guys
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input ng-minlength="11" class="mdl-textfield__input" type="text" name="cpf" id="cpf" ng-model="avaliacao.cpf" ng-required="true" ng-pattern="/^\d+$/">
<label class="mdl-textfield__label" for="cpf">CPF *</label>
</div>
<p style="color: #d50000;" ng-show="myForm.cpf.$error.required && myForm.cpf.$dirty">Field Required</p>
<p style="color: #d50000;" ng-show="myForm.cpf.$error.pattern">Only numbers</p>
<p style="color: #d50000;" ng-show="myForm.cpf.$error.minlength">Min 11 Chars</p>
I'm facing the same issue, and I think you can only disable the button or ignore the entered value by yourself. You can also check the $valid property in your controller and ignore the value... It is not so nice, but I found no other way.

Resources