Home Web Front-end JS Tutorial Introduction to JavaScript framework (xmlplus) components (10) Grid (DataGrid)

Introduction to JavaScript framework (xmlplus) components (10) Grid (DataGrid)

May 06, 2017 pm 03:29 PM
grid

xmlplus is a JavaScriptframework used for rapid development of front-end and back-end projects. This article mainly introduces the xmlplus grid in the xmlplus component design series. It has a certain reference value. Interested friends can refer to

. In this chapter, we are going to implement a grid component. This component In addition to the most basic data display function, it also provides sorting and data filtering functions.

Data source

In order to test that we are about to write the grid component, we use the data source in the following format. This data source contains two parts, namely header data set and table body data set. The final number of columns in the grid component instance is determined by the length of the header data set.

var data = {
 gridColumns: ['name', 'power'],
 gridData: [
 { name: 'Chuck Norris', power: Infinity },
 { name: 'Bruce Lee', power: 9000 },
 { name: 'Jackie Chan', power: 7000 },
 { name: 'Jet Li', power: 8000 }
 ]
};
Copy after login

Top-level design

Visually, we naturally divide the grid component into a table header and a table body. This grid component has three functions, so it should provide three dynamic interfaces. But we noticed that the sorting function is performed by clicking on the table header, and the table header is part of the grid component, so this function should be built-in. Therefore, in fact, our grid component only exposes two dynamic interfaces to the outside world: one for filtering and the other for receiving data sources. So we can get a top-level design as follows.

DataGrid: {
 xml: `<table id=&#39;table&#39;>
  <Thead id=&#39;thead&#39;/>
  <Tbody id=&#39;tbody&#39;/>
  </table>`,
 fun: function (sys, items, opts) {
 function setValue(data) {
  items.thead.val(data.gridColumns);
  items.tbody.val(data.gridColumns, data.gridData);
 }
 function filter(filterKey) {
  // 过滤函数
 }
 return { val: setValue, filter: filter };
 }
}
Copy after login

Design header

The header has only one row, so you can directly provide it with a tr element. The number of child items th of the tr element depends on the length of the header data set, so it needs to be created dynamically. Since the th element contains the sorting function, it needs to be encapsulated separately. Below is the design of the header we gave.

Thead: {
 xml: `<thead id=&#39;thead&#39;>
  <tr id=&#39;tr&#39;/>
  </thead>`,
 fun: function (sys, items, opts) {
 function setValue(value) {
  sys.tr.children().call("remove");
  data.forEach(item => sys.tr.append("Th").value().val(item));
 }
 return { val: setValue };
 }
}
Copy after login

The header data item component provides a text setting interface. The component itself is not responsible for sorting. It only completes the change of its viewstate and the dispatch of sorting commands. The dispatch of sorting commands needs to carry two pieces of data: one is the sorting keyword, which is the header text; the other is the sorting direction, ascending or descending.

Th: {
 css: "#active { color: #fff; } #active #arrow { opacity: 1; } #active #key { color: #fff; }\
  #arrow { display: inline-block; vertical-align: middle; width: 0; height: 0; margin-left: 5px; opacity: 0.66; }\
  #asc { border-left: 4px solid transparent; border-right: 4px solid transparent; border-bottom: 4px solid #fff;}\
  #dsc { border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 4px solid #fff; }",
 xml: "<th id=&#39;th&#39;>\
  <span id=&#39;key&#39;/><span id=&#39;arrow&#39;/>\
  </th>",
 fun: function (sys, items, opts) {
 var order = "#asc";
 this.watch("sort", function (e, key, order) {
  sys.key.text().toLowerCase() == key || sys.th.removeClass("#active");
 });
 this.on("click", function (e) {
  sys.th.addClass("#active");
  sys.arrow.removeClass(order);
  order = order == "#asc" ? "#dsc" : "#asc";
  sys.arrow.addClass(order).notify("sort", [sys.key.text().toLowerCase(), order]);
 });
 sys.arrow.addClass("#asc");
 return { val: sys.key.text };
 }
}
Copy after login

