TailwindCSS Template Card - build custom cards with HTML and TailwindCSS

Spoke too soon, if I add the option below it updates just fine:

        always_update: true

Not sure if that’s what’s intended, but it makes it work.

Thanks for the feedback and for reporting that bug - which is really a bug, it’s not intended.

“always_update” has a confusing name. its purpose is to make the card always rerender when the object hass changes

in other words: whenever any state or attribute in home assistant changes, it will render again your card, even if your content or bindings does not use those updated entities

No problem. Looking forward to actions being implemented. I’m planning on giving it a go at redoing my tablet dashboard with this. That would probably push the card to the limits but we’ll see how far can I get.

1 Like

The binding works for HTML selector, class selector, and for ID selector. But for id selector you need to wrap the ID selector in " or ’ to make it work as the # is a comment tag in yaml.

After adding the binding it doesn’t update with latest value. Only first state is shown. You have to enable ‘alway update’ option or it won’t show the changes.

Note: Since the updated version I cannot use the editor on mobile. It repositions the cursor and typing is laggy.

Whoa, that’s extremely strange and unexpected, since i did many improvements to the performance on mobile
For me, the editor was laggy before the update - and it was due to the editor updating the hass config every type i type any character (that’s why i added debounce)

Haven’t you tried to add the bindings through the UI? Actually that took 80% of the time i spent to implement bindings
For now, only the entity cannot be edited through UI (because i totally forgot that it exists), but i’m already working on it

The UI works fine to add bindings, but to modify the card I need to go through yaml mode as both editors keep refreshing every x seconds.

@silvio may you try v2.1.0-10 and check if Ace Editor is still laggy on your device?

It’s still unusable. The cursor is laggy and keeps jumping when typing.

Do you know how to call the more-info dialog? I tried using browser_mod but first attempts were unsuccessful.

Did you find any way to call the More-Info popup? The only way I’ve been able to make it work is calling a home assist script that calls browser_mod.more_info. Now I still need to find a way to pass the variable to the script using onclick event. I can pass a var using hame assistant, but I don’t know how to write the code for Hass.callservice

I cannot get the state of an element by using code underneath as it returns undefined

var t = states('person.silvio').state; return t;

It works if I do the following because I define the entity in the card

var t = entity.state; return t;

But as I have multiple entities in a card, I would like to call them directly and even be able to work with elements not defined in the card. Is that possible?

One of my examples is using the state of weather to show a badge on a person.

@silvio states is an object

Here are the docs for the hass object, which has hass.states:

Thanks for pointing me to the right direction. I indeed get an object.

Solved using the following to return the state:

var statusObj = hass.states['light.lichten_keuken'];
return statusObj.state;

When I return a html snippet it shows it as plain text. I even tried using document.getelementbyId and innerHTML but it doesn’t like it. I get undefined.

Not working:

var myElement = document.getElementById("icnPersonBmw");
myElement.style.color = "red";
      

Not working:

return '<ha-icon class=" animate-ping" style="color:red;--icon-size:5px !important;" icon="mdi:shield-account"></ha-icon>'; 
      

Full example not working (undefined)

var status = hass.states['light.lichten_keuken'].state;  
      var iconElement = document.getElementById('icnPersonBmw');

      if (status === 'on') {
        iconElement.innerHTML = '<ha-icon icon="mdi:shield-account"></ha-icon>';
      } else {
        iconElement.textContent = 'Off';
      }

Could this be undefined because the code is running before the html element is available?

  1. Can you show me how to return html snippet?

  2. It seems api calls will be depricated in the future. Do you know how to use ws? Could you provide me a snippet?

  3. Can we call an external js file holding all functions? And how would we include the js file in the view?

Thanks in avance for your help.

I’m still stuck. Even if I call js script via onclick it keeps returning null.
See a little example of what I’m trying.

  <div class=""> 
    <p id="demo" class='text-red-600'> Eerste waarde</p>
    <button class='button' onclick='myFunction();  function myFunction(){ 
    var str, element = document.getElementById("demo");
    if (element != null) {
    str = element.value;
  } else {
      str = null;
  }
    alert(str);
  }'>klik mij</button> </div>

Next try will be injecting the custom js via a theme. Will keep you posted.

Hi @usernein

Are you still active on this component? I’m trying to create a complete new dashboard with this.

There are a few things that should be possible to make this work:

  1. Be able to use your own javascript functions from inside the tailwind card and use Javascript from outside the card.
    A. Is there a way to add Javascript to the tailwind card?
    B. Is there a way to use function defined outside the card?

  2. Use the more info dialog as the original ones are becoming awesome. In other words, clicking on an element inside the card opens the More-Info dialog of a specific element defined in that card. Note a card can have multiple elements.

  3. Be able to call browser_mod services

  4. Be able to embed home assistant cards (original and custom ones) in the tailwind card.

This is my first attempt

After a few days of trial and error I’m still struggling to get javascript to work. I added my Javascript file as an external resource so it gets inserted at the end of the body tag, so that is fine. I even managed to get jQuery running, but I’m still unable to fire events triggered by clicking on a button in your card and do some stuff with it. After days of searching I’m getting the concept of shadow Dom and I’m trying to catch up on this. I believe there is my answer.

A few examples of what I want to achieve:

  • to be able to click on a button inside your tailwind widget and interacts with other elements in the same card/widget. For example … adding a class to another element in that tailwind widget.
  • to be able to click on a button inside your element and interacts with elements outside the tailwind widget.
  • to be able to click on a button outside your tailwind widget and interact on an element inside your tailwind widget.

Main reason is to be able to use tabs, hide show buttons and add styling/classes to elements

Can we use your binding for the above cases?
Can we add functions to a ‘general’ js file and call those from your component?

Could you point me in the right direction how I would be able to use my own Javascript functions (preferable importing them from a file stored locally) and use these from your component? Thanks in advance for your help.

1 Like

Hello @fabianluque ! I have great news: the Bindings and Actions are now 100% implemented and working! May you please test it?
It’s missing documentation yet, but it’s exactly the same logic of the card you presented (all the functions of the entity gets available through the entity object)

Also, @silvio, i did a huge refactor that improved a lot the performance and you should not notice the interface being laggy anymore

I also brought some cool new changes to the UI, like an entity picker

The beta version v2.4.0-0 is stable and it’s already available to download and test. thanks for the bug reports and the awesome suggestions!



image
image

Works pretty well! Great work!

I was testing with this template:

      - type: custom:tailwindcss-template-card
        entity: light.attic_lights
        bindings:
          - bind: return entity.state
            selector: span#state
            type: text
          - bind: return attr.brightness || 0
            selector: input
            type: value
          - bind: return attr.brightness || 0
            selector: span#brightness
            type: text
        actions:
          - selector: button
            type: click
            call: entity.toggle()
          - selector: input
            type: change
            call: >-
              this.value === 0 ? entity.turn_off() : entity.turn_on({ brightness: this.value })
        content: |
          <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
            Attic Lights State: <span id="state"></span>
            </br>
          </button>
          <span id="brightness"></span>
          <input id="default-range" type="range" min="0" max="255" class="w-full appearance-none bg-transparent [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-black/25 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:h-[15px] [&::-webkit-slider-thumb]:w-[15px] [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-red-500">

It seems the card is updating (rendering) even though the entity hasn’t changed. It happens to me that when I drag the slider and hold it in place, it gets reset to the previous position after a few seconds.

1 Like

With the new version the lag has improved a lot and the typing issue with the ace editor seems to be solved. Nice job!

Issues:

  1. Strange flickering. It seems there’s a refresh on the cards. Buttons that are bound to an entity keep flickering as if someone is clicking on it.

  2. I cannot open the more info dialog of an entity. @fabianluque did you find a way opening the more-info dialog?

General questions:

  1. How can we add classes to elements in the card? Javascript to getelementbytag,id,class isn’t working.

  2. Calling a function from outside script doesn’t work for me. Do you guys have any suggestions? Would be a nice feature to be able to use tabs and other cool Tailwind stuff.

Thanks for your great work!

@silvio Yes, I was able to trigger the More Info dialog like this:

      - type: custom:tailwindcss-template-card
        entity: light.attic_lights
        actions:
          - selector: button#more-info
            type: click
            call: >-
              hass.callService('browser_mod', 'more_info', { entity: entity.entity_id, browser_id: window.browser_mod.browserID });
        content: |
          <button id="more-info" class="bg-green-500 text-white font-bold py-2 px-4 rounded">More Info</button>


Tx for your help. This works! Are experiencing flickering / refreshes as well? If you have accordions or other collapsible elements on the page they’ll close automatically without any onteraction. Also the tailwind buttons seem to bounce as if there’s a hoover / click on the element without any interaction on it.

Yes, it seems the card it’s refreshing on every HA update instead of just the entity changes.