I have a requirement to pre-populate an input field with the value of another input field. So, once the first field loses focus, the second field gets the same value. The field is editable, but initially, it has the value of the first field. I've found that the ngModel of the second field is not updated.
I do this to set the value of the second field:
$("#" + fieldId).val(newstring);
Here's the HTML for the first field:
<td class="formLabel" vAlign="top" align="left">
<input validate-date-time val-type="date" val-start="true" val-end-id="endDate" id="startdate" size="10" max="10" width="20" ng-model="newEvent.startDate">
mm/dd/yyyy
</td>
Here's the HTML for the second field:
<td class="formLabel" vAlign="top" align="left">
<input size="10" validate-date-time val-type="date" id="endDate" max="10" width="20" ng-model="newEvent.endDate">
mm/dd/yyyy
</td>
This is done in a directive, by the way. Any pointers on how to make this work?
I've tried calling scope.$apply and scope.$digest after setting the input val to no avail. And if I shouldn't use jQuery, whats the angular way of setting the value?
Thanks
Try something like this:
// in the controller, add
$scope.isStartDateInitialized = false;
$scope.onStartDateSet = function() {
if (!$scope.isStartDateInitialized) {
$scope.isStartDateInitialized = true;
$scope.newEvent.endDate = $scope.newEvent.startDate;
}
};
<!-- add the following attribute to the start date input -->
<input ... ng-blur="onStartDateSet()" />
NOTE 1: The above code assumes that you only want to programmatically update the end date the very first time the start date is set. If you want it to always be set to the start date when the start date changes, then you can use ng-change instead of ng-blur.
NOTE 2: You should remove the following JQuery code that you mentioned:
$("#" + fieldId).val(newstring);
Related
I'm using Angular Moment Picker in my project. When it comes to edit page, ng-model value should be overwrite by data from API, howerver the values does not overwrite to moment picker ng-model anyway instead of bind the ng-model value with undefined. If i remove moment-picker it does working. Below is the demo for my situation.
JSFiddle
View
<input name="time_of_time"
class="form-control"
placeholder="Select a time"
ng-model="scheduler.timeOfTime"
ng-model-options="{updateOn: 'blur'}"
moment-picker="scheduler.timeOfTime" //Working if remove this line
format="HH:mm">
Controller
myApp.controller('HomeCtrl', function ($scope) {
$scope.scheduler = {};
$scope.scheduler.timeOfTime = '11:10';
console.log($scope.scheduler);
I was having the same problem.
This comment help me.
https://github.com/indrimuska/angular-moment-picker/issues/92#issuecomment-263669991
From the link. There are 2 way to do it.
1. Using formatted string date coming from moment-picker attribute
<input moment-picker="ctrl.formattedDate"
ng-model="ctrl.momentDate"
ng-model-options="{ updateOn: 'blur' }"
format="DD MMM YYYY"
start-view="month">
<!-- Use `ctrl.formattedDate` anywhere -->
Formatted date: {{ ctrl.formattedDate }}
2. Retrieving the formatted date using the Moment.js object
remove parameter from moment-picker
<input moment-picker
ng-model="ctrl.momentDate"
ng-model-options="{ updateOn: 'blur' }"
format="DD MMM YYYY"
start-view="month"
change="ctrl.setFormattedDate(newValue)">
<!-- Use `ctrl.formattedDate` anywhere -->
Formatted date: {{ ctrl.formattedDate }}
And in your controller
ctrl.setFormattedDate = function (momentDate) {
// do you stuff.. and
ctrl.formattedDate = momentDate.format('DD MMM YYYY');
};
I end up go with method 2.
Hope this help.
In a repeater and I display some records with some data, input field and a span tag in each row. When the user enters numeric value into the input field,
I want to do a calculation on it and display the result in the span tag. This will happen on keypress using ng-keyup
I’ve tried this but its not working, probably becuse I'm not using the model correctly...
<div ng-repeat="bet in $ctrl.bets">
<input class="form-control input-sm" ng-model="$index" type="text" ng-keyup="$ctrl.getReturn($index)">
<span>Return: </span><span id="$index" ng-model="$index"></span>
</div>
And in my controller I have this
vm.getReturn = function(index){
document.querySelector('#' + index ).html(value / 2);
}
I know its way off, but can someone tell me how to do this? Ta.
1st thing you can use ng-model only with input, select & special bootstrap components, Not span element. You could use ng-bind do bind value one way.
Other thing is don't play with $index which is added & managed by ng-repeat directive itself. I'd say rather add new property inside bet(each element of bets).
Markup
<div ng-repeat="bet in $ctrl.bets">
<input class="form-control input-sm" ng-model="bet.myValue" type="text" ng-keyup="$ctrl.getReturn(bet.myValue)">
<span>Return: </span><span id="$index" ng-bind="vm.getReturn(bet.myValue)"></span>
</div>
Accordingly manage calculation in getReturn function.
vm.getReturn = function(val) {
return (val > 0 ? (val / 2): 0);
}
I am trying to fetch a value from one input field (which is a reference field) to filter some values in another drop down based on first input field in a same form in ng-admin.
I tried to use permanent filters to filter value, it works if i give a hard coded value. but i am not able to figure out how to get value of filter dynamically from above input field .
any help will be appreciated. I am new to angular and ng-admin and finding hard to solve this .
below is the code.
nga.field('matchId', 'reference')
.label('Match')
.targetEntity(match)
.targetField(nga.field('description'))
.map(function(value) {
if (!value) return '';
return value.length > 20 ? value.substr(0, 20) + '...' : value;
}),
nga.field('slotId', 'reference')
.label('slot')
.targetEntity(match_slot)
.targetField(nga.field('matchSlotType')),
i want second field to be filtered based on input from first
On angular filter docs you can see how they implement dynamic filtering:
<label>Any: <input ng-model="search.$"></label> <br>
<label>Name only <input ng-model="search.name"></label><br>
<label>Phone only <input ng-model="search.phone"></label><br>
<label>Equality <input type="checkbox" ng-model="strict"></label><br>
<table id="searchObjResults">
<tr><th>Name</th><th>Phone</th></tr>
<tr ng-repeat="friendObj in friends | filter:search:strict">
<td>{{friendObj.name}}</td>
<td>{{friendObj.phone}}</td>
</tr>
</table>
Just put model name first parameter
Using ng-repeat I display some radio's in the edit form:
<label style="float: left;margin-right: 3px;" data-ng-repeat="gender in genders" data-ng-hide="$first">
<input type="radio" name="gender" value="{{gender.Id}}" data-ng-model="customerFormData.customer.Gender.Id" />{{gender.Description}}
</label>
As you can see, I've applied the 'dot practice'. The edit form is a pop-up over my detail form. In my detail form I have this:
<tr>
<td>Gender:</td>
<td>{{ customer.Gender.Description }} </td>
</tr>
All my bindings in the edit form are working, but I can't get the gender binding to work. I think it has something to do with scope inheriting by the use of ng-repeat.
I've also tried to use $parent, but the outcome remains the same:
<label style="float: left;margin-right: 3px;" data-ng-repeat="gender in genders" data-ng-hide="$first">
<input type="radio" name="gender" value="{{gender.Id}}" data-ng-model="$parent.customerFormData.customer.Gender.Id" />{{gender.Description}}
</label>
Setting the initial value works. When a female is set, the female radio is selected and when it is a male, the male radio is selected.
A second problem is (and I think it has to do with the binding), is that when Male is selected, I have to click twice on female to get female selected.
Edit: I've created a Fiddle to illustrate my issue.
One solution is to use ng-value(which evaluates its content as an expression) and set it to the whole gender object, and set ng-model to the Gender object on your FormData. This way, when you change the input, the gender object is set to FormData.Gender and you have access to both Id and Descr.
<label ng-repeat="gender in genders">
<input type="radio" name="gender" ng-value="gender" ng-model="customer.FormData.Gender">
{{gender.Descr}}
</label>
http://jsfiddle.net/ADukg/3194/
If you just want the Id in the model, you can use: (value evaluates its content as a string)
<label ng-repeat="gender in genders">
<input type="radio" name="gender" value="{{gender.Id}}" ng-model="customer.FormData.Gender.Id">
{{gender.Descr}}
</label>
And in the controller:
$scope.customer.FormData.Gender = {Id : $scope.genders[1].Id};
http://jsfiddle.net/ADukg/3195/
Strangely enough, it doesn't work when you set value and model to Id, but initially bind a whole gender object to the gender model. Weird!
I can't explain it 100% accurately. But you have too many nested objects in your scope!
Look at this example (fiddle: http://jsfiddle.net/ADukg/3193/)
<div ng-controller="MyCtrl">
<label ng-repeat="gender in genders">
<input type="radio" name="gender" value="{{ gender.Id }}" ng-model="$parent.selectedGenderId">{{gender.Descr}}
</label>
</div>
function MyCtrl($scope) {
$scope.genders = [{Id: 1, Descr:'Male'}, {Id:2, Descr:'Female'}];
$scope.selectedGenderId = $scope.genders[1].Id;
$scope.$watch('selectedGenderId', function(newValue, oldValue) {
console.log("selectedGenderId=" + newValue);
// TODO: set it into FormData?
});
}
If you set the "selectedGenderId" directly it will also be set correctly.
I think the selection problem has nothing to do with the binding directly but with the scope and nesting of scopes via the many objects.
Take also look at this explanation:
http://jimhoskins.com/2012/12/14/nested-scopes-in-angularjs.html
The problem lies with the binding on the radio buttons. You are binding on the customer.FormData.Gender.id model - note it is the id property that you bind to and not the Gender property.
Thus, when you select the radio button for Male, only the ID on the gender is changed - not the Descr field. This explains clearly the behaviour. When you select different radio buttons, notice how only the ID gets updated and not the Desc.
To change the Descr field as well, you will be wise to have a dedicated model for the radio buttons and then respond to changes to this model.
This is demonstrated in this fiddle.
Is there anyway that I can bind two model values to one input field?
Suppose I have input field which I want to be the value of two variables in the scope something like:
<input type="text" model="sn_number; id" >
You cannot, but there are some workarounds.
1. Use ngChange to update the other model
<input type="text"
ng-model="sn_number"
ng-change="id=sn_number"/>
2. You could watch a model, and when in changes, update another
$scope.$watch('sn_number', function(v){
$scope.id = v;
});
You would need to watch also for changes in id if you want to keep them in sync.
Example here
You can bind fields immediately, not only in ng-change, and actually it isn't data binding, its only angular expression
<label>Name</label>
<input type="text" ng-model="name" value="{{name}}"/>
<label>Key</label>
<input type="text" ng-model="key" value="{{key=name}}" />
It would make no sense to bind an input to two variables in the model. Binding works both ways, so if the model is updated, the field is updated and vice-versa. If you were to bind to two variables, what would be the single source of truth?
However you can use ng-change to call a method on the controller which can set two variables when the field changes.
with ng-init
<div ng-controller="ctrl" ng-init="model = { year: '2013', month:'09'}">
or
<div ng-repeat="c in contact" ng-init="likes = { food: 'steak', drink:'coke'}">