Angular ng-Model not showing up second time - javascript

I have this code inside a modal popup that is shown under certain circumstances, the first time the modal is shown everything is working normal.
I have this code:
<div class="form-group">
<p>First Name:</p>
{{vm.user.name_first}}
<input type="text" class="form-control" ng-model="vm.user.name_first" name="firstName" required />
</div>
After closing the modal and opening again, the text below the p is shown correctly, however, the ng-model (which has the same content after the p), is showing the input empty instead of the content of vm.user.name_first.
What can be happening that only affects the second time?

Try this:
<div class="form-group">
<p>First Name:</p>
{{vm.user.name_first}}
<input type="text" class="form-control" ng-model="vm.user.name_first" name="firstName" ng-model-options="{ getterSetter: true }" required />
Explanation:
Sometimes it's helpful to bind ngModel to a getter/setter function. A getter/setter is a function that returns a representation of the model when called with zero arguments, and sets the internal state of a model when called with an argument. It's sometimes useful to use this for models that have an internal representation that's different from what the model exposes to the view.
https://docs.angularjs.org/api/ng/directive/ngModel -> last paragraph

Related

duplicate div containing set of fields in the same dom

i am loading handlebar templates in the two div locations(like add and edit tabs both are jsps) from the same page. so i have duplicate elements in the DOM object, since it is a template which is coming from server location. you can see the sample code below
<div id="add">
<div id="exploding">
<input type="text" name="city" id="city"/>
<input type="text" name="state" id="state"/>
...
</div>
</div>
<div id="edit">
<div id="exploding">
<input type="text" name="city" id="city"/>
<input type="text" name="state" id="state"/>
...
</div>
</div>
I can't modify the div container ids i.e exploding since some javascript functions attached to it based on that id to explode address field.
here the problem is if i made any changes to the edit tab, address "exploding" div, it is effecting in add tab address "exploding" since ids are repeated. i have tried jquery detach method to remove the dom elements, but didn't get proper result. Its a web application based on spring boot.
is there any possibility to load jsps dynamically through jquery, i have tried load method as well, but the call is going through controller. I didn't feel it as better option.
Thanks & Regards
krishna K

Angular 2+ multi-part form validation, how to check validity of single input

