I was very happy with the addition of the sorting on columns however I see an issue that I am not sure how to resolve. If you use HTML markup in the modify command, the sorting seems to be based on the HTML markup and not some value.
Now the values for x[8] can be 2,3 or 4 really (this is the data). If I just output x[8] the auto sorting is fine, but using the above template and sorting the column I get this:
As you can see 4 … then 2 … then 3 because the sorting is not based on the value of x[8], it must be based on something that aligns with the HTML code in the cell to get specific colors.
Am I wrong? If not, then the “sort” for a column click should be separate from the “modify” for that column.
For completeness, that is from a decluttering template so it is used like this:
- type: custom:decluttering-card
template: sos_settings
variables:
- title: NHL Strength of Schedule
- entity: sensor.hockey_sos
- attribute: pageProps.dataRows
So x is “dataRows” and I want to sort by x[8] when I click the sort column and not by:
<div style="background-color:lightgreen">4</div>
If this is “how it is” then I will post an enhancement request which should allow one to specifiy what to sort-by when you click the sortable header.
Now I could add:
sort_by: pageProps.dataRows-
And add a hidden column for the first column, but the instant someone sorts the column, you can never return back to that view (so that is not the answer). I could create a non-hidden column just for that original sort and display nothing in it but that is a total kludge also.
Updated KLUDGE Workaround (put the number as the first entry in the cell and set display:none):
Does anybody know why an unavailable value is displayed as “undefinedundefinedundefined”, i.e. three times “undefined”?
I do not want to use strictbecause some values are available despite others not being available. Or is there an option I missed that allows omitting only “undefined” data?
EDIT: Found the workaround in the github issues and this thread, duh.
Just use
modify: if(x.length == 0){"-"}else{x}
It will replace all unavailable data with “-” (or whatever else you want)
Is there a way of comparing the value of column 3 with column 2 of the same row?
I think you mentioned this in another answer in this thread and said it is not diretcly possible but in another answer you mentioned that the attributes should be available.
So am I correct in thinking that I cannot “read” the value of column x but I can read the attribute that is being used in column x and it will automatically be the one from the same row?
Because x is always already the attribute of an entity. So how would I read a different attribute of that same entity? I cannot go to the parent of x, I don’t think
I can’t find any documentation on how these work or examples of how to use them, and try as I might, I can’t get them to work. It would be interesting to see what they do and if they are different than the the two “passed” formatters. Has anyone used them?
Assume some entity has attr1 and attr2 attributes.
If some column is associated to attr1 - then X is a value of this attribute.
You cannot use attr2 to modify a value of this column.
Next, assume 2 columns are associated to attr1.
In both columns you may use X (which points to same attribute) to modify values.
The only way to use ANY attribute in a column - keeping (sub)attributes in a dict as it was suggested earlier.
I created a workaround table that is more or less working.
I have not yet figured out where the small gap is coming from.
I also have not figured out how to make sure the rows are aligned because if the header of table 1 is 3 lines and that of table 2 is 2 lines, the rows no longer align.
I posted an enhancement request for those that do not follow on Github. Please take a look and comment on
Essentially I see this very similar (but different) to the formatters. Instead of canned functions that exist only within the core like CellFormatters are, I would think many folks would benefit from being able to create Javascript functions that can be used in “modify” and accept data, perform complex, user-written functions that are not common for anyone but the user (or perhaps to be shared with others that may use your implementation).
This is different than CellFormatters as they are burned into the core JS code and I would think external to that would be best. This is well beyond my JS capabilities for implementation but from what I did, it works perfect.
Comment, call me crazy, tell me how to do it differently … any/all answers welcome but chime in if you understand and think this is valuable.
As a note, I did manage to standardize this which requires one line change in the flex-table-card.js:
Step one, one minor change to the core JS (only the first few lines shown here and the change is adding the “import”):
"use strict";
// Import Plugins
import * as plugin from "./flex-table-card-plugins.js";
// VERSION info
var VERSION = "0.7.5";
This will import a separate JS file into a class named “plugin”. The file would be located in the same directory as “flex-table-card.js” and named “flex-table-card-plugins.js”. Of course you can change that name if you like.
Step two, put your function(s) in this file which will be imported. You add the keyword “export” in front of the function so that it is exported and available within the core JS. One example:
export function drawscore(place, score){
var cellstring = '';
if (place == 1 || place == '1T') {
cellstring = '<div style="font-weight:bold; color: black">' + score + ' ' + '<span style="font-size:14px">' + place + '</span></div>'}
else if (place == 2 || place == 3 || place == '2T' || place == '3T') {
cellstring = '<div style="font-weight:normal; color:black;">' + score + ' ' + '<span style="font-size:14px;font-weight:bold;color:black">' + place + '</span></div>'}
else {
cellstring = '<div style="font-weight:normal; color: #888;">' + score + ' ' + '<span style="font-size:14px">' + place + '</span></div>'}
return cellstring;
}
Step 3, use them! They are in the namespace “plugin” referred to on the “import” line. To use one you would call it by adding the namespace in front of the function name. So the example above becomes:
Now, if the install of flex-table would create an empty JS “plugins” file and never wiped it out on updates, it would provide this enhancement. Otherwise, on updates you could always reimplement this by adding the one line in the core JS.
When accessing attributes, sometimes an attribute object will itself contain objects. In that case, you can access the lower object using dotted notation. eg: object1.object2.field1
Oh wow, indeed - the 0 did the trick.
Interesting as I was trying similar things already (repositories[0|1].display_name, repositories.display_name[0|1] etc.).
Edit: this does not work. If there are two elements, using repositories.0.display_name really only lists exactly that first. In other words: I only get one row! So back to start, looking for a solution…
I was wondering if that could be done using a template for loop.
Do you know if the number of columns is available as information so the user does not need to define it?
In you rexample (and I am using it like that), you need to define the width of each column separately. So if you have 20 columns you need to repeat the same line of code 20 times.
Maybe a for loop would achieve the same, i.e. something like
{% for i in range(1, number_of_columns) %}
{% tbody tr td:nth-child(i)+: 'width: 1em' %}
{% endfor %}
where the number of columns is maybe readable from the card somehow?