Updating input values filled out by ng-repeat | Angular js - angularjs

I have to update the value of multiple Inputs using ng-repeat. i usually get the value with JQuery $(class/id).val() and get its value. but now i have no idea how to access the input values since i only have one id for each. (i have like 20 input in the table)
View:
<tr ng-repeat="i in list">
<td><input list="itemNames" class="item_name" ng-model="i.item_name" value="{{i.item_name}}" type="text"/></td>
<datalist id="itemNames">
<option ng-repeat="ii in list" class="idI" ng-model="ii.idI" data-item="{{ii.idI}}" value="{{ii.item_name}} {{ii.idI}}">
</datalist>
<td><input class="quantity" ng-model="i.quantity" value="{{i.quantity}}" type="number"/></td>
<td><input class="price" ng-model="i.price" value="{{i.price}}" type="number"/></td>
<tr>
<td ng-click="updateAll()">UPDATE</td>
</tr>
</tr>
I expect to store all values in an arrays, but what i got is only values of the first row.
JS:
$scope.updateAll=function(){
// getting vallues
var item_name=$(".item_name").val();
var quantity=$(".quantity").val();
var price=$(".price").val();
}

I think your list is a scope variable. So, in controller its defined as $scope.list. You need not to think about id as you are using angular code, angular framework will do it for you.
As you used the two way data binding with ng-model, so any change to the bind variable will be immediately visible to controller and html view.
The use of ng-model ensures the immediate update to the $scope.list variable.
For example, if you add any text for "item_name" in the control index 0 from html view, the variable $scope.list[0].item_name will be automatically updated, also the change in $scope.list[0].item_name = "Some name" in controller will be automatically reflected in the view.
So, your given code can be re-written as following:
<tr ng-repeat="i in list">
<td><input list="itemNames_{{$index}}" class="item_name" id="txt_name_{{$index}}" ng-model="selectedValue" ng-change = "getSelectedId(selectedValue, $index)" type="text"/></td>
<datalist id="itemNames_{{$index}}">
<option ng-repeat="ii in list" class="idI" ng-model="ii.idI" data-item="{{ii.idI}}" value="{{ii.item_name}} {{ii.idI}}">
</datalist>
<td><input class="quantity" ng-model="i.quantity" value="{{i.quantity}}" type="number"/></td>
<td><input class="price" ng-model="i.price" value="{{i.price}}" type="number"/></td>
<tr>
<td ng-click="updateAll()">UPDATE</td>
</tr>
The javascript method can be written as:
var getSelectedId = function(selectedValue, index) {
var val = document.getElementById('txt_name_' + index).value;
var text = $('#itemNames_' + index).find('option[value="' + val + '"]').attr('data-item');
alert(text);
}

Related

How to update parent model object using angularjs