Design table body

The table body can have multiple rows, but the table body is only responsible for displaying data, so it is much simpler to implement than the table header. .

Tbody: {
 xml: `<tbody id=&#39;tbody&#39;/>`,
 fun: function (sys, items, opts) {
 function setValue(gridColumns, gridData) {
  sys.tbody.children().call("remove");
  gridData.forEach(data => 
  tr = sys.tbody.append("tr");
  gridColumns.forEach(key => tr.append("td").text(data[key]));
  ));
 }
 return { val: setValue };
 }
}
Copy after login

Add sorting function

In order to facilitate management, we separately encapsulate the sorting function into a component, which provides a sorting interface and listens to a Sort messages. Once the sorting message is received, the keywords and sorting direction are recorded, and a table refresh command is issued.

Sort: {
 fun: function (sys, items, opts) {
 var sortKey, sortOrder;
 this.watch("sort", function (e, key, order) {
  sortKey = key, sortOrder = order;
  this.trigger("update");
 });
 return function (data) {
  return sortKey ? data.slice().sort(function (a, b) {
  a = a[sortKey], b = b[sortKey];
  return (a === b ? 0 : a > b ? 1 : -1) * (sortOrder == "#asc" ? 1 : -1);
  }) : data;
 };
 }
}
Copy after login

To fully realize the sorting function, make some modifications to the component DataGrid, mainly to build in the above sorting function component and listen for table body refresh instructions. Once the refresh command is received, the table body data is sorted and the table body is refreshed.

DataGrid: {
 xml: `<table id=&#39;table&#39;>
  <Thead id=&#39;thead&#39;/>
  <Tbody id=&#39;tbody&#39;/>
  <Sort id=&#39;sort&#39;/>
  </table>`,
 fun: function (sys, items, opts) {
 var data = {gridColumns: [], gridData: []};
 function setValue(value) {
  data = value;
  items.thead.val(data.gridColumns);
  items.tbody.val(data.gridColumns, data.gridData);
 }
 function filter(filterKey) {
  // 过滤函数
 }
 this.on("update", function() {
  items.tbody.val(items.sort(data.gridData));
 });
 return { val: setValue, filter: filter };
 }
}
Copy after login

Add filtering function

Similar to the process of adding sorting function, we encapsulate the filtering function into a separate component, which provides a filtering interface. Also listen for a filtered message. Once the message is received, the filter keyword is recorded and a table body refresh command is dispatched.

Filter: {
 fun: function (sys, items, opts) {
 var filterKey = "";
 this.watch("filter", function (e, key) {
  filterKey = key.toLowerCase();
  this.trigger("update");
 });
 return function (data) {
  return data.filter(function (row) {
  return Object.keys(row).some(function (key) {
   return String(row[key]).toLowerCase().indexOf(filterKey) > -1;
  });
  });
 };
 }
}
Copy after login

In addition, some modifications need to be made to the component DataGrid. The modification content is similar to the addition of the above-mentioned sorting function. The difference is that the filter interface is additionally improved and the message scope is restricted. Below is our final grid component.

DataGrid: {
 css: `#table { border: 2px solid #42b983; border-radius: 3px; background-color: #fff; }
  #table th { background-color: #42b983; color: rgba(255,255,255,0.66); cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }
  #table td { background-color: #f9f9f9; }
  #table th, #table td { min-width: 120px; padding: 10px 20px; }`,
 xml: `<table id=&#39;table&#39;>
  <Thead id=&#39;thead&#39;/>
  <Tbody id=&#39;tbody&#39;/>
  <Sort id=&#39;sort&#39;/>
  <Filter id=&#39;filter&#39;/>
  </table>`,
 map: { msgscope: true },
 fun: function (sys, items, opts) {
 var data = {gridColumns: [], gridData: []};
 function setValue(value) {
  data = value;
  items.thead.val(data.gridColumns);
  items.tbody.val(data.gridColumns, data.gridData);
 }
 function filter(filterKey) {
  sys.table.notify("filter", filterKey);
 }
 this.on("update", function() {
  items.tbody.val(items.filter(items.sort(data.gridData)));
 });
 return { val: setValue, filter: filter };
 }
}
Copy after login

