Need help editing this search code

I was supposed to edit my original thread but I accidentally deleted it.

Good news is I have the new code I needed I just need help combining it with my current code.

Basically, I made a search that searches locations and let’s it show by distance.

Then I needed to find a way how to search multiple tags (of those properties with different tags assigned) in an array and push it to the repeater for results.

I managed to do that but now when I try to combine it with my original search code it’s throwing it off because of the new elements are conflicting with the old ones.

Can someone teach me how to combine these 2 codes?

ORIGINAL CODE: (correctly works before adding 2nd code)

export function searchButton_click(event) {

wixWindow.getCurrentGeolocation()
   .then((obj)=>{
 let latitude = obj.coords.latitude;
 let longitude = obj.coords.longitude;
      wixData.query("Articles")
      .contains("city", $w("#iCity").value).contains("category", $w("#category").value).contains("tags", $w("#tagSearch").value)

      .find()
 
      .then((results) => {
 let props = results.items;
 for (var i = 0; i < props.length; i++) {
 let lat1 = latitude //current latitudo of the user
 let lon1 =   longitude //current longitude of the user
 let lat2 = props[i].propslat; //property latitude
 let lon2 =  props[i].propslon; //property longitude
 let distance = dist(lat1, lon1, lat2, lon2);
 // new property in object array to store the distance
             props[i].distance = distance;
 
 

         }
         props.sort((a, b) => (a.distance < b.distance) ? -1 : 1);
         console.log(props);

         $w("#articlesList").data = props;
      })    
   }) 

}

Need to add this new code below, so I can have more than one tag search: It works on its own but doesn’t work when I try to combine it to the new one, so I’m doing it wrong.


export function searchButton_click(event) {

 let searchValue = $w('#iSearch').value; 
  let searchWords = searchValue.split(' '); 
 
 let query = wixData.query('Articles')
     
  for (let i=0; i < searchWords.length; i++) 
    {       
        query = query.contains('tags', searchWords[i])
        console.log(query)
    }  
    query.find()
    .then(res => {
 
   console.log(res)
       $w('#articlesList').data = res.items; 
    });
}
 

The problem is when I try to combine it to the current search code it throws up all sorts of errors. Like let i=0 already being declared etc.

Is there a way to combine the two codes, maybe have the page run the codes together or after each other and combine the results? Not sure how this would work. It’s the last step in my page and then I’ll be pretty much finished with it.

Would really appreciate any help.

Hi there …

Can you share a link to your site? Maybe I can check it out.

1 Like

Yes here it is and thank you for your help. It’s greatly appreciated.

