Need to prioritize exact results in search

We’ve got a simplistic zip code search. We’re only in Massachusetts, so we wanted a more unique experience that prioritized our partners rather than using one of the map apps.

You can see the experience here: https://www.surroundinsurance.com/partners-preview

What it’s doing: there’s a field of all the zip codes in a 10 mile radius. It’s looking at that field and showing results if that number is anywhere in the field.

It’s working as intended, but we want to put the exact term match at the top of the list. Right now it’s a little bit random looking. There are no Filters or Sort on the database.

I’m not great at code (this was mostly written by someone else). But my thought is that I can say if it matches “Zipcode Single” then show that first. Then show a match from the Zipcode field.

Is this doable? What would that code look like?

function filter(search, dropdown1) {
 if (lastFilterSearch !== search) {

 let newFilter = wixData.filter();
 if (search)
            newFilter = newFilter.contains('zipcode',search);
 
            $w("#PartnersData09").setFilter(wixData.filter())
          .then( () => {
 let count = $w("#PartnersData09").getTotalCount();
 if(count === 0){
                $w("#NoResultsTextup09").show();
            }else{
                $w("#NoResultsTextup09").hide();
                $w("#ziprepeater99").expand();
            }
    }  )
        $w('#PartnersData09').setFilter(newFilter)
        lastFilterSearch = search;
      }
}

@melindarainsberger If you update the matching record with any data and have the dataset filtered on Updated Date descending (new to old), that should achieve what you’re aiming for. Something like this using a dropdown change event to query on that zip code, update that record with any data (I’m simply using the title field), and then run your filter code (slightly modified). Adjust your field and collection names as needed.

function filter(search) {
 if (lastFilterSearch !== search) {

 let newFilter = wixData.filter();
 if (search)
        newFilter = newFilter.contains('zipcode',search);
        $w("#PartnersData09").setFilter(newFilter)
        .then( () => {
 let count = $w("#PartnersData09").getTotalCount();
 if(count === 0){
                $w("#NoResultsTextup09").show();
            }else{
                $w("#NoResultsTextup09").hide();
                $w("#ziprepeater99").expand();
            }
        }  )
        lastFilterSearch = search;
      }
}
export function dropdown1_change(event) {
    wixData.query("zipcodes")
    .eq("zipcodeSingle",event.target.value)
    .find()
    .then((res) => {
         if (res.items.length === 1){
            res.items[0].title = "found";
            wixData.update("zipcodes",res.items[0])
            .then((updateResult) => {
                filter(event.target.value.trim());
            })
        }
    })
}

Thanks!

It’s not really doing anything. The latest updated might not be the one that matches their query exactly.

I’ve been using the zip code 01757 because it’s the exact zip code of one listing (zipcodeSingle) but is in the radius of three other listings. It still doesn’t place the 01757 listing at the top.

I’m not sure exactly what “found” is. This is my own lack of understanding. Is it literally what was found or the Field Key or something else?

@melindarainsberger The idea was to update the matching record with anything, and that would in turn automatically write the current date/time to the updated date field. I’ve tested the approach, and it did work correctly - always putting the chosen zip code at the top of the results.

Looking at my post, I mistakenly said that the dataset needed to be “filtered on” Updated Date when I meant to say “sorted on”.

Other than that you might put a console.log after the . then((res) => { line to be sure it’s actually finding that zip code record:

.then((res) => {
console.log(res);

Also, doublecheck that you’re using the exact field keys and collection name in the dropdown change code. They are case sensitive. You can verify the field key in the Content Manager for that collection in the properties dialog for that field.

@tony-brunsman Thanks for the fast response! Your answers make sense and are easy to implement.

Unfortunately, it’s still not working.
https://www.surroundinsurance.com/copy-of-partners-full2

It puts the chosen zip code 01757 at the bottom. Even if I change the sort order, it stays at the bottom. Even clearing the history and cache doesn’t affect it, so something isn’t getting passed through. I did catch and change that it should be zipcode and not zipcodes. That could have been the problem, but it’s not.

Maybe having the full code will help.

import wixData from "wix-data";
import {session} from 'wix-storage';

$w.onReady(function () {
    $w("#button17").target = "_self";
    $w("#button21").target = "_self";
}); 

$w.onReady(function () {
 let value = session.getItem("searchWord");
    console.log("searchWord:",value ) 
    $w("#iSearch").value = value
    $w("#ziprepeater99").collapse();
});


let lastFilterSearch;
let debounceTimer;


export function resetButton09_keyPress(event) {
 if (debounceTimer) {
        clearTimeout(debounceTimer);
        debounceTimer = undefined;
    }
    debounceTimer = setTimeout(() => {
        filter($w('#iSearch').value);
    }, 500);
}

export function iSearch_input(event) {
 if (debounceTimer) {
        clearTimeout(debounceTimer);
        debounceTimer = undefined;
    }
    debounceTimer = setTimeout(() => {
        filter($w('#iSearch').value);
    }, 500);
}


function filter(search) {
 if (lastFilterSearch !== search) {

 let newFilter = wixData.filter();
 if (search)
        newFilter = newFilter.contains('zipcode',search);
        $w("#PartnersData09").setFilter(newFilter)
        .then( () => {
 let count = $w("#PartnersData09").getTotalCount();
 if(count === 0){
                $w("#NoResultsTextup09").show();
            }else{
                $w("#NoResultsTextup09").hide();
                $w("#ziprepeater99").expand();
            }
        }  )
        lastFilterSearch = search;
      }
}
export function dropdown1_change(event) {
    wixData.query("zipcode")
    .eq("zipcodeSingle",event.target.value)
    .find()
    .then((res) => {
        console.log(res);
 if (res.items.length === 1){
            res.items[0].title = "found";
            wixData.update("zipcode",res.items[0])
            .then((updateResult) => {
                filter(event.target.value.trim());
            })
        }
    })
}

@melindarainsberger In the developer console, do you see anything? There should be an array if the query is successful, something like this when you click to expand it:


If you’re not seeing this, it may be a matter of needing to add the event handler to the page in the correct way. Simply copying and pasting the dropdown code that I wrote is not enough. You have to go through this step of clicking on the onChange event (at the bottom right) with the dropdown element selected. That will be the function name that gets called on the onChange event for that element. The query and update code needs to be in the new code block that is created.

@tony-brunsman Thanks! I went through and tried applying it to the field where they enter the zip code and the search button. It’s not actually a dropdown, just a field where they enter text.

Still didn’t work I don’t see the verification you showed. Nothing changed.

@melindarainsberger The query and update code is not running, and now I see why. I didn’t notice the iSearch_input code.

Try this code where the iSearch_input function calls the newly renamed FindZipCode function which in turn calls the filter function if successful. The input method fires after every number inputted. The first if statement will have it run only if a full zip code is entered.

export function iSearch_input(event) {
 if (event.target.value.length === 5){
   if (debounceTimer) {
        clearTimeout(debounceTimer);
        debounceTimer = undefined;
    }
    debounceTimer = setTimeout(() => {
        FindZipCode($w('#iSearch').value);
    }, 500);
  }
}


function filter(search) {
 if (lastFilterSearch !== search) {

 let newFilter = wixData.filter();
 if (search)
        newFilter = newFilter.contains('zipcode',search);
        $w("#PartnersData09").setFilter(newFilter)
        .then( () => {
 let count = $w("#PartnersData09").getTotalCount();
 if(count === 0){
                $w("#NoResultsTextup09").show();
            }else{
                $w("#NoResultsTextup09").hide();
                $w("#ziprepeater99").expand();
            }
        }  )
        lastFilterSearch = search;
      }
}
export function FindZipCode(zip) {
    wixData.query("zipcode")
    .eq("zipcodeSingle",zip)
    .find()
    .then((res) => {
        console.log(res);
 if (res.items.length === 1){
            res.items[0].title = "found";
            wixData.update("zipcode",res.items[0])
            .then((updateResult) => {
                filter(zip);
            })
        }
    })
}

@tony-brunsman Thanks! I think it’s close. Or, at least it’s making an error message, haha.

@melindarainsberger So, that tells you that there isn’t a collection by the name of “zipcode” - all lower case. Is it Zipcode? zipcodes? Zipcodes?

@tony-brunsman the dataset is called “PartnersData09.” I tried that too. “zipcode” is a column in that collection.

@melindarainsberger WixData.query and wixData.update use the collection name from the content manager, the collection that the dataset is tied to.

@tony-brunsman Oh! That got me really close, thanks!

I think this is the last hurdle: It only works in preview. I can’t make it work when I use the URL. I’ve cleared the cache and it’s still not loading. https://www.surroundinsurance.com/copy-of-partners-full2

@melindarainsberger It’s likely a permissions issue. Have a look at this article . In particular, “Who can update content for this collection?” needs to be set to Anyone since the FindZipCode function is updating a record.

@tony-brunsman OMG. That’s it! I knew it was something to do with permissions, but wasn’t sure where to change them. It WOOOORRRRRRRKS!!! Thank you so much for all your help.

I’m hoping you’ve got one more solution in you. When I search a zip code that’s not one of the "main zip codes (zipcodesingle) and use one from the bigger bucket of zip codes (zipcode) it can’t find it. My test code is 02123. This isn’t the exact zip code of any location, but is in the 10 mile radius of a couple locations.

https://www.surroundinsurance.com/copy-of-partners-full2

To keep it short, this is what it’s doing:

  • If something has a match from zipcodesingle, it also looks at the secondary location column and includes them in the search results.
  • If there’s no match in the primary column, it doesn’t return anything.

@melindarainsberger If I’m understanding you correctly, just a slight modification is needed. The filter function also needs to be called if no match is found. This code assumes that you will never have more than one record with the same zipcodeSingle value.

export function FindZipCode(zip) {
    wixData.query("zipcode")
    .eq("zipcodeSingle",zip)
    .find()
    .then((res) => {
        console.log(res);
        if (res.items.length === 1){
            res.items[0].title = "found";
            wixData.update("zipcode",res.items[0])
            .then((updateResult) => {
                filter(zip);
            })
        } else {
            filter(zip);
        }
    })
}

@tony-brunsman Yes! that worked, I think. I’ve gotta test with dozens of zip codes now. But I think I’m all set. Thanks!