Directive customize a table in Angularjs _angularjs

Source: Internet
Author: User
Tags rowcount


First of all, the need for a table:



Table structure


<table>
<thead>
<tr>
<th>Name</th>
<th>Street</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr>
<td >></td>
<td>></td>
<td>></td>
</tr>
</ tbody>
</table>
<div>4 line </div>


Click on an th and sort the column
You can alias a table header
You can set whether a column displays
One row below the table shows the total number of rows



We want the form to be shown as follows:


<table-helper datasource="customers" clumnmap="[{name: 'Name'}, {street: 'Street'}, {age: 'Age'}, {url: 'URL', hidden: true}]"></table-helper>


Above, the DataSource data source is from controller $scope.customers, roughly {name: ' David ', street: ' 1234 Anywhere St. ', Age:25,url: ' Index.html '} Such a format, specifically omitted.



Columnmap is responsible for the alias of the column and determines whether a column is displayed.



How to achieve it?



The directive is roughly like this:


var tablehelper = function () {
var template = ',
link = function (scope, element, Attrs) {
} return
{
R Estrict: ' E ',
scope: {
columnmap: ' = ',
datasource: ' = '
},
Link:link,
template:template
}; 
}
Angular.module (' Directivemodule ')


Specifically,



First, monitor the datasource changes and reload the table as soon as it changes.


Scope. $watchCollection (' datasource ', render);
Initialize table
function render () {
if (Scope.datasource && scope.datasource.length) {
table = = Tablestart;
Table + = Renderheader ();
Table + + renderrows () + tableend;
Load statistic row
rendertable ();
}


The loading table is roughly divided into three steps, loading the table header, loading the table body, loading the statistic rows.


// Load the header
function renderHeader () {
var tr = '<tr>';
for (var prop in scope.datasource [0]) {
// {name: 'David', street: '1234 Anywhere St.', age: 25, url: 'index.html'}
// Get the alias based on the original column name, and consider whether to display the column
var val = getColumnName (prop);
if (val) {
// visibleProps stores the original column names
visibleProps.push (prop);
tr + = '<th>' + val + '</ th>';
}
}
tr + = '</ tr>';
tr = '<thead>' + tr '</ thead>';
return tr;
}
// Load rows
function renderRows () {
var rows = '';
for (var i = 0, len = scope.datasource.length; i <len; i ++) {
rows + = '<tr>';
var row = scope.datasource [i];
for (var prop in row) {
// The original column name being traversed is in the visibleProps collection, which stores the original column name
if (visibleProps.indexOf (prop)> -1) {
rows + = '<td>' + row [prop] + '</ td>';
}
}
rows + = '</ tr>';
}
rows = '<tbody>' + rows + '</ tbody>';
return rows;
}
// Load statistics rows
function renderTable () {
table + = '<br /> <div class = "rowCount">' + scope.datasource.length + 'row </ div>';
element.html (table);
table = '';
}


When loading the header, a method is used to get an alias based on the original column name.


Gets the alias of the column based on the original column name and considers whether to hide the condition of the column
function getColumnName (prop) {
if (!scope.columnmap) return prop;
Get [{name: ' name '}]
var val = filtercolumnmap (prop);
if (Val && val.length &&!val[0].hidden) return Val[0][prop];
else return null;
}


In the getColumnName method, you use a name from the original column


For example, according to the Name property, this gets [{name: ' name '}]
//[{name: ' name '}, {street: ' street '}, {age: ' age '}, {url: ' url ', hidden:true}]< C10/>function Filtercolumnmap (prop) {
var val = scope.columnmap.filter (function (map) {
if (Map[prop)) { return
true;
}
return false;
});
return val;
}


The specific code is as follows:


(function () {
var tableHelper = fucntion () {
var template = '<div class = "tableHelper"> </ div>',
link = function (scope, element, attrs) {
var headerCols = [], // Table header columns
tableStart = '<table>',
tableEnd = '</ table>',
table = '',
visibleProps = [], // visible columns
sortCol = null, // sort
sortDir = 1;
// watch collection
sscope. $ watchCollection ('datasource', render);
// Bind event to table header th
wireEvents ();
// Initialize the form
function render () {
if (scope.datasource && scope.datasource.length) {
table + = tableStart;
table + = renderHeader ();
table + = renderRows () + tableEnd;
// Load statistics rows
renderTable ();
}
}
// Add a click event to th
function wireEvents ()
{
element.on ('click', function (event) {
if (event.srcElement.nodeName === 'TH') {
// Get the name of the column
var val = event.srcElement.innerHTML;
// Get the original column name based on the alias of the column
var col = (scope.columnmap)? getRawColumnName (val): val;
if (col) {
// sort the column
sort (col);
}
}
});
}
// sort a column
function sort (col) {
if (sortCol === col) {
sortDir = sortDir * -1;
}
sortCol = col;
scope.datasource.sort (function (a, b) {
if (a [col]> b [col]) return 1 * sortDir;
if (a [col] <b [col]) return -1 * sortDir;
return 0;
});
// Reload the table
render ();
}
// Load the header
function renderHeader () {
var tr = '<tr>';
for (var prop in scope.datasource [0]) {
// {name: 'David', street: '1234 Anywhere St.', age: 25, url: 'index.html'}
// Get the alias based on the original column name, and consider whether to display the column
var val = getColumnName (prop);
if (val) {
// visibleProps stores the original column names
visibleProps.push (prop);
tr + = '<th>' + val + '</ th>';
}
}
tr + = '</ tr>';
tr = '<thead>' + tr '</ thead>';
return tr;
}
// Load rows
function renderRows () {
var rows = '';
for (var i = 0, len = scope.datasource.length; i <len; i ++) {
rows + = '<tr>';
var row = scope.datasource [i];
for (var prop in row) {
// The original column name being traversed is in the visibleProps collection, which stores the original column name
if (visibleProps.indexOf (prop)> -1) {
rows + = '<td>' + row [prop] + '</ td>';
}
}
rows + = '</ tr>';
}
rows = '<tbody>' + rows + '</ tbody>';
return rows;
}
// Load statistics rows
function renderTable () {
table + = '<br /> <div class = "rowCount">' + scope.datasource.length + 'row </ div>';
element.html (table);
table = '';
}
// Get the original column name based on the alias of the column
function getRawColumnName (friendlyCol) {
var rawCol;
// columnmap = [{name: 'Name'}, {street: 'Street'}, {age: 'Age'}, {url: 'URL', hidden: true}]
scope.columnmap.forEach (function (colMap) {
// {name: 'Name'}
for (var prop in colMap) {
if (colMap [prop] === friendlyCol) {
rawCol = prop;
break;
}
}
return null;
});
return rawCol;
}
function pushColumns (rawCol, renamedCol) {
visibleProps.push (rawCol);
scope.columns.push (renamedCol);
}
// For example, according to the name attribute, here is [{name: 'Name'}]
// [{name: 'Name'}, {street: 'Street'}, {age: 'Age'}, {url: 'URL', hidden: true}]
function filterColumnMap (prop) {
var val = scope.columnmap.filter (function (map) {
if (map [prop]) {
return true;
}
return false;
});
return val;
}
// Get the alias of the column according to the original column name and consider whether to hide the column
function getColumnName (prop) {
if (! scope.columnmap) return prop;
// Get [{name: 'Name'}]
var val = filterColumnMap (prop);
if (val && val.length &&! val [0] .hidden) return val [0] [prop];
else return null;
}
};
return {
restrict: 'E',
scope: {
columnmap: '=',
datasource: '='
},
link: link,
template: template
};
};
angular.module ('directiveModule')
.directive ('tableHelper', tableHelper);
} ()); 


The above is a small set to share the ANGULARJS in the directive custom a form of knowledge, I hope to help you.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.