Object-table - How can select all items in the one page

Hi Support team. I’m using the object-table to create a table that has a multi-select like below:

  1. Then I need to select all the items on the same page (not all items on the table), But I can’t find out the solution for this one ( I can select base on the index of each item for selection, but when I do some filter or sort, then my logic will not working fine).
    So do you have any solution or idea for this one? Just “select all” on the current page.

  2. And another question about ‘on-state-change’ attribute of object-table, I want to get the action “change page” of the user, to disable or enable the button, So when the user changes the page, in the JS file, the value is changed, but the UI is updated quite slow (take the 30s - 1m), Do you know why?

XML file:

 <object-table label="" query="jobs_array" loading="$: isLoading" init-state="$:initState()" limit="$: entries" mode="paginate" on-state-change="tableStateChanged($state)" empty-message="Your items will appear here">
        <column-group heading="Jobs">
            <column heading="Well" filter="true">{well_name}: {well_type} [{well_status}]</column>
            <column heading="Job">{job_number}: {job_name}</column>
            <column heading="Type" filter="true">{job_type}</column>
            <column heading="Status" filter="true">{job_status}</column>
            <column heading="Days on Well">{days_on_well}</column>
            <column heading="Spud Date">{spud_date}</column>
            <column heading="Locked By" filter="true">{$:getUserName($object)}</column>
            <column show-if="$: RoleUtil.isAdmin()" filter="true" sort="false" sorting="false" style="$:getRowStyles($object)" fit="shrink">
                <header-action on-press="$:selectAll()" icon="$: checkIcon()"/>
                <edit-boolean value="$object.archived" on-change="$:valueChanged($object, newValue, oldValue)" />
            </column>
        </column-group>
        <action on-press="$: jobOptions($selection)" icon="$: getJobSubscribeIcon($object)" />
        <button-group mode="split">
            <button on-press="$: onSelectEntries(15)" label="$: entries"/>
            <button on-press="$: onSelectEntries(25)" label="25"/>
            <button on-press="$: onSelectEntries(50)" label="50"/>
            <button on-press="$: onSelectEntries(100)" label="100"/>
            <button on-press="$: onSelectEntries(200)" label="200"/>
        </button-group>
    </object-table>

JS file:

var isLoading = false;
var isSelectAll = false;
function selectAll() {   // when click icon select all (action header)
    isSelectAll = !isSelectAll;
    jobSelected = [];
    if(page == 1){
        for( var i = 0; i < (view.jobs_array.length >= entries ? entries : view.jobs_array.length); i++){
        var job = view.jobs_array[i];
        if (isSelectAll) {
            job.archived = true;
            job.save();
            jobSelected.push(job.job_number);
        } else {
            job.archived = false;
            job.save();
        }
        }
    }else{
        for( var i = entries*(page-1); i < (view.jobs_array.length >= entries*page ? entries*page : view.jobs_array.length); i++){
        var job = view.jobs_array[i];
        if (isSelectAll) {
            job.archived = true;
            job.save();
            jobSelected.push(job.job_number);
        } else {
            job.archived = false;
            job.save();
        }
        }
    }
    isJobSelected = jobSelected.length > 0 ? true : false;
}

var page = 1;
function tableStateChanged(state){  // on-state-change
    if(page == state.page){
        saveState = state;
    }
    if(page != state.page && isSelectAll){   // will take 30s - 1m to update UI??
        isLoading = true;
        component.dialog({ id: "confirm" }).show();
        onReset();
    }
    page = state.page;
}

Any solution for this one?

Hi Kien,

This is not currently possible using a header-action, however we’ve added this to our product feedback.

One possible workaround would be to add an action button to your table, something like this:

image

Let me know if this is an acceptable workaround for you and I can share the code for how that button would access the rows currently rendered.

Yah, Can you share your code?, I need to review and if it is possible, I’ll include it in my code. Thanks

@kien.tran2 Something like this is what @kobie is referring to

VIEW XML

<object-table label="Select one to view details" query="tickets" empty-message="Your items will appear here" limit="5">
    <column heading="Date">{date}</column>
    <column filter="true" heading="Customer">{customer}</column>
    <column filter="true" heading="Pad">{pad_name}</column>
    <column style-align="right" heading="Total">{$object.ticket_total}</column>
        
    <button-group>
        <button label="Select all" icon="fa-check" on-press="$:selectAll($filteredData, controls)" validate="false" style="outline" />
    </button-group>
