AngularJS NG-Repeat Select and set selected on page load? - angularjs

I am generating a grid thru Angular and each row will have a dropdown. I want the dropdown to populate with data from the server which is working but during page load, it needs to set the selected item of each dropdown to the value of the property it's bound to. Simple example below...
Class CategoryField
ID
Name
CategoryID = 2
Select
Option1 text=Category A value=1
Option2 text=Category B value=2 <--- This item should be selected on load.
The code i have appears to have a selected attribute on an item in each dropdown from page source but the dropdown is loading and selecting the blank item angular adds. Code below for grid...UPDATED CODE BELOW
<div ng-app="CategoryFieldsApp">
Search:<input ng-model="search" type="text" placeholder="Search" />
#using (Html.BeginForm("CategoryFields", "Maintenance", FormMethod.Post))
{
<div ng-controller="CategoryFieldsCtrl">
<table class="table table-striped table-hover">
<thead>
<tr>
<th></th>
<th width="200">Category</th>
<th ng-click="sort('Name')" width="200">Name</th>
<th width="150">Active</th>
</tr>
</thead>
<tbody id="CategoryFieldGrid">
<tr dir-paginate="categoryField in categoryFields|orderBy:sortKey:reverse|filter:search|itemsPerPage:10">
<td>
<input type="hidden" name="CategoryFields[{{$index}}].CategoryFieldID" ng-model="categoryField.CategoryFieldID" />
</td>
<td>
<input class="hdnCategoryID" type="hidden" name="CategoryFields[{{$index}}].CategoryID" />
<select ng-model="categoryField.CategoryID" ng-options="category.CategoryID as category.Name for category in categories"></select>
</td>
<td>
<input type="text" name="CategoryFields[{{$index}}].Name" ng-model="categoryField.Name" />
</td>
<td>
<input type="checkbox" class="active checkBox checkbox-inline" value="{{categoryField.Active}}" ng-model="categoryField.Active" name="CategoryFields[{{$index}}].Active" />
</td>
<td>
<input type="button" ng-click="remove($index)" value="Remove" />
</td>
</tr>
</tbody>
</table>
<dir-pagination-controls max-size="5"
direction-links="true"
boundary-links="true">
</dir-pagination-controls>
<br />
<a class="btn btn-default" ng-click="add()">Add Category Field</a>
<input class="btn-primary btn-sm" type="submit" value="Save" />
</div>
}
<script>
var App = angular.module('CategoryFieldsApp', ['angularUtils.directives.dirPagination']).controller('CategoryFieldsCtrl', function ($scope, $http) {
$http.get("#Url.Action("GetCategoryFields", "Maintenance")").success(function (response) {
$scope.categoryFields = response; //ajax request to fetch data into $scope.data
});
$http.get("#Url.Action("GetCategories", "Maintenance")").success(function (response) {
$scope.categories = response; //ajax request to fetch data into $scope.data
});
$scope.sort = function (keyname) {
$scope.sortKey = keyname; //set the sortKey to the param passed
$scope.reverse = !$scope.reverse; //if true make it false and vice versa
}
$scope.remove = function (index) {
$scope.categoryFields.splice(index, 1);
};
$scope.add = function () {
$scope.categoryFields.push({
CategoryFieldID: 0,
CategoryID: 0,
Name: '',
Active: true,
ShowRemove: true
});
};
});
//$(document).ready(function () {
// $('#CategoryFieldGrid tr').each(function (i, row) {
// var categoryID = $(row).find('.hdnCategoryID').val();
// console.log(categoryID);
// $(row).find('.ddlCategories').val(categoryID);
// });
// $('.ddlCategories').on('change', function (e) {
// var hidden = $(e.target).closest('tr').find('.hdnCategoryID');
// $(hidden).val($(e.target).closest('tr').find('.ddlCategories').val());
// });
//});

Have you considered using ng-options? It could be used to replace the explicit definition of your options:
<select ng-model="categoryField.CategoryID" ng-options="category.CategoryID as category.Name for category in categories"></select>
if you break down the expression we pass to ng-options, we're setting the value of the selected item to the CategoryID property, the visible name of each option to the category Name property, and we're passing in all the categories defined $scope.categories as options:
"category.CategoryID as category.Name for category in categories"
Here's a working example I put together: http://plnkr.co/edit/CXZaUYfqcIv7PbeUrT9j?p=preview

