Creating a Wishlist using Wix Stores with add to cart function

Updated: Sep 14, 2020


Tutorial Video

Coming soon



About the Tutorial

Wix recently created a Wishlist tutorial using heart icons to display if item is in the User's wishlist and using 'x' icon to remove item from wishlist.  Here is a link to their tutorial: https://support.wix.com/en/article/corvid-tutorial-adding-a-wishlist-to-a-wix-stores-site In our version of the Wishlist tutorial, we will use less steps to create the Wishlist and will use buttons to add or delete items from a Wishlist.  As a bonus, we will also create an 'add to cart' button for single items and add the entire Wishlist to the cart in one click. Please be advised that this tutorial does NOT REQUIRE the Members Area pages but it does require for users to log into the site in order to come back and view the products they have saved.


Note: Wix Stores released a native Wishlist function that requires zero code but installing the Members Area is mandatory. Link to Wix Support article regarding their new feature: https://support.wix.com/en/article/adding-and-setting-up-a-wishlist-in-wix-stores


Follow Along #1

Tutorial Site


https://codequeen.wixsite.com/wishlist-2020



Logic & Requirements #1

About the Products

Our tutorial uses products with zero variations or extra choices.  This allows us to use the native Wix widget that is located on the Product Details Page.  Since there is no code available to detect which selections a User makes on this widget, we are unable to use it for Products that have variations.  In order to create a Wishlist function for Wix Stores that have at least 1 product with variations, then you must create the Product Details page from scratch by hiding the native Wix widget and adding your own elements on the page.  Or you can create each variation into it's own separate product.


Logic & Requirements #2

About the User

In order for a User to create and save a Wishlist to come back to it at a later time, the User has to be logged in as a Member of your website. You will have to make a choice and decide at what point you want the User to login.  Our Wishlist tutorial has 2 methods for this. 

Method #1 uses zero code by simply changing the Product Page Setting Permissions to be for Members Only.  This means the User must be logged in before they can view the Product Details Page.  So if the User is not logged in, the website will prompt the login window to appear. (If you created a custom login, then your custom login will be prompted.)



Method #2 uses some code on the Product Page Details to check if person is logged in before the user can see the "Add to Wishlist" button, meaning they can view the Product Page Details without being forced to be logged in first.




Method One & Two - Step #1

Create a Custom Database Collection



The Database

We will need to create one database collection to store a Members wishlist items.  Using the arrow in the bottom left hand corner, open up the Site Structure panel to add a new Database.  You can also add a new database using the Site Menu Database Icon.




The Settings

Make sure to click on the database settings to configure the permissions in accordance to what your website needs are.  In our tutorial site, our permission settings look like this:




The Fields

In our example, we only required 1 field so we created the following for our database:

  • 1 Reference Field to store the ID of the product from Wix Stores  /  #productId

  • The Reference Field is connected to the Stores/Products collection



Method One - Step #2

Method 1 for Members Only Permissions

(Keep scrolling to the next section if you want Public Permissions)



The Page

The page that we will be using to add the elements will be the Product Page from the Wix Stores app.  Using the Site Menu icon, find the Store Pages and select Product Page.  Once you open the page, you are ready to start adding the elements.




How many buttons will you add?

Depending on what design you want on your Product Page, you can either have:


  • One Button that does both the adding and deleting.  The code will check to see if the item exists in the User's Wishlist and either add or delete the item accordingly.  The button label will also change accordingly, for example:  "Add to Wishlist" vs "Delete from Wishlist"

  • Two Buttons where one button takes care of the "Add to Wishlist" function and the second button takes care of the "Delete from Wishlist".  The code will check to see if the item exists in the User's Wishlist and will either disable or enable the buttons accordingly but both buttons will remain visible at all times.


In our example, we used the following elements with the following ID names:

  • 1 Button Element to click to add only  /  #addButton

  • 1 Button Element to click to delete only  /  #deleteButton

  • 1 Button Element to add or delete accordingly  /  #oneButton


We positioned the elements above and over the native Wix product widget on the page.  Please note that sometimes by placing elements over the native widget will cause the elements to randomly 'float' away.  Choose which button combination you would like on your page.  Only add the button 'combination' that you prefer to use:  either add the 2 buttons or the one button.  Our tutorial has both so you can test and see what they would look like.  The code will tell you which lines to remove depending which buttons you choose to keep or delete.




The Permissions

From the Site Menu Icon, click on Store Pages and find Product Page and click on the settings icon.  Select the Permissions tab and click on Members Only.  Depending on your site logic and structure, select if All Members can access the Product Page or if a specific group of paying members only.




The Code



import wixUsers from 'wix-users';
import wixLocation from 'wix-location';
import wixData from 'wix-data';
let wishlist = true;

$w.onReady(function () {
 let user = wixUsers.currentUser;
 let userId = user.id;

 //In case the user navigations to another product using the product page navigation, we must trigger the code again

 wixLocation.onChange((location) => {
 let newPath = location.path;  //This line gets the current URL path
  $w('#productPage1').getProduct() //This line gets the current item the User is viewing
   .then((product) => {
 const ofProduct = product._id; //We will search the database for the item ID since we are using a reference field
    wixData.query("wishlist") //We will be checking the database to see if the item already exists on their list
     .hasSome("productId", ofProduct) //This line checks the column in our database labeled productId
     .eq("_owner", userId) //This line checks the owner ID of the person who was logged in when they added the item to the database
     .find()
     .then((results) => {
 if (results.items.length > 0) {
       $w("#addButton").disable(); //This line is used if you are using 2 buttons
       $w("#deleteButton").enable(); //This line is used if you are using 2 buttons
       $w("#oneButton").label = "Delete from Wishlist"; //This line is used if you are only using 1 button
      } else {
       $w("#addButton").enable();
       $w("#deleteButton").disable();
       $w("#oneButton").label = "Add to Wishlist"; //This line is used if you are only using 1 button
      }
     })
     .catch((err) => {
 let errorMsg = err;
     });
   });
 });

 $w('#productPage1').getProduct()
  .then((product) => {
 const ofProduct = product._id;
   wixData.query("wishlist") //We will be checking the database to see if the item already exists on their list
    .hasSome("productId", ofProduct) //By using .hasSome we are able to search through a reference field (column)
    .eq("_owner", userId)
    .find()
    .then((results) => {
 if (results.items.length > 0) {
      $w("#addButton").disable(); //This line is used if you are using 2 buttons
      $w("#deleteButton").enable(); //This line is used if you are using 2 buttons
      $w("#oneButton").label = "Delete from Wishlist"; //This line is used if you are only using 1 button
     } else {  //This is what will happen if there are zero matching results
      $w("#addButton").enable();
      $w("#deleteButton").disable();
      $w("#oneButton").label = "Add to Wishlist"; //This line is used if you are only using 1 button
     }
    })
    .catch((err) => {
 let errorMsg = err;
    });
  });

 //These lines are used if you are using 2 buttons. Your first button is to 'add' and the second button is to 'delete' from wishlist.
 //This button is to 'add'

 $w("#addButton").onClick((event) => {
  $w('#productPage1').getProduct()
   .then((product) => { //This will insert 1 record with the current item
 let productName = product._id;
 let toInsert = { //We will only insert the product ID, as we are using a reference field (only ID can be used)
 "productId": productName
    };
    wixData.insert("wishlist", toInsert)
     .then((results) => {
      $w("#addButton").disable();
      $w("#deleteButton").enable();
      $w("#oneButton").label = "Delete from Wishlist"; //This line is just for this tutorial page
     })
     .catch((err) => {
 let errorMsg = err;
     });

   })
 });

 //This button is to 'delete'

 $w("#deleteButton").onClick((event) => {
  $w('#productPage1').getProduct()
   .then((product) => {
 let ofProduct = product._id;
    wixData.query("wishlist") //First we search for this matching product in the database
     .hasSome("productId", ofProduct)
     .eq("_owner", userId)
     .find()
     .then((results) => {
 if (results.items.length > 0) { 
 let resItem = results.items[0]._id; //When the matching record is found, we get the ID of the product
       console.log(resItem)
       wixData.remove("wishlist", resItem) //This line will prompt the database to delete the matching record
        .then((res) => {
 let item = results; 
         $w("#addButton").enable();  //After the item is removed, we will re-enable the "add to wishlist" button
         $w("#deleteButton").disable();
         $w("#oneButton").label = "Add to Wishlist"; //This line is just for this tutorial page
        })
        .catch((err) => {
 let errorMsg = err;
         console.log("Cannot delete") //This error will appear in your console if record was unable to delete
        });
      } else {
       console.log("There were no matches found") //This error will appear in your console if no matches were found
      }
     })
     .catch((err) => {
 let errorMsg = err; //This error will appear in your console if there was an error performing the query
     });
   });

 });

 //These lines are used if you are only using 1 button

 $w("#oneButton").onClick((event) => {
  $w('#productPage1').getProduct()
   .then((product) => {
 let ofProduct = product._id;
    wixData.query("wishlist") //First we search for this matching product in the database
     .hasSome("productId", ofProduct)
     .eq("_owner", userId)
     .find()
     .then((results) => {
 if (results.items.length > 0) { //This line counts how many matching records were found
 let resItem = results.items[0]._id; //When the matching record is found, we get the ID of the product
       console.log(resItem)
       wixData.remove("wishlist", resItem) //Since we are using 1 button, if a match is found, we will delete it
        .then((res) => { 
         $w("#addButton").enable(); //This line is just for this tutorial page ; delete because you are not using 2 buttons
         $w("#deleteButton").disable();  //This line is just for this tutorial page ; delete because you are not using 2 buttons
         $w("#oneButton").label = "Add to Wishlist"; //After deletion, we change the label of the button
        })
        .catch((err) => {
 let errorMsg = err;
         console.log("Cannot delete")
        });
      } else { //This line is triggered only when no matches were found
 let toInsert = { 
 "productId": ofProduct
       };
       wixData.insert("wishlist", toInsert) //We insert the matching item into the database
        .then(() => {
         $w("#addButton").disable(); //This line is just for this tutorial page ; delete because you are not using 2 buttons
         $w("#deleteButton").enable(); //This line is just for this tutorial page ; delete because you are not using 2 buttons
         $w("#oneButton").label = "Delete from Wishlist"; //After inserting, we change the label of the button
        })
        .catch((err) => {
 let errorMsg = err; //This error will appear in the console if an error occurred when trying to insert
        });
      }
     })
     .catch((err) => {
 let errorMsg = err;  //This error will appear in your console if there was an error performing the query
     });
   });
 });

});


