Hi Elizabeth:
Two things I can suggest:
The function I proposed needs you to send it an element not just the element’s name. My mistake. Basically, the repeater uses a scoped selector - the $w. What this does is ensures that the data that you retrieve from elements in this specific repeater iteration is the correct repeater collection. Because the $w isn’t being passed to the assignment function the $w used is the one that is used to select elements in the global scope.
So if you are familiar with the DOM, the repeater looks something like this
document.repeater.containerForItem1.businessname
document.repeater.containerForItem2.businessname
So when this handler is executed:
$w("#repeater1").onItemReady(($w, itemData, index) => {
itemData is pointing to the correct data set value and the $w parameter is pointing to document.repeater.containerForItem1 so to configure the element with id businessname in containerForItem1 you access $w(‘#businessname’);
In the next iteration $w points to containerForItem2. and so on.
So to fix this you need to pass the whole element object (for each assignment call), not just the element name, like this:
assignValidValue($w('#businessname'), 'text', itemData.businessName);
Then you need to modify the assignValidValue function like this:
function assignValidValue(element, elementProperty, elementValue) {
// Debug info
console.log('assignValidValue('
// We are getting an element object we want to print its id
+(element && element['id']?element.id:',missing element') + ', '
+(elementProperty?elementProperty:',missing property') + ', '
+(elementValue?elementValue:',missing value') + ')');
// Make sure we have arguments with values to work with
if (element && elementProperty && elementValue) {
// Assign the value to the element's property
element[elementProperty] = elementValue;
// If this element is optional show it because we have a value
if (element.id === 'addline2' ||
element.id === 'description' ||
element.id === 'logo') {
element.show();
}
} else if (element && elementProperty) {
// We don't have a value for this element
// so don't try to set its value
// If it is one of our optional elements then hide it
if (element.id === 'addline2' ||
element.id === 'description' ||
element.id === 'logo') {
element.hide();
}
}
}
Additionally you are not doing anything with your debounce timer. The setTimeout function takes three arguments, the first two are what you are interested in at this point.
The first one is a callback function, which you have defined as an argument-less anonymous function. The second is the timer value which you have set to 500ms (half a second).
The anonymous function that you have defined executes the following code when your 500ms timer completes:
($w('#iTitle').value);
This doesn’t really do anything except return the value of the title input element that you have on your page. It doesn’t get assigned to anything so it essentially disappears, effectively not doing the filtering you are expecting it to.
If your idea is to execute the this code when the timer completes:
wixData.query('Business_Directory')
.contains('businessName',$w('#iTitle').value)
.find()
.then(res => {
$w('#repeater1').data = res.items;
});
Then you will not get what you expect. Why? Well it executes immediately after you set the timer. When it executes it is likely that only one letter has been entered in your input field.
For this code to execute and perform the search it needs to replace the code highlighted above [($w(‘#iTitle’).value);] in the anonymous function. So when the timeout completes this code will have the value in $w(#iTitle1’).value .
Try this:
function iTitle_keyPress(event, $w) {
// Starting a new search reset debounce and give the user 500ms to enter a search term
if (debounceTimer){
// New extra text entered before search function fired
clearTimeout (debounceTimer);
debounceTimer = undefined;
}
// Start new timer
debounceTimer = setTimeout(()=> {
// When timeout fires start query to find search term
wixData.query('Business_Directory')
.contains('businessName',$w('#iTitle').value)
.find()
.then(res => {
// Update repeater data set with result
// NOTE: If the search returns with zero results then the repeater
// will end up removing all items and an empty page will be shown
$w('#repeater1').data = res.items;
});
// Set timeout for 500ms.
} , 500);
}
Good luck
Steve