Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix dot notation with arrays #155

Merged
merged 2 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/config-ref.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ definition. Apart from `sort_by` no other option requires referencing of this id
*Use `modify` and `footer_modify` with _caution_ and at your own risk only. This will directly execute code using `eval()`, which is by definition a safety risk. Especially avoid processing any third party APIs / contents with `flex-table-card` using the `modify` or `footer_modify` parameters, *only apply these parameters if you are 100% sure about the contents and origin of the data.*
Apart from that `modify` and `footer_modify` are very powerful, see [advanced cell formatting](https://github.com/custom-cards/flex-table-card/blob/master/docs/example-cfg-advanced-cell-formatting.md).

**Note: In releases after v0.7.7, using `modify` as a data selector is discouraged. The `data` option can now be used to walk complex structures where `modify` was once needed.**

### Currently the available *formatters are:
* `full_datetime`
Expand Down
4 changes: 4 additions & 0 deletions docs/example-cfg-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ columns:
multi_delimiter: ','
```

### Complex attribute examples
If an attribute or the result of a service call is a complex structure, dotted notation may be used to identify the desired data to display.
See [Loading from Services](https://github.com/custom-cards/flex-table-card/blob/master/docs/example-cfg-services.md) for examples.

<!-- [example image section] -->
<!-- use issue #29 for dumping images and link them here -->
<!-- ![image description](http://url/to/img.png) -->
Expand Down
47 changes: 21 additions & 26 deletions docs/example-cfg-services.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,30 @@
<!-- [full text section] -->
### Demonstration of converting a flex-table-card from using `weather` entity attributes to using a service call response

Home Assistant is moving away from large attribute structures in favor of using service call responses. As a result, you may find yourself needing to convert from using
attributes to using service calls to populate your `flex-table-card`. Fortunately, the process is usually very simple. Consider this card definition that gets the weather
forecast from a `weather` entity's attributes.

<!-- [listing section] -->
``` yaml
type: custom:flex-table-card
title: Weather Forecast Example
entities:
- weather.kboi_daynight
columns:
- name: Detailed Forecast
data: forecast
modify: x.detailed_description
- name: Time Valid
data: forecast
modify: new Date(x.datetime).toLocaleString()
data: forecast.datetime
modify: new Date(x).toLocaleString()
- name: Temperature
data: forecast
modify: x.temperature
data: forecast.temperature
suffix: �
- name: Humidity
data: forecast
modify: x.humidity
suffix: '%'
- name: Precipitation
data: forecast.precipitation_probability
suffix: "%"
- name: Wind Speed
data: forecast
modify: x.wind_speed
suffix: mph
data: forecast.wind_speed
modify: x.toFixed(0)
suffix: " mph"
```

To convert from using a `weather` entity's attributes to using the `get_forecasts` service call, simply add these lines (adjust `type` as needed):
Expand All @@ -39,9 +38,8 @@ service_data:
type: twice_daily
```

This works because the `get_forecasts` service returns information in the same format as the `weather` entity's attributes did. This simple technique may not work with other integrations.
This will work if the `get_forecasts` service returns information in the same format as the `weather` entity's attributes did. Adjustments must be made if this is not the case.

Whether using attributes or the service call, the result is exactly the same:
<!-- [example image section] -->
<img src="../images/WeatherServiceExample.png" alt="Weather service example result" width="500px">

Expand All @@ -59,17 +57,16 @@ entities:
- todo.second_list
columns:
- name: Summary
data: items
modify: x.summary
data: items.summary
- name: Description
data: items
modify: x.description || ""
data: items.description
modify: x || ""
- name: Needs Action
data: items
modify: if (x.status == "needs_action") {"Yes"} else {"No"}
- name: Due
data: items
modify: x.due || ""
data: items.due
modify: x || ""
```

<!-- [example image section] -->
Expand All @@ -89,11 +86,9 @@ service: script.test_response
entities: []
columns:
- name: Name
data: family
modify: x.name
data: family.name
- name: Birth Year
data: family
modify: x.year
data: family.year
```
This is the script:

Expand Down
4 changes: 3 additions & 1 deletion docs/example-cfg-sorting-strict.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ By default, if a column uses the `modify` option, the column will be sorted usin
In some cases, it is absoutely necessary to use the modified values. For example, in cases where `data` contains a complex structure and `modify` is used to select
a subset of that data, the sort operation _must_ use the modified value in order to get a meaningful result. Otherwise, the entire `data` value would be used for the sort.

However, there are cases where the `modify` operation results in values that do not sort correctly. For example, if the modification is used to dynamically create prefixes or suffixes
**Note: In releases after v0.7.7, using `modify` as a data selector is discouraged. The `data` option can now be used to walk complex structures where `modify` was once needed.**

There are cases where the `modify` operation results in values that do not sort correctly. For example, if the modification is used to dynamically create prefixes or suffixes
such as HTML tags, the entire string including the HTML tags will be used for the sort operation.

Another example is a date formatted in the locale of the user. If a date such as "2024-06-23", which sorts correctly, is converted using `modify` to "6/23/2024" or "23/06/2024",
Expand Down
21 changes: 16 additions & 5 deletions flex-table-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,14 +323,25 @@ class DataRow {
// until the final object value is found.
// if at any point in the traversal, the object is not found
// then null will be used as the value.
// Works for arrays as well as single values.
let objs = col_key.split('.');
let value = this.entity.attributes;
if (value) {
for (let idx = 0; value && idx < objs.length; idx++) {
value = (objs[idx] in value) ? value[objs[idx]] : null;
let struct = this.entity.attributes;
let values = [];
if (struct) {
for (let idx = 0; struct && idx < objs.length; idx++) {
if (Array.isArray(struct)) {
struct.forEach(function (item, index) {
values.push(struct[index][objs[idx]]);
});
}
else {
struct = (objs[idx] in struct) ? struct[objs[idx]] : null;
}
}
// If no array found, single value is in struct.
if (values.length == 0) values = struct;
}
raw_content.push(value);
raw_content.push(values);
}
}

Expand Down
Binary file modified images/MultiExample.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/ScriptExample.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/WeatherServiceExample.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.