Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Capo Chord Converter App

I want to make an App where you can input a guitar chord and a capos fret placement then the chord that sounds will be output.

I converted this chart I found online into a JSON document:

http://www.theguitarcapo.com/wp-content/uploads/2012/08/capo-chart-landscape-1.png

[
  {
    "A": {
      "NO_CAPO" : "A",
      "FRET1" : "Bb",
      "FRET2" : "B",
      "FRET3" : "C",
      "FRET4" : "C#",
      "FRET5" : "D",
      "FRET6" : "Eb",
      "FRET7" : "E"
    }
  },
  {
    "B": {
      "NO_CAPO" : "B",
      "FRET1" : "C",
      "FRET2" : "C#",
      "FRET3" : "D",
      "FRET4" : "Eb",
      "FRET5" : "E",
      "FRET6" : "F",
      "FRET7" : "F#"
    }
  },
  {
    "C": {
      "NO_CAPO" : "C",
      "FRET1" : "C#",
      "FRET2" : "D",
      "FRET3" : "Eb",
      "FRET4" : "E",
      "FRET5" : "F",
      "FRET6" : "F#",
      "FRET7" : "G"
     }
   },
   {
     "D": {
       "NO_CAPO" : "D",
       "FRET1" : "Eb",
       "FRET2" : "E",
       "FRET3" : "F",
       "FRET4" : "F#",
       "FRET5" : "G",
       "FRET6" : "G#",
       "FRET7" : "A"
     }
   },
   {
      "E": {
        "NO_CAPO" : "E",
        "FRET1" : "F",
        "FRET2" : "F#",
        "FRET3" : "G",
        "FRET4" : "G#",
        "FRET5" : "A",
        "FRET6" : "Bb",
        "FRET7" : "B"
      }
    },
    {
       "F": {
         "NO_CAPO" : "F",
         "FRET1" : "F#",
         "FRET2" : "G",
         "FRET3" : "G#",
         "FRET4" : "A",
         "FRET5" : "Bb",
         "FRET6" : "B",
         "FRET7" : "C"
       }
     },
     {
        "G": {
          "NO_CAPO" : "G",
          "FRET1" : "G#",
          "FRET2" : "A",
          "FRET3" : "Bb",
          "FRET4" : "B",
          "FRET5" : "C",
          "FRET6" : "C#",
          "FRET7" : "D"
       }
     }
   ]

I ran it through a validator and everything checks out. Then I created a xhr request and parsed the response to log to my console. My next step will be writing the jQuery to capture a users input from two select menus once submit is clicked, then append the result into the output <div>.

Here is this HTML:

<html>
  <head>
    <meta charset="UTF-8">
    <title>Capo Chord Conversion</title>
  </head>
  <body>
    <header>
    </header>
      <h1>Capo Chord Converter</h1>
    <div>
      <form id="chordConverter">
        <label>
          <strong>You play:</strong>
            <select id="chord">
              <option value="0">A</option>
              <option value="1">B</option>
              <option value="2">C</option>
              <option value="3">D</option>
              <option value="4">E</option>
              <option value="5">F</option>
              <option value="6">G</option>
            </select>
        </label>
        <label>
          <strong>With capo on fret:</strong>
            <select id="capo">
              <option value="NO_CAPO">No Capo</option>
              <option value="FRET1">1</option>
              <option value="FRET2">2</option>
              <option value="FRET3">3</option>
              <option value="FRET4">4</option>
              <option value="FRET5">5</option>
              <option value="FRET6">6</option>
              <option value="FRET7">7</option>
            </select>
      </label>
             <input type="submit" value="Go">
      </form>
    </div>
      <h3>You will Hear:</h3>
    <div id="output">

    </div>
    <footer>
    </footer>
    <script type="text/javascript" src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
    <script type="text/javascript" src="js/conversionCode.js"></script>
  </body>
</html>

The jQuery:

