ProductSheet

This sample uses a TransposedGrid control to display products on the grid columns, and their properties on the grid rows.

Transposed layouts are especitally useful when there are few data items, and each items has many properties.

Learn about FlexGrid | TransposedGrid API Reference

import 'bootstrap.css'; import '@mescius/wijmo.styles/wijmo.css'; import './styles.css'; import { FlexGrid } from '@mescius/wijmo.grid'; import { TransposedGrid } from '@mescius/wijmo.grid.transposed'; import { ObservableArray } from '@mescius/wijmo'; import { getData, getDataColumns } from './data'; document.readyState === 'complete' ? init() : window.onload = init; function init() { // data source shared by both grids let data = new ObservableArray(getData()); // default grid new FlexGrid('#theGrid', { alternatingRowStep: 0, showSelectedHeaders: 'Row', headersVisibility: 'Row', isReadOnly: true, copyHeaders: 'Row', selectionMode: 'CellRange', formatItem: formatItem, autoGenerateColumns: false, columns: getDataColumns(), itemsSource: data }); // transposed grid new TransposedGrid('#theTransposedGrid', { alternatingRowStep: 0, showSelectedHeaders: 'Row', headersVisibility: 'Row', isReadOnly: true, copyHeaders: 'Row', selectionMode: 'CellRange', formatItem: formatItem, // customize transposed product grid row/column sizes loadedRows: (s) => { s.columns.defaultSize = 200; setTimeout(() => { s.autoSizeColumn(0, true, 10); // auto-size row headers s.autoSizeRows(); // auto-size data rows s.rows[0].height = 180; // make product images large }); }, autoGenerateRows: false, rows: getDataColumns(), itemsSource: data }); function formatItem(s, e) { if (e.panel == s.cells) { // get binding from row if possible, then from column let binding = s.rows[e.row].binding || s.columns[e.col].binding; switch (binding) { // product image case 'img': e.cell.innerHTML = '<img src="{img}" draggable="false"/>'.replace('{img}', e.cell.textContent); break; // stars for rating case 'rating': let rating = s.getCellData(e.row, e.col, false), html = new Array(Math.floor(rating) + 1).join('&#x2605;'); if (rating > Math.floor(rating)) { html += '&#9734;'; // white star (half star doesn't work...) } e.cell.innerHTML = '<span class="rating">' + html + '</span>'; break; } } } }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>MESCIUS Wijmo TransposedGrid</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.21.5/system.src.js" integrity="sha512-skZbMyvYdNoZfLmiGn5ii6KmklM82rYX2uWctBhzaXPxJgiv4XBwJnFGr5k8s+6tE1pcR1nuTKghozJHyzMcoA==" crossorigin="anonymous"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app'); </script> </head> <body> <div class="container-fluid"> <h2> Default Grid </h2> <p> Products are rendered as rows. </p> <div id="theGrid" class="product-grid"></div> <h2> Transposed Grid </h2> <p> Products are rendered as columns. </p> <div id="theTransposedGrid" class="product-grid"></div> </div> </body> </html>
export function getData() { return [ { name: 'SAMSUNG 65-INCH Q9FN QLED TV', rating: 4, price: 2539.99, size: 65, type: 'LCD with Quantum Dots', refresh: 120, hdmi: 4.5, img: 'https://cdn.mescius.com/wijmo/images/1.png' }, { name: 'TCL 6 SERIES 65-INCH ROKU TV', rating: 4, price: 999.99, size: 65, type: 'LCD', refresh: 60, hdmi: 3, img: 'https://cdn.mescius.com/wijmo/images/2.png' }, { name: 'LG 55-INCH C7 OLED (OLED55C7P)', rating: 4.5, price: 679.99, size: 55, type: 'OLED', refresh: 120, hdmi: 4, img: 'https://cdn.mescius.com/wijmo/images/3.png' }, { name: 'VIZIO P-SERIES 65-INCH P65-F1', rating: 4, price: 1124.67, size: 65, type: 'LCD', refresh: 120, hdmi: 5, img: 'https://cdn.mescius.com/wijmo/images/4.png' }, { name: 'TCL 43S517 ROKU SMART 4K TV', rating: 3.5, price: 319.99, size: 43, type: 'LCD', refresh: 60, hdmi: 3, img: 'https://cdn.mescius.com/wijmo/images/1.png' }, { name: 'SAMSUNG 65-INCH Q6F QLED TV', rating: 3, price: 1597.99, size: 65, type: 'LCD with Quantum Dot', refresh: 120, hdmi: 4, img: 'https://cdn.mescius.com/wijmo/images/2.png' } ]; } export function getDataColumns() { return [ { binding: 'img', header: ' ', align: 'center' }, { binding: 'name', header: 'Model', align: 'center', wordWrap: true }, { binding: 'rating', header: 'Rating', align: 'center', format: 'n1' }, { binding: 'price', header: 'Price', format: 'c2', align: 'center' }, { binding: 'size', header: 'Screen Size (")', align: 'center' }, { binding: 'type', header: 'Screen Type', align: 'center' }, { binding: 'refresh', header: 'Refresh Rate (Hz)', align: 'center' }, { binding: 'hdmi', header: 'HMI ports', format: 'n0', align: 'center' } ]; }
.product-grid { max-height: 2000px; } .product-grid .wj-rowheaders .wj-cell { text-transform: uppercase; font-size: 80%; } .product-grid .wj-cell { padding: 12px; border-bottom: none; } .product-grid .wj-cell span.rating { font-size: 200%; color: #e7711b; } .product-grid img { height: 100%; }
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, meta: { '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { 'jszip': 'npm:jszip/dist/jszip.js', '@mescius/wijmo': 'npm:@mescius/wijmo/index.js', '@mescius/wijmo.input': 'npm:@mescius/wijmo.input/index.js', '@mescius/wijmo.styles': 'npm:@mescius/wijmo.styles', '@mescius/wijmo.cultures': 'npm:@mescius/wijmo.cultures', '@mescius/wijmo.chart': 'npm:@mescius/wijmo.chart/index.js', '@mescius/wijmo.chart.analytics': 'npm:@mescius/wijmo.chart.analytics/index.js', '@mescius/wijmo.chart.animation': 'npm:@mescius/wijmo.chart.animation/index.js', '@mescius/wijmo.chart.annotation': 'npm:@mescius/wijmo.chart.annotation/index.js', '@mescius/wijmo.chart.finance': 'npm:@mescius/wijmo.chart.finance/index.js', '@mescius/wijmo.chart.finance.analytics': 'npm:@mescius/wijmo.chart.finance.analytics/index.js', '@mescius/wijmo.chart.hierarchical': 'npm:@mescius/wijmo.chart.hierarchical/index.js', '@mescius/wijmo.chart.interaction': 'npm:@mescius/wijmo.chart.interaction/index.js', '@mescius/wijmo.chart.radar': 'npm:@mescius/wijmo.chart.radar/index.js', '@mescius/wijmo.chart.render': 'npm:@mescius/wijmo.chart.render/index.js', '@mescius/wijmo.chart.webgl': 'npm:@mescius/wijmo.chart.webgl/index.js', '@mescius/wijmo.chart.map': 'npm:@mescius/wijmo.chart.map/index.js', '@mescius/wijmo.gauge': 'npm:@mescius/wijmo.gauge/index.js', '@mescius/wijmo.grid': 'npm:@mescius/wijmo.grid/index.js', '@mescius/wijmo.grid.detail': 'npm:@mescius/wijmo.grid.detail/index.js', '@mescius/wijmo.grid.filter': 'npm:@mescius/wijmo.grid.filter/index.js', '@mescius/wijmo.grid.search': 'npm:@mescius/wijmo.grid.search/index.js', '@mescius/wijmo.grid.style': 'npm:@mescius/wijmo.grid.style/index.js', '@mescius/wijmo.grid.grouppanel': 'npm:@mescius/wijmo.grid.grouppanel/index.js', '@mescius/wijmo.grid.multirow': 'npm:@mescius/wijmo.grid.multirow/index.js', '@mescius/wijmo.grid.transposed': 'npm:@mescius/wijmo.grid.transposed/index.js', '@mescius/wijmo.grid.transposedmultirow': 'npm:@mescius/wijmo.grid.transposedmultirow/index.js', '@mescius/wijmo.grid.pdf': 'npm:@mescius/wijmo.grid.pdf/index.js', '@mescius/wijmo.grid.sheet': 'npm:@mescius/wijmo.grid.sheet/index.js', '@mescius/wijmo.grid.xlsx': 'npm:@mescius/wijmo.grid.xlsx/index.js', '@mescius/wijmo.grid.selector': 'npm:@mescius/wijmo.grid.selector/index.js', '@mescius/wijmo.grid.cellmaker': 'npm:@mescius/wijmo.grid.cellmaker/index.js', '@mescius/wijmo.nav': 'npm:@mescius/wijmo.nav/index.js', '@mescius/wijmo.odata': 'npm:@mescius/wijmo.odata/index.js', '@mescius/wijmo.olap': 'npm:@mescius/wijmo.olap/index.js', '@mescius/wijmo.rest': 'npm:@mescius/wijmo.rest/index.js', '@mescius/wijmo.pdf': 'npm:@mescius/wijmo.pdf/index.js', '@mescius/wijmo.pdf.security': 'npm:@mescius/wijmo.pdf.security/index.js', '@mescius/wijmo.viewer': 'npm:@mescius/wijmo.viewer/index.js', '@mescius/wijmo.xlsx': 'npm:@mescius/wijmo.xlsx/index.js', '@mescius/wijmo.undo': 'npm:@mescius/wijmo.undo/index.js', '@mescius/wijmo.interop.grid': 'npm:@mescius/wijmo.interop.grid/index.js', '@mescius/wijmo.touch': 'npm:@mescius/wijmo.touch/index.js', '@mescius/wijmo.cloud': 'npm:@mescius/wijmo.cloud/index.js', '@mescius/wijmo.barcode': 'npm:@mescius/wijmo.barcode/index.js', '@mescius/wijmo.barcode.common': 'npm:@mescius/wijmo.barcode.common/index.js', '@mescius/wijmo.barcode.composite': 'npm:@mescius/wijmo.barcode.composite/index.js', '@mescius/wijmo.barcode.specialized': 'npm:@mescius/wijmo.barcode.specialized/index.js', 'jszip': 'npm:jszip/dist/jszip.js', 'bootstrap.css': 'npm:bootstrap/dist/css/bootstrap.min.css', 'css': 'npm:systemjs-plugin-css/css.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', 'systemjs-babel-build':'npm:systemjs-plugin-babel/systemjs-babel-browser.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'js' }, "node_modules": { defaultExtension: 'js' }, } }); })(this);