Get an array of date values from dataset, and based on the values, filter a date array, to get the ones available

The idea is that a user should be able to choose 2 dates, to search when a preferred rental is available. After choosing, they click a button, and boom there is a list of available rentals.

So, I have 2 datepickers, and a code that saves those CHOSEN Dates to an array, like below:

Code:

export function btnSave_click(event, $w) {

 let searchValue = [];
  searchValue = getDates();

 let query = wixData.query('Vuokravaunut') 
 .contains('aikavali', searchValue[0]);
 
 for (let i=1; i < searchValue.length; i++) {
    query = query.or(wixData.query('Vuokravaunut')
 .contains('aikavali', searchValue[i]));
 } 
 
  query.find() 
 .then(results => {

 if (results.totalCount > 0) 
 {
 return;
 } else
 {
            $w("#repeater1").expand();
 }
        console.log(results);
 
 });
}

Meanings:
aikavali = time frame (column name (typeof array))
Vuokravaunut = dataset name
getDates() = the array made of start and end Dates

Page looks like this:

So, as you can see, the way of doing this, is not the best. Any suggestions?

And yes, im using moment.js to format time, so that can be also used.

Thanks in advance,
Alvar

Can I take a look at this getDates() function? Can you show me if there is any error?

the function:


No errors, but I’m just not sure what is the best way to make this work.

How would you do this feature:

User can choose 2 dates with datepickers (month-day-year).

After that, the repeater should show all the rentals that are available between that time.

At the moment, it is an array of dates, but there also could be start and end dates in different columns, but I don’t know how to implement it to work in the code.

Hope this clarifies.

I forgot to reply to this, I only answered.
Below is the function.

I think I understood what you need. You want to filter your Collection with the available rentals. Your code above where the btnSave_click function is, is not going to work properly, cause it is making a loop of query requests to the Collection.

Can you show me Collection? I want to see how you are storing what is rented and what it is not? That way, I can try to give you a solution I would implement.

@bwprado


I’m not even sure that this is the best way. But its like this.

@allu112apina Those are the unavailable dates, correct?

@bwprado Yes, and this is the listing, which holds all the rentals.

It would maybe be better to have only:
Start time | End time | Rental

Those in a separate dataset, which keeps track of the current and old bookings.

But i dont know how to implement this in code… Everything else relating to that, i know how to do.
Thats the issue.

Maybe if you give me a hint to a structure where the code asks for all the different rentals, and then looks their start/end times, and after that it filters with “not()” which exludes the ones with maching dates.

-A

I’m finishing the code, just hang on, I’ll be back.

Yeah, no worries. Thanks for helping!

Hello there, here it is:

import moment from "moment"
import wixData from "wix-data"


$w.onReady(async () => {

 //When you change the End Date Date Picker date, it queries and updates the table
  $w("#datePickerEnd").onChange(async (event) => {
 
 //This creates the search
 let searchAvailableRentals = await createSeach($w("#datePickerFrom").value, $w("#datePickerTo").value)

 //This feeds the table with the data that was searched
    feedTable($w('#tableAvailableRentals'), searchAvailableRentals)
 })

 

})

//This is a function to query the collection.
async function queryCollection(collection, field, array) {
 let query = await wixData
 .query(collection)
 .not(wixData.query(collection).hasSome(field, array))
 .find()
 .then(result => result)
 return query
}

//This function creates the Date Array
function createDateArray(start, end) {
 let dateArray = []
  start = moment(start)
  end = moment(end)
 while (start <= end) {
    dateArray.push(start.format("YYYY-MM-DD"))
    start = moment(start).add(1, "days")
 }
 return dateArray
}


//This function feeds the table with the data
function feedTable(table, data) {
  table.rows = data
 const tableColumns = [
 {
      id: "col1",
      dataPath: "_id",
      label: "ID",
      width: 100,
      visible: true,
      type: "string",
 },
 {
      id: "col2",
      dataPath: "title",
      label: "Title",
      width: 100,
      visible: true,
      type: "string",
 },
 ]
  table.columns = tableColumns
}

//This function does the search and treats it
async function createSeach(startDate, endDate) {
 let rentalDates = createDateArray(startDate, endDate)
 let search = await queryCollection("Rentals", "rentedDates", rentalDates)
 if (search.items.length > 0) {
 return search.items
 }
 return "No rental available!"
}

Thanks I will test it later.

Its giving me this error.


Its in line 211:

Also btw I would like it to work on repeaters, not tables. Is that harder to implement?

And my deepest thanks for the indepth answering. :slight_smile:

-A

This error is not related to that part of the code, is where you are using it.

You can adapt it to a repeater easily, you have to loop through the data and fill the repeater.

@allu112apina
How do look like your data? Did you already tried to make a console-log?
Normaly you should be able to resolve this problem by your own.

