Home > Blockchain >  Need help sorting global list by the currently selected value
Need help sorting global list by the currently selected value

Time:05-21

I'm taking a Javascript Basics course and I'm stuck on getting the list to sort. Specifically with Step 8. How do I get it to recognize that they select either ascending or descending and make it populate? Right now it disappears and I see no console errors. Thanks for any help!

Here is what I have so far. You can ignore the controlling your code section in the html. I took that js section out to hopefully make it easier to follow:

/* FETCH */
// Step 1: Declare a global empty array variable to store a list of temples
let templeList = [];

// Step 2: Declare a function named output that accepts a list of temples as an array argument and does the following for each temple:
function output(temples) {
  templeList = temples;
  let div = document.getElementById('temples');

  temples.forEach(temple => {

    // - Creates an HTML <article> element
    let article = document.createElement('article');

    // - Creates an HTML <h3> element and add the temple's templeName property to it
    // - Appends the <h3> element, the two <h4> elements, and the <img> element to the <article> element as children
    let h3 = document.createElement('h3');
    h3.innerHTML = temple.templeName;
    article.appendChild(h3);

    // - Creates an HTML <h4> element and add the temple's location property to it
    // - Appends the <h3> element, the two <h4> elements, and the <img> element to the <article> element as children
    let h4First = document.createElement('h4');
    h4First.innerHTML = temple.location;
    article.appendChild(h4First);

    // - Creates an HTML <h4> element and add the temple's dedicated property to it
    // - Appends the <h3> element, the two <h4> elements, and the <img> element to the <article> element as children
    let h4Second = document.createElement('h4');
    h4Second.innerHTML = temple.dedicated;
    article.appendChild(h4Second);

    // - Creates an HTML <img> element and add the temple's imageUrl property to the src attribute and the temple's templeName property to the alt attribute
    let image = document.createElement('img');
    image.setAttribute('src', temple.imageUrl);
    article.appendChild(image);
    
    // - Appends the <article> element to the HTML element with an ID of temples
    div.appendChild(article);

  });
  
};


// Step 3: Create another function called getTemples. Make it an async function.
async function getTemples() {

  // Step 4: In the function, using the built-in fetch method, call this absolute URL: 'https://byui-cse.github.io/cse121b-course/week05/temples.json'. Create a variable to hold the response from your fetch. You should have the program wait on this line until it finishes.
  let responseFromURL = await fetch('https://byui-cse.github.io/cse121b-course/week05/temples.json');

  // Step 5: Convert your fetch response into a Javascript object ( hint: .json() ). Store this in the templeList variable you declared earlier (Step 1). Make sure the the execution of the code waits here as well until it finishes.
  let templeArray = await responseFromURL.json();
  output(templeArray);

};

// Step 6: Finally, call the output function and pass it the list of temples. Execute your getTemples function to make sure it works correctly.
getTemples(templeList);

// Step 7: Declare a function named reset that clears all of the <article> elements from the HTML element with an ID of temples
function reset() {
  return document.getElementById('temples').innerHTML = '';
};

// Step 8: Declare a function named sortBy that does the following:

function sortBy() {
  // - Calls the reset function
  reset();

  // - Sorts the global temple list by the currently selected value of the HTML element with an ID of sortBy
  let asc = document.getElementById('templeNameAscending');
  let dsc = document.getElementById('templeNameDescending');
  let sort = document.getElementById('sortBy');

  
  if (asc) {
    let sorted = templeList.sort(function(a,b) {return a-b});
    return output(sorted);

  }else if (dsc) {
    let sorted = templeList.sort(function(a,b) {return a-b});
    return output(sorted);
  };
  
};

// Step 9: Add a change event listener to the HTML element with an ID of sortBy that calls the sortBy function
document.getElementById('sortBy').addEventListener('change', sortBy);

/* STRETCH */

// Consider adding a "Filter by" feature that allows users to filter the list of temples
// This will require changes to both the HTML and the JavaScript files
/* HTML Selectors */
article {
    margin: 10px;
}

body {
    font-family: 'Kalam', cursive;
}

div {
    margin: 10px;
    text-align: center;
}

footer {
    background-color: gray;
    color: white;
    padding: 5px;
    text-align: center;
}

header {
    margin: auto;
    text-align: center;
}

img {
    width: 80%;
}

label {
    display: inline-block;
    min-width: 120px;
    text-align: right;
}

main {
    text-align: center;
}

nav {
    background-color: black;
    color: white;
}

nav ul {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-content: space-around;
    margin: 0;
    padding: 0;
}

nav ul li:first-child {
    display: block;
}

nav ul li {
    display: none;
    list-style: none;
    margin: 10px;
}

nav ul li a {
    color: white;
    display: block;
    padding: 10px;
    text-decoration: none;
}
nav ul li a:hover {
    background-color: #efefef;
    color: black;
}