Method Two - Step #2

Method 2 for Public Permissions



The Page

The page that we will be using to add the elements will be the Product Page from the Wix Stores app.  Using the Site Menu icon, find the Store Pages and select Product Page.  Once you open the page, you are ready to start adding the elements.





How many buttons will you add?

Depending on what design you want on your Product Page, you can either have:


  • One Button that does both the adding and deleting.  The code will check to see if the item exists in the User's Wishlist and either add or delete the item accordingly.  The button label will also change accordingly, for example:  "Add to Wishlist" vs "Delete from Wishlist"

  • Two Buttons where one button takes care of the "Add to Wishlist" function and the second button takes care of the "Delete from Wishlist".  The code will check to see if the item exists in the User's Wishlist and will either disable or enable the buttons accordingly but both buttons will remain visible at all times.


In our example, we used the following elements with the following ID names:

  • 1 Button Element to click to add only  /  #addButton

  • 1 Button Element to click to delete only  /  #deleteButton

  • 1 Button Element to add or delete accordingly  /  #oneButton


We positioned the elements above and over the native Wix product widget on the page.  Please note that sometimes by placing elements over the native widget will cause the elements to randomly 'float' away.  Choose which button combination you would like on your page.  Only add the button 'combination' that you prefer to use:  either add the 2 buttons or the one button.  Our tutorial has both so you can test and see what they would look like.  The code will tell you which lines to remove depending which buttons you choose to keep or delete.

The Permissions

From the Site Menu Icon, click on Store Pages and find Product Page and click on the settings icon.  Select the Permissions tab and click on Everyone.  




The Code

If you followed Method #1, you may probably notice that the code will be doubled in length simply by changing the logic of your page interaction:  public viewer vs member only page.  The code will tell you which lines to remove depending which buttons you choose to keep or delete.


import wixUsers from 'wix-users';
import wixLocation from 'wix-location';
import wixData from 'wix-data';
let wishlist = true;

