Event Listener for Dynamic Lists (React Version)

Hi guys,

New React lists feel great! I would love to learn more about Even Listeners for the new React lists to move our custom codes to the new version. Some of our use cases:
_ Listen for when the list finishes loading.
_ Listen for filter value change.
_ Count the number of total items
_ Mutation Observer / when a node is inserted

Regards,
Son

2 Likes

Huge ++ to this please. @artur

here are few events that could be helpful

block-loaded event is triggered when React mounts the block into DOM. It can be used instead of DOMContentLoaded event that is used in old custom codes.

window.addEventListener('block-loaded-table1', () => {
	console.log('Block loaded');
});

get-records event is triggered on every data response from softr data service. It can be used for getting the data manipulating before it get’s rendered.

const onRecords = (e) => {
	// we got new data under e.details
	console.log(e.detail);
	//console.log [{id: '***', fields: {...}}]
};

window.addEventListener('get-records-table1', onRecords);
const onRecords = (e) => {
	setTimeout(() => {
		// The block finish rendering 
		// I may do some staff here.
	}, 50);
};

window.addEventListener('get-records-table1', onRecords);

get-records:before event that is triggered before sending request, It can be used to catch the inline filter or search field changes.

const onFilterChange = (e) => {
	console.log(e.detail);
	//console.log { search: '', filter: [ { field: 'size', value: 'M' } ] }
};

window.addEventListener('get-records-table1:before', onFilterChange);

Note: table1 is the block name in studio settings

3 Likes

Thank you so much.
You save my week :slight_smile:

1 Like

@artur this code doesn’t appear to work when targeting header blocks.

I’ve tried a handful of different approaches in this topic and I haven’t been able to get it to work.

Using a DOMContentLoaded event works, but for some reason Safari has a hard time finding the HTML element to update (separate issue).

IMPORTANT NOTE

When using this event listener in a script=> window.addEventListener('block-loaded-BLOCKID', () => {
You absolutely need to place your script in the header custom code not the footer.

As now Softr blocks are loaded faster than before => sometimes block loads faster than the footer code is being executed. Which means that the script won’t work properly (it will work 50% to 60% of the time…)

In general, any script with one of those event listeners listed above should be placed now in the header custom code.

Even more specifically when the script should be executed, using one of those event listeners, just after a page load.

1 Like

Thanks a lot for this, @matthieu_chateau. Much appreciated!

1 Like

In theory, could we use get-records to intercept a timestamp field and dynamically update it to the user’s timezone based on their browser?

Hello colleagues, I have this code and it works. But the question is how to modify it so that it does not count the values ​​​​in the field from the table, but provides a single value from the field in the list-details component:

<div class="subtotal-container">
  <span>Suma Ilości Przyjętej:</span>
  <button class="subtotal_value">0</button>
</div>

<style>
.subtotal-container {
  display: flex;
  align-items: center;
  justify-content: flex-end; /* Align to the right */
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 5px;
  background-color: #f0f0f0;
}

.subtotal-container span {
  font-weight: bold;
  margin-right: 10px;
}

.subtotal-container button {
  background-color: #645d67;
  color: #fff;
  border: none;
  border-radius: 5px;
  padding: 5px 10px;
  cursor: pointer;
}
</style>

<script>
window.addEventListener('get-records-table2', (data) => {
    let totalSum = 0;
    
    if (data.detail) {
        data.detail.forEach(item => {
            let amountString = item.fields["Ilość Otrzymana"];
            let amountInt = parseFloat(amountString);
            if (!isNaN(amountInt)) {
                totalSum += amountInt;
            }
        });
    }
    
    document.querySelector(".subtotal_value").innerText = totalSum;
});
</script>


Thank for your answer