Display Referenced Query Results To Table

Hello. I know this code can be a bit spotty. I am learning as I am putting this together.

:confused:

We currently have the following collections:

Bookings/Services

Tutors

I have also added an on-page user input “search bar” element to where the users can search for either their Tutor name or their Service Name.

These items are then displayed on a collapsed table directly below the search bar.

What I am trying to figure out is how to query both of these items to have them show side by side in Column 1 and Column 2 respectively. Please help! :cry:

Initially the plan was to have all of these items display within the same row, which is where .concat was able to help. Now that I am trying to split both of these data items into 2 different columns, I am so lost I don’t even know how to move forward. Here is my on-page code:

  
import wixData from 'wix-data'
import wixLocation from 'wix-location'
// For full API documentation, including code examples, visit http://wix.to/94BuAAs

$w.onReady(function () {

    $w("#table1").columns = [

       {

 "id": "col1",
 "dataPath": "serviceName",
 "label": "Service Name",
 "width": 300,
 "visible": true,
 "type": "text",
 "linkPath": "servicePageUrl",

        },

{

 "id": "col2",
 "dataPath": "serviceName",
 "label": "Service Name",
"width": 300,
"visible": true,
"type": "text",
 

}
 
    ];

});

export function search1_keyPress(event) {

    setTimeout(function () {

        wixData.query("Bookings/Services")
            .contains("serviceName", $w("#search1").value.toLowerCase()) 

//if I didn't use this, the .contains fails to find any items. I was told .contains is not case sensitive, however, when I tested it...it most definitely was

            .find()
            .then((results1) => {

 let results1Items = results1.items;

                wixData.query("Tutors")
                    .contains("staffName", $w("#search1").value.toLowerCase())
                    .find()
                    .then((results2) => {

 let results2Items = results2.items;

 const allResults = results1Items.concat(results2Items);

 if ($w("#search1").value.length === 0) {

                            $w("#table1").collapse();

                        } else {

                            $w("#table1").rows = allResults;

                            $w("#table1").expand()
                        }

                        console.log("Search Completed");
                    })

            })

    }, 500)
}

export function table1_rowSelect(event) {
 
 let rowData = event.rowData;
 let rowIndex = event.rowIndex;
 const myRow = event.target.rows[rowIndex];
    wixLocation.to(`${myRow["servicePageUrl"]}`) 
} 

1 Like
  1. Why do you need a tutor collection when wix booking provide a staff collection?

  2. I would suggest to query staff and service only once (you load everything on start so you don’t have to query anything later)

let ServicePromise = wixData.query("Bookings/Services").find().then(result => result.items);
let StaffPromise = wixData.query("Bookings/Staff").find().then(result =>  result.items);


