简体   繁体   中英

Using Jinja2 to pass unique ids to JavaScript function in Flask application?

I have a for loop in Jinja that is iterating over each row in a SQL query. My initial pass in Javascript was as follows:

 var myFunction = function() { Hide = document.getElementsByClassName("card"); if(Hide.length>0){ for(var i = 0; i < Hide.length; i++){ if( Hide[i].style.display== "none"){ Hide[i].style.display = "block"; }else{ Hide[i].style.display = "none"; } }} }

And in HTML:

 <p><button id="hide" class="btn btn-primary" onclick="myFunction()">Not Interested</button></p>

My intention is for a bootstrap card to disappear when the hide button is clicked, but currently with this code, all cards within the Jinja loop disappear at once.

I tried to pass in a unique div id using Jinja per below:

 {% for movie in movies %} <div class="card" id="div-{{ movie["id"] }}"> <div class="row no-gutters"> <div class="col-auto"> <img src="https://image.tmdb.org/t/p/w500/{{ movie["poster_path"] }}" class="img-fluid" alt=""> </div> <div class="col"> <div class="card-block px-2"> <h5 class="card-title"><b>{{ movie["title"] }}</b> ({{ movie["date"] }})</h5> <p class="card-text">Rating: {{ movie["rating"] }}</p> <div style="display:inline-block"><form method="get" action="/love/{{ movie["id"] }}"> <input type="submit" class="btn btn-primary" value="Loved It"> </form></div> <div style="display:inline-block"><form method="get" action="/like/{{ movie["id"] }}"> <input type="submit" class="btn btn-primary" value="Liked It"> </form></div> <div style="display:inline-block"><form method="get" action="/add/{{ movie["id"] }}"> <input type="submit" class="btn btn-primary" value="Watchlist"> </form></div> <p><button id="hide" class="btn btn-primary" onclick="myFunction("div-{{ movie["id"] }}")">Not Interested</button></p> </div> </div> {% endfor %}

And in JS:

 var myFunction = function(movieID) { Hide = document.getElementsById("div-{{ movie["id"] }}") if(Hide.style.display== "none"){ Hide.style.display = "block"; }else{ Hide.style.display = "none"; } }} }

My modifications to my JS result in no action at all when the hide button is clicked. Is there any way to do this? A couple of my design elements depend on being able to execute a JS function only on the card that is clicked, but my first attempt executes on every card. Is this possible?

You have multiple syntax errors, please take attention to your browser's console and to your editor.

At the hide button you have invalid HTML because you used the quotation mark in the HTML attributes and also at the JS function's argument list. Furthermore it's enough to pass just the movie's ID instead of div-{{ movie["id"] }} string:

<button id="hide" class="btn btn-primary" onclick="myFunction({{ movie["id"] }})">Not Interested</button>

You also have to fix the myFunction JS function. First of all you have to understand the different scope of Jinja2 and client side JS. The Jinja2 renders at the backend, the JS lives on the client side. So in general you cannot use the {{ movie["id"] }} in the definition of a client side JS function, because Jinja2 on the backend cannot know which button will be pressed on the client side. Therefore any JS function has to receive these values as a function parameter:

function myFunction(movieID) {
    let movie = document.getElementById(`div-${movieID}`);
    movie.style.display = 'none';
}

When eg movieID is 42, this function will hide the movie having div-42 ID.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM