AngularJS - dynamic rows and columns with a two way bound custom control - angularjs

I am new to Angular and am stuck on my next step of development which is to have a custom control bound to a dynamic row-column table.
I have a simple fiddle here which shows how to data bind a custom control:
http://jsfiddle.net/paull3876/WPWAc/2/
And another fiddle here which is my starting point, shows how to bind a row-column table with data driven column names:
http://jsfiddle.net/paull3876/3mz5L/1/
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>Angular</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.min.js"></script>
<script>
var app = angular.module("myApp", []);
function datacontroller($scope, $http)
{
$scope.mydata = [{f1:"r1f1", f2:"r1f2"}, {f1:"r2f1",f2:"r2f2"}, {f1:"r3f1",f2:"r3f2", f3:"Hello"}];
$scope.mycolumns = [{name:"Column 1", fieldname:"f1"}, {name:"Column 2", fieldname:"f2"}, {name:"Column 3", fieldname:"f3"}];
$scope.showdata = function()
{
alert(JSON.stringify($scope.mydata));
}
$scope.getcolumnname = function(cell)
{
return cell.fieldname;
}
}
</script>
</head>
<body>
<div data-ng-controller="datacontroller">
<table>
<tr>
<td data-ng-repeat="cell in mycolumns">{{cell.name}}</td>
</tr>
<tr data-ng-repeat="record in mydata">
<td data-ng-repeat="cell in mycolumns">
<input type="text" data-ng-init="mycol=getcolumnname(cell);" data-ng-model="record[mycol]" />
</td>
</tr>
</table>
<br />
<input type="button" value="Save Data" ng-click="showdata()" />
<br />
<br />
</div>
</body>
</html>
Now I want to take the second fiddle above, and replace the INPUT element with a user control which has two way data binding. I've spend a day on this already and can't get it working, so I guess I'm also needing some help on the concepts here
An explanation on top of a solution greatly appreciated.
http://jsfiddle.net/paull3876/rc7uC/1/

Here's the full working solution, I hope someone finds it useful.
<!DOCTYPE html>
<html >
<head>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="expires" content="-1">
<title>Angular</title>
<!--scr ipt src="htt ps://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.min.js"></script-->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.js"></script>
</head>
<body>
<div data-ng-app="myApp" data-ng-controller="datacontroller">
<table>
<tr>
<td data-ng-repeat="cell in mycolumns">{{cell.name}}</td>
</tr>
<tr data-ng-repeat="record in mydata">
<td data-ng-repeat="cell in mycolumns">
<mycontrol data-my-model="record[cell.fieldname]"></mycontrol>
</td>
</tr>
</table>
<br />
<input type="button" value="Save Data" ng-click="showdata()" />
<input type="button" value="Change Divs" onclick="changediv()" />
<input type="button" value="Change Scope" onclick="changescope()" />
<br />
<br />
</div>
</body>
</html>
<script>
var globalscope;
var app = angular.module("myApp", [])
.directive("mycontrol", function ($compile) {
return {
restrict: "E",
scope: {
value: "=myModel"
},
template: "<div data-ng-bind='value'/>"
};
});
function datacontroller($scope, $http) {
globalscope = $scope;
var mydata = [];
// generate some data
for (var i = 0; i < 20; i++)
{
var row = {
f1:"f1x" + i,
f2:"f2x" + i,
f3:"f3x"+i,
f4:"f4x"+i,
f5:"f5x"+i,
f6:"f6x"+i,
f7:"f7x"+i,
f8:"f8x"+i,
f9:"f9x"+i,
f10:"f10x"+i,
f11:"f11x"+i,
f12:"f12x"+i,
f13:"f13x"+i
};
mydata.push(row);
}
// push it to angulars scope
$scope.mydata = mydata;
// generate some metadata for the columns
$scope.mycolumns = [{
name: "Column 1",
fieldname: "f1",
type: "input"
}, {
name: "Column 2",
fieldname: "f2",
type: "textarea"
}, {
name: "Column 3",
fieldname: "f3",
type: "div"
}, {
name: "Column 4",
fieldname: "f4",
type: "div"
}, {
name: "Column 5",
fieldname: "f5",
type: "div"
}, {
name: "Column 6",
fieldname: "f6",
type: "div"
}, {
name: "Column 7",
fieldname: "f7",
type: "div"
}, {
name: "Column 8",
fieldname: "f8",
type: "div"
}, {
name: "Column 9",
fieldname: "f9",
type: "div"
}, {
name: "Column 10",
fieldname: "f10",
type: "div"
}, {
name: "Column 11",
fieldname: "f11",
type: "div"
}, {
name: "Column 12",
fieldname: "f12",
type: "div"
}, {
name: "Column 13",
fieldname: "f13",
type: "div"
}];
$scope.showdata = function () {
alert(JSON.stringify($scope.mydata));
};
$scope.getcolumnname = function (cell) {
return cell.fieldname;
};
}
function changediv()
{
// this will change the data in the divs but it won't reflect back to the scope
var divs = document.getElementsByClassName("fred");
for (var i = 0; i < divs.length; i++)
{
var div = divs[i];
div.innerText = "XXXX";
}
}
function changescope()
{
// shows how to change data programmatically and have it reflected in the controls and in the scope data
var scope = globalscope;
for (r in scope.mydata)
{
scope.mydata[r].f3 = "UUUU";
}
scope.$apply();
}
</script>

Related

Filtering on a formatted datefield

I've started recently with AngularJS, and I've come across this problem.
I'm filtering a list with a Angular Filter object. It all works, but I want to be able to type a date value to filter the date column. Problem is, the date that comes from my webservice is (ofcourse) in another format than the showed date.
Here is an example:
View:
Name: <input type="text" ng-model="search.Name"><br>
Date: <input type="text" ng-model="search.Date"><br>
<table>
<tr ng-repeat="item in filtered = (list | filter:search)">
<td>{{item.Name}}</td>
<td>{{item.Date | date:'dd-MM-yyyy'}}</td>
</tr>
</table>
Controller:
app.controller('MainCtrl', function($scope) {
$scope.list = [{
Name: "Item1",
Date: "2018-08-06T13:43:11.82Z"
},{
Name: "Item2",
Date: "2018-08-05T13:43:11.82Z"
},{
Name: "Item3",
Date: "2018-08-04T13:43:11.82Z"
},{
Name: "Item4",
Date: "2018-08-03T13:43:11.82Z"
}
];
$scope.search = {};
$scope.$watch('search', function (newVal, oldVal) {
$scope.filtered = filterFilter($scope.list, newVal);
}, true);
});
working example:
http://plnkr.co/edit/O7j1DAzoxArHK4mnjyeP?p=info
How can I alter this, so I can type the date-value as formatted?
At this case you should create custom filter:
angular.module('plunker', []).controller('MainCtrl', function($scope) {
$scope.list = [{
Name: "Item1",
Quantity: 21,
Date: "2018-08-06T13:43:11.82Z"
}, {
Name: "Item2",
Quantity: 20,
Date: "2018-08-05T13:43:11.82Z"
}, {
Name: "Item3",
Quantity: 31,
Date: "2018-08-04T13:43:11.82Z"
}, {
Name: "Item4",
Quantity: 25,
Date: "2018-08-03T13:43:11.82Z"
}];
$scope.search = {};
}).filter('custom', function() {
return function(array, search) {
function Norm(x) {
return (x + '').toLocaleLowerCase();
}
return array.filter(function(x) {
for (var prop in search) {
if (prop != 'Date' && search[prop] &&
Norm(x[prop]).indexOf(Norm(search[prop])) == -1)
return false;
}
if (x.Date) {
var formatted = x.Date.substring(0, 10).split('-').reverse().join('-');
if (search.Date && !formatted.startsWith(search.Date))
return false;
return true;
}
});
}
});
table,
th,
td {
border: 1px solid black;
border-collapse: collapse;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js">
</script>
<body ng-app='plunker' ng-controller="MainCtrl">
Name: <input type="text" ng-model="search.Name">
<br> Quantity: <input type="text" ng-model="search.Quantity">
<br> Date: <input type="text" ng-model="search.Date">
<br>
<table>
<tr ng-repeat="item in list | custom : search | orderBy : 'Quantity'">
<td>{{item.Name}}</td>
<td>{{item.Quantity}}</td>
<td>{{item.Date | date:'dd-MM-yyyy'}}</td>
</tr>
</table>
</body>
Html:
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset="utf-8" />
<title>AngularJS</title>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.2.x" src="https://code.angularjs.org/1.2.28/angular.js" data-semver="1.2.28"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
Name:
<input type="text" ng-model="search.Name">
<br>
Date:
<input type="text" ng-model="search.Date">
<table>
<tr ng-repeat="item in list2 | filter : search.Date">
<td>{{item.Name}}</td>
<td>{{item.Date}}</td>
</tr>
</table>
</body>
</html>
Js:
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope, $filter) {
const list = [{
Name: "Item1",
Date: "2018-08-06T13:43:11.82Z"
},{
Name: "Item2",
Date: "2018-08-05T13:43:11.82Z"
},{
Name: "Item3",
Date: "2018-08-04T13:43:11.82Z"
},{
Name: "Item4",
Date: "2018-08-03T13:43:11.82Z"
}
];
$scope.list2 = list.map(x => (
{
Name: x.Name,
Date: $filter('date')(x.Date, 'dd-MM-yyyy')
})
);
});