I am facing a problem with the below code.
<tr ng-repeat="diag in diags track by diag.id">
<td>
<select id="ddTest" ng-change="changeevent()">
<option value="">Select Number</option>
<option ng-repeat="o in orderNumbers" data-diagId="{{diag.id}}" ng-selected="o==diag.ordernumber">{{order}}
</option>
</select>
</td>
</tr>
$scope.orderNumbers= [1,2,3,4,5,6,7,8,9,10];
In diags object is an array which contains ordernumber in it. I am trying to update the specific ordernumber from ddTest dropdown change to the diags object using the custom attribute data-diagId. I don't have any model for ddTest dropdown (I can add it if needed). I want to populate the value on load and also need to update the parent object with the new order number selected. Can anybody help me to do this ?
Use ng-options directive and ng-model in Your select, then diag.ordernumber will change every time select is changed, so selected option is connected to model without any additional programming. Here full working example:
var app = angular.module("diagApp", []);
app.controller("diagController", function($scope) {
$scope.orderNumbers= [1,2,3,4,5,6,7,8,9,10];
//test diags
$scope.diags=[
{id:1,ordernumber:1},
{id:2,ordernumber:2},
{id:3,ordernumber:3}
];
//to prove that diag is changing
$scope.change=function(diag){
console.log(diag);
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="diagApp">
<table ng-controller="diagController">
<tr ng-repeat="diag in diags track by diag.id">
<td>
<select ng-change="change(diag)" id="ddTest" ng-model="diag.ordernumber" ng-options="item as item for item in orderNumbers track by item">
</select>
</td>
</tr>
</table>
</div>

how to get select value with input values in angularjs

Can any one help how to get input and selected values by dynamically added with angularjs?
Here is my code in Plunkr
When I select vegtables, another input shows with some values. when I click submit button I need a json like
{
"itemName":"Mango",
"itemType":"fruits"
},
{
"itemName":"Carrot",
"itemType":"vegtables",
"iteminfo":"you selected Carrot"
},
{
"itemName":"Apple",
"itemType":"fruits"
}
I forked your plunker
You can bind itemInfo to an item object using ng-model. Rather than placing the text in a value attribute I just initialized the model value using ng-init.
<tr ng-repeat="item in Items">
<td>
<input type="text" ng-model="item.itemName">
</td>
<td>
<select ng-model="item.itemType">
<option value="">--Select--</option>
<option vaue="fruits">Fruits</option>
<option value="vegtables">Vegtables</option>
</select>
</td>
<td>
<div ng-switch on="item.itemType">
<input type="text" ng-model="item.itemInfo" ng-switch-when="vegtables" ng-init="item.itemInfo='you selected '+ item.itemName">
</div>
</td>
</tr>
Also I had to change the Items array to match your requested naming:
$scope.Items = [{itemName: "Mango"}, {itemName: "Carrot"}, {itemName: "Apple"}];
You can parse the JSON object in a for loop to get the selected value and add the new key value pair.
angular.forEach($scope.vegetables, function(value, key){
if(value.itemName== 'Carrot')
value.iteminfo = 'you selected Carrot';
});
I guess you might be looking for something like this, if I am not wrong.

How to see both masked and unmasked values with AngularUI ui-mask and ng-repeat?

I'm using AngularUI's ui-mask directive to mask phone numbers. We'd like to save both the masked and unmasked value to the database.
I see the docs have the option to use the model-view-value="true" to store the $viewValue as the model giving us the masked value.
However since we'd like both I'd prefer a way to leave this false and access the $viewValue on my own. I see in the demo however this is for a single input. It looks like it is bound to the name of the inputs.
My issue is this is a ng-repeat and so the names vary. I got it working for a single item (you can see in the first table it works).
The last <td> is where I'm trying to show the $viewValue. I'm also trying to pass it in to the setPhoneValue function but it is undefined there also.
Edit: Created a fiddle: https://jsfiddle.net/n35u7ncz/
<form name="phone_form" id="crm_phonegrid" ng-app="crm_phonegrid" ng-controller="phoneCtrl">
<table cellpadding="2">
<tr>
<td><input type="text" name="new_phone" placeholder="Number" ng-model="addNumber.phoneNumber" onfocus="onFocusUpdateMask()" ui-mask="{{mask}}" ui-mask-placeholder ui-mask-placeholder-char="_" /></td>
<td><select name="phoneTypeSelect" ng-model="addNumber.phoneType" ng-options="option.name for option in phoneTypeOptions track by option.Value"></select></td>
<td><input type="button" ng-click="addNumber()" value="Add" /></td>
<td>{{phone_form.new_phone.$viewValue}}</td>
<td>{{addNumber.phoneNumber}}</td>
</tr>
</table>
<table cellpadding="2">
<thead>
<tr>
<th>Phone Link</th><th>Phone Number</th><th>Phone Type</th><th>Primary Flag</th><th>Mask</th><th>View</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="number in numbers">
<td><a style="color:#1160B7;text-underline-position:below" href="" ng-click="openPhoneRecord(number)">{{ number.crm_phonenumber }}</a></td>
<td><input type="text" id="crm_phonegrid_number" name="phone_number_input" model-view-value="true" ng-model="number.crm_phonenumber" ng-change="setPhoneValue(number)" ui-mask="{{number.crm_crm_country_crm_phonenumber.crm_PhoneMask}}" ui-mask-placeholder ui-mask-placeholder-char="_" /></td>
<td><select name="phoneTypeSelect" ng-model="number.crm_phonetypecode" ng-change="setValue(number)" ng-options="option.name for option in phoneTypeOptions track by option.Value"></select></td>
<td><input type="radio" name="primary" id="primaryRadio" ng-checked="number.crm_isprimary" ng-model="number.crm_isprimary" ng-change="setValue(number)" ng-value="number.crm_isprimary" ng-click="setFlag(number)" /></td>
<td>{{number.crm_crm_country_crm_phonenumber.crm_PhoneMask}}</td>
<td>View: {{phone_form.phone_number_input.$viewValue}}</td>
</tr>
</tbody>
</table>
</form>
We got this working. The trick was to use the $index to generate a unique Id for the element and then pass that to the controller.
I've updated the fiddle here: https://jsfiddle.net/n35u7ncz/3/
The general idea is that the input field needs to be tagged and have an ng-change:
<input type="text" id="phone_input_id" name="phone_input_name_{{$index}}" ng-model="number.crm_phonenumber" ng-change="setValue(number, $index)" ui-mask="{{number.crm_crm_country_crm_phonenumber.crm_PhoneMask}}" ui-mask-placeholder ui-mask-placeholder-char="_" />
And then:
$scope.setValue = function(item, index)
{
item.crm_phonenumbermasked = $scope.phone_form["phone_input_name_" + index].$viewValue;
}

adding watch for an editable row in angularjs

I am using xeditable for editing a table row in angular js. HTML Code is shown below.
<tr ng-repeat="expense in viewModel.expenses">
<td>{{expense.eid}}</td>
<td><span editable-text="expense.billAmt" e-ng-model="editForm.billAmt" e-name="billAmt" e-form="rowform">{{expense.billAmt}}</span></td>
<td><span ng-show="!rowform.$visible">{{expense.split}}</span><input type="text" ng-show="rowform.$visible" class="form-control input-sm" e-ng-model="editForm.split" ng-disabled="true" /></td>
I want to update the 'split' value in last column when the value in 'billAmt' changes. So I add a watch in angularjs but is not updating.
$scope.$watch('editForm.billAmt',function(newValue,oldValue) {
$scope.editForm.split=newValue/$scope.viewModel.members.length;
});
Is there any other way to add a watch while using xeditable?? How can I solve this?
I'd refrain from using $scope.$watch() and turn to a more efficient solution. You can use the e-ng-change directive to fire a function computing new value of $scope.editForm.split every time the billAmt value changes. It would look like this:
<tr ng-repeat="expense in viewModel.expenses">
<td>{{expense.eid}}</td>
<td><span editable-text="expense.billAmt" e-ng-model="editForm.billAmt" e-name="billAmt" e-form="rowform" e-ng-change="checkSplit();">{{expense.billAmt}}</span></td>
<td><span ng-show="!rowform.$visible">{{expense.split}}</span><input type="text" ng-show="rowform.$visible" class="form-control input-sm" e-ng-model="editForm.split" ng-disabled="true" /></td>
And in your controller add function checkSplit():
$scope.checkSplit = function(){
$scope.editForm.split = $scope.editForm.billAmt / $scope.viewModel.members.length;
}
The checkSplit() function is invoked explicitly in a response to a event of value change, whereas $scope.$watch() handler runs on every digest cycle, so you can technically save some performance too.

Combobox value isn't captured using ng -model when inside a table generated by ng -repeat (AngularJS)

This is my code
<thead>
<tr>
<th>Id Detalle_Venta</th>
<th>Id Producto</th>
<th>Producto </th>
<th>Cantidad </th>
<th>Direccion </th>
<th>Repartidor </th>
</tr>
</thead>
<tbody>
<tr ng-repeat="det in detalleVenta">
<td>{{det.id_Detalle_Venta}}</td>
<td>{{det.id_Producto}}</td>
<td>{{det.nombre_Producto}} {{det.formato}}</td>
<td>{{det.cantidad}}</td>
<td>{{det.direccion}}</td>
<td>
<select name="test" class="form form-control" ng-model="comboRepartidor" ng-change="escogerRepartidor()">
<option class="form form-control" id="idRepartidor" ng-repeat="rep in repartidores" value="{{rep.id_Repartidor}}">{{rep.nombre}}</option>
</select>
</td>
</tr>
</tbody>
The problem is in this lines:
<select name="test" class="form form-control" ng-model="comboRepartidor" ng-change="escogerRepartidor()">
<option class="form form-control" id="idRepartidor" ng-repeat="rep in repartidores" value="{{rep.id_Repartidor}}">{{rep.nombre}}</option>
</select>
Angular doesn't capture the value of select with the ng-model="comboRepartidor". The event ng-change="escogerRepartidor() shoud be show de combo value but it show Undefined. If I move the combo out of the table works fine. What's the problem?
Edited for clarity:
The problem in this case is that ng-repeat creates child scopes for each item.
comboRepartidor is in the scope of the controller, so when you place <select> outside the table, ng-model will be bound to that scope.
ng-repeat directive creates a number of items, each one having its own scope that inherits from the parent scope. comboRepartidor property in the parent scope will be visible in every one of these child scopes; however, when you change the selection of any of the dropdowns, ng-model of that will assign a property "comboRepartidor" in its own scope.
This is because scopes in angular are based on javascript prototype "inheritance".
See more about that: https://groups.google.com/forum/#!topic/angular/nGCeSXsNcYk
You can fix it, for example, by binding the model to a property in the item "det" of the array detalleVenta.

Resources