Basically if you try to search more than one keyword it might not show because of not being in the correct order (keywords are like restaurant miami etc. The new code allows you to add different keywords in any order and it will show, the problem is adding it to my current code.

UPDATE

After searching through the forums I think i need to make 2 queries to make this work? and OR query… or am i wrong?

I found the code below from ziv on another thread BUT i have not touched it to work on mine.

query1 = wixData.query('DATABASENAME')
    .eq('category', selectedCategory)
    .contains('keywords', keyword1);

the second one will be:

query2 = wixData.query('DATABASENAME')
    .eq('category', selectedCategory)
    .contains('keywords', keyword2);

and then OR them and run:

let full_query = query1.or(query2);
full_query.find().then(...)

However, I’m not sure how to implement my 2 codes to make this work…

How can I use both of my search codes in one click or to combine them in the results?

I have a similar function on one of my sites.

https://www.media-junkie.com/pflegeservice

I called that function —> manual_Search…


To see if the function is similar to your project, type in like shown in this example and press on the blue button.

Is this one part of your function ? —> Multiple-Serach-Function ?

$w( ‘#inputManualSearch’ ).onClick( async (event)=>{ //console.log(event.target.id)
let opts =
for ( var i = 0 ; i < DropDowns.length; i++) {
// console.log(settingsDATA.items[dropdownREFERENCES][“setup”+(i+1)])
opts.push({ “label” : settingsDATA.items[dropdownREFERENCES][ “setup” +(i+ 1 )], “value” : settingsDATA.items[dropdownREFERENCES][ “setup” +(i+ 1 )]})
$w( ‘#MSTB1’ ).changeState( “SearchOptions” )
}
$w( ‘#DDsearchOptions’ ).options = opts
FILTER_ENGINE()
}

function manual_Search (VALUE) {console.log( “Start manual search!” )
let searchValue = $w(‘#inputManualSearch’).value
let searchWords = searchValue.split(’ ');
let query = wixData.query(DATABASE) .limit(Number(dbLIMIT))
myFilter =
//console.log(“Search-Words:” , searchWords)
for (let i=0; i < searchWords.length; i++){
query.eq($w(‘#DDsearchOptions’).value, searchWords[i]).find()
.then((res)=>{
for ( var i = 0 ; i < res.length; i++) {
myFilter.push(res.items[i])
}
result_COUNTER(myFilter.length, myFilter)
})
}
$w( ‘#MSTB1’ ).changeState( “FilterOverview” )
}

To solve this problem…

Like let i=0 already being declared etc.
You have just to change the letter in your second FOR-LOOP, for example from “i” to → “a” or any else of letters.

Your code has surprisingly a lot of similarity to my own :wink:

EDIT:
Forgot to mention, that you have first to choose the right DB-PRESET. In your case it is the PRESET-1


But you can do for all of the preinstalled DB-Presets. Just play around and you will see, it should have a lot of similarity to what you want to achieve (i think).

@russian-dima

Thank you so much for your help. I’m still confused but I will try to understand your templates.

So just to confirm. I need to make 2 queries (in a loop) and assign it to my search button to get my results? Or do I need to make a function to call first?

searchButton is my main search and click
tagSearch is the field where you can input the keywords.

So I need to make something like under searchButton onclick?
I’m also assuming I should remove the tagSearch original code from the first query since that will be in the second one.

query1 = wixData.query('articlesList')

  wixWindow.getCurrentGeolocation()
   .then((obj)=>{
 let latitude = obj.coords.latitude;
 let longitude = obj.coords.longitude;
      wixData.query("Articles")
      .contains("authorCountry", $w("#iCity").value).contains("businessCategory", $w("#dropBusinessType1").value).contains("state", $w("#iState").value).contains("tags", $w("#tagSearch").value)
      .find()
 
      .then((results) => {
 let props = results.items;
 for (var i = 0; i < props.length; i++) {
 let lat1 = latitude //current latitudo of the user
 let lon1 =   longitude //current longitude of the user
 let lat2 = props[i].propslat; //property latitude
 let lon2 =  props[i].propslon; //property longitude
 let distance = dist(lat1, lon1, lat2, lon2);
 // new property in object array to store the distance
             props[i].distance = distance;
    .eq('category', selectedCategory)
    .contains('keywords', keyword1);

and then I add this after?

query2 = wixData.query('articles')
   
    
    
export function searchTags_click(event) {

 let searchValue = $w('#tagSearch').value; 
 let searchWords = searchValue.split(' '); 
 
 let query = wixData.query('articles')
      .descending("created");
 
 //add a "contains" condition to the query for each word:
 //assumes we search in the field 'myField'
 //CHANGE THIS TO YOUR FIELD NAME
 for (let b=0; i < searchWords.length; i++) 
    {       
        query = query.contains('tags', searchWords[i])
        console.log(query)
    }  
 
 //actually run the query:
    query.find()
    .then(res => {
 
   console.log(res)
       $w('#propertiesRepeater').data = res.items; 
    });
}
 

and finally loop them?

let full_query = query1.or(query2);
full_query.find().then(...)

I know the above code is wrong but I’m just trying to understand how to place them.

Also is the last part of the above code correct. is it really .then(…)

what should I put in or after the then. is that the push data to repeater?

This is my full page code below but I have not tried doing the loop yet as I’m still trying to put it together.

import wixData from "wix-data";
import wixLocation from 'wix-location';
import wixWindow from 'wix-window';

let location = wixWindow.getCurrentGeolocation();

$w.onReady(function () {
    setUpRepeater();
});

function dist(lat1, lon1, lat2, lon2) {
 function rad(x) { return x * Math.PI / 180; }

 let R = 6371;
 let dLat = rad(lat2 - lat1);
 let dLong = rad(lon2 - lon1);

 let a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(rad(lat1)) * Math.cos(rad(lat2)) * Math.sin(dLong / 2) * Math.sin(dLong / 2);
 let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
 var d = R * c * 0.621371;
 //console.log(d.toFixed(3));
 return d.toFixed(1);

}

async function setUpRepeater() {

    $w('#articlesList').onItemReady(($item, itemData, index,) => {
 

 /// when repeater is ready get users current geolocation
        wixWindow.getCurrentGeolocation()
            .then((obj) => {
 let latitude = obj.coords.latitude;
 let longitude = obj.coords.longitude;
 //console.log("my location is: " + latitude + longitude)

 let lat1 = latitude //current latitudo of the user
 let lon1 = longitude //current longitude of the user
 let lat2 = itemData.propslat; //get the latitude of each property
 let lon2 = itemData.propslon; //get the longitude of each property
 let distance = dist(lat1, lon1, lat2, lon2) // call the fucntion dist to calculate the distance between the curren user and the properties 
 //$item("#txtDistance").text =  distance + " Miles Away";
                $item("#txtDistance").text = distance + " miles";


            })
            .catch((error) => {
 let errorMsg = error;
            });
    })
}

$w.onReady(() => {
  loadStateList();
});



export function button5_click(event) {

 

    $w('#iCity').value = "";
// filters reset

    $w('#dropBusinessType1').value = "Select";
    $w('#iState').value = "";
    $w('#tagSearch').value = "";
    $w('#iCity').resetValidityIndication();
    $w('#dropBusinessType1').resetValidityIndication();
    $w('#iState').resetValidityIndication();
    $w('#tagSearch').resetValidityIndication();
    $w("#dataset1").setFilter(wixData.filter());


}


function loadStateList() {
  wixData.query('stateID')
     .find()
     .then(res => {
 let options = [{"value": '', "label": 'All States'}];
      options.push(...res.items.map(state => {
 return {"value": state.stateList, "label": state.stateList};
      }));
      $w('#iState').options = options;
     });

}



export function distanceButton_click(event) {

 

   wixWindow.getCurrentGeolocation()
   .then((obj)=>{
 let latitude = obj.coords.latitude;
 let longitude = obj.coords.longitude;
      wixData.query("Articles")
      .find()
      .then((results) => {
 let props = results.items;
 for (var i = 0; i < props.length; i++) {
 let lat1 = latitude //current latitudo of the user
 let lon1 =   longitude //current longitude of the user
 let lat2 = props[i].propslat; //property latitude
 let lon2 =  props[i].propslon; //property longitude
 let distance = dist(lat1, lon1, lat2, lon2);
 // new property in object array to store the distance
             props[i].distance = distance;
 
 

         }
 // now sort
         props.sort((a, b) => (a.distance > b.distance) ? 1 : -1);
         console.log(props);
 // lastly, connect it to the repeater
         $w("#articlesList").data = props;
      })    
   }) 
}

export function searchButton_click_1(event) {



          wixWindow.getCurrentGeolocation()
   .then((obj)=>{
 let latitude = obj.coords.latitude;
 let longitude = obj.coords.longitude;
      wixData.query("Articles")
      .contains("authorCountry", $w("#iCity").value).contains("businessCategory", $w("#dropBusinessType1").value).contains("state", $w("#iState").value).contains("tags", $w("#tagSearch").value)
      .find()
 
      .then((results) => {
 let props = results.items;
 for (var i = 0; i < props.length; i++) {
 let lat1 = latitude //current latitudo of the user
 let lon1 =   longitude //current longitude of the user
 let lat2 = props[i].propslat; //property latitude
 let lon2 =  props[i].propslon; //property longitude
 let distance = dist(lat1, lon1, lat2, lon2);
 // new property in object array to store the distance
             props[i].distance = distance;
 
 

         }
 // now sort
         props.sort((a, b) => (a.distance < b.distance) ? -1 : 1);
         console.log(props);
 // lastly, connect it to the repeater
         $w("#articlesList").data = props;
      })    
   }) 
 
}

export function sortDistance_click(event) {

 

 

          wixWindow.getCurrentGeolocation()
   .then((obj)=>{
 let latitude = obj.coords.latitude;
 let longitude = obj.coords.longitude;
      wixData.query("Articles")
      .contains("authorCountry", $w("#iCity").value).contains("pickupDelivery", $w("#iPickupdelivery").value).contains("businessCategory", $w("#dropBusinessType1").value).contains("state", $w("#iState").value).contains("tags", $w("#tagSearch").value)
 
      .find()
      .then((results) => {
 let props = results.items;
 for (var i = 0; i < props.length; i++) {
 let lat1 = latitude //current latitudo of the user
 let lon1 = longitude //current longitude of the user
 let lat2 = props[i].propslat; //property latitude
 let lon2 = props[i].propslon; //property longitude
 let distance = dist(lat1, lon1, lat2, lon2);
 // new property in object array to store the distance
             props[i].distance = distance;
 
         }
 // now sort
         props.sort((a, b) => (a.distance > b.distance) ? 1 : -1);
         console.log(props);
 // lastly, connect it to the repeater
 
         $w("#articlesList").data = props;
 
      })    
   }) 

}

@shrimpbgnet

Ok, just to be clear, all you want is to …

" Basically, I made a search that searches locations and let’s it show by distance."
right?

You want to create a multiple search-engine/searchfilter, which will show you all in the filter/seach included cities the distance to the current user’s location.

To illustrate your project, i think this is what you want to realize…

For example we take this Germany-Map with some locations on it, and let us say on this map your location will be green.

Now you have a DATABASE where you have stored all your location- coordinates (long/lat).

Now how your filter should work?

  1. You want to search for multiple location…
  2. by a multiple input …
  3. which will show all the filtered locations on map, right?

For example you types into your search-inputfield → “Hamburg Dortmund Berlin”
The result should be like shown on the pic below, right?

Here you get the distance between 2 geolocations (USER-LOCATION + GEOLOCATION-X) and you save all the found geolocation(n)-distances in an ARRAY —> “props

That means …

props[0] —> distance-A
props[1] —> distance-B
props[2] —> distance-C
props[3] —> distance-D
props[4] —> distance-E
and so on…

Perhaps this way…

export function distanceButton_click(event) {
   wixWindow.getCurrentGeolocation()
   .then((obj)=>{
      let latitude = obj.coords.latitude;
      let longitude = obj.coords.longitude;
      wixData.query("Articles")  
      .contains("city", $w("#iCity").value)
      .contains("category", $w("#category").value)
      //.contains("tags", $w("#tagSearch").value)
      .find()
      .then((results) => {
           let query2 = results
           X2(query2)  
      })    
   }) 
}
function X2(QUERY){
  let searchValue = $w('#iSearch').value; 
  let searchWords = searchValue.split(' '); 
 
 let query = QUERY
     
  for (let i=0; i < searchWords.length; i++) 
    {       
        query = query.contains('tags', searchWords[i])
        console.log(query)
    }  
    query.find()
    .then(res => {console.log(res)
        let props = res.items; 
        for (var i = 0; i < props.length; i++) {
            let lat1 = latitude //current latitudo of the user
            let lon1 = longitude //current longitude of the user
            let lat2 = props[i].propslat; //property latitude
            let lon2 =  props[i].propslon; //property longitude
            let distance = dist(lat1, lon1, lat2, lon2);
            //new property in object array to store the distance
            //props[i].distance = distance;
         }
         // now sort
         props.sort((a, b) => (a.distance > b.distance) ? 1 : -1);
         console.log(props);
         // lastly, connect it to the repeater
         $w("#articlesList").data = props;
    });
}   

But perhaps i totaly missunderstood your project and just am stupid :laughing:

1 Like

@russian-dima Sorry I wasn’t clear I’m so sorry but what you did is still helping me learn. It’s very interesting and I’ll be sure to learn that now. Maybe I can try to modify the code you gave me to work with the one I have.

I just wanted to combine the multi keywords code that I found to combine it with my main search export function searchButton_click_1 ( event ) {

the multi keywords code is just keywords of categories (tags in my database)

I want to search something like… restaurant and delivery in the keywords field into the main search i have which has location distance to user already plugged in.

basically this code I found for multi keywords and implement it into the code below it:

export function searchButton_click(event) {


 let searchValue = $w('#iSearch').value; 
  let searchWords = searchValue.split(' '); 
 
 let query = wixData.query('Articles')
     
  for (let i=0; i < searchWords.length; i++) 
    {       
        query = query.contains('tags', searchWords[i])
        console.log(query)
    }  
    query.find()
    .then(res => {
 
   console.log(res)
       $w('#articlesList').data = res.items; 
    });
}

combine the above code into my main search below


wixWindow.getCurrentGeolocation()
   .then((obj)=>{
 let latitude = obj.coords.latitude;
 let longitude = obj.coords.longitude;
      wixData.query("Articles")
      .contains("city", $w("#iCity").value).contains("category", $w("#category").value).contains("tags", $w("#tagSearch").value)

      .find()
 
      .then((results) => {
 let props = results.items;
 for (var i = 0; i < props.length; i++) {
 let lat1 = latitude //current latitudo of the user
 let lon1 =   longitude //current longitude of the user
 let lat2 = props[i].propslat; //property latitude
 let lon2 =  props[i].propslon; //property longitude
 let distance = dist(lat1, lon1, lat2, lon2);
 // new property in object array to store the distance
             props[i].distance = distance;
 
 

         }
         props.sort((a, b) => (a.distance < b.distance) ? -1 : 1);
         console.log(props);

         $w("#articlesList").data = props;
      })    
   }) 

}

I will try to read the code you made and see if I can just modify that.

Thank you so much for your help. you are amazing!

@russian-dima

So just for coding purposes and learning I tried to implement your 2 codes.
However it says that .obj and latitude and longitude were not declared was not identified so I had to add these lines of code:

    wixWindow.getCurrentGeolocation()
   .then((obj)=>{
 let latitude = obj.coords.latitude;
 let longitude = obj.coords.longitude;

this is for the function code:

It looks like this but whatever comes after the function is giving an error to the next export function

Parsing error: ‘import’ and ‘export’ may only appear at the top level

This is the code of yours that I added to my functions: (notice the lines i added ian the above code because they were not declared - maybe i did this wrong)

function X2(QUERY){

 
 let searchValue = $w('#tagSearch').value; 
 let searchWords = searchValue.split(' '); 
    wixWindow.getCurrentGeolocation()
   .then((obj)=>{
 let latitude = obj.coords.latitude;
 let longitude = obj.coords.longitude;
 let query = QUERY

 
 for (let i=0; i < searchWords.length; i++) 
    {       
        query = query.contains('tags', searchWords[i])
        console.log(query)
    }  

    query.find()
.then(res => {console.log(res)
 let props = res.items; 
 for (var i = 0; i < props.length; i++) {
 let lat1 = latitude //current latitudo of the user
 let lon1 = longitude //current longitude of the user
 let lat2 = props[i].propslat; //property latitude
 let lon2 =  props[i].propslon; //property longitude
 let distance = dist(lat1, lon1, lat2, lon2);
 //new property in object array to store the distance
 //props[i].distance = distance;
         }
 // now sort
         props.sort((a, b) => (a.distance > b.distance) ? 1 : -1);
         console.log(props);
 // lastly, connect it to the repeater
         $w("#articlesList").data = props;
    });



Below is the full page code with your code implemented:

import wixData from "wix-data";
import wixLocation from 'wix-location';
import wixWindow from 'wix-window';

let location = wixWindow.getCurrentGeolocation();

$w.onReady(function () {
    setUpRepeater();
});



function dist(lat1, lon1, lat2, lon2) {
 function rad(x) { return x * Math.PI / 180; }

 let R = 6371;
 let dLat = rad(lat2 - lat1);
 let dLong = rad(lon2 - lon1);

 let a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(rad(lat1)) * Math.cos(rad(lat2)) * Math.sin(dLong / 2) * Math.sin(dLong / 2);
 let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
 var d = R * c * 0.621371;
 //console.log(d.toFixed(3));
 return d.toFixed(1);

}

async function setUpRepeater() {

    $w('#articlesList').onItemReady(($item, itemData, index,) => {
 

 /// when repeater is ready get users current geolocation
        wixWindow.getCurrentGeolocation()
            .then((obj) => {
 let latitude = obj.coords.latitude;
 let longitude = obj.coords.longitude;
 //console.log("my location is: " + latitude + longitude)

 let lat1 = latitude //current latitudo of the user
 let lon1 = longitude //current longitude of the user
 let lat2 = itemData.propslat; //get the latitude of each property
 let lon2 = itemData.propslon; //get the longitude of each property
 let distance = dist(lat1, lon1, lat2, lon2) // call the fucntion dist to calculate the distance between the curren user and the properties 
 //$item("#txtDistance").text =  distance + " Miles Away";
                $item("#txtDistance").text = distance + " miles";


            })
            .catch((error) => {
 let errorMsg = error;
            });
    })
}


function X2(QUERY){

 
 let searchValue = $w('#tagSearch').value; 
 let searchWords = searchValue.split(' '); 
    wixWindow.getCurrentGeolocation()
   .then((obj)=>{
 let latitude = obj.coords.latitude;
 let longitude = obj.coords.longitude;
 let query = QUERY

 
 for (let i=0; i < searchWords.length; i++) 
    {       
        query = query.contains('tags', searchWords[i])
        console.log(query)
    }  

    query.find()
.then(res => {console.log(res)
 let props = res.items; 
 for (var i = 0; i < props.length; i++) {
 let lat1 = latitude //current latitudo of the user
 let lon1 = longitude //current longitude of the user
 let lat2 = props[i].propslat; //property latitude
 let lon2 =  props[i].propslon; //property longitude
 let distance = dist(lat1, lon1, lat2, lon2);
 //new property in object array to store the distance
 //props[i].distance = distance;
         }
 // now sort
         props.sort((a, b) => (a.distance > b.distance) ? 1 : -1);
         console.log(props);
 // lastly, connect it to the repeater
         $w("#articlesList").data = props;
    });
 
 //add a "contains" condition to the query for each word:
 //assumes we search in the field 'myField'
 //CHANGE THIS TO YOUR FIELD NAME


$w.onReady(() => {
  loadStateList();
});





function loadStateList() {
  wixData.query('stateID')
     .find()
     .then(res => {
 let options = [{"value": '', "label": 'All States'}];
      options.push(...res.items.map(state => {
 return {"value": state.stateList, "label": state.stateList};
      }));
      $w('#iState').options = options;
     });

}



export function distanceButton_click(event) {
 // This function was added from the Properties & Events panel. To learn more, visit http://wix.to/UcBnC-4
 // Add your code for this event here: 
 

   wixWindow.getCurrentGeolocation()
   .then((obj)=>{
 let latitude = obj.coords.latitude;
 let longitude = obj.coords.longitude;
      wixData.query("Articles")
      .find()
      .then((results) => {
 let props = results.items;
 for (var i = 0; i < props.length; i++) {
 let lat1 = latitude //current latitudo of the user
 let lon1 =   longitude //current longitude of the user
 let lat2 = props[i].propslat; //property latitude
 let lon2 =  props[i].propslon; //property longitude
 let distance = dist(lat1, lon1, lat2, lon2);
 // new property in object array to store the distance
             props[i].distance = distance;
 
 

         }
 // now sort
         props.sort((a, b) => (a.distance > b.distance) ? 1 : -1);
         console.log(props);
 // lastly, connect it to the repeater
         $w("#articlesList").data = res.items;
      })    
   }) 
}

export function searchButton_click_1(event) {





          wixWindow.getCurrentGeolocation()
   .then((obj)=>{
 let latitude = obj.coords.latitude;
 let longitude = obj.coords.longitude;
      wixData.query("Articles")
      .contains("authorCountry", $w("#iCity").value).contains("category", $w("#takeoutOptions").value).contains("delivery", $w("#deliveryOptions").value).contains("tags", $w("#tagSearch").value)
      .find()
 
      .then((results) => {
 let props = results.items;
 for (var i = 0; i < props.length; i++) {
 let lat1 = latitude //current latitudo of the user
 let lon1 =   longitude //current longitude of the user
 let lat2 = props[i].propslat; //property latitude
 let lon2 =  props[i].propslon; //property longitude
 let distance = dist(lat1, lon1, lat2, lon2);
 // new property in object array to store the distance
             props[i].distance = distance;
 
 

         }
 // now sort
         props.sort((a, b) => (a.distance < b.distance) ? -1 : 1);
         console.log(props);
 // lastly, connect it to the repeater
         $w("#articlesList").data = props;
      })    
   }) 
 // This function was added from the Properties & Events panel. To learn more, visit http://wix.to/UcBnC-4
 // Add your code for this event here: 
}

export function sortDistance_click(event) {

 

 

          wixWindow.getCurrentGeolocation()
   .then((obj)=>{
 let latitude = obj.coords.latitude;
 let longitude = obj.coords.longitude;
 let query1 = wixData.query("Articles")
      .contains("authorCountry", $w("#iCity").value).contains("curbsidePickup", $w("#curbsidePickupOptions").value).contains("businessCategory", $w("#dropBusinessType1").value).contains("state", $w("#iState").value)
 
      .find()
      .then((results) => {
 let props = results.items;
 for (var i = 0; i < props.length; i++) {
 let lat1 = latitude //current latitudo of the user
 let lon1 = longitude //current longitude of the user
 let lat2 = props[i].propslat; //property latitude
 let lon2 = props[i].propslon; //property longitude
 let distance = dist(lat1, lon1, lat2, lon2);
 // new property in object array to store the distance
             props[i].distance = distance;
 
         }
 // now sort
         props.sort((a, b) => (a.distance > b.distance) ? 1 : -1);
         console.log(props);
 // lastly, connect it to the repeater
 
         $w("#articlesList").data = props;
 
      })    
   }) 


the new function is causing a conflict one the next export fuction. Maybe I didn’t close it correctly or its in the wrong place?

Well i can give you a good advice!

USE MUCH MORE —> CONSOLE-LOGs → this will open you your eyes in many issue-situations. You will be able to understand your own CODE better.

The CONSOLE-LOGs should be your BEST-FRIEND.

You have a problem in one of your coding-lines? → Then console-log it!
You do not really know how results looks like? → Then console-log it!
and so on …

“Maybe I can try to modify the code you gave me to work with the one I have.”

P.S.: The code i gave you —> is already combined! Perhaps there are still some bugs and some little failures, which have to be modified and eliminated (i did not test it), but i think it should work the shown way for you.

Do not work with whole your code. Concentrate just on this part of code → the combination of two desired functions —> “multiple search” + distance-calculation!

1 Like

@russian-dima

Thank you so much for your time and patience.

I have been fiddling with it all day and finally got rid of any console errors and managed to get it to run but I’m still doing something wrong.

I have implemented the codes together as you mentioned and call the function when hitting the search, but now the categories sections (like city, state, category) dont work (all the listings show in my database instead of the actual search values). It’s like its just ignoring whatever I input into the categories and only focusing on the tag search.

Example if I put category as restaurants in the dropdown menu it will show all categories like restaurant, gift shop, etc

I also lost my distances by closet sort, they seem to be in the wrong order again).

But the good news is the multi-keyword tag search works so i can type in several keywords in the tag search input and it will show the correct ones. So it’s progress but I’m still stuck. I’ve fixed one problem but broke the original search somehow.

on your function code, you put this:

 let query = QUERY

But wix console gave me an error that query.contains is not a function

so I changed it to

 let query = wixData.query('Articles')

I’m not sure if what I did above messed up the code but it was the only way I got it to run without any errors.

This is my final page code, I’m not sure what else I’m doing wrong.

If you could kindly take one last look at it, I already know you put so much effort or if someone else could guide me what I’m doing wrong

import wixData from "wix-data";
import wixLocation from 'wix-location';
import wixWindow from 'wix-window';

let location = wixWindow.getCurrentGeolocation();

$w.onReady(function () {
    setUpRepeater();
});

$w.onReady(function () {
  $w("#expandFilters").onClick(() => {
    $w('#filterBox').changeState("Expanded");
  } );
  $w("#hideFilters").onClick(() => {
    $w('#filterBox').changeState("Closed");
  } );
});

function dist(lat1, lon1, lat2, lon2) {
 function rad(x) { return x * Math.PI / 180; }

 let R = 6371;
 let dLat = rad(lat2 - lat1);
 let dLong = rad(lon2 - lon1);

 let a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(rad(lat1)) * Math.cos(rad(lat2)) * Math.sin(dLong / 2) * Math.sin(dLong / 2);
 let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
 var d = R * c * 0.621371;
 //console.log(d.toFixed(3));
 return d.toFixed(1);

}

function X2(QUERY){
 let searchValue = $w('#tagSearch').value; 
 let searchWords = searchValue.split(' '); 
   wixWindow.getCurrentGeolocation()
   .then((obj)=>{   
 let query = wixData.query('Articles')
 
 for (let i=0; i < searchWords.length; i++) 
    {       
        query = query.contains('tags', searchWords[i])
        console.log(query)
    }  
    query.find()
    .then(res => {console.log(res)
 let props = res.items; 
 for (var i = 0; i < props.length; i++) {
 
 let latitude = obj.coords.latitude;
 let longitude = obj.coords.longitude;
 let lat1 = latitude //current latitudo of the user
 let lon1 = longitude //current longitude of the user
 let lat2 = props[i].propslat; //property latitude
 let lon2 =  props[i].propslon; //property longitude
 let distance = dist(lat1, lon1, lat2, lon2);
 //new property in object array to store the distance
 //props[i].distance = distance;
         }
 // now sort
         props.sort((a, b) => (a.distance - b.distance) ? 1 : -1);
         console.log(props);
 // lastly, connect it to the repeater
         $w("#articlesList").data = props;
    });    
   }) 
}




async function setUpRepeater() {

    $w('#articlesList').onItemReady(($item, itemData, index,) => {
 

 /// when repeater is ready get users current geolocation
        wixWindow.getCurrentGeolocation()
            .then((obj) => {
 let latitude = obj.coords.latitude;
 let longitude = obj.coords.longitude;
 //console.log("my location is: " + latitude + longitude)

 let lat1 = latitude //current latitudo of the user
 let lon1 = longitude //current longitude of the user
 let lat2 = itemData.propslat; //get the latitude of each property
 let lon2 = itemData.propslon; //get the longitude of each property
 let distance = dist(lat1, lon1, lat2, lon2) // call the fucntion dist to calculate the distance between the curren user and the properties 
 //$item("#txtDistance").text =  distance + " Miles Away";
                $item("#txtDistance").text = distance + " miles";


            })
            .catch((error) => {
 let errorMsg = error;
            });
    })
}

$w.onReady(() => {
  loadStateList();
});



export function resetOptions_click(event) {

 
    $w('#iCity').value = "";
    $w('#dropBusinessType1').value = "Select";
    $w('#iState').value = "";
    $w('#tagSearch').value = "";
    $w('#iCity').resetValidityIndication();

    $w('#dropBusinessType1').resetValidityIndication();

    $w('#iState').resetValidityIndication();
    $w('#tagSearch').resetValidityIndication();
    $w("#dataset1").setFilter(wixData.filter());


}


function loadStateList() {
  wixData.query('stateID')
     .find()
     .then(res => {
 let options = [{"value": '', "label": 'All States'}];
      options.push(...res.items.map(state => {
 return {"value": state.stateList, "label": state.stateList};
      }));
      $w('#iState').options = options;
     });

}


export function searchButton_click_1(event) {


 
      wixData.query("Articles")
      .contains("authorCountry", $w("#iCity").value).contains("businessCategory", $w("#dropBusinessType1").value).contains("state", $w("#iState").value)
 //.contains("tags", $w("#tagSearch").value)
      .find()
 
      .then((results) => {
 let query2 = results
      X2(query2)

      })    
 
 
}

@shrimpbgnet
:grin: Ok! You made some progress! You could SOLVE one of your own problems by yorself!

Another good advise of me → A programmer has to be patient.
The interactive example which i gave you to work with, was programmed not in one day :wink: (it took me about 1,5-month to realize this “interactive-example” which now can help others to work with filters and give the user VISUALISATION what’s going on and how it works).

You should also take your time and overwork your CODE over and over again, till you get your desired result. You will probably have 10-20-30 attempts of different code-versions, till you get your end-result!

And always USE —> CONSOLE!

And an additional advise → just concentrate on related-code-parts , do not work with your whole CODE.

This code-parts for example, have nothing to to with your current issue…

export function resetOptions_click(event) { 
    $w('#iCity').value = "";
    $w('#dropBusinessType1').value = "Select";
    $w('#iState').value = "";
    $w('#tagSearch').value = "";
    $w('#iCity').resetValidityIndication();

    $w('#dropBusinessType1').resetValidityIndication();

    $w('#iState').resetValidityIndication();
    $w('#tagSearch').resetValidityIndication();
    $w("#dataset1").setFilter(wixData.filter());
}


function loadStateList() {
  wixData.query('stateID')
     .find()
     .then(res => {
 let options = [{"value": '', "label": 'All States'}];
      options.push(...res.items.map(state => {
 return {"value": state.stateList, "label": state.stateList};
      }));
      $w('#iState').options = options;
     });
}

This is your issue-code…

import wixData from "wix-data";
import wixLocation from 'wix-location';
import wixWindow from 'wix-window';

let location = wixWindow.getCurrentGeolocation();

$w.onReady(function () {
    setUpRepeater();
});

$w.onReady(function () {
  $w("#expandFilters").onClick(() => {
    $w('#filterBox').changeState("Expanded");
  } );
  $w("#hideFilters").onClick(() => {
    $w('#filterBox').changeState("Closed");
  } );
});

function dist(lat1, lon1, lat2, lon2) {
 function rad(x) { return x * Math.PI / 180; }

 let R = 6371;
 let dLat = rad(lat2 - lat1);
 let dLong = rad(lon2 - lon1);

 let a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(rad(lat1)) * Math.cos(rad(lat2)) * Math.sin(dLong / 2) * Math.sin(dLong / 2);
 let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
 var d = R * c * 0.621371;
 //console.log(d.toFixed(3));
 return d.toFixed(1);

}

function X2(QUERY){
 let searchValue = $w('#tagSearch').value; 
 let searchWords = searchValue.split(' '); 
   wixWindow.getCurrentGeolocation()
   .then((obj)=>{   
 let query = wixData.query('Articles')
 
 for (let i=0; i < searchWords.length; i++) 
    {       
        query = query.contains('tags', searchWords[i])
        console.log(query)
    }  
    query.find()
    .then(res => {console.log(res)
 let props = res.items; 
 for (var i = 0; i < props.length; i++) {
 
 let latitude = obj.coords.latitude;
 let longitude = obj.coords.longitude;
 let lat1 = latitude //current latitudo of the user
 let lon1 = longitude //current longitude of the user
 let lat2 = props[i].propslat; //property latitude
 let lon2 =  props[i].propslon; //property longitude
 let distance = dist(lat1, lon1, lat2, lon2);
 //new property in object array to store the distance
 //props[i].distance = distance;
         }
 // now sort
         props.sort((a, b) => (a.distance - b.distance) ? 1 : -1);
         console.log(props);
 // lastly, connect it to the repeater
         $w("#articlesList").data = props;
    });    
   }) 
}

And why the hell do you have 2x-onReady ??? :smile:

$w.onReady(function () {
    setUpRepeater();
});

$w.onReady(function () {
  $w("#expandFilters").onClick(() => {
    $w('#filterBox').changeState("Expanded");
  } );
  $w("#hideFilters").onClick(() => {
    $w('#filterBox').changeState("Closed");
  } );
});

Always just —> 1x —> onReady-function!!!

$w.onReady(()=>{
  setUpRepeater();
  $w("#expandFilters").onClick(() => {$w('#filterBox').changeState("Expanded");});
  $w("#hideFilters").onClick(() =>   {$w('#filterBox').changeState("Closed");});
});