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.
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>