What you have to do?

You get your —> data <— from somewhere into your —> feedTable-function <—.
Now put a console-log into the first line of your “feedTable”-function to inspect the recieved- DATA-PACK.

Now there could be 2-scenarios!

  1. The recieved data-pack has a wrong format.
  2. The recieved data-pack is still in the promise and waits to be fullfilled.

How to resolve, if it is the first scenario?
Simply modify your data-object, which should normaly have the following data-structure…

myDataPack = [
	{"data1": "hereMyData1"},
	{"data2": "hereMyData2"},
	{"data3": "hereMyData3"}
]

Your const —> “tableColums” has this structure for example.

What to do if it is scenario-2?
You can add an ASYNC-AWAIT → i think somewhere in your output-function, or even try to do it in your “feedTable”-function.

async function feedTable(table, data){
	table.rows = await data
	........
	......
	...
	..
	.
}

How to set a repeater data?

$w("#myRepeater").data= data;

If you would take a look onto the API of the repeater, than you would find all the needed coding steps and commands, EVEN THE RIGHT EXPECTED DATA_FORMAT!

Look here......

@allu112apina Sorry, I found two errors in my code, I changed the datepicker element name to make it more readable, but forgot to change it in every place used, here is the corrected version:

import moment from "moment"
import wixData from "wix-data"


$w.onReady(async () => {

 //When you change the End Date Date Picker date, it queries and updates the table
  $w("#datePickerEnd").onChange(async (event) => {
 
 //This creates the search
 let searchAvailableRentals = await createSeach($w("#datePickerStart").value, $w("#datePickerEnd").value)

 //This feeds the table with the data that was searched
    feedTable($w('#tableAvailableRentals'), searchAvailableRentals)
 })

 

})

//This is a function to query the collection.
async function queryCollection(collection, field, array) {
 let query = await wixData
 .query(collection)
 .not(wixData.query(collection).hasSome(field, array))
 .find()
 .then(result => result)
 return query
}

//This function creates the Date Array
function createDateArray(start, end) {
 let dateArray = []
  start = moment(start)
  end = moment(end)
 while (start <= end) {
    dateArray.push(start.format("YYYY-MM-DD"))
    start = moment(start).add(1, "days")
 }
 return dateArray
}


//This function feeds the table with the data
function feedTable(table, data) {
  data.forEach((element, index) => {
    element.rowNumber = index + 1
 })
  table.rows = data
 const tableColumns = [
 {
      id: "col1",
      dataPath: "rowNumber",
      label: "Number",
      width: 30,
      visible: true,
      type: "string",
 },
 {
      id: "col2",
      dataPath: "_id",
      label: "ID",
      width: 100,
      visible: true,
      type: "string",
 },
 {
      id: "col3",
      dataPath: "title",
      label: "Title",
      width: 100,
      visible: true,
      type: "string",
 },
 ]
  table.columns = tableColumns
}

//This function does the search and treats it
async function createSeach(startDate, endDate) {
 let rentalDates = createDateArray(startDate, endDate)
 let search = await queryCollection("Rentals", "rentedDates", rentalDates)
 if (search.items.length > 0) {
 return search.items
 }
 return "No rental available!"
}


Yeah, no worry, I saw that. This is the code that I came up with.
Using repeaters.

function getDates(startDate, stopDate) {
 var dateArray = [];
 var currentDate = $w("#datePickerFrom").value;
 var stopDate = $w("#datePickerTo").value;
 while (currentDate <= stopDate) {
        dateArray.push( moment(currentDate).format('YYYY-MM-DD') )
        currentDate = moment(currentDate).add(1, 'days');
 }
 

    console.log(dateArray);
 return dateArray;
}


//This function does the search and treats it
async function createSearch(startDate, endDate) {
 let rentalDates = createDateArray(startDate, endDate)
 let search = await queryCollection("VVaunut", "aikavali", rentalDates)
 if (search.items.length > 0) {
let searchItems = search.items
$w("#repeaterAvailableRentals").data = searchItems;
 return searchItems
 }
 return "No rental available!"
}

export function btnSave_click(event, $w) {

 createSearch($w("#datePickerFrom").value, $w("#datePickerTo").value)


}


//This is a function to query the collection.
async function queryCollection(collection, field, array) {
 let query = await wixData
 .query(collection)
 .not(wixData.query(collection).hasSome(field, array))
 .find()
 .then(result => result)
 return query
}

//This function creates the Date Array
function createDateArray(start, end) {
 let dateArray = []
  start = moment(start)
  end = moment(end)
 while (start <= end) {
    dateArray.push(start.format("YYYY-MM-DD"))
    start = moment(start).add(1, "days")
 }
 return dateArray
}

Thanks a lot for your help! <3
-A