Lovelace: Button card

Ha, I didnā€™t know that, thanks!
this is the verbose url of course, while I would love to use the view, to make things simpler and easier to read in the templates. Like we can do in Custom header as described on Custom Header
would it be an accepted FR to support some of these builtin variables on Button-card too?

ok thanks, will give it a go. should I use templates on each property individually, like below, or is there a smart way of doing so in short-hand:

hold_action:
  action: >
    [[[ if (window.loaction == 'path.to.home') return 'navigate';
        return 'call-service' ;]]]
  navigation_path: >
    [[[ if (window.loaction == 'path.to.home') return 'developer';
        return none ;]]]
  service: >
    [[[ if (window.loaction == 'path.to.home') return none;
        return 'automation.trigger'; ]]]
  service_data: >
    [[[ if (window.loaction == 'path.to.home') return none;
        return 'entity_id: entity' ;]]]

btw using this to test:

      - type: custom:button-card
        show_label: true
        name: >
          [[[return hass.user]]]
        label: >
          [[[return window.location]]]

returns:
Schermafbeelding 2020-05-08 om 10.34.36

meaning the window.location is displayed alright, but I cant see the user.
Tbh, I am struggling with whatā€™s written at the bottom here button-card/README.md at master Ā· custom-cards/button-card Ā· GitHub on the variables available inside the JS codeā€¦ How do I use that? I didnā€™t find any example or documentation about user (or has for that matterā€¦) must be missing the obvious, but in all my button configs, Iā€™ve simply never encountered the need/issue

No, itā€™s not, you didnā€™t read the link. You have access to the path also directly.

Yes, you can return a complete object for hold_action. Static example:

hold_action: |
 [[[
    let res = {
      action: "call-service",
      service: "whatever"
   };
   res.service_data = {};
   res.service_data.entity_id = entity.entity_id;
   return res;
 ]]] 

correct, sorry, didnt realize it was a link to the W3schoolā€¦still, it doesnā€™t allow finding the view name only, or the Lovelace path, as defined in the view config:

title: Test
icon: mdi:test-tube
path: test
cards:

window.location.pathname coming closest, but still returning ā€œ/lovelace/testā€
so

label: >
  [[[return window.location.pathname.split('lovelace/')[1] ]]]

is needed for
Schermafbeelding 2020-05-08 om 10.51.23

now how to find the userā€¦

wow, thatā€™s a first for me, have to study whatā€™s done there, and how to use the templates in that.
let and ā€˜resā€™ being the great unknowns to meā€¦back to w3schools I fear :wink:

using the template I need, could it be something like:

        hold_action: |
         [[[
             let res = (window.location.pathname.split('lovelace/')[1] == 'home'
             ? {
                 action: "navigate",
                 navigation_path: "developer"
                 }
             : {
                 action: "call_service",
                 service: "automation.trigger",
                 service_data.entity_id: "entity.entity_id"
               }
            return res;
            );
          ]]]

I tried a standard construction with if (window.location.pathname.split('lovelace/')[1] == 'home') but got stuck declaring the let that way.
Now I am stuck returning the resā€¦with the double ā€˜returnā€™ in the template

You have to convert it to a string :wink: Remember how I always tell you that you need to learn these damn languages so you can do things on your own?

String(window.location.pathname).split('lovelace/')[1]

Petro, he speak with forked tongue

:rofl: :joy: :rofl: :joy:

You are a bit harsh on me here, I am trying to do something I havenā€™t seen any example of yetā€¦
and btw,

        label: >
          [[[let res = window.location.pathname.split('lovelace/')[1];
             return res ]]]

works just fineā€¦

its the template for the hold action based on this value I cant get right

Lol, CSS is the ONLY exception! Although Iā€™d have to admit that Iā€™ve learned a lot about it in recent months.

Thatā€™s the thing here. Youā€™ve been here a LONG time. One basic element of all langauges (doesnā€™t matter the language) is object typing. If you take a beginner course in ANY language, you learn about this in the first 3 tutorials. Iā€™ve been harping on you for years to take something with the amount of developing that you do and itā€™s clear you still havenā€™t.

If you get Object object in js as your returned string, that means you have an OBJECT and not a STRING. I.E. you convert the object to a string with a simple google search ā€œconvert window.location.pathname to stringā€.

EDIT: And just to clarify, I didnā€™t know how to do this and simply googled that and showed you the first result that I found.

think there is some misunderstanding goin onā€¦ what did you think I was asking? because thereā€™s no problem getting the path(name) to the button frontend.

right now, this is my quest:

Sorry I miss interpreted the post and thought you needed the location when you needed the username.

As for your quest, you didnā€™t follow @RomRiderā€™s post.

thatā€™ declares the object as a dictionaryā€¦

which allows

So, with your knowledge. How would you declare a dictionary?

I am not sure, but this seems to pass the parser:

         [[[
             let res = (window.location.pathname.split('lovelace/')[1] == 'home'
             ? {
                 action: "navigate",
                 navigation_path: "developer"
                 }
             : {
                 action: "call_service",
                 service: "automation.trigger",
                 entity_id: "entity.entity_id"
               });
            return res;
          ]]]

havenā€™t tested it in my button yet, only in the inspector.

Youā€™re declaring 2 dictionaries in your post. If that helps. And no, that wont work.

Also, is entity an object?

Yes I understand thatā€¦ that is because depending on the state of the pathname, I either want to trigger the entity_id, or navigate to another view. These 2 different actions need to different dictionaries. Or so I thoughtā€¦

Right, so if youā€™re declaring 2 dictionaries and service_data needs to be a dictionaryā€¦ how would you add entity_id to itā€¦

youā€™re returning a string here but it should be the value of the variable, not the string. Also youā€™re missing the service_data. Iā€™ve cleaned up your code a bit.

         [[[
           let res; // let is same as var. res is just a variable name.
           if (window.location.pathname.split('lovelace/')[1] == 'home') {
             res = {
               action: "navigate",
               navigation_path: "developer"
             };
           } else {
             res = {
               action: "call-service",
               service: "automation.trigger",
               service_data: {
                 entity_id: entity.entity_id,
               }
             };
           }
           return res;
         ]]]

EDIT: Actually, it might not work (just re-looking at the button-card code right now and how Iā€™ve handled it :smiley: But you can give it a try)

1 Like

like this?

[[[
  let res = (window.location.pathname.split('lovelace/')[1] == 'home'
  ? {
     action: "navigate",
     navigation_path: "developer"
    }
  : {
     action: "call_service",
     service: "automation.trigger",
     service_data: {
       entity_id: entity.entity_id }
       });
  return res;
]]]

ā€“editā€“
now see @romrider chiming inā€¦

Thanks!
I started out that way but didnt know I had to start with

let res;

so tried the ternary route.

is there an advantage of doing it like this in anyway?

btw: think to have learned by now that let is a block variable and var is a global variable?

Readability :slight_smile:

let is block scoped and var is function scoped. Better use let than var, itā€™s cleaner and avoids strange stuffā€¦

1 Like

thanks Romrider and @petro, your efforts, And educating me are appreciated.