I have a form, and the form has multiple inputs that are all bound to different variables. Before submitting the form, I need to do validity checks, pristine checks, etc. For example, I want my submit button to be disabled if every part of the form is pristine, or if something is invalid.
Using Angular 5, I am trying to get access to the .pristine, .valid, and .invalid flags for each input field, but the values are either undefined or "cannot get .pristine of undefined".
I am able to get these flags on the entire form itself, but this doesn't help, because I want to know how to get it for each individual input.
Here is my current code (I've removed a number of my inputs to simplify the example).
<form #editDetailsForm="ngForm" name="editDetailsForm" >
<label for="name"> Name </label>
<input type="text" id="name" name="name" maxlength="40" [(ngModel)]="myName" required />
<label for="description"> Description </label>
<textarea id="description" name="description" maxlength="250" [(ngModel)]="myDescription" required ></textarea>
<button id="submit" type="button"
[disabled]="saveButtonDisabled(editDetailsForm.invalid, editDetailsForm.name.invalid, editDetailsForm.description.invalid)"
(click)="updateDetails()" >
Save
</button>
</form>
If you see, I bind disabled attribute on the Save button to saveButtonDisabled() function, where I want to pass in information about each input's validity. The first argument, editDetailsForm.invalid returns a true or false, but the other values return undefined.
How do I check validity of these individual inputs?
EDIT: I realize I can derive all of this info inside my component because all of the input values are bound. However, it'd be easier just to check a flag or two.
I'm not sure I totally understand what you want to do, but this is how you get access to the form controls .pristine, .invlaid
<input type="text" id="name" name="name" #name="ngModel" maxlength="40" [(ngModel)]="myName" required />
The #name="ngModel" sets a template reference to the FormControl angular creates
Then you should be able to do something like this:
<input type="text" id="name" name="name" #name="ngModel" maxlength="40" [(ngModel)]="myName" required />
<div *ngIf="name.pristine">
Name is Pristine
</div>
Just to clarify, the individual form fields bubble up to the form itself. So if any field has been touched, then the whole form will be pristine == false.
You can access the input controls using the .controls property, like:
<button id="submit" type="button"
[disabled]="editDetailsForm.controls.name?.invalid || editDetailsForm.controls.description?.invalid">
Created a stackblitz. https://stackblitz.com/edit/angular-5ir4k7
Added template reference variable for ngModel and validate using isValid.

How to handle different input types bound to same ng-model?

In a page, I have a section for date-range selection. A large portion of our user base is IE 10/11, which does not support input type="date". I'm using Modernizr to show/hide the date input based on the support, and when not, provide an input of type="text", both bound to the same ng-model. Typing into the text spams the console with errors, as the text and date are incompatible. Is there a way to fix this console spam? Using a third-party library is not an option.
<div class="col-md-3" data-ng-show="searchBillCreatedDate == 'custom'">
<label>From</label>
<input data-ng-model="searchFromDate" type="date" class="form-control" data-ng-show="browser.supportsDateInput">
<input data-ng-model="searchFromDate" type="text" class="form-control" data-ng-show="!browser.supportsDateInput" placeholder="yyyy-mm-dd">
</div>
Change your ng-show to ng-if like this:
<input data-ng-model="searchFromDate" type="date" class="form-control" data-ng-if="browser.supportsDateInput">
<input data-ng-model="searchFromDate" type="text" class="form-control" data-ng-if="!browser.supportsDateInput" placeholder="yyyy-mm-dd">
You're getting the error because it's binding to the the first input's model, which is a date input. ng-show just uses CSS to hide the element but it still exists in the DOM. ng-if, however, completely removes it from the DOM, leaving you with one ng-model="searchFromDate"

Does a ng-model work on ng-repeated fields?

I am using ng-repeat and I am various levels in such as:
`ul in output.content.innercontent` or `li in ul.content.innercontent`
my input looks like this:
<input id="{{input.key}}" name="{{input.label}}" type="text"
value="{{input.value}}" placeholder="{{input.defaultValue}}"
value="{{input.label}}"
class="form-control input-md" uib-tooltip="{{input.tooltip}}"
ng-if="input.type == 'input'">
On any one of those whenever a change happens and then an onBlur I want to make a call. Is this possible with ng-model & ng-model-options="{updateOn:'blur'}" with all these fields? The bind behavior I see online are mostly of an input to read-only field somewhere. Should I use ng-blur followed with a on("change") type of behavior?
try with
<input id="{{input.key}}" name="{{input.label}}" type="text"
ng-model="{{input.value}}" <!-- this -->
placeholder="{{input.defaultValue}}"
class="form-control input-md" uib-tooltip="{{input.tooltip}}"
ng-if="input.type == 'input'">
ng-model should do it
<input ng-model-options"{updateOn: 'blur'}"/>
==> This update the model only when user get outside the input
To call a function on-blur :
<input ng-blur="callThisFn()"/>

getElementByID Not working because field is in some sort of frame, how do I access it?

Please go to this page real quick and hit the login at the top right:
Here's the link: http://forums.gamesalad.com
I'm trying to pre-fill these two fields that pop up. They seem to be in some sort of frame. I am unable to access the fields using getElementByID (or any getElement for that matter). How can I access these two fields using javascript?
NOTE: (don't worry about firing the javascript, just getting access to the fields).
Here's my current code:
document.getElementById('login-dialog-email').value = 'the user name';
If you look at your HTML in a debugger, like the Chrome Debugger, you'll see that you have two instances of the input elements with id="login-dialog-email".
The W3C spec says that only one instance of an id attribute can be used in a single HTML document, and browser vendors implement this spec in a manner where the behavior is considered to be undefined if more than one id attribute of the same value is on the page.
In my experience, this really only affects the second instance of the element with said id, and if you do a search for login-dialog-email and examine which element gets highlighted, you'll see that the second instance is the one that represents your form.
Remove the first instance, or use a unique id, and then you'll be able to target the element.
The first instance of this login field appears to be part of a template that is hidden on the page.
<div id="login-form-template" style="display: none">
<form accept-charset="UTF-8" action="https://auth.gamesalad.com/auth/signIn" class="dialog dialog-form" id="common-login-form" method="post">
...
<li class="email">
<label for="login-dialog-email">
Email:
<input id="login-dialog-email" name="emailAddress" type="text" value=""></input>
</label>
</li>
<li class="password">
<label for="login-dialog-password">
Password:
<input id="login-dialog-password" name="password" type="password" value="">
</label>
...
The second instance of this field actually appears inside the fancybox, which is where the actual HTML is located that you are trying to target.
<div id="fancybox-content" style="border-top-width: 10px; border-right-width: 10px; border-bottom-width: 10px; border-left-width: 10px; width: 300px; height: 233px; "><div style="width:300px;height:auto;overflow: auto;position:relative;">
<form accept-charset="UTF-8" action="https://auth.gamesalad.com/auth/signIn" class="dialog dialog-form" id="common-login-form" method="post">
...
<li class="email">
<label for="login-dialog-email">
Email:
<input id="login-dialog-email" name="emailAddress" type="text" value="">
</label>
</li>
<li class="password">
<label for="login-dialog-password">
Password:
<input id="login-dialog-password" name="password" type="password" value="">
</label>
<span>
...
Thus, even if the site owner were trying to target these fields from the page, he/she would have the same problem.
The solution to this problem is to use className attributes within any template. This ensures that all of the fields can be targeted via DOM methods.
However, this doesn't mean that you can't still target the elements:
JavaScript:
document.getElementsByClassName("email")[2].
getElementsByTagName("input")[0].value = "test#example.com";
jQuery:
The site is using jQuery, so you may also be able to use this:
$('input[name="emailAddress"]').val( "test#example.com" );
you have the same id login-dialog-email for password and email input box. javascript is confused when you try to assign value. Assign different id's and you are good to go.

Categories

Resources