0

I would like to extend a question which I've asked not long time ago: enter link description here

As before, I'm also trying to write an HTML/JavaScript file which would play an animal sound (.mp3) according to the given name of an animal.

Only here, if the user enters the name of a certain animal that has numerous sounds, then the result would be multiple audio players (tags) to choose from.

For example, If there is only one result for the input, like the "cow" example, then it's not a problem, it only prints cow and enables the sound just for cow. So far, all the above mentioned works!

But if the user enters "Bird" in the field, the program searches it in the array (dictionary). If it exists in the array, it prints different kinds of birds ("Blackbird", "Sparrow", "Cuckoo") and enables the audio for each of them in different audio players. Of course it should be dynamic and fit to 2, 4, 5 or any other number of value results.

So this is what I'm trying to figure out - how to allow multiple audio tags for each element (value) attributed to the same key. That is, if there are 3 values for "Bird": "Blackbird", "Sparrow" and "Cuckoo" then for each should appear a separate audio player tag.

as in this example:

-Blackbird --> audio player tag1 (plays Blackbird.mp3)

-Cuckoo --> audio player tag2 (plays Cuckoo.mp3)

-Sparrow --> audio player tag3 (plays Sparrow.mp3)

/

Here is again a simplified picture (but with only one audio tag..)for this example and the JavaScript/HTML below:

I would very appreciate any help! Thanks in advance!

enter image description here

var animal_sub = {"Bird":"- (Blackbird) "+"\n "+"- (Cuckoo) "+ "\n "+"- (Sparrow) "
 };

function animalVoice(){
    // Get the names from the text field
    theAnimal=document.animals.newAnimal.value; 
    if(theAnimal in animal_sub) { 
        document.animals.outAnimal.value=animal_sub[theAnimal];  //printing the word in the textarea
        var line=animal_sub[theAnimal];                     
        regex=line.match(/\(([^\)]*)\)/g);               //finds what's in the () and puts it in ARRAY using regular ex. 
        document.getElementById("myPlayer").src = "audio/animals/" + regex[0].substring(1,regex[0].length-1) + ".mp3"; //executes audio for the first appeared index (regex[0])
        }
    else if(!(theAnimal in animal_sub)) {
    theAnimal=document.animals.newAnimal.value;
    document.animals.outAnimal.value=theAnimal;
    document.getElementById("myPlayer").src = "audio/animals/" + theAnimal + ".mp3"; //if the animal is NOT in the array, it simply prints it and plays the audio
    }
        
};
<!DOCTYPE html>
<html 
    <head>
    <script type="text/javascript" src="animal_voices.js"></script>
    </head>
    <body>  
        <p>please enter the animal's name here: </p>
        <form name="animals">
        <input type="text" name="newAnimal" size ="30" />
        <input type="button" name="animal" value="find the sound"
        onclick="animalVoice();">
        <br/>
        <h4>output:</h4>
        <textarea cols = "31" rows = "4" name="outAnimal"> 
        </textarea>
        <audio
            src="audio/animals/"
            id="myPlayer"
            preload="auto"
            controls>      
        </audio>    
        </form>
</body>
</html>
Community
  • 1
  • 1
Apython
  • 453
  • 6
  • 19

2 Answers2

1

If I understand your question correctly:

//var animal_sub = {"Bird":"- (Blackbird) "+"\n "+"- (Cuckoo) "+ "\n "+"- (Sparrow) "
// };

var animal_sub = {
    bird: [
      'Blackbird', 'Cuckoo', 'Sparrow'
    ]
}

function animalVoice(){
    // Get the names from the text field
    theAnimal=document.animals.newAnimal.value; 
    
    if(theAnimal in animal_sub) { 
      var result = animal_sub[theAnimal];
      document.animals.outAnimal.value=result.join(',');  //printing the word in the textarea
      for(var i = 0; i < result.length; i++) {
        var a = document.createElement('audio');
        document.body.appendChild(a);
        a.setAttribute('src', 'audio/animals/' + result[i]);
        a.setAttribute('controls', 'controls');
      }
    }
};
<p>please enter the animal's name here: </p>
<form name="animals">
<input type="text" name="newAnimal" size ="30" value="bird" />
<input type="button" name="animal" value="find the sound"
onclick="animalVoice();">
<br/>
<h4>output:</h4>
<textarea cols = "31" rows = "4" name="outAnimal"> 
</textarea>
<!--<audio
    src="audio/animals/"
    id="myPlayer"
    preload="auto"
    controls>      
</audio>-->
</form>
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
1

You will need to insert Arrays into your dictionnary (animal_sub object).
Then if the object returned is an Array, iterate over all its keys and append as much new Audios as needed.
Note: to detect if the object is an Array, I do use Array.isArray() method, which was unfortunately not supported by older browsers (IE8-). You can find some polyfills out-there.

var animal_sub = {"Bird":["Blackbird", "Cuckoo","Sparrow"], "Fish":"Sardine"};

function animalVoice(){
    var multiAud = document.querySelectorAll('.multiple_audio');
    // remove the added audio players
    for(var i=0; i<multiAud.length; i++){
        multiAud[i].parentNode.removeChild(multiAud[i]);
      }
    // Keep some references of our elements
    var player = document.getElementById("myPlayer");
    var output = document.animals.outAnimal;
    var theAnimal=document.animals.newAnimal.value; 
    // if the input value is in the Dictionnary
    if(theAnimal in animal_sub) {
      var animal = animal_sub[theAnimal];
      // reset the textArea
      output.value='';
      // if our object is an Array
      if(Array.isArray(animal)){
        
        for(var i=0; i<animal.length; i++){
          output.value+=animal[i]+'\n';
          // if it's the first in the array
          if(i<1){
            player.src= "audio/animals/" + animal[i] + ".mp3";
            }
          else {
            // create a new Audio
            var audio = new Audio("audio/animals/" + animal[i] + ".mp3");
            // add a class so that we can delete it on next call
            audio.className = 'multiple_audio';
            audio.controls=true;
            // insert it in the document
            player.parentNode.insertBefore(audio, player.nextNode);
            }
          }
        }
      // it's not an Array
      else if(typeof animal === 'string'){
        output.value = animal;
        player.src = "audio/animals/" + animal + ".mp3";
        }
      }
    else { // if (!(theAnimal in animal_sub)) {
      output.value = theAnimal;
      // are you sure you want to do it ?
      player.src = "audio/animals/" + theAnimal + ".mp3";
    }
        
};
<!DOCTYPE html>
<html 
    <head>
    <script type="text/javascript" src="animal_voices.js"></script>
    </head>
    <body>  
        <p>please enter the animal's name here: </p>
        <form name="animals">
        <input type="text" name="newAnimal" size ="30" />
        <input type="button" name="animal" value="find the sound"
        onclick="animalVoice();">
        <br/>
        <h4>output:</h4>
        <textarea cols = "31" rows = "4" name="outAnimal"> 
        </textarea>
        <audio
            src="audio/animals/"
            id="myPlayer"
            preload="auto"
            controls>      
        </audio>    
        </form>
</body>
</html>
Community
  • 1
  • 1
Kaiido
  • 123,334
  • 13
  • 219
  • 285