How to pass foreach variable from laravel blade to javascript?

Viewed 1160

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 Answers

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>

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>
Related