make JSON array from dynamic form data angular

i have a dynamic form in angular. and i want to send the response as json. how do i generate JSON from the form?
here's the complete code,I have to get json, and post it to some api.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="dyf" ng-submit="submit()">
<form name="userFormOne" novalidate>
<table>
<tr class="form-group" ng-repeat="x in names">
<td><label>{{ x.Field }}</label>
</td><td><input type="text" class="form-control" placeholder="{{x.Comment}}" required>
</td>
</tr>
</table>{{data}}
</form>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('dyf', function($scope, $http) {
$http.get("http://localhost:5000/gu")
.then(function (response) {$scope.names = response.data;console.log(response.data);});
$scope.data ={};
});
</script>
</body>
</html>
In AngularJs we use ng-model to bind inputs value to our controller, sample:
This full sample to figure out how to create a simple form, from array and how to send it as JSON to your API.
Note: On submit check your console, and see the objects value.
var app = angular.module("app", []);
app.controller("ctrl",
function ($scope) {
var options = [
{ name: "a" },
{ name: "b" },
{ name: "c" }
];
$scope.names = [
{ id: 1, field: "insert name", name: "name", placeholder: "your name is", value:null, type:"text" },
{ id: 2, field: "insert phone", name: "phone", placeholder: "your phone is", value: null, type: "tel" },
{ id: 3, field: "insert age", name: "age", placeholder: "your age is", value: null, type: "number", min: 0, max: 20 },
{ id: 4, field: "select country", name: "country", placeholder: "your country is", value: null, type: "select", options: options }
];
$scope.sendMe = function() {
console.log($scope.names);
}
});
<!DOCTYPE html>
<html ng-app="app" ng-controller="ctrl">
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<form name="userFormOne" novalidate>
<table>
<tr class="form-group" ng-repeat="x in names">
<td>
<label>{{ x.field }}</label>
</td>
<td ng-if="x.type != 'select'">
<input type="{{x.type}}" min="{{x.min}}" max="{{x.max}}" ng-model="x.value" name="{{x.name}}" placeholder="{{x.placeholder}}" ng-required="true">
{{x.value}}
</td>
<td ng-if="x.type == 'select'">
<select ng-model="x.value" name="{{x.name}}" ng-options="item as item.name for item in x.options">
</select>
{{x.value}}
</td>
</tr>
</table>
<button ng-disabled="userFormOne.$invalid" ng-click="sendMe()">sendMe</button>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</body>
</html>

AngularJS filter items by array of properties (checkbox)

I would like to filter the results by multiple properties.
My code:
(function () {
'use strict';
angular.
module('myApp', []).
filter('byFeatures', byFeatures).
controller('MyCtrl', MyCtrl);
function byFeatures() {
return function (items, conditions) {
if (Object.getOwnPropertyNames(conditions).length === 0) {
return items;
}
var filtered = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
angular.forEach(item.features, function (feature) {
if (conditions[feature.name] !== undefined && conditions[feature.name][feature.value] !== undefined) {
if (conditions[feature.name][feature.value]) {
//filtered.push(item);
filtered[item.id] = item;
}
}
});
}
//console.log(filtered);
return filtered;
};
};
function MyCtrl($scope, $filter) {
$scope.allProducts = [{
id: 0,
name: "Product A",
features: [{
name: "Brand",
value: "Apple"
},
{
name: "Memory",
value: "16"
},
{
name: "Color",
value: "Black"
}
]
},
{
id: 1,
name: "Product B",
features: [{
name: "Brand",
value: "Apple"
},
{
name: "Memory",
value: "32"
},
{
name: "Color",
value: "Black"
}
]
},
{
id: 2,
name: "Product C",
features: [{
name: "Brand",
value: "Nokia"
},
{
name: "Memory",
value: "16"
},
{
name: "Color",
value: "Black"
}
]
},
{
id: 3,
name: "Product A",
features: [{
name: "Brand",
value: "Samsung"
},
{
name: "Memory",
value: "16"
},
{
name: "Color",
value: "Black"
}
]
},
];
$scope.filters = [{
name: "Brand",
values: [
"Apple",
"Nokia",
"Samsung",
]
},
{
name: "Memory",
values: [
"16",
"32",
]
},
];
$scope.currentFilter = {};
$scope.$watch('currentFilter', function (newValue, oldValue, scope) {
//console.log(newValue);
$scope.products = $filter('byFeatures')($scope.allProducts, newValue);
}, true);
};
}());
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="robots" content="noindex, nofollow">
<meta name="googlebot" content="noindex, nofollow">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<title></title>
</head>
<body ng-app="myApp" class="ng-scope">
<div ng-controller="MyCtrl" style="width: 100%;">
<div style="width: 50%; float: left;">
<h2>Available Phones</h2>
<div ng-repeat="product in products">
<h3>
{{ product.name }}
</h3>
<ul>
<li ng-repeat="feature in product.features">
{{feature.name}} : {{feature.value}}
</li>
</ul>
</div>
</div>
<div style="width: 50%; float: left;">
<h2>Filters</h2>
<pre>{{currentFilter|json}}</pre>
<div ng-repeat="filter in filters">
<span>{{filter.name}}</span>
<ul>
<li ng-repeat="value in filter.values">
<input type="checkbox" ng-model="currentFilter[filter.name][value]"> {{value}}<br>
</li>
</ul>
</div>
</div>
</div>
</body></html>
If i filter by brand "Apple" are displayed 2 phones with brand "apple" (16 and 32 memory) - its ok. But if i add second filter by memory "16" - will must display only 1 phone apple with memory "16".
How to do it? . Link to JSFiddle
The problem is that you are doing the opposite from what you want: You are checking that the product contains a valid property for one of the items (Brand or Memory). What we need to do is check if the product has a valid property for all the items (Brand and Memory).
It would be enough to change the loop inside the function byFeatures in order to find every relevant condition (When its value is true!) and make sure that our product has one of the selected properties for each, Brand and Memory. Here you can see the right snippet:
(function () {
'use strict';
angular.
module('myApp', []).
filter('byFeatures', byFeatures).
controller('MyCtrl', MyCtrl);
function byFeatures() {
return function (items, conditions) {
if (Object.getOwnPropertyNames(conditions).length === 0) {
return items;
}
var filtered = [];
for (var i = 0; i < items.length; i++) {
var item = items[i],
hasProperties = true;
angular.forEach(conditions, function (value, key) {
for (var i = 0; i < item.features.length; i++) {
if (item.features[i].name === key && (!value.hasOwnProperty(item.features[i].value) || !value[item.features[i].value])) {
for (var j in value) {
if (value[j]) {
hasProperties = false;
}
}
}
}
});
if (hasProperties) {
filtered.push(item);
}
}
//console.log(filtered);
return filtered;
};
};
function MyCtrl($scope, $filter) {
$scope.allProducts = [{
id: 0,
name: "Product A",
features: [{
name: "Brand",
value: "Apple"
},
{
name: "Memory",
value: "16"
},
{
name: "Color",
value: "Black"
}
]
},
{
id: 1,
name: "Product B",
features: [{
name: "Brand",
value: "Apple"
},
{
name: "Memory",
value: "32"
},
{
name: "Color",
value: "Black"
}
]
},
{
id: 2,
name: "Product C",
features: [{
name: "Brand",
value: "Nokia"
},
{
name: "Memory",
value: "16"
},
{
name: "Color",
value: "Black"
}
]
},
{
id: 3,
name: "Product A",
features: [{
name: "Brand",
value: "Samsung"
},
{
name: "Memory",
value: "16"
},
{
name: "Color",
value: "Black"
}
]
},
];
$scope.filters = [{
name: "Brand",
values: [
"Apple",
"Nokia",
"Samsung",
]
},
{
name: "Memory",
values: [
"16",
"32",
]
},
];
$scope.currentFilter = {}; //$scope.filters;
$scope.$watch('currentFilter', function (newValue, oldValue, scope) {
$scope.products = $filter('byFeatures')($scope.allProducts, newValue);
}, true);
};
}());
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="robots" content="noindex, nofollow">
<meta name="googlebot" content="noindex, nofollow">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="js/script.js"></script>
<title></title>
</head>
<body ng-app="myApp" class="ng-scope">
<div ng-controller="MyCtrl" style="width: 100%;">
<div style="width: 50%; float: left;">
<h2>Available Phones</h2>
<div ng-repeat="product in products">
<h3>
{{ product.name }}
</h3>
<ul>
<li ng-repeat="feature in product.features">
{{feature.name}} : {{feature.value}}
</li>
</ul>
</div>
</div>
<div style="width: 50%; float: left;">
<h2>Filters</h2>
<pre>{{currentFilter|json}}</pre>
<div ng-repeat="filter in filters">
<span>{{filter.name}}</span>
<ul>
<li ng-repeat="value in filter.values">
<input type="checkbox" ng-model="currentFilter[filter.name][value]"> {{value}}<br>
</li>
</ul>
</div>
</div>
</div>
</body>
</html>
I also changed the way you were adding the new product to the filtered array. Otherwise, if the ID of the only item is 2, the array would keep the first 2 positions as 'undefined' and this would cause troubles through the ngRepeat iterations

