Sorting by numbers and alphabetically

Below is my Codepen which contains a project with 4 Products with Prices and
titles of Products and on the left are Filters.
And on JavaScript added a small code by seeing tutorials on W3School and other forums to sort by highest number and alphabetically, so I added function sortPrice so It would sort my products by the Price and by the Name of Products from a - z ,but it doesn’t work because it says “title.sort is not a function” and "product.sort is not a function ", could someone tell me what’s the issue, thank you.
https://codepen.io/beh4r/pen/GaMjjY

Are title and product arrays?

1 Like

<div class="cart"> is the main div and <div class="products"> is the child of “cart” and added “products” to set a smaller width for product images, because with “cart” the width couldn’t be changed.
And “title” is with ID in each 4 products because there’s a class with “title1,title2,title3,title4” and all of these 4 titles have a different position and added an ID for all products to use in JavaScript hopefully you understood what I mean to say.

1 Like

The reason I asked is because the sort() function exists on arrays, but not on other data types. If the variables title and product do not contain arrays, you’ll get the “.sort is not a function” error.

2 Likes

What @ArielLeslie was alluding to was unless title and product are arrays, you can not used the sort function on them. You will need to read about how you might use querySelectorAll which will return an “array-like” object which you will then need to convert to an actual array some other way (hint: spread operator).

That being said, I suggest you rethink the way you create the filter by checkboxes and display the products and their respective pricing. It would be better to have an array of objects containing the applicable details for each product (i.e. title, price, image url) then dynamically create the HTML instead of hard coding the HTML. Then you can simply extract the product titles (used for the name filter by) or the product prices (used for the price filter by) and use a modified version of your current sortName and sortPrice functions.

The following is an example structure of what the products array might look like:

const products = [
  {
    title: 'Corsair Case',
    price: 299.89,
    imageUrl: 'http://cdn.shopify.com/s/files/1/2227/7667/products/Corsair_Crystal_Series_570X_RGB_grande.jpg?v=1536348480'
  },
  {
    title: 'Intel Core i9',
    price: 479.99,
    imageUrl: 'https://i.ebayimg.com/images/g/Z10AAOSwlJBb2JlL/s-l300.jpg'  
  }
];
1 Like

Yeah I have seen mostly of sort examples were with an array and I was thinking to add products in arrays instead of adding them in HTML, but do mostly of developers add products on HTML or they put them in an array like you showed ? Which is better to use ?

1 Like

Ideally you want to keep the data separate from the presentation of the data. That way if you want to change the look and feel of the presentation, you do not have to worry about rewriting the code which makes calculations with (or sorts/filters) the data. You would only have to rewrite the code which presents the data.

Also, most of the time the data is stored in a database or external file somewhere and you would “import” the data in as you need it instead of putting it directly into your main code. If you only had a few products and the pricing would not change often, then I would create a JSON file to store the data. If you have many products and the prices could change at any time, then I would store them in a database and write a separate application to make it easy to administer the products in it.

2 Likes

Thanks for explaining and looks I will add products in an array of JS Code instead of HTML because looks like I have to use querySelector like you said and looks more difficult so I am going with the array.

And about data store, I’m just creating these products like an exercise and haven’t learned JSON and SQL yet, but the database looks is the better option to use for storing data.

@RandellDawson
Hello Randell, I was seeing some tutorials on YouTube with Vue and you have images of video I’m talking below and first he created a table with data and with buttons to sort by Project Title, Person, Due by date then he added on HTML Project Title, Person and Due By and then with Vue he added name of Projects for each row, different Person name for each and a different date for each table row within array and wanted to ask you is that JSON how it works because I still haven’t learned JSON?

And with Vanilla JS is more hard to sort my project because first I have to add elements title, price, image in JavaScript, but with Vue looks more easier because you can include JSON like {{product.price}} in HTML and then I could add price of products with Vue, but with Vanilla JS you told me to add Name, Price, Image in an array and tried to do that in the Codepen below but it didn’t worked and wanted to ask you if I would be able to do this sorting with Vanilla JS by using JSON in HTML or JSON can only be used with framework like Vue, Angular, React.
https://codepen.io/beh4r/pen/pmaxPJ



@behari97 Currently you are getting an error “Uncaught TypeError: element.appendChild is not a function” on line 6 because when you use document.getElementsByClassName("col-4"), you get a NodeList and not an element. You should use some console.log statements to see what values are actually being assigned to your variables to help you debug most of your issues.

You assign the value of document.getElementsByClassName("col-4") to element, element2, element3, and element4.

Using what I originally told you about how to use an array of products to dynamically create the HTML, I have given you an example of showing the title and the image below. You should be able to figure out to add the price based on my example:

HTML

<div class="container">
  <div id="products" class="row justify-content-center"></div>
</div>

JavaScript

var products = [
  {
    title: 'Corsair Case',
    price: 299.89,
    imageUrl: 'http://cdn.shopify.com/s/files/1/2227/7667/products/Corsair_Crystal_Series_570X_RGB_grande.jpg?v=1536348480'
  },
  {
    title: 'Intel Core i9',
    price: 479.99,
    imageUrl: 'https://i.ebayimg.com/images/g/Z10AAOSwlJBb2JlL/s-l300.jpg'  
  }
];

var productsElem = document.getElementById('products');

// iterate through the list of products and create applicable div elements
for (var i = 0; i < products.length; i++) {
  var divElem = document.createElement("div");
  divElem.setAttribute("class", "col-4");
  
  var spanElem = document.createElement("span");
  var spanText = document.createTextNode(products[i].title); // assign the current title here
  spanElem.appendChild(spanText);
  divElem.appendChild(spanElem);

  var imgElem = document.createElement("img");
  imgElem.src = products[i].imageUrl; // assign the current image url from the current object here
  
  divElem.appendChild(imgElem);
  
  productsElem.appendChild(divElem)
}

Thanks Randell, looks I’ve gone in the easy way by skipping iteration and I have been using the wrong way to createElements, thanks.

I would say the way you were trying to do it (manually) is much more difficult and more prone to making a mistake.

1 Like