$w.onReady(function () {
 let user = wixUsers.currentUser;
 let userId = user.id;

 if (wixUsers.currentUser.loggedIn) {
  $w('#productPage1').getProduct()
   .then((product) => {
 const ofProduct = product._id;
    wixData.query("wishlist") //We will be checking the database to see if the item already exists on their list
     .hasSome("productId", ofProduct) //By using .hasSome we are able to search through a reference field (column)
     .eq("_owner", userId)
     .find()
     .then((results) => {
 if (results.items.length > 0) {
       $w("#addButton").disable(); //This line is used if you are using 2 buttons
       $w("#deleteButton").enable(); //This line is used if you are using 2 buttons
       $w("#oneButton").label = "Delete from Wishlist"; //This line is used if you are only using 1 button
      } else { //This is what will happen if there are zero matching results
       $w("#addButton").enable();
       $w("#deleteButton").disable();
       $w("#oneButton").label = "Add to Wishlist"; //This line is used if you are only using 1 button
      }
     })
     .catch((err) => {
 let errorMsg = err;
     });
   });
 } else {
  $w("#addButton").label = "Login to Save"; //Delete this line if you are using the one button method
  $w("#oneButton").label = "Login to Save"; //Delete this line if you are using the two button method
 }

 //In case the user navigations to another product using the product page navigation, we must trigger the code again

 wixLocation.onChange((location) => {
 if (wixUsers.currentUser.loggedIn) {
 let newPath = location.path; //This line gets the current URL path
   $w('#productPage1').getProduct() //This line gets the current item the User is viewing
    .then((product) => {
 const ofProduct = product._id; //We will search the database for the item ID since we are using a reference field
     wixData.query("wishlist") //We will be checking the database to see if the item already exists on their list
      .hasSome("productId", ofProduct) //This line checks the column in our database labeled productId
      .eq("_owner", userId) //This line checks the owner ID of the person who was logged in when they added the item to the database
      .find()
      .then((results) => {
 if (results.items.length > 0) {
        $w("#addButton").disable(); //This line is used if you are using 2 buttons
        $w("#deleteButton").enable(); //This line is used if you are using 2 buttons
        $w("#oneButton").label = "Delete from Wishlist"; //This line is used if you are only using 1 button
       } else {
        $w("#addButton").enable();
        $w("#deleteButton").disable();
        $w("#oneButton").label = "Add to Wishlist"; //This line is used if you are only using 1 button
       }
      })
      .catch((err) => {
 let errorMsg = err;
      });
    });
  } else {

   $w("#addButton").label = "Login to Save"; //Delete this line if you are using the one button method
   $w("#oneButton").label = "Login to Save"; //Delete this line if you are using the two button method
  }

 });

 //These lines are used if you are using 2 buttons. Your first button is to 'add' and the second button is to 'delete' from wishlist.
 //This button is to 'add'

 $w("#addButton").onClick((event) => {

 if (wixUsers.currentUser.loggedIn) {
   $w('#productPage1').getProduct()
    .then((product) => { //This will insert 1 record with the current item
 let productName = product._id;
 let toInsert = { //We will only insert the product ID, as we are using a reference field (only ID can be used)
 "productId": productName
     };
     wixData.insert("wishlist", toInsert)
      .then((results) => {
       $w("#addButton").disable();
       $w("#deleteButton").enable();
       $w("#oneButton").label = "Delete from Wishlist"; //This line is just for this tutorial page
      })
      .catch((err) => {
 let errorMsg = err;
      });
    })
  } else {
   wixUsers.promptLogin()
    .then((theUser) => {
 let theId = user.id;
 let isLoggedIn = user.loggedIn;
     $w('#productPage1').getProduct()
      .then((product) => { //This will insert 1 record with the current item
 let productName = product._id;
 let toInsert = { //We will only insert the product ID, as we are using a reference field (only ID can be used)
 "productId": productName
       };
       wixData.insert("wishlist", toInsert)
        .then((results) => {
         $w("#addButton").disable();
         $w("#deleteButton").enable();
         $w("#oneButton").label = "Delete from Wishlist"; //This line is just for this tutorial page
        })
        .catch((err) => {
 let errorMsg = err;
        });
      })
    })
    .catch((err) => {
 let errorMsg = err; // "The user closed the login dialog"
    });
  }
 });

 //This button is to 'delete'

 $w("#deleteButton").onClick((event) => {
  $w('#productPage1').getProduct()
   .then((product) => {
 let ofProduct = product._id;
    wixData.query("wishlist") //First we search for this matching product in the database
     .hasSome("productId", ofProduct)
     .eq("_owner", userId)
     .find()
     .then((results) => {
 if (results.items.length > 0) {
 let resItem = results.items[0]._id