I’m trying to set up a component that lets me display multiple items, add items, remove items and modify items, pretty simple stuff. I thought of making it using a List View, so I started testing with that.
I added the component to the page and without changing anything tried to run an action which only does:
return {{ui.listView.value}}
And the result is… just [{},{},{},{},{},{}] an array of empty objects… What?
Maybe there’s something wrong in the settings, or I’m not asking for the right thing, I thought, but no, nothing I tried actually returned the values of the items. So I checked out the documentation for the List view and the very similar Grid view and in the docs for Grid view there was an example that shows how to set/get values. But it doesn’t do it with the properties ui.gridView.value and ui.gridView.setValue, but instead with an extra State variable.
If it is intended that the List view and Grid view are used like that, with a State variable, why do they have ui.<component>.value and ui.<component>.setValue?
On the other hand, these components are similar to the Accordion component, which has no issues with getting/setting the value.
I see how it is. Since the List view is under the Structure category, I thought the component is more of a pure display type. But it does make sense to do it that way.
Sorry for re-opening a year-old discussion, I wasn’t sure i need to create a new topic, because my question is actually a follow-up.
Given that:
ui.list.value contains data from the inputs added to the ListView, not the data used to render the ListView.
How could we access the data of editable non-input components in a list view? Ex.: In my list view, i have a table with editable columns. Is there a way to get the edited value of these tables ? I don’t know if this is possible to achieve.
Don’t worry, it makes perfect sense adding to this post.
This is actually pretty easy when you think about it. As was said previously, ui.listView.value gives you the values of all inputs on the cards. The Rating component is an input.
Therefore, if you have Rating components in the cards
Thanks for your reply.
Rating components are working perfectly, but in my example i don’t have rating components, i just have a table with rating columns.
The table is not itself an input component, so i can’t access its values.
But the same problem occurs if i use simple numeric or text columns in my tables: i still can’t access the table’s value.
This is already a known issue with ListView/GridView components. While these components are described in the docs like
The List View component serves to display a collection of items.
they do also provide utility for inputs and such, but only directly on the component. It would be nice if the cards generated would be indexed and callable in a more direct way, for example {{ui.listView.get(n)}}, but nothing of the like is implemented yet.
But ultimately it’s all about using the things we’ve got in the best way possible. Personally, I also think that tables inside the ListView make it squeezed/compressed. If possible for what you’re trying to achieve, think about restructuring with the inputs directly on the ListView, using entirely different components, or creating a custom component using modules.
This is sadly a limitation of the current state of such structural display components.
Assuming you’ve already set up that the data from the table is updated properly when edited, all you need to do is add {{JSON.stringify(item)}} as the Text Input’s value:
Finally, make a JavaScript action that grabs the values of the inputs directly from the DOM, so something like
// action named 'getTableValues'
const index = {{data}};
const lvs = [...document.querySelectorAll('.listView2 .content>ub-slot')];
if (typeof index === 'number' && index < lvs.length) {
return JSON.parse(lvs[index].querySelector('.input input').value);
}
return lvs.map( lv => JSON.parse(lv.querySelector('.input input').value ));
Now you can call the action as actions.getTableValues.trigger(n), where n is either a number between 0 and amount of ListView items - 1, or any falsey value (null, undefined, etc. so just don’t pass anything). That way you can get either the values of a specific item or all items: