TableJs
An enhanced Array with extra features to works as 2D Table
The library is currently in DEV and README.md as well. You can use it for development & tests (for feedback). Main features are available. v1.0.0 will be released when coverage test will be done.
TableJs
is a little library to create a 2D Array (Rows with Cells) to
simplify data selection. The strength of this library is the instantiated
TableJs
is a standard Array
with enhanced features.
That means all your knowledge regarding Array
can be applied for
this object. You have just keep in mind your are working with a 2D Array
It can also used in for Web Site using the following CDN :
<!-- Do not use "Latest" in production -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/neooblaster/TableJs@main/releases/latest.min.js"></script>
<!-- Use specified version in production -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/neooblaster/TableJs@main/releases/v0.1.x.min.js"></script>
Summary
- Summary
- Getting Started
- Detailed documentation
Getting Started
You can confer to file demo.js
to retrieve back / execute the
Getting Started documentation.
TableJs
Initializing a new Please considering the following table data :
Brand | Camera | Date | Format | Purpose |
---|---|---|---|---|
Nikon | D3 | 2007 | Full Frame | Professional |
Nikon | D750 | 2014 | Full Frame | Action |
Nikon | D800 | 2011 | Full Frame | Semi-Professional |
Nikon | D810A | 2015 | Full Frame | Astro |
Nikon | D7100 | 2013 | APS-C | Expert |
Nikon | D6 | 2020 | Full Frame | Professional |
Canon | 1Ds Mark III | 2007 | Full Frame | Professional |
Canon | 5D Mark II | 2008 | Full Frame | Semi-Professional |
Canon | 60Da | 2012 | APS-C | Astro |
Canon | 250D | 2019 | APS-C | Compact |
To create a new TableJs
you can instantiate it step by step*
when the content is full dynamic or in one shot like this :
* See Detailed Documentation
let cameras = new TableJs(
// List of Fields (At least one required)
['Brand', 'Camera', 'Date', 'Format', 'Purpose'],
// Indicating which fields compose the key
// -> Optional, but at least empty Array must be passed
['Camera', 'Brand'],
// Table Data
[
[ 'Nikon', 'D3', '2007', 'Full Frame', 'Professional' ],
[ 'Nikon', 'D750', '2014', 'Full Frame', 'Action' ],
[ 'Nikon', 'D800', '2011', 'Full Frame', 'Semi-Professional' ],
[ 'Nikon', 'D810A', '2015', 'Full Frame', 'Astro' ],
[ 'Nikon', 'D7100', '2013', 'APS-C', 'Expert' ],
[ 'Nikon', 'D6', '2020', 'Full Frame', 'Professional' ],
[ 'Canon', '1Ds Mark III', '2007', 'Full Frame', 'Professional' ],
[ 'Canon', '5D Mark II', '2008', 'Full Frame', 'Semi-Professional' ],
[ 'Canon', '60Da', '2012', 'APS-C', 'Astro' ],
[ 'Canon', '250D', '2019', 'APS-C', 'Compact' ],
]
);
Result is the following Array :
console.log(cameras);
[
[ 'Nikon', 'D3', '2007', 'Full Frame', 'Professional' ],
[ 'Nikon', 'D750', '2014', 'Full Frame', 'Action' ],
[ 'Nikon', 'D800', '2011', 'Full Frame', 'Semi-Professional' ],
[ 'Nikon', 'D810A', '2015', 'Full Frame', 'Astro' ],
[ 'Nikon', 'D7100', '2013', 'APS-C', 'Expert' ],
[ 'Nikon', 'D6', '2020', 'Full Frame', 'Professional' ],
[ 'Canon', '1Ds Mark III', '2007', 'Full Frame', 'Professional' ],
[ 'Canon', '5D Mark II', '2008', 'Full Frame', 'Semi-Professional' ],
[ 'Canon', '60Da', '2012', 'APS-C', 'Astro' ],
[ 'Canon', '250D', '2019', 'APS-C', 'Compact' ]
]
Important : As field name will become methods for the table, the name must respect JavaScript function naming convention.
Get distinct values
From this enhanced Array
,
you can easily get distinct values
by calling method where the name is one of field set previously
without parameters :
console.log('Brand List:', cameras.Brand());
console.log('Camera List:', cameras.Camera());
console.log('Date List:', cameras.Date());
console.log('Format List:', cameras.Format());
console.log('Purpose List:', cameras.Purpose());
Result :
Brand List: [ 'Nikon', 'Canon' ]
Camera List: [
'D3', 'D750',
'D800', 'D810A',
'D7100', 'D6',
'1Ds Mark III', '5D Mark II',
'60Da', '250D'
]
Date List: [
'2007', '2008',
'2011', '2012',
'2013', '2014',
'2015', '2019',
'2020'
]
Format List: [ 'Full Frame', 'APS-C' ]
Purpose List: [
'Professional',
'Action',
'Semi-Professional',
'Astro',
'Expert',
'Compact'
]
Get rows
The main purpose of TableJs
is to retrieve
rows where the field value is equal to specified value(s).
Important: TableJs
can select rows for one field at the same time.
But you can chain fields to complete your selection.
Below, an example to return
all Professionnal
cameras from brand Nikon
:
let NikonProCam = cameras.Brand('Nikon').Purpose('Professional');
console.log('Table Result: ', NikonProCam);
console.log('New Camera List: ', NikonProCam.Camera());
The result is a new TableJs
* reflecting a part of our initial table
where this part is our result :
* This means all features stay available.
Table Result: [
[ 'Nikon', 'D3', '2007', 'Full Frame', 'Professional' ],
[ 'Nikon', 'D6', '2020', 'Full Frame', 'Professional' ]
]
New Camera List: [ 'D3', 'D6' ]
Get field value of row
When you are handling a row of your table, you can also call method where the name is one of field set, but instead of returning distinct value, it returns the value of the field.
// Return the camera name of the first entry
let cameraName = NikonProCam[0].Camera();
console.log("Camera name of the first row:", cameraName);
Result :
Camera name of the first row: D3
Remember, you can use all existing method of Array.
So please find below an example to display camera name
using forEach
method
NikonProCam.forEach(function($row){
console.log('Camera: ', $row.Camera());
});
Result :
Camera: D3
Camera: D6
Appending new rows
Take acknowledge that the unique method which has been rewrote
regarding the standard Array method is the push
method.
In native arrays, push
method add a new value in the table.
The rewrote method now push a new row instead of unique value.
So, if you push a unique value, the result will be a new row
where the first field contains your single value and all other fields with
an empty value.
If you push an array, if the number of values in your array
will not match with field number, empty field will be push at the end.
In case of you have more fields than those defined in TableJs
,
they stay here, but you will not have any method to retrieve them.
Example by pushing a single value :
cameras.push('Sony Alpha');
console.log("Updated Cameras table:", cameras);
result :
Updated Cameras table: [
[ 'Nikon', 'D3', '2007', 'Full Frame', 'Professional' ],
[ 'Nikon', 'D750', '2014', 'Full Frame', 'Action' ],
[ 'Nikon', 'D800', '2011', 'Full Frame', 'Semi-Professional' ],
[ 'Nikon', 'D810A', '2015', 'Full Frame', 'Astro' ],
[ 'Nikon', 'D7100', '2013', 'APS-C', 'Expert' ],
[ 'Nikon', 'D6', '2020', 'Full Frame', 'Professional' ],
[ 'Canon', '1Ds Mark III', '2007', 'Full Frame', 'Professional' ],
[ 'Canon', '5D Mark II', '2008', 'Full Frame', 'Semi-Professional' ],
[ 'Canon', '60Da', '2012', 'APS-C', 'Astro' ],
[ 'Canon', '250D', '2019', 'APS-C', 'Compact' ],
[ 'Sony Alpha', '', '', '', '' ]
]
Example by pushing a row
cameras.push([
"Sony Alpha", "α 9 II", "2019", "Full Frame", "Sport-Pro"
]);
console.log("Updated 2 Cameras table:", cameras);
Result :
Updated 2 Cameras table: [
[ 'Nikon', 'D3', '2007', 'Full Frame', 'Professional' ],
[ 'Nikon', 'D750', '2014', 'Full Frame', 'Action' ],
[ 'Nikon', 'D800', '2011', 'Full Frame', 'Semi-Professional' ],
[ 'Nikon', 'D810A', '2015', 'Full Frame', 'Astro' ],
[ 'Nikon', 'D7100', '2013', 'APS-C', 'Expert' ],
[ 'Nikon', 'D6', '2020', 'Full Frame', 'Professional' ],
[ 'Canon', '1Ds Mark III', '2007', 'Full Frame', 'Professional' ],
[ 'Canon', '5D Mark II', '2008', 'Full Frame', 'Semi-Professional' ],
[ 'Canon', '60Da', '2012', 'APS-C', 'Astro' ],
[ 'Canon', '250D', '2019', 'APS-C', 'Compact' ],
[ 'Sony Alpha', '', '', '', '' ],
[ 'Sony Alpha', 'α 9 II', '2019', 'Full Frame', 'Sport-Pro' ]
]
Pushing a new row will automatically update indexes table.
console.log("Updated Cameras List:", cameras.Camera());
Result :
Updated Cameras List: [
'D3', 'D750',
'D800', 'D810A',
'D7100', 'D6',
'1Ds Mark III', '5D Mark II',
'60Da', '250D',
'', 'α 9 II'
]
Setting (Updating) field value of one row
Important: Keep in mind when you get a new array next to filtering using 'field methods', updating a row in the secondary array will update the main table.
let sonyCamera = cameras.Brand('Sony Alpha');
// Update Row where there is no Camera Name
let inc = 1;
sonyCamera.Camera('').forEach(function($row){
// Camera field is a component of key,
// So we have to set a "unique" name for brand (here sony)
$row.Camera(`Camera ${inc}`);
inc++;
});
console.log("Updated Sony Alpha Camera", cameras.Brand('Sony Alpha'));
console.log("Updated Camera Table", cameras);
Result next to the update :
Updated Sony Alpha Camera Table [
[ 'Sony Alpha', 'Camera 1', '', '', '' ],
[ 'Sony Alpha', 'α 9 II', '2019', 'Full Frame', 'Sport-Pro' ]
]
Updated Camera Table [
[ 'Nikon', 'D3', '2007', 'Full Frame', 'Professional' ],
[ 'Nikon', 'D750', '2014', 'Full Frame', 'Action' ],
[ 'Nikon', 'D800', '2011', 'Full Frame', 'Semi-Professional' ],
[ 'Nikon', 'D810A', '2015', 'Full Frame', 'Astro' ],
[ 'Nikon', 'D7100', '2013', 'APS-C', 'Expert' ],
[ 'Nikon', 'D6', '2020', 'Full Frame', 'Professional' ],
[ 'Canon', '1Ds Mark III', '2007', 'Full Frame', 'Professional' ],
[ 'Canon', '5D Mark II', '2008', 'Full Frame', 'Semi-Professional' ],
[ 'Canon', '60Da', '2012', 'APS-C', 'Astro' ],
[ 'Canon', '250D', '2019', 'APS-C', 'Compact' ],
[ 'Sony Alpha', 'Camera 1', '', '', '' ],
[ 'Sony Alpha', 'α 9 II', '2019', 'Full Frame', 'Sport-Pro' ]
]
Setting (Updating) field value of result of rows
To prevent you to make a forEach
loop on the array,
you can use method update()
to set new field(s) value
of you table or you filtered selection.
Below an example to update the Format Full Frame
to a detailed version Full Frame (24x36)
:
cameras.Format('Full Frame').update({
Format: 'Full Frame(24x36)'
});
console.log("Updated Table:", cameras);
Properties of the object passed to the method update()
are the name of defined field.
The result is :
// <<< is pointing updated lines
Updated Table: [
[ 'Nikon', 'D3', '2007', 'Full Frame(24x36)', 'Professional' ], <<<
[ 'Nikon', 'D750', '2014', 'Full Frame(24x36)', 'Action' ], <<<
[ 'Nikon', 'D800', '2011', 'Full Frame(24x36)', 'Semi-Professional' ], <<<
[ 'Nikon', 'D810A', '2015', 'Full Frame(24x36)', 'Astro' ], <<<
[ 'Nikon', 'D7100', '2013', 'APS-C', 'Expert' ],
[ 'Nikon', 'D6', '2020', 'Full Frame(24x36)', 'Professional' ], <<<
[ 'Canon', '1Ds Mark III', '2007', 'Full Frame(24x36)', 'Professional' ], <<<
[ 'Canon', '5D Mark II', '2008', 'Full Frame(24x36)', 'Semi-Professional' ], <<<
[ 'Canon', '60Da', '2012', 'APS-C', 'Astro' ],
[ 'Canon', '250D', '2019', 'APS-C', 'Compact' ],
[ 'Sony Alpha', 'Camera 1', '', '', '' ],
[ 'Sony Alpha', 'α 9 II', '2019', 'Full Frame(24x36)', 'Sport-Pro' ] <<<
]
Delete rows from the table
In the same way of method update()
which allows you to make a mass update,
you can massively delete rows next to a selection.
The method is delete()
and it purposed to used next to a selection
made by calling 'field method'.
Called on the main table, it will drop entirely the table.
Below an example to clear all APS-C
Camera in the table :
cameras.Format('APS-C').delete();
console.log(cameras);
result :
[
[ 'Nikon', 'D3Rename', '2007', 'Full Frame(24x36)', 'Professional' ],
[ 'Nikon', 'D750', '2014', 'Full Frame(24x36)', 'Action' ],
[ 'Nikon', 'D800', '2011', 'Full Frame(24x36)', 'Semi-Professional' ],
[ 'Nikon', 'D810A', '2015', 'Full Frame(24x36)', 'Astro' ],
[ 'Nikon', 'D6', '2020', 'Full Frame(24x36)', 'Professional' ],
[ 'Canon', '1Ds Mark III', '2007', 'Full Frame(24x36)', 'Professional' ],
[ 'Canon', '5D Mark II', '2008', 'Full Frame(24x36)', 'Semi-Professional' ],
[ 'Sony Alpha', 'Camera 1', '', '', '' ],
[ 'Sony Alpha', 'α 9 II', '2019', 'Full Frame(24x36)', 'Sport-Pro' ]
]
Make a copy of table
As saw previously in chapter Setting (Updating) field value of one row
and as it in standard, Arrays work with references.
Updating a row in intermediate variable will update the table.
TableJs
comes with a dedicated method named copy
to get a full new table where reference are broken.
Please find below normal behavior using reference
let D3Cam = cameras.Camera('D3'); // Table with 1 row
let D3Cam2 = D3Cam; // This is not a copy
D3Cam2[0].Camera('D3Rename'); // Rename the camera name
console.log("D3Cam: ", D3Cam); // D3 --> D3Rename
console.log("D3Cam2: ", D3Cam2); // D3 --> D3Rename
console.log("Cameras Table: ", cameras); // D3 --> D3Rename
Result
D3Cam: [ [ 'Nikon', 'D3Rename', '2007', 'Full Frame', 'Professional' ] ]
D3Cam2: D3Rename
Cameras Table: [
[ 'Nikon', 'D3Rename', '2007', 'Full Frame', 'Professional' ], << Also updated
[ 'Nikon', 'D750', '2014', 'Full Frame', 'Action' ],
[ 'Nikon', 'D800', '2011', 'Full Frame', 'Semi-Professional' ],
[ 'Nikon', 'D810A', '2015', 'Full Frame', 'Astro' ],
[ 'Nikon', 'D7100', '2013', 'APS-C', 'Expert' ],
[ 'Nikon', 'D6', '2020', 'Full Frame', 'Professional' ],
[ 'Canon', '1Ds Mark III', '2007', 'Full Frame', 'Professional' ],
[ 'Canon', '5D Mark II', '2008', 'Full Frame', 'Semi-Professional' ],
[ 'Canon', '60Da', '2012', 'APS-C', 'Astro' ],
[ 'Canon', '250D', '2019', 'APS-C', 'Compact' ],
[ 'Sony Alpha', 'Camera 1', '', '', '' ],
[ 'Sony Alpha', 'α 9 II', '2019', 'Full Frame', 'Sport-Pro' ]
]
Now the same process using copy()
:
let D6Cam = cameras.Camera('D6'); // Table with 1 row
let D6Cam2 = D6Cam.copy(); // Make a true copy of the table
D6Cam2[0].Camera('D6Rename'); // Rename the camera name
console.log("D6Cam: ", D6Cam); // D6 --> D6
console.log("D6Cam2: ", D6Cam2); // D6 --> D6Rename
console.log("Cameras Table: ", cameras); // D6 --> D6
Result :
D6Cam: [ [ 'Nikon', 'D6', '2020', 'Full Frame', 'Professional' ] ]
D6Cam2: [ [ 'Nikon', 'D6Rename', '2020', 'Full Frame', 'Professional' ] ]
Cameras Table: [
[ 'Nikon', 'D3', '2007', 'Full Frame', 'Professional' ],
[ 'Nikon', 'D750', '2014', 'Full Frame', 'Action' ],
[ 'Nikon', 'D800', '2011', 'Full Frame', 'Semi-Professional' ],
[ 'Nikon', 'D810A', '2015', 'Full Frame', 'Astro' ],
[ 'Nikon', 'D7100', '2013', 'APS-C', 'Expert' ],
[ 'Nikon', 'D6', '2020', 'Full Frame', 'Professional' ], << Unchange
[ 'Canon', '1Ds Mark III', '2007', 'Full Frame', 'Professional' ],
[ 'Canon', '5D Mark II', '2008', 'Full Frame', 'Semi-Professional' ],
[ 'Canon', '60Da', '2012', 'APS-C', 'Astro' ],
[ 'Canon', '250D', '2019', 'APS-C', 'Compact' ],
[ 'Sony Alpha', 'Camera 1', '', '', '' ],
[ 'Sony Alpha', 'α 9 II', '2019', 'Full Frame', 'Sport-Pro' ]
]
For more feature, please confer to detailed documentation.
Detailed documentation
From this point, you will find the detailed documentation with all user method. Internal method will not be detailed (even if they are callable).
Minimal Instantiation
You can easily create a new TableJs instance like this :
let cameras = new TableJs(); // Will return an empty Array
Managing fields
Field can be managed later next to the TableJs instantiation. That allows you to use TableJs dynamically.
Fields manager is available from your array and return some sub method :
cameras.fields()
.
set
Method The method set()
defines the field list.
This method will overwrite existing field list.
If you only want to add a new field, please confer to method
add()
.
It accept none to many argument with following type :
- String
- Array of String
Important: Field name must respect the naming convention of functions name. For instance, a field can not start with a number.
Sample :
let cameras = new TableJs(); // Will return an empty Array
cameras.fields().set( 'Field1', 'Field2', ['Field3', 'Field4'] );
Each defined field will generates a method on the Array and
on each rows of the Array.
Please confer chapter Dynamic Methods
in this detailed documentation.
add
Method get
Method Managing keys
set
Method add
Method get
Method Managing Data
set
Method add
(Alias append
)
Method get
Method getRow
Method Dynamic Methods
Each defined field will generates a method on the Array and on each rows of the Array.