section {
    /* display: flex;
    flex-direction: column;
    align-items: center; */
}


/* Class Selectors */
.active {
    background-color: white;
    color: black;
}

.open li {
    display: block;
}

/* ID Selectors */
#favorite-foods, #hobbies, #places-lived {
    margin: 0;
    padding: 0;
    list-style: none;
    display: inline-block;
    text-align: left;
    vertical-align: top;
}

#temples {
    display: grid;
    grid-template-columns: 1fr;
}

/* Media Queries */
@media only screen and (min-width: 32.5em) {
    nav ul {
        flex-direction: row;
    }
    
    nav ul li:first-child {
        display: none;
    }

    nav ul li {
        display: inline;
        margin: 0 10px;
    }

    #temples {
        grid-template-columns: 1fr 1fr;
    }
}

@media only screen and (min-width: 64em) {
    #temples {
        grid-template-columns: 1fr 1fr 1fr;
    }
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>CSE 121b: Week 05 | Sample Solution</title>
    <link href="https://fonts.googleapis.com/css?family=Kalam&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="styles/main.css">
</head>

<body>
    <nav>
        <ul id="menu">
            <li><a id="toggleMenu">&equiv;</a></li>
            <li><a href="#">Home</a></li>
            <li><a href="#">Lesson 2</a></li>
            <li><a href="#">Lesson 3</a></li>
            <li><a href="#">Lesson 4</a></li>
            <li><a href="#" >Lesson 5</a></li>
        </ul>
    </nav>
    <header>
        <h1>Controlling Your Code</h1>
    </header>
    <main>
        <section>
            <h2>
                Today is <span id="message2"></span>.
            </h2>
            <h3>
                <span id="message1"></span>
            </h3>
        </section>
        <hr>
        <section>
            <h2>Temples in Utah</h2>
            <p>
                Sort by: 
                <select id="sortBy">
                    <option value="templeNameAscending">Temple Name Ascending</option>
                    <option value="templeNameDescending">Temple Name Descending</option>
                </select>
            </p>
            <div id="temples">
            </div>
        </section>
    </main>
    <footer>
        &copy;<span id="year"></span> | Controlling Your Code | Lesson 5
    </footer>
    <script src="scripts/main.js"></script>
    <script src="scripts/task5.js"></script>
</body>

</html>

CodePudding user response:

Here it is. First of all, you are tracking changes on input field and checking if it's equal to templeNameAscending or templeNameDescending, and based on it sort the results. Main thing is this part of code:

if (e.target.value === 'templeNameAscending') {
    let sorted = templeList.sort(function(a,b) {return a.templeName>b.templeName ? 1 : -1});
    
    return output(sorted);

  }else if (e.target.value === 'templeNameDescending') {
    let sorted = templeList.sort(function(a,b) {return b.templeName>a.templeName ? 1 : -1});
    
    return output(sorted);
  };

You made a mistake by trying to select those fields by id, and you never assigned id to them. If you're confused with events, take a look at event objects Here is the working snippet:

/* FETCH */
// Step 1: Declare a global empty array variable to store a list of temples
let templeList = [];

// Step 2: Declare a function named output that accepts a list of temples as an array argument and does the following for each temple:
function output(temples) {
  templeList = temples;
  let div = document.getElementById('temples');

  temples.forEach(temple => {

    // - Creates an HTML <article> element
    let article = document.createElement('article');

    // - Creates an HTML <h3> element and add the temple's templeName property to it
    // - Appends the <h3> element, the two <h4> elements, and the <img> element to the <article> element as children
    let h3 = document.createElement('h3');
    h3.innerHTML = temple.templeName;
    article.appendChild(h3);

    // - Creates an HTML <h4> element and add the temple's location property to it
    // - Appends the <h3> element, the two <h4> elements, and the <img> element to the <article> element as children
    let h4First = document.createElement('h4');
    h4First.innerHTML = temple.location;
    article.appendChild(h4First);

    // - Creates an HTML <h4> element and add the temple's dedicated property to it
    // - Appends the <h3> element, the two <h4> elements, and the <img> element to the <article> element as children
    let h4Second = document.createElement('h4');
    h4Second.innerHTML = temple.dedicated;
    article.appendChild(h4Second);

    // - Creates an HTML <img> element and add the temple's imageUrl property to the src attribute and the temple's templeName property to the alt attribute
    let image = document.createElement('img');
    image.setAttribute('src', temple.imageUrl);
    article.appendChild(image);
    
    // - Appends the <article> element to the HTML element with an ID of temples
    div.appendChild(article);

  });
  
};