How to modify row content in angular js?

HI i Learning Angular js and i have created a project.
All most i have do but i m face one problum .
My Data is repeat throw tr and i have inline editable option Type, Description, Priority
if i have click in both link than show to editable mode but show all i want to show only one how to do this
HTML Code
<body ng-app="myApp" ng-controller="myCtrl">
<table class="table ">
<tbody>
<tr class="list-row" ng-repeat="form in todoData">
<td class="list-row-content">
<p>
<a>{{form.title}}</a>
</p>
<span>
Type: <a ng-show="!typeAction" ng-click="selectTypeAction($index)">{{selectedAction.label}}</a>
<select ng-change="changeTypeAction()" ng-show="typeAction" ng-model="selectedAction" ng-options="opt as opt.label for opt in options"></select>
</span>
<span class="tag-sec">
Description: <a ng-show="!typeDescAction" ng-click="desTypeAction($index)">{{desType}}</a>
<input type="text" value="" ng-show="typeDescAction" ng-model="desType" ng-blur="changeDesAction($index)" />
</span>
<span class="tag-sec">
Priority: <a ng-show="!typePriAction" ng-click="priTypeAction($index)">{{priAction.label}}</a>
<select ng-change="changePriTypeAction()" ng-show="typePriAction" ng-model="priAction" ng-options="opt as opt.label for opt in priOptions"></select>
</span>
</td>
</tr>
</tbody>
</table>
</body>
Angular jS code
var myApp = angular.module('myApp', []);
myApp.controller('myCtrl', function($scope){
/* ************************************************ */
$scope.todoData = [
{'title':'Create Google Logo'},
{'title':'Talk to XYZ about Google'},
{'title':'Testing Google Coding'},
{'title':'Create Documentaion about Google'},
{'title':'Create Client Sample form'},
{'title':'Modify Top Navigation'},
{'title':'Change Footer text and color'},
{'title':'Redesign Google Dashboard'}
]
$scope.options = [
{ label: 'Action Item', value: 1 },
{ label: 'Defect', value: 2 },
{ label: 'Meeting Invite', value: 3 },
{ label: 'Issue', value: 4 },
{ label: 'Enhancement', value: 5 },
{ label: 'Risk', value: 6 },
{ label: 'Proposal', value: 7 }
];
$scope.selectedAction =$scope.options[1];
$scope.selectTypeAction = function(index){
console.log(index);
$scope.typeAction = true;
};
$scope.changeTypeAction = function(){
$scope.typeAction = false;
}
$scope.desType = 'Google logo needs a new concept';
$scope.desTypeAction = function(idx){
$scope.typeDescAction = true;
}
$scope.changeDesAction = function(idx){
$scope.typeDescAction = false;
}
$scope.priOptions = [
{ label: 'High', value: 1 },
{ label: 'Medium', value: 2 },
{ label: 'Low', value: 3 }
];
$scope.priAction =$scope.priOptions[1];
$scope.priTypeAction = function(index){
console.log(index);
$scope.typePriAction = true;
};
$scope.changePriTypeAction = function(){
$scope.typePriAction = false;
}
/* ************************************************ */
});
[Plunker URL][1]
Plunker Link
Try this Way go by index by index not as global scope
var myApp = angular.module('myApp', []);
myApp.controller('myCtrl', function($scope){
/* ************************************************ */
$scope.todoData = [
{'title':'Create google Logo','discription':'google logo needs a new concept'},
{'title':'Talk to Sandeep about google','discription':'google logo needs a new concept'},
{'title':'Testing google Coding','discription':'google logo needs a new concept'},
{'title':'Create Documentaion about google','discription':'google logo needs a new concept'},
{'title':'Create Client Sample form','discription':'google logo needs a new concept'},
{'title':'Modify Top Navigation','discription':'google logo needs a new concept'},
{'title':'Change Footer text and color','discription':'google logo needs a new concept'},
{'title':'Redesign google Dashboard','discription':'google logo needs a new concept'}
]
$scope.options = [
{ label: 'Action Item', value: 1 },
{ label: 'Defect', value: 2 },
{ label: 'Meeting Invite', value: 3 },
{ label: 'Issue', value: 4 },
{ label: 'Enhancement', value: 5 },
{ label: 'Risk', value: 6 },
{ label: 'Proposal', value: 7 }
];
$scope.selectedAction =$scope.options[1];
$scope.selectTypeAction = function(index){
$scope.todoData[index].typeAction = true;
};
$scope.changeTypeAction = function(index){
$scope.todoData[index].typeAction = false;
}
$scope.desTypeAction = function(idx){
$scope.todoData[idx].typeDescAction = true;
}
$scope.changeDesAction = function(idx){
$scope.todoData[idx].typeDescAction = false;
}
$scope.priOptions = [
{ label: 'High', value: 1 },
{ label: 'Medium', value: 2 },
{ label: 'Low', value: 3 }
];
$scope.priAction = $scope.priOptions[1];
$scope.priTypeAction = function(index){
$scope.todoData[index].typePriAction = true;
};
$scope.changePriTypeAction = function(index){
$scope.todoData[index].typePriAction= false;
}
/* ************************************************ */
});
HTML CODE
<tr ng-repeat="form in todoData">
<td >
<p><a>{{form.title}}</a></p>
<span class="tag-sec">
Type: <a ng-show="!form.typeAction" ng-click="selectTypeAction($index)">{{selectedAction.label}}</a>
<select ng-change="changeTypeAction($index)" ng-show="form.typeAction" ng-model="selectedAction" ng-options="opt as opt.label for opt in options"></select>
</span>
<span class="tag-sec">
Description: <a ng-show="!form.typeDescAction" ng-click="desTypeAction($index)">{{form.discription}}</a>
<input type="text" ng-show="form.typeDescAction" ng-model="form.discription" ng-blur="changeDesAction($index)" />
</span>
<span class="tag-sec">
Priority: <a ng-show="!form.typePriAction" ng-click="priTypeAction($index)">{{priAction.label}}</a>
<select ng-change="changePriTypeAction($index)" ng-show="form.typePriAction" ng-model="priAction" ng-options="opt as opt.label for opt in priOptions"></select>
</span>
</td>
</tr>
Plunker Demo URL
Here is plunker for you.
You should keep flag for every individual properties, so define array for these flag like this,
$scope.typeAction = [];
$scope.typeDescAction = [];
$scope.typePriAction = [];
and set them by using $index property of ng-repeat, for example
ng-show="!typeAction[$index]"
and you should edit your functions by sending index all time, for example,
$scope.changeTypeAction = function(index){
$scope.typeAction[index] = false;
}
I have the simple one catch the context (using 'this') of the particular element and set the local variable of ng -repeat typeAction.
<!DOCTYPE html>
<html>
<head>
<link data-require="bootstrap-css#*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
<script data-require="angular.js#*" data-semver="1.4.0-beta.5" src="https://code.angularjs.org/1.4.0-beta.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<table class="table ">
<tbody>
<tr class="list-row" ng-repeat="form in todoData">
<td class="list-row-content">
<p>
<a>{{form.title}}</a>
</p>
<span>
Type: <a ng-show="!typeAction" ng-click="selectTypeAction($index,this)">{{selectedAction.label}}</a>
<select ng-change="changeTypeAction(this)" ng-show="typeAction" ng-model="selectedAction" ng-options="opt as opt.label for opt in options"></select>
</span>
<span class="tag-sec">
Description: <a ng-show="!typeDescAction" ng-click="desTypeAction($index,this)">{{desType}}</a>
<input type="text" value="" ng-show="typeDescAction" ng-model="desType" ng-blur="changeDesAction($index,this)" />
</span>
<span class="tag-sec">
Priority: <a ng-show="!typePriAction" ng-click="priTypeAction($index,this)">{{priAction.label}}</a>
<select ng-change="changePriTypeAction(this)" ng-show="typePriAction" ng-model="priAction" ng-options="opt as opt.label for opt in priOptions"></select>
</span>
</td>
</tr>
</tbody>
</table>
</body>
</html>
var myApp = angular.module('myApp', []);
myApp.controller('myCtrl', function($scope){
/* ************************************************ */
$scope.todoData = [
{'title':'Create Google Logo'},
{'title':'Talk to XYZ about Google'},
{'title':'Testing Google Coding'},
{'title':'Create Documentaion about Google'},
{'title':'Create Client Sample form'},
{'title':'Modify Top Navigation'},
{'title':'Change Footer text and color'},
{'title':'Redesign Google Dashboard'}
]
$scope.options = [
{ label: 'Action Item', value: 1 },
{ label: 'Defect', value: 2 },
{ label: 'Meeting Invite', value: 3 },
{ label: 'Issue', value: 4 },
{ label: 'Enhancement', value: 5 },
{ label: 'Risk', value: 6 },
{ label: 'Proposal', value: 7 }
];
$scope.selectedAction =$scope.options[1];
$scope.selectTypeAction = function(index,context){
console.log(index);
context.typeAction = true;
};
$scope.changeTypeAction = function(context){
context.typeAction = false;
}
$scope.desType = 'Google logo needs a new concept';
$scope.desTypeAction = function(idx,context){
context.typeDescAction = true;
}
$scope.changeDesAction = function(idx,context){
context.typeDescAction = false;
}
$scope.priOptions = [
{ label: 'High', value: 1 },
{ label: 'Medium', value: 2 },
{ label: 'Low', value: 3 }
];
$scope.priAction =$scope.priOptions[1];
$scope.priTypeAction = function(index,context){
console.log(index);
context.typePriAction = true;
};
$scope.changePriTypeAction = function(context){
context.typePriAction = false;
}
/* ************************************************ */
});
Plunker
Use "This" object
Past this HTML COde
<!DOCTYPE html>
<html>
<head>
<link data-require="bootstrap-css#*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
<script data-require="angular.js#*" data-semver="1.4.0-beta.5" src="https://code.angularjs.org/1.4.0-beta.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<table class="table ">
<tbody>
<tr class="list-row" ng-repeat="form in todoData">
<td class="list-row-content">
<p>
<a>{{form.title}}</a>
</p>
<span>
Type: <a ng-show="!typeAction" ng-click="selectTypeAction($index,this)">{{selectedAction.label}}</a>
<select ng-change="changeTypeAction(this)" ng-show="typeAction" ng-model="selectedAction" ng-options="opt as opt.label for opt in options"></select>
</span>
<span class="tag-sec">
Description: <a ng-show="!typeDescAction" ng-click="desTypeAction($index,this)">{{desType}}</a>
<input type="text" value="" ng-show="typeDescAction" ng-model="desType" ng-blur="changeDesAction($index,this)" />
</span>
<span class="tag-sec">
Priority: <a ng-show="!typePriAction" ng-click="priTypeAction($index,this)">{{priAction.label}}</a>
<select ng-change="changePriTypeAction(this)" ng-show="typePriAction" ng-model="priAction" ng-options="opt as opt.label for opt in priOptions"></select>
</span>
</td>
</tr>
</tbody>
</table>
</body>
</html>
Past this js code
var myApp = angular.module('myApp', []);
myApp.controller('myCtrl', function ($scope) {
/* ************************************************ */
$scope.todoData = [
{ 'title': 'Create Google Logo' },
{ 'title': 'Talk to XYZ about Google' },
{ 'title': 'Testing Google Coding' },
{ 'title': 'Create Documentaion about Google' },
{ 'title': 'Create Client Sample form' },
{ 'title': 'Modify Top Navigation' },
{ 'title': 'Change Footer text and color' },
{ 'title': 'Redesign Google Dashboard' }
]
$scope.options = [
{ label: 'Action Item', value: 1 },
{ label: 'Defect', value: 2 },
{ label: 'Meeting Invite', value: 3 },
{ label: 'Issue', value: 4 },
{ label: 'Enhancement', value: 5 },
{ label: 'Risk', value: 6 },
{ label: 'Proposal', value: 7 }
];
$scope.selectedAction = $scope.options[1];
$scope.selectTypeAction = function (index, objVal) {
console.log(index);
objVal.typeAction = true;
};
$scope.changeTypeAction = function (objVal) {
objVal.typeAction = false;
}
$scope.desType = 'Google logo needs a new concept';
$scope.desTypeAction = function (idx, objVal) {
objVal.typeDescAction = true;
}
$scope.changeDesAction = function (idx, objVal) {
objVal.typeDescAction = false;
}
$scope.priOptions = [
{ label: 'High', value: 1 },
{ label: 'Medium', value: 2 },
{ label: 'Low', value: 3 }
];
$scope.priAction = $scope.priOptions[1];
$scope.priTypeAction = function (index, objVal) {
console.log(index);
objVal.typePriAction = true;
};
$scope.changePriTypeAction = function (objVal) {
objVal.typePriAction = false;
}
/* ************************************************ */
});
Working Demo

kendo-ui grid inline edit angularjs

I want to have inline editing in my kendo-ui grid. Databinding seems to work fine but when I click the Update button after editing something the scope gets updated but the edit dialogs do not disappear. If a click on another edit button it gets into a defunct state. And after all it only does update the scope if I provide at least a dummy function as k-save. And for some reason clicking the Cancel button does update the scope. So the Cancel button does what I would expect from the Update button.
As you may see I want to update the local scope on client side and not send anything to any server.
Can somebody enlighten me about what is going wrong here?
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1119/styles/kendo.common.min.css" />
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1119/styles/kendo.default.min.css" />
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1119/styles/kendo.dataviz.min.css" />
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1119/styles/kendo.dataviz.default.min.css" />
</head>
<body>
<div id="example" ng-app="gridTestApp" ng-controller="TestController">
<kendo-grid
k-data-source="gridData"
k-columns="gridColumns"
k-on-change="selected = data"
k-selectable="true"
k-editable="editableOptions"
k-schema="gridSchema"
k-save="saveFunction">
</kendo-grid>
<p ng-show="selected">
<label>Artist: <input ng-model="selected.artist" /></label>
<br />
<label>Track: <input ng-model="selected.track" /></label>
</p>
<p>This is for testing data-binding</p>
<ul>
<li data-ng-repeat="gridRow in gridData">
<input ng-model="gridRow.artist"></input><input ng-model="gridRow.track"></input>
<br>
</li>
</ul>
<p>This is for testing data-binding</p>
<ul>
<li data-ng-repeat="gridRow in gridData">
<span ng-bind="gridRow.artist"></span> -<span ng-bind="gridRow.track"></span>
<br>
</li>
</ul>
</div>
<script src="https://code.jquery.com/jquery-1.11.2.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.js"></script>
<script src="http://cdn.kendostatic.com/2014.3.1119/js/kendo.all.min.js"></script>
<script>
angular.module("gridTestApp",[ "kendo.directives" ])
.controller("TestController", function($scope){
$scope.gridData = new kendo.data.ObservableArray([
{ artist: "Pink Floyd", track: "The dark side of the Moon" },
{ artist: "The Beatles", track: "I've just seen a face" },
{ artist: "Queen", track: "Innuendo" }
]);
$scope.gridColumns = [
{ field: "artist", title: "Artist" },
{ field: "track", title: "Track" },
{ command: /*"destroy"*/["edit", "destroy"], title: " ", width: "175px", editable: "inline" }
];
$scope.editableOptions = {mode: "inline", update: true, destroy: true};
$scope.gridSchema = {
model: {
id: "artist",
fields: {
artist: { type: "string", validation: { required: true } },
track: { type: "string", validation: { required: true } }
}
}
}
$scope.saveFunction = function(){
console.log("somehting was modified");
}
});
</script>
</body>
</html>
I have created a plnkr for you.
Your problem is the schema - this is not a grid configuration option but a DataSource configuration option.
I'd suggest creating an actual DataSource instead of an ObservableArray (using a string id might not be ideal either):
$scope.gridData = new kendo.data.DataSource({
data: [{
artist: "Pink Floyd",
track: "The dark side of the Moon"
}, {
artist: "The Beatles",
track: "I've just seen a face"
}, {
artist: "Queen",
track: "Innuendo"
}],
schema: {
model: {
id: "artist",
fields: {
artist: {
type: "string",
validation: {
required: true
}
},
track: {
type: "string",
validation: {
required: true
}
}
}
}
}
});
(demo)

Resources