export function filterResult(event){
      if ($w("#search1").value.length === 0) { 
           $w("#table1").collapse(); 
      } else {
           Promise.all([ServicePromise, StaffPromise]).then( results => {
               //filter the service by name
               let data = results[0].filter(service => {
                    return service.name.includes(event.target.value);
               }).map(item => {
                    text: item.name,
                    url: item.servicePageUrl
               });
               
               // add the filtered staff to services
               data.concat(results[1].filter(staff => {
                    return staff.name.includes(event.target.value);
               }).map(item => {
                    text: item.name,
                    url: item.staffPageUrl
               }))
               
               
               $w("#table1").rows = data // row column are text and url)
               $w("#table1").expand()  
      }  
    }
}

I did not run the code, there is probaly mistake but that’s the idea. It will be super fast because you query the data only once

does it make sense to you?

Due to the Bookings/Services and Bookings/Staff collections being read-only, how would I be able to add any data as to “connect” these two items? Service Name and Tutor Name?

Indeed there is no native way to consolidate the 2. You have to create a collection staffForService where you store staffId and serviceId (with a reference so you can query data in one query)

you could do something like

...
let rowSelector = $w(...); 
promise = wixData.query(staffForService).include(staff).include(service).find().then(result => result.item);
...

function updateData(event) {
    search = event.target.value;
        
    promise.then(items => {
       let itemsToDisplay;
       if(!search.length){
         itemsToDisplay = items;   
       } else {
           itemsToDisplay = items.filter(item => {
                return item.staff.name.includes(search) || item.service.name.includes(search);
            })
        }
        rowSelector.data= itemsToDisplay;
    })
}


Did I answer your question? :slight_smile:

Novice Alert! I think I broke it by getting confused.

This is what I have right now…Trying to follow along. :confused:

authors includes 3 columns of data:

  1. Referenced Data From “Bookings/Services” - titled “courses”
  2. Referenced Data From “Bookings/Staff” - titled “staff”
  3. Empty data field - titled “title” - just didn’t remove this one is all, added others instead.

import wixData from 'wix-data'
import wixLocation from 'wix-location'

$w.onReady(function () {

 


let rowSelector = ($w("#search1").value.toLowerCase()); //I wasn't too sure what to add here

let promise = wixData.query("authors").include("staff").include("courses").find().then(result => result.item);   //added let before promise. Changed "authors", "staff", and "courses"
 
function updateData(event) {

 let search = event.target.value;
 
    promise.then(items => {

 let itemsToDisplay;

 if(!search.length){

         itemsToDisplay = items;   

       } else {

           itemsToDisplay = items.filter(item => {

 return item.staff.includes(search) || item.courses.includes(search);

 //should this be item.collectionname.fieldkey.includes  ? for both of these items? I deleted staff.name. and service.name. for example to try to get them to match the keys within the data. Not sure if I messed this part up or not.

            })

        }

        rowSelector.data.data= itemsToDisplay;

    })
}

})


import wixData from 'wix-data'
import wixLocation from 'wix-location'

$w.onReady(function () {

 


let rowSelector = $w("#search1");// you just want the selector here not so later you can do rowSelector.value.lowerCase();
let promise = wixData.query("authors").include("staff").include("courses").find().then(result => result.item);   //added let before promise. Changed "authors", "staff", and "courses"
 
function updateData(event) {

 let search = event.target.value;
 
    promise.then(items => {

 let itemsToDisplay;

 if(!search.length){

         itemsToDisplay = items;   

       } else {

           itemsToDisplay = items.filter(item => {
 //ho i messed up. it should be item.referenceField.referencedCollectionField.includes(search) 
 return item.staff.name.includes(search) || item.courses.name.includes(search);
            })
        }
        rowSelector.data.data= itemsToDisplay;

    })
}

})

checkout includes
I’ve not tested the code, it just on the top of my head to give you the logic

maybe do a console.log(items to see what is in it so you can better compare)

Feel free to add me as a contributor if you want me to have a closer look :slight_smile:

Thank you so much for your help! I think I’m almost through this.

Here is my updated code

import wixData from 'wix-data'
import wixLocation from 'wix-location'

$w.onReady(function () {

$w("#table1").columns = [
       {
 "id": "col1",
 "dataPath": "serviceName",
 "label": "Service Name",
 "width": 300,
 "visible": true,
 "type": "text",
 "linkPath": "servicePageUrl",
        },
{
 "id": "col2",
 "dataPath": "name",
 "label": "Tutor Name",
"width": 300,
"visible": true,
"type": "text",
 
}
     ];
})

export function search1_keyPress(event) {

let rowSelector = $w("#search1");// you just want the selector here not so later you can do rowSelector.value.lowerCase();
let promise = wixData.query("authors").include("staff").include("courses").find();
 
 let search = $w("#table1");
 
    promise.then(items => {

 let itemsToDisplay;

 if(!search.length){

         itemsToDisplay = items.items; 

         console.log(itemsToDisplay)  


//returns all items needed! (: 

       } else {

           itemsToDisplay = items.filter(item => {
  
 return item.staff.name.includes(search) || item.courses.serviceName.includes(search);


//filter does not seem to work here

//console logs do not make it past this section. Any ideas? 

//staff is name of field key in read/write collection. 

//name is field key used within bookings/staff collection, the referenced collection. 

//courses is the name of the field key within the read/write collection. 

//serviceName is the field key for bookings/services collection, the referenced collection.


console.log("else end")
 
            })

            
            
        }

         $w("#table1").rows = itemsToDisplay;


//I wasn't sure how to modify this area. It seemed that I needed to bring my table in here at some point but, I think I need to fix the above section beforehand.

    })


}