It is worth noting that the option to limit the scope of the message must be configured in the mapping item. Otherwise, when multiple grid components are instantiated in an application, messages will interfere with each other.

Testing

Finally, let’s test the components we completed. The main functions of the test are the three mentioned at the beginning: data display, sorting and filter.

Index: {
 css: "#index { font-family: Helvetica Neue, Arial, sans-serif; font-size: 14px; color: #444; }\
  #search { margin: 8px 0; }",
 xml: "<p id=&#39;index&#39;>\
  Search <input id=&#39;search&#39;/>\
  <Table id=&#39;table&#39;/>\
  </p>",
 fun: function (sys, items, opts) {
 items.table.val(data);
 sys.search.on("input", e => items.table.filter(sys.search.prop("value")));
 }
}
Copy after login

This series of articles is based on the xmlplus framework. If you don’t know much about xmlplus, you can visit www.xmlplus.cn. Detailed getting started documentation is available here.

【Related recommendations】

1. Free js online video tutorial

2. JavaScript Chinese Reference Manual

3. php.cn Dugu Jiujian (3) - JavaScript video tutorial

The above is the detailed content of Introduction to JavaScript framework (xmlplus) components (10) Grid (DataGrid). For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
1 months ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
1 months ago By 尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. Have Crossplay?
1 months ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How do I create and publish my own JavaScript libraries? How do I create and publish my own JavaScript libraries? Mar 18, 2025 pm 03:12 PM

Article discusses creating, publishing, and maintaining JavaScript libraries, focusing on planning, development, testing, documentation, and promotion strategies.

How do I optimize JavaScript code for performance in the browser? How do I optimize JavaScript code for performance in the browser? Mar 18, 2025 pm 03:14 PM

The article discusses strategies for optimizing JavaScript performance in browsers, focusing on reducing execution time and minimizing impact on page load speed.

What should I do if I encounter garbled code printing for front-end thermal paper receipts? What should I do if I encounter garbled code printing for front-end thermal paper receipts? Apr 04, 2025 pm 02:42 PM

Frequently Asked Questions and Solutions for Front-end Thermal Paper Ticket Printing In Front-end Development, Ticket Printing is a common requirement. However, many developers are implementing...

How do I debug JavaScript code effectively using browser developer tools? How do I debug JavaScript code effectively using browser developer tools? Mar 18, 2025 pm 03:16 PM

The article discusses effective JavaScript debugging using browser developer tools, focusing on setting breakpoints, using the console, and analyzing performance.

Who gets paid more Python or JavaScript? Who gets paid more Python or JavaScript? Apr 04, 2025 am 12:09 AM

There is no absolute salary for Python and JavaScript developers, depending on skills and industry needs. 1. Python may be paid more in data science and machine learning. 2. JavaScript has great demand in front-end and full-stack development, and its salary is also considerable. 3. Influencing factors include experience, geographical location, company size and specific skills.

How do I use source maps to debug minified JavaScript code? How do I use source maps to debug minified JavaScript code? Mar 18, 2025 pm 03:17 PM

The article explains how to use source maps to debug minified JavaScript by mapping it back to the original code. It discusses enabling source maps, setting breakpoints, and using tools like Chrome DevTools and Webpack.

How to merge array elements with the same ID into one object using JavaScript? How to merge array elements with the same ID into one object using JavaScript? Apr 04, 2025 pm 05:09 PM

How to merge array elements with the same ID into one object in JavaScript? When processing data, we often encounter the need to have the same ID...

The difference in console.log output result: Why are the two calls different? The difference in console.log output result: Why are the two calls different? Apr 04, 2025 pm 05:12 PM

In-depth discussion of the root causes of the difference in console.log output. This article will analyze the differences in the output results of console.log function in a piece of code and explain the reasons behind it. �...

See all articles