custom-cards / flex-table-card

Highly Flexible Lovelace Card - arbitrary contents/columns/rows, regex matched, perfect to show appdaemon created content and anything breaking out of the entity_id + attributes concept
GNU General Public License v3.0
208 stars 26 forks source link

Adding CSS selectors to specific rows based on attribute #32

Open shawly opened 4 years ago

shawly commented 4 years ago

Similar to sorting it would be nice if one could add a CSS selector based on an attribute of the entity, that way it would be possible to apply different styling to rows based on the selector.

For example:

type: 'custom:flex-table-card'
entities:
  include: sensor.example.*
columns:
  - prop: state
    name: 'Status'
    as_css_selector: 'tr' # apply state as css selector for row
css:
  tr.state-on: 'color: green' # to make the font of rows with the .state-on selector green
  tr.state-off: 'color: gray' # to make the font of rows with the .state-off selector gray
daringer commented 4 years ago

mmmh, that's a smart approach, buying it!

shawly commented 4 years ago

tr.state-on is just the css selector, since the table row has the class "state-on" you can style it via "tr.state-on", that way you could technically also use as_css_selector with something other than tr, td for example to give a cell a specific styling. Here is an example for package tracking:

type: 'custom:flex-table-card'
entities:
  include: sensor.parcel.*
columns:
  - prop: state
    name: 'Package delivery'
    as_css_selector: 'tr'
  - attr: carrier
    name: 'Carrier'
    as_css_selector: 'td'
css:
  tr.state-delivered: 'color: gray'
  td.carrier-dhl: 'background: yellow'

Would produce html like this:

<table>
...
  <tr class="state-delivered">
    <td>delivered</td>
    <td class="carrier-dhl">
  </tr>
...
</table>
daringer commented 4 years ago

ok ok, getting closer, means as_css_selector (btw. think it should be called css_class_for) will additionally add the class to the chosen html-tag. So your output example would actually look like this:

<table>
...
  <tr class="state-delivered">
    <td>delivered</td>
    <td class="carrier-dhl">carrier-dhl</td>
  </tr>
...
</table>

correct?

shawly commented 4 years ago

Yeah this is how I imagined it, css_class_for indeed fits better.

gsolem commented 4 years ago

Any chance to format a cell based on value? E.g. if it contains a negative value it should have red background or font color.

daringer commented 4 years ago

@gsolem, the approach above somehow not trivial to realize. But you can easily use modify for this behavior, you'll get the value as x into the modify-scope and from there just select your path to the designated cell and change its css

gsolem commented 4 years ago

@daringer I looked at the css option but can only do it for a row or column as far as I can see. Also not sure how you mean css can be used inside the modify parameter?

ghost commented 4 years ago

@daringer: Care to elaborate a little bit?

I get the data/values from x, but given you want to color the cell or (in my case) the whole row depending on some value, I'm struggling to figure out how to append a css class to the cell or row. Is it possible to modify the table from the modify-scope? I don't see how the data from x will help me here as there is no information about the table in there. For now I've added a wrapper div around the data, but that does not color the whole row, just the cell with some horrible css.

Doing something like document.getElementsByTagName("table");or this.data does not seem to work.

This is by far one of the most versatile and usefull cards for Home Assistant, great work!

daringer commented 4 years ago

for some reason I have been under the impression this was working before, but just tried it and have to admit: no it doesn't! anyways this is not too trivial to be solved without breaking backwards compatibility... open for suggestions/PRs how to solve this

teskanoo commented 1 year ago

FYI I have achieved adding CSS to a row based on the value of a single cell in that row as follows

image

The CSS section looks like this


      css:
        'tr:has(> td div.triggered)': 'background-color:lightgreen !important;'

The column definition looks like this


      - name: observation
        align: right
        data: observations
        modify: >-
          if(undefined === x.observation){
            "none"
          }
          else{
            x.observation
              ? '<div class="triggered" style="color:green;">true</div>'
              : '<div class="not-triggered" style="color:red;">false</div>'
          }