I was able to figure out the other side of the bindings so that the mvc model was updated for post back. I simply created a hidden field that was bound to the same property. When angular's ng-model updates, it updated the value of the hidden field also. Below is the syntax for those who needs it.
<input class="hdnCategoryFieldID" type="hidden" name="CategoryFieldApprovers[{{$index}}].CategoryFieldID" value="{{categoryFieldApprover.CategoryFieldID}}" />
<select ng-model="categoryFieldApprover.CategoryFieldID" ng-options="categoryField.CategoryFieldID as categoryField.Name for categoryField in categoryFields"></select>

Related

How can I pass a Camunda process variable containing JSON from one form to the next?

I want to get json array Data from service and then display this data inside table (with checkboxes)
after that i want to get data ( which was checked by user , i mean checkbox was clicked) and put it another json Array and then wrap this variable as camVariable in order to export it for second user form,
i have tried this in several ways but can’t accomplish my goal, what should i change to make it possible?
here is my code:
camForm.on('form-loaded', function() {
camForm.variableManager.fetchVariable('jsonData');
});
camForm.on('variables-fetched', function() {
$scope.jsonData = camForm.variableManager.variableValue('jsonData');
});
var selectedDocuments=$scope.selectedDocuments=[];
$scope.content = '';
$scope.isChecked = function(id){
var match = false;
for(var i=0 ; i < $scope.selectedDocuments.length; i++) {
if($scope.selectedDocuments[i].id == id){
match = true;
}
}
return match;
};
$scope.sync = function(bool, item){
if(bool){
// add item
$scope.selectedDocuments.push(item);
} else {
// remove item
for(var i=0 ; i < $scope.selectedDocuments.length; i++) {
if($scope.selectedDocuments[i].id == item.id){
$scope.selectedDocuments.splice(i,1);
}
}
}
};
camForm.on('submit', function() {
camForm.variableManager.createVariable({
name: 'selectedDocuments',
type: 'json',
value:$scope.selectedDocuments
});
});
function toJsonValue(arr) {
var myJSON = "";
var FinalResult = JSON.stringify(arr);
myJSON = JSON.stringify({FinalResult});
var json=$scope.json={};
json=JSON.parse(myJSON);
return json;
}
$scope.toggle = function (index){
if($scope.jsonData[index].hidethis == undefined){
$scope.jsonData[index].hidethis = true;
}else{
$scope.jsonData[index].hidethis = !$scope.jsonData[index].hidethis;
}
}
</script>
<h2>My job List</h2>
<div class="container">
<table name ="table" class="table table-hover" style="width:100%;" cellspacing="0">
<thead>
<tr>
<th style="width:80px; height:25px;"><input style="width:25px; height:25px;" type="checkbox" onclick="checkAll(this)"></th>
<th style="width:140px;">id</th>
<th style="width:305px;">organizationNameEN</th>
<th style="width:305px;">organizationNameGE</th>
<th> </th>
</tr>
</thead>
<tbody ng-repeat="item in jsonData" >
<tr>
<td><input type="checkbox" ng-change="sync(bool, item)" ng-model="bool" ng-checked="isChecked(item.id)" ></td>
<td><input style="width:305px;" type="number" id="id" ng-model="item.id" readonly /></td>
<td><input style="width:305px;" type="text" id="organizationNameEN" ng-model="item.organizationNameEN" required /></td>
<td><input style="width:305px;" type="text" id="organizationNameGE" ng-model="item.organizationNameGE" required/></td>
<td><button class="btn btn-default btn-xs" ng-click="toggle($index)"><span class="glyphicon glyphicon-eye-open"></span></button></td>
</tr>
<tr id="{{hideid + $index}}" ng-show="item.hidethis">
<td>
<label for="startDate" class="control-label">startDate</label>
<div class="controls">
<input style="width:105px;" id="strtDate" class="form-control" type="text" ng-model="item.startDate" required readonly/>
</div>
<br>
<label for="endDate" class="control-label">endDate</label>
<div class="controls">
<input style="width:105px;" id="endDate" class="form-control" type="text" ng-model="item.endDate" required readonly/>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<script>
function checkAll(bx) {
var cbs = document.getElementsByTagName('input');
for(var i=0; i < cbs.length; i++) {
if(cbs[i].type == 'checkbox') {
cbs[i].checked = bx.checked;
}
}
}
</script>
</form>
I do something similar. In my first form, the user captures some transactions. Form 2 they double-capture (new transactions which must match the first capture) and form 3 they view they successful transactions and authorise them.
I have handled this by creating a JSON array of transactions in the first form. I save this to a process variable in the on-submit event using code like this:
camForm.on('submit', function() {
// this callback is executed when the form is submitted, *before* the submit request to
// the server is executed
// creating a new variable will add it to the form submit
variableManager.createVariable({
name: 'customVariable',
type: 'String',
value: 'Some Value...',
isDirty: true
});
I retrieve it in the subsequent forms like you do in the form-loaded/variables-fetched events.
If the JSON array data is updated in subsequent forms, I save it back to the same variable using code like this:
camForm.on('submit', function(evt) {
var fieldValue = customField.val();
var backendValue = variableManager.variable('customVariable').value;
if(fieldValue === backendValue) {
// prevent submit if value of form field was not changed
evt.submitPrevented = true;
} else {
// set value in variable manager so that it can be sent to backend
variableManager.variableValue('customVariable', fieldValue);
}
});
These code snippets are from the Camunda documentation.

Selecting default value using ngModel ngRepeat, ngOptions

Hopefully someone can help.
I am developing an application using HTML AngularJs which uses ng-repeat,ng-options and ng-model and populates multiple rows based on the data in the database for a user. Each row has static data coming from DB (returned as object via restAPI) and dynamic select option for user selection. Select option is hardcoded in app.js and linked to model on HTML for DB update upon selection using update button. Each row has its own button and i can see update function is working at row level.
I want to set the default value of the drop down list dynamically as value of an element coming from database. Object is same as one being used to populate rows with static data .
Code is in the fiddle at https://jsfiddle.net/6j88L61y/4/
HTML below
<body>
<h1 align="center">User Tracker</h1>
<div ng-controller="MainController as main">
<div>
<p>Please Enter ID </p>
<p>
<input type="text" ng-model="main.model.userName"></input>
<button ng-click="main.model.getOrgList()">List State List</button>
</p>
</div>
<hr ng-show="main.model.formSubmitted"></hr>
<div>
<table class="table table-bordered" border="1">
<thead>
<tr>
<th>ID</th>
<th>User Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="org in main.model.orgList" id="{{org.id}}">
<td>{{org.id}}</td>
<td align="center">{{org.user}}</td>
<td align="center">
<select ng-model="main.model.selectedRecord.appCurrentStateSelected[$index]" ng-options="option.value as option.value for option in main.model.appCurrentStateList" ></select>
</td>
<td>
<button ng-click="main.model.updateAppDetailsList({id:org.id,userName:org.name,appCrntState:main.model.selectedRecord.appCurrentStateSelected})">Update</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
JS
"use strict";
angular.module('myApp',[]);
angular.module('myApp').service('AppModel', function( $http) {
this.userId='';
this.userName ="";
this.formSubmitted="";
this. selectedRecord ={appCurrentStateSelected:''};
this.appCurrentStateList =[{name: 'New',value:'New',id:1}, {name: 'InUse',value:'InUse',id:2},{name: 'Inactive',value:'Inactive',id:3},{name: 'Deleted',value:'Deleted',id:4}];
this.submittedAppDetailsList=[];
console.log(' json sample:'+this.submittedAppDetailsList);
var path = 'home';
var currentProtocol = location.protocol;
var host =location.host;
var apiHost = currentProtocol+'//'+host+'/api/';
console.log('API url is : ' +apiHost);
// Get method
this.getOrgList = function() {
var path = 'home/userid';
console.log(this.userName);
console.log(this.selectedRecord);
$http.get(apiHost+path+'/'+this.userName+'/')
.then(function(response) {
this.orgList =response.data;
this.formSubmitted = true;
console.log(response.data);
}.bind(this),
function(response) {
console.log(response.data);
});
}
// Post method
this.updateAppDetailsList = function(appdetailsList) {
var path = 'home/update';
console.log(this.selectedRecord);
$http.post(apiHost+'home/update/',appdetailsList)
.then(function(response) {
this.submittedAppDetailsList.push(response.data);
this.formSubmitted = false;
console.log(response.data);
}.bind(this),
function(response) {
console.log('Error : '+response.data);
});
}
});
angular.module('myApp').controller('MainController', ['AppModel', function (AppModel) {
this.model = AppModel;
}]);

How to bind data based dropdown selection in multiple rows in table grid

i have table grid with one customer dropdown, and two input values and + buton to add new row
am able to bind data to inputs on dropdown change,
if i select madhu , madhu data binding.
then am adding row,
then if i select bhanu data binding correctly but previous row madhu data going empty,
again i add row and select madhu, data binding to all madhu selected dropdown rows, and remaining empty
$scope.rvm = [{}];
$scope.GetAccountBalance = function (c) {
//getting pending data from database based on customer
var getPendingData = ReceiptsService.GetPendings(c);
getPendingData.then(function (d) {
var Testdata = d.data;
$scope.GetEmployeeDetail = function (c) {
var result = $.grep(Testdata, function (e) { return e.Party == c; });
$scope.testRvm = result;
return $scope.testRvm[0];
};
});
//adding row on plus click
$scope.addRow = function (index,c) {
if ($scope.rvm.length == (index + 1)) {
$scope.rvm.push( {
});
}
}
view
<table id="myTable">
<tr>
<th>Customer</th>
<th>Pendings</th>
<th>Pending Value</th>
</tr>
<tr ng-repeat="r in rvm" #*ng-init="$index"*# #*ng- ng-class-odd="'odd'" ng-class-even="'even'"*#>
<td>
<select ng-model="c" ng-change="GetAccountBalance(c)" ng-options="c.ID as c.Name for c in customer track by c.ID" style="width:150px;height:22px;" name="tCustomer" required>
<option value="">select Customer</option>
</select>
</td>
<td>
<input type="text" ng-value="0.00" ng-model="GetEmployeeDetail(c).Pendings" class="input-large" name="tPendings" readonly />
</td>
<td>
<input type="text" ng-value="0.00" ng-model="GetEmployeeDetail(c).PendingsAdjusted" ng-model-onblur ng-change="GetTotalAmount()" class="input-large" name="tPendingsAdjusted" />
</td>
<td ng-if="$last">
<a href="#">
<span class="glyphicon glyphicon-plus orange" ng-click="addRow($index,c)"></span>
</a>
</td>
</tr>
</table>

How to get the text of a binding inside a repeater in Protractor

Using this example web, how could I get the value of {{result.first}} with Protractor? That one is inside a repeater, so I can't accesss it by a binding.
This is an example where I want to use that value.
<div ng-controller="CalcCtrl" class="container">
<div>
<h3>Super Calculator</h3>
<form class="form-inline">
<input ng-model="first" type="text" class="input-small"/>
<select ng-model="operator" class="span1"
ng-options="value for (key, value) in operators">
</select>
<input ng-model="second" type="text" class="input-small"/>
<button ng-click="doAddition()" id="gobutton" class="btn">Go!</button>
<h2>{{latest}}</h2>
</form>
</div>
<h4>History</h4>
<table class="table">
<thead><tr>
<th>Time</th>
<th>Expression</th>
<th>Result</th>
</tr></thead>
<tr ng-repeat="result in memory">
<td>
{{result.timestamp | date:'mediumTime'}}
</td>
<td>
<span>{{result.first}}</span>
<span>{{result.operator}}</span>
<span>{{result.second}}</span>
</td>
<td>{{result.value}}</td>
</tr>
</table>
</div>
And this is the Protractor code:
describe('Protractor Demo App', function() {
var firstNumber = element(by.model('first'));
var secondNumber = element(by.model('second'));
var goButton = element(by.id('gobutton'));
var latestResult = element(by.binding('latest'));
var history = element.all(by.repeater('result in memory'));
function add(a, b) {
firstNumber.sendKeys(a);
secondNumber.sendKeys(b);
goButton.click();
}
beforeEach(function() {
browser.get('http://juliemr.github.io/protractor-demo/');
});
it('should have a history', function() {
add(1, 2);
add(3, 4);
expect(history.count()).toEqual(2);
});
});
read more in the API for protractor, and about repeaters
element.all(by.repeater('result in results')).first()
element.all(by.repeater('result in results')).get(0)
both will return the first result, for each element inside of that, chain it with element.all(by.repeater('result in results')).first().element...

AngularJS update table data

I have to create a simple CRUD page with AngularJS.
I am able to add data with save button. Now when clicked on edit link form should get filled with the values with the row value. I am using angular's '.copy' object to get data into form.
For now text box getting valuse successfully but the select box not updating. And also want to make the select menu disable once clicked on edit link.
Below is the code:
apsApp.controller('clusterController', function ($scope ) {
var uid = 1;
$scope.clusters=[
{id:0, 'cluster':''},
];
$scope.environments = [
{name: 'DEV'},
{name: 'PROD'},
{name: 'QA'},
{name: 'Linux_Dev'}
];
$scope.selectedEnvironment = $scope.environments[0];
//add new cluster
$scope.saveNewClust = function() {
if($scope.clust.id == null) {
//if this is new cluster, add it in clusters array
$scope.clust.id = uid++;
$scope.clust.environment = $scope.selectedEnvironment.name;
console.log($scope.clust);
$scope.clusters.push($scope.clust);
}
else {
//for existing cluster, find this cluster using id and update it.
for(i in $scope.clusters) {
if($scope.clusters[i].id == $scope.clust.id) {
$scope.clusters[i] = $scope.clust;
}
}
};
//clear the add clusters form
$scope.clust = {};
};
//delete cluster
$scope.remove = function(id) {
//search cluster with given id and delete it
for(i in $scope.clusters) {
if($scope.clusters[i].id == id) {
confirm("This Cluster will get deleted permanently");
$scope.clusters.splice(i,1);
$scope.clust = {};
}
}
};
$scope.edit = function(id) {
//search cluster with given id and update it
for(i in $scope.clusters) {
if($scope.clusters[i].id == id) {
//we use angular.copy() method to create copy of original object
$scope.clust = angular.copy($scope.clusters[i]);
}
}
};
});
HTML Template is:
<div class="menuContent">
<div class="maincontent">
<div class="article">
<form>
<section>
<!-- Environment -->
<div class="col-md-6">
<label>Environment:</label>
<select ng-model="selectedEnvironment" class="form-control" ng-options="environment.name for environment in environments">
<option value='' disabled style='display:none;'>
Select Environment
</option>
</select>
</div>
<!-- cluster Name -->
<div class="col-md-6">
<label>Cluster Name:</label>
<input type="text" class="form-control" name="clusterName" placeholder="Cluster" ng-model="clust.cluster" required>
<br/>
<input type="hidden" ng-model="clust.id" />
</div>
</section>
<!-- submit button -->
<section class="col-md-12">
<button type="button" class="btn btn-default pull-right" ng-click="saveNewClust()">Save Cluster</button>
</section>
</form>
</div>
<!-- table -->
<div class="article">
<table class="table table-bordered table-striped">
<tr>
<th colspan="4">
<div class="pull-left">Cluster Info</div>
</th>
</tr>
<tr>
<th>#</th>
<th>Environment</th>
<th>Cluster</th>
<th>Edit</th>
</tr>
<tr ng-repeat="clust in clusters">
<td>{{}}</td>
<td>{{clust.environment}}</td>
<td>{{clust.cluster}}</td>
<td>
<span class="glyphicon glyphicon-edit" ></span> |
<span class="glyphicon glyphicon-trash"></span>
</td>
</tr>
</table>
</div>
</div>
</div>
I went over your code and changed a lot. Here is the new javascript part:
var app = angular.module('myApp', []);
app.controller('clusterController', function ($scope) {
var uid = 0;
$scope.clusters = [];
$scope.environments = [
{name: 'DEV'},
{name: 'PROD'},
{name: 'QA'},
{name: 'Linux_Dev'}
];
$scope.select = {};
$scope.select.selectedEnvironment = $scope.environments[0];
$scope.select.buttonLabel = 'Save Cluster';
$scope.select.showCancel = false;
//add new cluster
$scope.saveNewClust = function () {
if ($scope.select.id == undefined) {
//if this is new cluster, add it in clusters array
$scope.clusters.push({
id: uid++,
cluster: $scope.select.cluster,
environment: $scope.select.selectedEnvironment
});
} else {
//for existing cluster, find this cluster using id and update it.
$scope.clusters[$scope.select.id].cluster = $scope.select.cluster;
$scope.select.id = undefined;
$scope.select.buttonLabel = 'Save Cluster';
$scope.select.showCancel = false;
};
//clear the add clusters form
$scope.select.cluster = "";
$scope.select.selectedEnvironment = $scope.environments[0];
};
//delete cluster
$scope.remove = function (id) {
//search cluster with given id and delete it
for (i in $scope.clusters) {
if ($scope.clusters[i].id == id) {
confirm("This Cluster will get deleted permanently");
$scope.clusters.splice(i, 1);
$scope.clust = {};
}
}
};
$scope.cancelUpdate = function () {
$scope.select.buttonLabel = 'Save Cluster';
$scope.select.showCancel = false;
$scope.select.id = undefined;
$scope.select.cluster = "";
$scope.select.selectedEnvironment = $scope.environments[0];
};
});
First of all, set the var uid to 0. Don't start from 1, because the array, which you want to check starts also indexing from 0. Secondly, I added an object which persists the data for the form, where the user chooses the environment and types the name for the cluster. The object is assigned to $scope.select. There we save the preselect environment for the select box. I also save the name "Save Cancel" here, because I made it so after editing one cluster, the label of the button changes from "Save Cluster" to "Update Cluster". Like this your users will know, when exactly they edit a cluster or when they add a cluster. Furthermore, while editing a cluster, another button Cancel Update appears, so the user can also stop editing a cluster. If this button should show or not is saved in $scope.select.showCancel.
The saveNewClust function handles both routines, one for saving and one for updating. The function for editing is therefore removed. I added another function cancelUpdate, which is called in case the user cancels the action.
This is the HTML part. I just updated the form to use the new select object and the ng-click routine when the user clicks on edit. The select box is now surrounded with ng-switch. If the user edits an existing cluster, the select box is disabled.
<div ng-controller="clusterController" class="menuContent">
<div class="maincontent">
<div class="article">
<form>
<section>
<!-- Environment -->
<div class="col-md-6">
<label>Environment:</label>
<span ng-switch on="select.showCancel">
<select ng-switch-when="true" disabled ng-model="select.selectedEnvironment" class="form-control"
ng-options="environment.name for environment in environments">
<option value='' disabled style='display:none;'>
Select Environment
</option>
</select>
<select ng-switch-default ng-model="select.selectedEnvironment" class="form-control"
ng-options="environment.name for environment in environments">
<option value='' disabled style='display:none;'>
Select Environment
</option>
</select>
</span>
</div>
<!-- cluster Name -->
<div class="col-md-6">
<label>Cluster Name:</label>
<input type="text" class="form-control" name="clusterName" placeholder="Cluster"
ng-model="select.cluster" required>
<br/>
<input type="hidden" ng-model="clust.id"/>
</div>
</section>
<!-- submit button -->
<section class="col-md-12">
<button type="button" class="btn btn-default pull-right" ng-click="saveNewClust()">{{select.buttonLabel}}
</button>
<button ng-show="select.showCancel" type="button" class="btn btn-default pull-right" ng-click="cancelUpdate()">Cancel update
</button>
</section>
</form>
</div>
<!-- table -->
<div class="article">
<table class="table table-bordered table-striped">
<tr>
<th colspan="4">
<div class="pull-left">Cluster Info</div>
</th>
</tr>
<tr>
<th>#</th>
<th>Environment</th>
<th>Cluster</th>
<th>Edit</th>
</tr>
<tr ng-repeat="clust in clusters">
<td>{{}}</td>
<td>{{clust.environment.name}}</td>
<td>{{clust.cluster}}</td>
<td>
<span class="glyphicon glyphicon-edit"></span>Edit
|
<a href="" ng-click="remove(clust.id)" title="Delete"><span
class="glyphicon glyphicon-trash"></span>Delete</a>
</td>
</tr>
</table>
</div>
</div>
</div>
Here is the jsfiddle for testing: http://jsfiddle.net/hv7Pb/

Resources