2

Below script is that when press the button, the browser speaks the variable word. However, I use @foreach in laravel blade. So the only first button works. But rest of buttons generated by foreach doesn't work.

index.blade.php

@foreach($data as $val)
<h2><a class="word" href="/?keyword={{$val->word}}">{{$val->word}}</a></h2>      
<input id="text" type="hidden" value="{{$val->word}}">
<button id="speak-btn">play</button>
@endforeach

<script>
const text = document.querySelector('#text')
const speakBtn = document.querySelector('#speak-btn')
speakBtn.addEventListener('click', function() {
const uttr = new SpeechSynthesisUtterance(text.value)
speechSynthesis.speak(uttr)
})
</script>

So how can I make all the buttons work? I think I need to use this in javascript. However, I'm new to JS and I don't know how to properly use it. Thank you.

2
  • ID has to be unique. Try put class="text" on input and query the document with ('.text') Commented May 27, 2020 at 3:37
  • @Lucas It was same result. Rest of buttons doesn't work. Commented May 27, 2020 at 3:43

2 Answers 2

2

You can not have same id for all your buttons, you can use same class and query by class or call a function and pass the text there and play that

@foreach($data as $val)
<h2><a class="word" href="/?keyword={{$val->word}}">{{$val->word}}</a></h2>      
<input id="text" type="hidden" value="{{$val->word}}">
<button class="speak-btn" onclick="play('{{$val->word}}')">play</button>
@endforeach

<script>
function play(text) {
  // Change these 2 lines if you need 
  const uttr = new SpeechSynthesisUtterance(text)
  speechSynthesis.speak(uttr)
}
</script>

Sign up to request clarification or add additional context in comments.

Comments

0

If you're generating multiple buttons, they shouldn't all have the same id.

You should use classes instead.

@foreach($data as $val)
    <h2><a class="word" href="/?keyword={{$val->word}}">{{$val->word}}</a></h2>      
    <input class="text" type="hidden" value="{{$val->word}}">
    <button class="speak-btn">play</button>
@endforeach

And you'll want to query the buttons with the selector .speak-btn instead, then loop over them.

The method I'm using here is a bit clunky, but attempts to follow your logic to make it easier to understand.

<script>
    const speakBtns = document.querySelector('.speak-btn')

    speakBtns.forEach(function(speakBtn, index) {
        speakBtn.addEventListener('click', (function(index) {
            return function() {
                const text = document.querySelector('.text')[index]
                const uttr = new SpeechSynthesisUtterance(text.value)
                speechSynthesis.speak(uttr)
            }
        })(index))
    }

</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.