0

I'm trying to display a list of songs my band plays on a new website. The user enters a song name (in the input tag called "liveSearchBox") and clicks the "findSong" button. If we play the song, I want to alert "Yes, we play it!". If we don't, I want to alert "Sorry, we don't play it." I've been trying for hours to figure out the solution, but am not advanced enough yet. Thanks for any help!

Here's my HTML code:

<div class="live-search-list">

    <input type="text" id="liveSearchBox" placeholder=" Search Songs or Artist">
    <button id="findSong"> Click to Find!</button>
    <ul id="songList">
        <li class="song"> Margaritaville</li>
        <li class="song"> Boys of Summer</li>
        <li class="song"> Somebody Like You</li>
    </ul>

</div>

And here's my Javascript:

var songList = ["Margaritaville","Boys of Summer","Somebody Like You"];
var findButton = document.getElementById("findSong");
var songQuery = document.getElementById("liveSearchBox");
var songListItem = document.getElementsByClassName("song");

findButton.onclick = function(){
   for (var i = 0; i<songList.length; i++){
       if (songQuery.value === songList[i]){
           alert('Yes, we play "' +  songQuery.value + '"!');
       }  else {
             i++;
          }

  } 

};
alamoot
  • 1,966
  • 7
  • 30
  • 50
brandonstiles
  • 113
  • 1
  • 9
  • Which part are you having issues with? In order to alert "No" you'll need to have a boolean value that is false initially and only set to true if there is a match, then when your loop is finished, if the boolean is still false, you know there was no match - at which point you can alert "No". – Goose Apr 22 '16 at 20:50
  • 2
    You're skipping a lot of them. Don't put `i++` in your `else` clause. You're already incrementing `i` in your `for` loop. Also, listen to Shomz. There's a much easier way of doing this. – Mike Cluck Apr 22 '16 at 21:02
  • 1
    Additionally, you'll want to add a `break;` after you find the song to exit the `for` loop early. – Eric Phillips Apr 22 '16 at 21:09

4 Answers4

3

Use indexOf:

if (songList.indexOf(songQuery.value) != -1)
    alert('yes');
else
    alert('no');
Shomz
  • 37,421
  • 4
  • 57
  • 85
1

Using indexOf would work, but if you want a solution that works in any browser, here is the fastest way to do that:

function isInArray(array, item) {
    for (i = 0; i < array.length; i++)
        if (array[i] === item)
            return true;
    return false;
}

findButton.onclick = function() {
    if (isInArray(songList, songQuery.value))
        alert('Yes, we play "' + songQuery.value + '"!');
    else
        alert('Sorry, we don\'t play "' + songQuery.value + '".');
};
4castle
  • 32,613
  • 11
  • 69
  • 106
  • 2
    Why do you think a Javascript loop is faster than `indexOf`? What do you think `indexOf` does that's different from your loop? – Barmar Apr 22 '16 at 21:16
  • Haha, I think if that array contained the names of all the songs in the world, we'd be able to actually see the difference between the for loop and the indexOf. Btw. using globals is terrible. – Shomz Apr 22 '16 at 21:16
  • @Shomz It doesn't have to be global, it can be in any scope adjacent or above the `onclick` handler. – 4castle Apr 22 '16 at 21:18
  • @Barmar See [this question](http://stackoverflow.com/questions/6682951/why-is-looping-through-an-array-so-much-faster-than-javascripts-native-indexof) – 4castle Apr 22 '16 at 21:19
  • 1
    @4castle See [this answer](http://stackoverflow.com/a/36218454/1491895) to that question. – Barmar Apr 22 '16 at 21:19
  • 2
    `indexOf` was slow 5 years ago. It's gotten better. – Barmar Apr 22 '16 at 21:20
  • 1
    @4castle, you can't expect that from a beginner - you need to teach them the right way without assumptions. – Shomz Apr 22 '16 at 21:20
  • @Barmar Yes, but that is the newest version of Chrome. This will work great with any browser. – 4castle Apr 22 '16 at 21:25
  • I expect that `indexOf` will work just fine in any recent browser. And unless the array is thousands of items, it's probably not a big difference in either case. Just stick to standard functions, there's no reason to reinvent the wheel. – Barmar Apr 22 '16 at 21:27
0
findButton.onclick = function(){
    var msg = !!~songList.indexOf(songQuery.value) ? 'Yes, we play "' +  songQuery.value + '"!' : 'No we do not play this song.';
    alert(msg);
}

Maybe this will be more understandable for you:

findButton.onclick = function(){
    var msg = songList.includes(songQuery.value) ? 'Yes, we play "' +  songQuery.value + '"!' : 'No we do not play this song.';
    alert(msg);
}

Or this:

findButton.onclick = function(){
    if(songList.includes(songQuery.value)) {
        alert('Yes, we play "' +  songQuery.value + '"!');
    } else {
        alert('No we do not play this song.');
    }
}
Yuriy Yakym
  • 3,616
  • 17
  • 30
  • 2
    Because OP is admittedly not advanced, throwing these operators at him without explanation probably isn't going to be of benefit to him – Eric Phillips Apr 22 '16 at 21:03
  • Yura, that definitely did the trick, but Eric is right- I don't understand how it all worked! Very impressive though, and I'll try and figure out the syntax. Thank you!! – brandonstiles Apr 22 '16 at 21:15
  • 1
    `.includes()` is a pretty new function. It isn't supported in IE or Edge. – 4castle Apr 22 '16 at 21:17
  • in first two examples ternary operator is used ` ? : `. If expr1 == true, then expr2 will be executed, and expr3 in another case. – Yuriy Yakym Apr 22 '16 at 21:18
  • `!!` double negation just casts operand to `boolean`. And `~` is a bitwise operator that flips all bits in its operand – Yuriy Yakym Apr 22 '16 at 21:20
  • There's no need to cast to boolean for a ternary expression. – shmosel Apr 22 '16 at 22:54
0

var songList = ["Margaritaville", "Boys of Summer", "Somebody Like You"],
  findButton = document.getElementById("findSong"),
  songQuery = document.getElementById("liveSearchBox");

findButton.onclick = function() {
  if (typeof songQuery.value === 'undefined' || songQuery.value === null || songQuery.value === '') {
    alert('please input the song name.');
    return false;
  }
  if (songList.indexOf(songQuery.value) > -1) {
    alert('Yes, we play "' + songQuery.value + '"!');
  } else {
    alert('Sorry "' + songQuery.value + '" was not found!');
  }


};
<div class="live-search-list">

  <input type="text" id="liveSearchBox" placeholder=" Search Songs or Artist">
  <button id="findSong">Click to Find!</button>
  <ul id="songList">
    <li class="song">Margaritaville</li>
    <li class="song">Boys of Summer</li>
    <li class="song">Somebody Like You</li>
  </ul>

</div>
Monochrome Yeh
  • 180
  • 1
  • 8