How do I specify an element's relationship to another element so that I can write HTML content inside that element?

Viewed 62

I am trying to get certain output to appear in a particular spot on the webpage. The user clicks a button (id="start_button") and a script that does speech recognition begins. A transcript is produced and that transcript is supposed to appear near that button that was clicked. There is a series of buttons, and near each button, the transcript relevant to that button that was clicked is supposed to appear. I have chosen a span element for the transcript to show up within. This span element has the id of "transcription".

I have linked to jQuery and Bootstrap in my script.

<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>    
<link rel="stylesheet" 
  href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script 
    src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js">. 
    </script>

The HTML part where the buttons are is like this:

<div class="d-flex mt-3 ml-0 mb-5">
   <div class="controls pl-1">
       <audio>
          <source src="2x.mp3" type="audio/mpeg">
          <source src="2x.ogg" type="audio/ogg">
       </audio>
       <button type="button" class="btn final_button text-white"  style="height: 40px; width: 40px; font-size: 11px; background-color: goldenrod;"><%- user.japanese1.japanese1g.value%></button>     
       <button type="button" class="btn btn-default btn-success points_button" style="height: 40px; width: 40px; font-size: 11px">0</button>
       <button type="button" id="start_button" onclick="startButton(this)" class="btn btn-default btn-primary score_button fas fa-microphone" data-question="japanese1g" data-field="japanese1" style="height:40px; width: 40px;"></button>
       <button type="button" onclick="playAudio(this)" class="btn btn-default talk_button fas fa-play text-white" data-string="hello" style="height:40px; width: 40px; background-color: hotpink"></button>&nbsp;&nbsp;<b>Say the whole dialogue</b>&nbsp;<br/>
       <span id="transcription" style="font-size: 12px;"></span>   
  </div>
</div>

This is the javascript that I have tried and it failed:

buttonpress.siblings("#transcription").html() = final_transcript;

The script below worked perfectly when I wrote the javascript like this:

buttonpress.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.innerHTML = final_transcript;

However, I cannot use this javascript anymore as the placement of the span element, within which the transcript is supposed to appear, varies for the different buttons. It is not always at the "nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling" position.

For example, there is this type of button:

<div class="d-flex mt-3 ml-0">
   <div class="controls pl-1">
     <button type="button" class="btn final_button text-white"  style="height: 40px; width: 40px; font-size: 11px; background-color: goldenrod;"><%- user.japanese1.japanese1j.value%></button>     
     <button type="button" class="btn btn-default btn-success points_button" style="height: 40px; width: 40px; font-size: 11px">0</button>
     <button type="button" id="start_button" onclick="startButton(this)" class="btn btn-default btn-primary score_button fas fa-microphone" data-question="japanese1j" data-field="japanese1" style="height:40px; width: 40px;"></button>
     &nbsp;&nbsp;&nbsp;I lost mine.<br/>
     <span id="transcription" style="font-size: 12px;"></span>   
   </div>
 </div>

As you can see, the span element is not in the same position as the first example of button that I showed above this one.

(The speech recognition button is the same however. It is the button with id="start_button".)

In the second case, there is no button following the "start_button". So this is why I can no longer use "nextSibling ....". I prefer not to write a separate script for this other type of button.

EDITED: I didn't make it clear in the question above but the "buttonpress" in the line of code comes from the following. I declared a variable: var buttonpress in the script. "buttonpress" is the same as the button with the id of "start_button" that starts the process of speech recognition when clicked.

2 Answers

use closest and find to trap the closest span following the button pressed:

avoid to put function inside html. i'am trapping the button start with the class fa-microphone

$(this).closest("div.controls.pl-1").find("span");  

closest go up to the first div with classes controls and pl-1, and find search all childrens with span tag

$("button.fa-microphone").on("click", function(){
 //find the selector wuth tag span closest to the button pressed
  var transcription = $(this).closest("div.controls.pl-1").find("span");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="d-flex mt-3 ml-0 mb-5">
  <div class="controls pl-1">
    <audio>
          <source src="2x.mp3" type="audio/mpeg">
          <source src="2x.ogg" type="audio/ogg">
       </audio>
    <button type="button" class="btn final_button text-white" style="height: 40px; width: 40px; font-size: 11px; background-color: goldenrod;"><%- user.japanese1.japanese1g.value%></button>
    <button type="button" class="btn btn-default btn-success points_button" style="height: 40px; width: 40px; font-size: 11px">0</button>
    <button type="button"  class="btn btn-default btn-primary score_button fas fa-microphone" data-question="japanese1g" data-field="japanese1" style="height:40px; width: 40px;"></button>
    <button type="button" onclick="playAudio(this)" class="btn btn-default talk_button fas fa-play text-white" data-string="hello" style="height:40px; width: 40px; background-color: hotpink"></button>&nbsp;&nbsp;<b>Say the whole dialogue</b>&nbsp;<br/>
    <span id="transcription" style="font-size: 12px;"></span>
  </div>
</div>



<div class="d-flex mt-3 ml-0">
  <div class="controls pl-1">
    <button type="button" class="btn final_button text-white" style="height: 40px; width: 40px; font-size: 11px; background-color: goldenrod;"><%- user.japanese1.japanese1j.value%></button>
    <button type="button" class="btn btn-default btn-success points_button" style="height: 40px; width: 40px; font-size: 11px">0</button>
    <button type="button"  class="btn btn-default btn-primary score_button fas fa-microphone" data-question="japanese1j" data-field="japanese1" style="height:40px; width: 40px;"></button> &nbsp;&nbsp;&nbsp;I
    lost mine.<br/>
    <span class="transcription" style="font-size: 12px;"></span>
  </div>
</div>

I was able to get the transcript to show in the right place by writing this code below. I ended up not using jQuery and stayed with vanilla javascript.

I didn't make it clear in my question but I declared a variable "buttonpress". This is the button with the id of "start_button" that begins the process of speech recognition when clicked.

var buttonpress; 

Then the line of code that tells the script where to display the transcript is:

buttonpress.parentElement.querySelector("span").innerHTML = final_transcript; 

This code also works if you use the class of the span element to identify it:

buttonpress.parentElement.querySelector(".transcription").innerHTML = final_transcript; 

and this code works too if you use the id of the span element to identify it:

buttonpress.parentElement.querySelector("#transcription").innerHTML = final_transcript; 
Related