</object-table>

VIEW JS

function selectAll(filteredData, controls) {
    var startIndex = (controls.page - 1) * controls.limit;
    var endIndex = controls.limit * controls.page;
    // slice the current visible page's objects out of the array of all objects currently rendered (sorting and filtering included)
    var selectedObjects = filteredData.rows.slice(startIndex, endIndex);

    // Now you can do what you need to with the selectedObjects
}

In short, the object-table variable $filteredData contains an array of all the DB objects currently rendered in the table across all pages. And so we just need to ‘slice’ out the specific page that we are interested in, the current page in this case, which is stored in controls

2 Likes

Thanks @tielman , It helps me to resolve the first issue!
And how about the second issue? with the on-state-change, Purpose I want to clear all selected from page 1 when I move to page 2, And my tableStateChanged function will take some 30s - 1min to do it. So how can I do this action quickly ? or any solution for doing it?
Thanks

Hi @kien.tran2

Object-table performance is split into 2 broad groups.

  1. Query performance (how long it takes to get the data from the DB)
  2. Rendering performance (how long it takes to render the data in the table)

Since both of these are app and data specific, the solution/optimization will be specific to your app. Without looking at the specific code, but based on the fact that the performance issue is on state-change, I would assume that the problem is with the rendering aspect (but that depends on exactly what you are doing in your functions)

I would look at these articles below to start and then if you need more help with App Optimization then you can reach out to your JourneyApps Customer Success team as this is a service that they can provide

  1. Best Practices
  2. Improving App Performance

Hi @tielman / Support
I have a similar problem using object-table

  <var name="cip" type="query:cip_verification_form_supply_line"  />

    <object-table query="cip" label="CIP Verification form Supply Line" controls="top" empty-message="There is no data" >
        <column  heading="ID Number">{user.id} </column>
        <column  heading="Province">{customer.province} </column>
        <column  heading="Name">{name}</column>
        <column heading="Date">{date}</column>
        <column heading="Status">{status}</column>
                
    </object-table>

  1. The SEARCH isn’t showing
  2. I would like to know if its possible to display records in one table from different Data models and and when the user clicks Edit view open allowing user to update the specific record. (Different Edit views for each Data Model)

Thank you

Hi @desiremuson,

Can you send us a support ticket at support@journeyapps.com for the issue where the search is not showing with a link to your app and which branch and view you are experiencing this issue on. This will help us investigate this issue further.

In regards to showing objects from different data models on one table, you can achieve this by creating a LocalDB model and creating the objects from different DB models within the LocalDB model.

For example, if you have the following models fruit, vegetable, and bread and you are wanting to show the objects for each of these models in the same table, you will need to first create another model, for example, food. You will only use the food model for LocalDB.

On your view, you can query for each model’s objects and then create them within the food model using LocalDB as shown below.

for (var fruit in fruits) {
   var local_fruit = LocalDB.food.create();
   local_fruit.setAll(fruit);
   local_fruit.idn = fruit.id;
   local_fruit.item_type = "fruit";
}

for (var veg in vegetables) {
   var local_veg = LocalDB.food.create();
   local_veg.setAll(veg);
   local_veg.idn = veg.id;
   local_veg.item_type = "vegetable";
}
....

You can follow this same approach for all models that you are wanting to display in the table. I would suggest you save the object’s ID to the LocalDB copy so that you can easily reference it if needed as shown above with the idn field.

After you’ve created all the copies of the objects to LocalDB, you can then query your food model to display all of the objects in the table.

In order to then navigate to the appropriate view if a user selects to edit the object from the table, you can also save the item_type as a new field on your LocalDB object as shown above in the code example. This will allow you to see what the actual model is in order to navigate to the correct view. With saving the ID, you can also then pass in the database object rather than the LocalDB copy to the view to edit.

Please note that after editing the object, the LocalDB copy will either need to be updated, or all LocalDB objects destroyed and re-created to show correctly in the table.

Let me know if you have any questions.

Hope this helps!

1 Like

I realise that this might be solved already through support, but for anyone else in future: that table looks like a V2 Object table, and not the latest V3 object-table