I have an existing HTML table. I'd like a thin JS library to add simple search and sorting. GridJS looks promising, but I don't understand the docs for loading from HTML. For example, I'm unable to use the useRef function. Even the first line of code in the example fails for me:
>>> gridjs.useRef(null)
Uncaught TypeError: Bt is undefined
Preact 3
<anonymous> debugger eval code:1
Here is a minimal example:
<html>
<head>
<link href='https://unpkg.com/gridjs/dist/theme/mermaid.min.css' rel='stylesheet'>
<script src="https://cdn.jsdelivr.net/npm/gridjs/dist/gridjs.umd.js"></script>
</head>
<body>
<table id='table'>
<tr>
<td>Foo</td>
<td>Bar</td>
<td>Baz</td>
</tr>
</table>
<script>
window.onload = function() {
var node = document.getElementById('table');
new gridjs.Grid({'from': node});
}
</script>
</body>
</html>
I get the error
Uncaught TypeError: t.querySelector(...) is null
fromHTMLTable header.ts:288
fromUserConfig header.ts:256
fromUserConfig config.ts:179
update config.ts:146
e grid.ts:15
onload example.html:17
EventHandlerNonNull* example.html:15
I know this answer comes a bit late, but I hope it helps future visitors.
It looks like you still need to call the render function, and the way it seems to work is it hides the table in the DOM and injects the Grid.js table into the wrapper you specify.
For example, this worked for me:
new gridjs.Grid({
from: document.getElementById('mySourceTable'),
}).render(document.getElementById('myDestinationWrapper'));
Lastly, I think thead & tbody is needed - the documentation shows these elements as well: From HTML Table
Here's a snippet as a demo:
document.addEventListener("DOMContentLoaded", function() {
new gridjs.Grid({
from: document.getElementById('sourceTable')
}).render(document.getElementById('destinationWrapper'));
});
<html>
<head>
<link href='https://unpkg.com/gridjs/dist/theme/mermaid.min.css' rel='stylesheet'>
<script src="https://cdn.jsdelivr.net/npm/gridjs/dist/gridjs.umd.js"></script>
</head>
<body>
<div id='destinationWrapper'></div>
<table id='sourceTable'>
<thead>
<tr>
<th>One</th>
<th>Two</th>
<th>Three</th>
</tr>
</thead>
<tbody>
<tr>
<td>Foo</td>
<td>Bar</td>
<td>Baz</td>
</tr>
</tbody>
</table>
</body>
</html>
Related
I am using a asp.net mvc web app. I have created a table and now I am wanting to use the plugin in datatables. I saw you only needed 3 lines of code to make this work. I attempted to do exactly what it required in order for it to work and give me the desired datatable, but it does not give me the table I am expecting. I even went to examples -> HTML (DOM) source data -> and under Javascript tab I entered the lines required.
Is there something I am doing incorrect here with the script tags or is the plug in just not working? I do not have the files downloaded and imported to my project.
Expecting a standard look like this
But am getting this... so I am missing the look of the datatable plugin and the following Error.
Cannot set properties of undefined (setting '_DT_CellIndex')
my view:
#model List<Fright>
#{
ViewData["Title"] = "Home Page";
var result = Model.GroupBy(gb => gb.Value);
}
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<link href="//cdn.datatables.net/1.11.2/css/jquery.dataTables.min.css" rel="stylesheet"/>
<script type="text/javascript" charset="utf8" src="//cdn.datatables.net/1.11.2/js/jquery.dataTables.min.js" defer></script>
<script>
$(document).ready(function () {
$('#homeTable').DataTable();
});
</script>
</head>
<body>
<div>
<table id="homeTable" class="display" style="width:100%">
<thead>
<tr>
<th>Value</th>
<th>Option</th>
</tr>
</thead>
<tbody>
#foreach (var item in result)
{
var url = "/frightSummary/SummaryIndex?id=" + item.Key;
<tr>
<td>
<a href=#url>#item.Key</a>
</td>
</tr>
}
</tbody>
</table>
</div>
</body>
</html>
Your problem is a mismatch in the number of <td> </td>. You are just rendering 1 <td> in foreach loop but you have two <th></th> in the table header
#model List<Fright>
#{
ViewData["Title"] = "Home Page";
var result = Model.GroupBy(gb => gb.Value);
}
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<link href="//cdn.datatables.net/1.11.2/css/jquery.dataTables.min.css" rel="stylesheet"/>
<script type="text/javascript" charset="utf8" src="//cdn.datatables.net/1.11.2/js/jquery.dataTables.min.js" defer></script>
<script>
$(document).ready(function () {
$('#homeTable').DataTable();
});
</script>
</head>
<body>
<div>
<table id="homeTable" class="display" style="width:100%">
<thead>
<tr>
<th>Value</th>
<th>Option</th>
</tr>
</thead>
<tbody>
#foreach (var item in result)
{
var url = "/frightSummary/SummaryIndex?id=" + item.Key;
<tr>
<td>
<a href=#url>#item.Key</a>
</td>
<td>
<a href=#url>#item.Option</a> /* output you Option value*/
</td>
</tr>
}
</tbody>
</table>
</div>
</body>
</html> ```
I want to make a table, based on this model (Material Design Lite) :
https://getmdl.io/components/index.html#tables-section
In my code, I have a list, and I try to display it, in the following way, by using a ng-repeat :
<table class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp">
<thead>
<tr>
<th class="mdl-data-table__cell--non-numeric">Id. administrateurs</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="admin in listAdmins">
<td class="mdl-data-table__cell--non-numeric" ng-model="adminselected">{{admin}}</td>
</tr>
</tbody>
</table>
But the result is not the same than in the illustration example :
As we can see, there is no checkbox on the left and I don't understand why.
Also, how to make a table, where we can directly add data on it ?
In fact, with a fixed list, it works. But mine is generated by a request in a database, and its value can be changed. My listadmin is empty at the beginning, and it is completed by an authentification process.
Your code work correct.
<html ng-app="myApp">
<head>
<!-- Material Design Lite -->
<script src="https://code.getmdl.io/1.3.0/material.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
<!-- Material Design icon font -->
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<script>
angular.module('myApp', []).controller('MainController', ['$scope', function($scope){
$scope.listAdmins = ['admin1', 'admin2', 'admin3'];
}]);
</script>
</head>
<body ng-controller="MainController as main">
<table class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp">
<thead>
<tr>
<th class="mdl-data-table__cell--non-numeric">Id. administrateurs</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="admin in listAdmins">
<td class="mdl-data-table__cell--non-numeric" ng-model="adminselected">{{admin}}</td>
</tr>
</tbody>
</table>
</body>
</html>
May be some errors occurred? Can you see browser console.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Game</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
<script src="script.js"></script>
</head>
<body>
<div class="container">
<table class="table ">
<tr>
<td id="1">a</td>
<td id="2">a</td>
<td id="3">a</td>
<td id="4">a</td>
</tr>
<tr>
<td id="5">a</td>
<td id="6">a</td>
<td id="7">a</td>
<td id="8">a</td>
</tr>
<tr>
<td id="9">a</td>
<td id="10">a</td>
<td id="11">a</td>
<td id="12">a</td>
</tr>
<tr>
<td id="13">a</td>
<td id="14">a</td>
<td id="15">a</td>
<td id="16">a</td>
</tr>
</table>
</div>
</body>
function startFunction() {
var table = document.querySelector('#table');
var table_cells = table.querySelectorAll('td');
}
window.onload = function() {
startFunction();
};
I keep getting an error of "uncaught typeError: cannot read property 'querySelectorAll' of null."
I think this has to do with the fact when I'm calling a function that tries to grab said element node before it exists perhaps?
I'm loading my Javascript file in the <head> section of my HTML file so I added a window.onload function to make sure everything is loaded before the page runs. However, I still keep getting this error.
Take a look at this line in your JavaScript:
var table = document.querySelector('#table');
The pound-sign indicates an ID, and so your javascript is looking for an element with the ID of "table".
But, if you look at your table, it doesn't have an ID; only class.
The solution is to give your <table> an ID of "table" so that the javascript properly finds it:
<table id="table">
The table is missing id attribute. Instead, it has class attribute. Fix by adding id
<table class="table" id="table">
Or modify your query selector to select by class:
var table = document.querySelector('.table');
I want tableRow.html to be drawn under the table head but the ng-repeat is not drawing at all and the examples are above the table head. If I drop the row with examples directly into the proper location in index.html it will draw just fine. What am I doing wrong?
index.html
<html>
<head>
<title>Currency Exchange</title>
<link rel="stylesheet" href="css/bootstrap.min.css">
<link type="text/css" rel="stylesheet" href="css/stylesheet.css"/>
<script type="text/javascript" src="js/angular.min.js"></script>
</head>
<body ng-app="myApp">
<h1>A title to the table</h1>
<div>
<div class= "ExTableDiv">
<table class= "ExTable">
<thead>
<tr>
<th class="column">Currency Code</th>
<th class="column">Currency Name</th>
<th class="column">Exchange Rate vs USD</th>
</tr>
</thead>
<tbody ng-controller="TestController"><!--**if you try TestController as TC it will throw an error, why?**-->
<test-directive></test-directive>
</tbody>
</table>
</div>
</div>
</body>
<script type="text/javascript" src="js/app.js"></script>
<script type="text/javascript" src="js/directives/tableFiller.js"></script>
</html>
app.js
(function(){
var app = angular.module('myApp',['exchange-directives']);
app.controller('TestController', ['$http', function($http) {
var table = this;
table.rows = [];
$http.get('/item.json').success(function(data){
table.rows = [{"name":"Captain","rate":"0.8910","inverce":"1.1223"}]; //I added this here so I know I am getting json data
});
}]);
})();
tableFiller.js
(function(){
var app = angular.module('exchange-directives', []);
app.directive('testDirective', function(){
return {
restrict: 'E',
templateUrl: 'js/directives/tableRow.html'
};
});
})();
tableRow.html
<tr ng-repeat='row in TestController.table.rows'>
<td>{{row.name}}</td>
<td>{{row.rate}}</td>
<td>{{row.inverse}}</td>
</tr>
<tr>
<td>Example 1</td>
<td>Example 2</td>
<td>Example 3</td>
</tr>
Replace <tr ng-repeat='row in TestController.table.rows'> with
<tr ng-repeat='row in TestController.rows'>
In your controller you're setting table = this, so table.rows actually is this.rows and thus available to the markup via TestController.rows
I am choosing to answer this question:
Also the tutorial I followed on codeschool wraps angular.module within a function but I see that most other examples don't. What is the difference? Why choose one over the other?
This is called an immediately invoked function expression or (IIFE). It is a light-weight way to introduce modules into JavaScript. The goal of using something like this is to ensure lexical scoping of all variables declared at the top level of the module. Without something like this, it is easy to accidentally introduce global variables, which in general is a baaaaad thing.
I'm having trouble accessing a declaratively created datagrid by ID, so that I can set its datastore.
Here's my code, but tree is coming back as undefined.
Thanks in advance for any help.
<!DOCTYPE html>
<html lang="en">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js" data-dojo-config="async: true"></script>
</head>
<body>
<table data-dojo-id="myTree" dataType="dojox.grid.TreeGrid" summary="This is a test">
<thead>
<tr>
<th field="a" width="200px">A</th>
<th field="items" aggregate="sum" itemAggregates="count">
<table>
<thead>
<tr>
<th field="name" width="200px">Name</th>
<th field="count" width="200px">Count</th>
</tr>
</thead>
</table>
</th>
</tr>
</thead>
</table>
</body>
<script>
require(["dijit/registry", "dojo/data/ItemFileReadStore"], function( Registry, ReadStore ) {
var store = new ReadStore();
var tree = Registry.byId("myTree");
console.log(tree);
// tree.setStore( store );
});
</script>
</html>
Your code has several issues leading to your problem.
dataType is not a thing; you want data-dojo-type (you're probably confusing it with the deprecated dojoType)
Setting data-dojo-id creates a global variable, not an ID for Dijit's registry; set id instead
You're never actually running dojo/parser on the document, either, so even with these issues addressed, you won't end up with an actual widget
Here is a fixed example:
<body>
<table id="myTree" data-dojo-type="dojox/grid/TreeGrid" summary="This is a test">
...
</table>
</body>
<script>
require([
"dojo/parser",
"dijit/registry",
"dojo/data/ItemFileReadStore",
"dojox/grid/TreeGrid"
], function(parser, registry, ReadStore) {
parser.parse();
//var store = new ReadStore(...);
var tree = registry.byId("myTree");
console.log(tree);
// tree.setStore( store );
});
</script>