// Step 3: Create another function called getTemples. Make it an async function.
async function getTemples() {

  // Step 4: In the function, using the built-in fetch method, call this absolute URL: 'https://byui-cse.github.io/cse121b-course/week05/temples.json'. Create a variable to hold the response from your fetch. You should have the program wait on this line until it finishes.
  let responseFromURL = await fetch('https://byui-cse.github.io/cse121b-course/week05/temples.json');

  // Step 5: Convert your fetch response into a Javascript object ( hint: .json() ). Store this in the templeList variable you declared earlier (Step 1). Make sure the the execution of the code waits here as well until it finishes.
  let templeArray = await responseFromURL.json();
  output(templeArray);

};

// Step 6: Finally, call the output function and pass it the list of temples. Execute your getTemples function to make sure it works correctly.
getTemples(templeList);

// Step 7: Declare a function named reset that clears all of the <article> elements from the HTML element with an ID of temples
function reset() {
  return document.getElementById('temples').innerHTML = '';
};

// Step 8: Declare a function named sortBy that does the following:

function sortBy(e) {
  // - Calls the reset function
  reset();

  // - Sorts the global temple list by the currently selected value of the HTML element with an ID of sortBy
  let sort = document.getElementById('sortBy');

  
  if (e.target.value === 'templeNameAscending') {
    let sorted = templeList.sort(function(a,b) {return a.templeName>b.templeName ? 1 : -1});
    
    return output(sorted);

  }else if (e.target.value === 'templeNameDescending') {
    let sorted = templeList.sort(function(a,b) {return b.templeName>a.templeName ? 1 : -1});
    
    return output(sorted);
  };
  
};

// Step 9: Add a change event listener to the HTML element with an ID of sortBy that calls the sortBy function
document.getElementById('sortBy').addEventListener('change', sortBy);

/* STRETCH */

// Consider adding a "Filter by" feature that allows users to filter the list of temples
// This will require changes to both the HTML and the JavaScript files
/* HTML Selectors */
article {
    margin: 10px;
}

body {
    font-family: 'Kalam', cursive;
}

div {
    margin: 10px;
    text-align: center;
}

footer {
    background-color: gray;
    color: white;
    padding: 5px;
    text-align: center;
}

header {
    margin: auto;
    text-align: center;
}

img {
    width: 80%;
}

label {
    display: inline-block;
    min-width: 120px;
    text-align: right;
}

main {
    text-align: center;
}

nav {
    background-color: black;
    color: white;
}

nav ul {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-content: space-around;
    margin: 0;
    padding: 0;
}

nav ul li:first-child {
    display: block;
}

nav ul li {
    display: none;
    list-style: none;
    margin: 10px;
}

nav ul li a {
    color: white;
    display: block;
    padding: 10px;
    text-decoration: none;
}
nav ul li a:hover {
    background-color: #efefef;
    color: black;
}

section {
    /* display: flex;
    flex-direction: column;
    align-items: center; */
}


/* Class Selectors */
.active {
    background-color: white;
    color: black;
}

.open li {
    display: block;
}

/* ID Selectors */
#favorite-foods, #hobbies, #places-lived {
    margin: 0;
    padding: 0;
    list-style: none;
    display: inline-block;
    text-align: left;
    vertical-align: top;
}

#temples {
    display: grid;
    grid-template-columns: 1fr;
}

/* Media Queries */
@media only screen and (min-width: 32.5em) {
    nav ul {
        flex-direction: row;
    }
    
    nav ul li:first-child {
        display: none;
    }

    nav ul li {
        display: inline;
        margin: 0 10px;
    }

    #temples {
        grid-template-columns: 1fr 1fr;
    }
}

@media only screen and (min-width: 64em) {
    #temples {
        grid-template-columns: 1fr 1fr 1fr;
    }
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>CSE 121b: Week 05 | Sample Solution</title>
    <link href="https://fonts.googleapis.com/css?family=Kalam&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="styles/main.css">
</head>

<body>
    <nav>
        <ul id="menu">
            <li><a id="toggleMenu">&equiv;</a></li>
            <li><a href="#">Home</a></li>
            <li><a href="#">Lesson 2</a></li>
            <li><a href="#">Lesson 3</a></li>
            <li><a href="#">Lesson 4</a></li>
            <li><a href="#" >Lesson 5</a></li>
        </ul>
    </nav>
    <header>
        <h1>Controlling Your Code</h1>
    </header>
    <main>
        <section>
            <h2>
                Today is <span id="message2"></span>.
            </h2>
            <h3>
                <span id="message1"></span>
            </h3>
        </section>
        <hr>
        <section>
            <h2>Temples in Utah</h2>
            <p>
                Sort by: 
                <select id="sortBy">
                    <option value="templeNameAscending">Temple Name Ascending</option>
                    <option value="templeNameDescending">Temple Name Descending</option>
                </select>
            </p>
            <div id="temples">
            </div>
        </section>
    </main>
    <footer>
        &copy;<span id="year"></span> | Controlling Your Code | Lesson 5
    </footer>
    <script src="scripts/main.js"></script>
    <script src="scripts/task5.js"></script>
</body>

</html>

  • Related