var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
      if(xhr.readyState === 4 && xhr.status === 200) {
        var data = JSON.parse(xhr.responseText);
        console.log(data);

        var chord = ($('#chord').find(":selected").val());
        var capo = ($('#capo').find(":selected").val());

        $('output').append("<p></p>").text(data[chord].capo);



      }
    };

    xhr.open('GET', 'data/conversionData.json');
    xhr.send();

I tested my chord and capo variables to display as alerts which worked. I know this code is incorrect but I'm a little stumped here. I still need to add the submit function as well. Any ideas?

Nice idea, you put a lot of work into that.

1 Answer

Steven Parker
Steven Parker
229,921 Points

This was such a cute idea!   :wink:

But I didn't understand why you would want to make it dependent on a server for such a small data block.

I couldn't resist tweaking it a bit. I made these changes:

  • removed the dependency on server (xhr stuff)
  • eliminated the chord-name tier in the data (the index made it redundant)
  • consolidated data into a single array
  • eliminated empty HTML sections
  • eliminated an unneeded div container
  • un-nested the selects from the labels
  • eliminated the form
  • moved the output into the h3
  • minor corrections to the update function
  • converted data access from double indexing to calculation
  • named the update function chordCalc
  • triggered the update when a select choice is made
  • performed the update on loading
  • removed the "Go" button
  • added the 5 missing chords
  • used the actual musical sharp/flat symbols

Happy coding!   -sp:sparkles:   (and picking :guitar:)

code.html
<html>
  <head>
    <meta charset="UTF-8">
    <title>Capo Chord Conversion</title>
  </head>

  <body>
    <h1>Capo Chord Converter</h1>
    <label><strong>If you play:</strong></label>
    <select id="chord">
      <option value="0">A</option>
      <option value="1">B&flat;</option>
      <option value="2">B</option>
      <option value="3">C</option>
      <option value="4">C&sharp;</option>
      <option value="5">D</option>
      <option value="6">E&flat;</option>
      <option value="7">E</option>
      <option value="8">F</option>
      <option value="9">F&sharp;</option>
      <option value="10">G</option>
      <option value="11">G&sharp;</option>
    </select>
    <label><strong>with capo on fret:</strong></label>
    <select id="capo">
      <option value="0">No Capo</option>
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
      <option value="4">4</option>
      <option value="5">5</option>
      <option value="6">6</option>
      <option value="7">7</option>
    </select>
    <h3>You will hear: &nbsp; <span id="output"></span></h3>
    <script type="text/javascript" src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
    <script type="text/javascript" src="js/conversionCode.js"></script>
  </body>
</html>
conversionCode.js
data = [
  "A", "B&flat;", "B", "C", "C&sharp;", "D", "E&flat;",
  "E", "F", "F&sharp;", "G", "G&sharp;", "A", "B&flat;",
  "B", "C", "C&sharp;", "D", "E&flat;"
];

function chordCalc() {
  var chord = parseInt($('#chord').val());
  var capo = parseInt($('#capo').val());
  $('#output').html(data[chord + capo]);
}

$("select").change(chordCalc);

chordCalc();

Thanks for responding, Steven!

Your method is much more clean. I Like how you eliminated the server stuff, simplified the object and kept everything in one js file. That .on("change") method is perfect as well!

Now to start the CSS to spruce things up. I want to have a sound file that plays the chord that is output however ill need to look into how to do that. Anyways, thanks again!

Steven Parker
Steven Parker
229,921 Points

Hey Joseph Greco, it shouldn't be too hard — you'll just need a collection of audio element files that you can invoke with the .play() method. If you're not familiar with the technique, you might enjoy this short (less than 1 hour) Car Sounds project.

Please post again when it's done (and tag me)! You could create a workspace for this and then make a snapshot to allow you to share the code and audio files at once.

And I tweaked my code above a bit more, adding the 5 other chords and compacting the data a bit further. :arrow_heading_up: