JavaScript function in twig foreach - javascript

I have this code that has the phone number of different posters.
{% for ad in ads %}
...
<a class="btn" onclick="showNumber()" id="showNumber"><span class="fa fa-phone"></span> View Phone Number</a>
<input id="phonenum" style="display: none;" type="text" value="{{ ad.user.phone }}">
...
{% endfor %}
and the Javascript function
<script type="text/javascript">
function showNumber() {
document.getElementById('showNumber').innerHTML = document.getElementById('phonenum').value;
}
</script>
the above works and the input field shows correctly the different numbers of the posters when i change it to block. But the problem is that the phone number of the first button on the first button shows regardless of which button i click. what else should i do there?

IDs are meant to be unique, you're creating elements in a loop and giving them the same ID (phonenum), instead of IDs you should use class names and retrieve the appropriate element base on which anchor was clicked. Here is an example:
{% for ad in ads %}
...
<a class="btn" onclick="showNumber(e)"><span class="fa fa-phone"></span> View Phone Number</a>
<input class="phonenum" style="display: none;" type="text" value="{{ ad.user.phone }}">
...
{% endfor %}
<script type="text/javascript">
function showNumber(e) {
e.target.innerHTML = e.target.parent.querySelector('.phonenum').value;
}
</script>
In this example, e.target is the clicked anchor and I'm using e.target.parent.querySelector('.phonenum') to retrieve the input associated with the anchor (I'm assuming they have the same parent element).

Related

Show and hide text of different posts

I have several posts each of them composed of three parts : a title, a username/date and a body. What I want to do is to show the body when I click on either the title or the username/date and hide it if I click on it again. What I've done so far works but not as expected because when I have two or more posts, it only shows the body of the last post even if I click on another post than the last one. So my goal is only to show the hidden text body corresponding to the post I'm clicking on. Here is my code:
{% extends 'base.html' %}
{% block header %}
<h1>{% block title %}Test page{% endblock %}</h1>
<a class="action" href="{{ url_for('main_page.create') }}">New</a>
{% endblock %}
{% block content %}
{% for post in posts %}
<article class="post">
<header>
<script language="JavaScript">
function showhide(newpost)
{var div = document.getElementById(newpost);
if (div.style.display !== "block")
{div.style.display = "block";}
else {div.style.display = "none";}}
</script>
<div onclick="showhide('newpost')">
<h1>{{ post['title'] }}</h1>
<div class="about">by {{ post['username'] }} on {{ post['created'].strftime('%d-%m-%Y') }}</div>
</div>
</header>
<div id="newpost">
<p class="body">{{ post['body'] }}</p>
</div>
</article>
{% if not loop.last %}
<hr>
{% endif %}
{% endfor %}
{% endblock %}
Of course I looked for a solution as much as I could but I'm kind of stuck plus I'm a complete beginner in HTML/JS/CSS. And one last thing, I'm currently using Python's framework Flask. Thank you by advance.
You need to give each of your posts a unique id for your approach to work.
Change your code to
<div id="{{post_id}}">
<p class="body">{{ post['body'] }}</p
</div>
where post_id is that post's unique id e.g. its id in the database you are using that you pass to the template in your view. Then, change the call to the onclick event handler to
<div onclick="showhide('{{post_id}}')">
If you don't have a unique id you can also use the for loop's index: replace all post_id instances above with loop.index. See Jinja's for loop docs for more information.

How to get selected value of <a> tag from html?

This is my drop down
<div class="dropdown" >
<button onclick="myFunction()" class="dropbtn">Course List</button>
<div id="myDropdown" class="dropdown-content">
<input type="text" placeholder="Search.." id="myInput" onkeyup="filterFunction()">
{% for list in list1%}
<a id="courseName" onclick="addCourse()"> {{list.courseName}}</a>
{% endfor %}
</div>
</div>
here i am trying to access value of the selected course name
function addCourse() {
var x = document.getElementById("courseName").value
document.getElementById("demo").innerHTML = x;
}
But this is giving me "undefined" as a result.
looks like you are running a loop, don't use the id for multiple elements, Id's must be unique, instead use classes.
not sure what what language you are using, laravel? anyway try this.
{% for list in key=>list1%}
<a class="courseName" onclick="addCourse(e)"> {{list.courseName}}</a>
{% endfor %}
</div>
function addCourse(e){
var x = e.target.textContent
document.getElementById("demo").innerHTML = x;
}
I think you want a dynamic element
` {% for list in list1%}
<a id="courseName" onclick="addCourse(this)" name ={{list.courseName}} >
{{list.courseName}}</a>`
{% endfor %}
function addCourse(obj){
var x = $(obj).attr("name");
alert(x);
}
`

Get attribute from a specific element of a class

Basically I have to develop a Tic-Tac-Toe game, here is the HTML file which I can't rewrite only reformat a bit, but the idea should stay the same.
{% block content %}
<nav class="navbar fixed-top navbar-light">
<button id="retry-button" class="btn btn-success">Try again?</button>
Reset settings
</nav>
<div id="game-board" class="mb-3" data-row-num="{{ row_num }}" data-col-num="{{ col_num }}" data-win-size="{{ win_size }}">
{% for row in range(row_num) %}
<div>
{% for col in range(col_num) %}
<div class="game-cell"
data-coordinate-x="{{ col }}"
data-coordinate-y="{{ row }}"></div>
{% endfor %}
</div>
{% endfor %}
</div>
{% endblock %}
As you can see i have a game-cell class which contains by default 9 elements. I would like to return the data-coordinate-x and data-coordinate-y when I click one of the game-cells. I had a previous try but if I clicked it returned all of the blocks not just the one i clicked on. I have to write it in Js. If you can point me in the right direction that's more than enough for me.
Thanks!
If I understood correctly, you need to access data attributes of your game-cell element. In order to do this, you need to select the element by some ID or class. I have modified your code a little to make it run inside stackoverflow`s platform. I have added an ID which i called "unique" and I also set some values into your coordinate-x and y data attributes. Please review the code bellow and see how I managed to get those data attributes. It's important to notice that this is not the only way to access them.
var gamecell = document.getElementById('unique');
console.log(gamecell.dataset.coordinateX);
console.log(gamecell.dataset.coordinateY);
<nav class="navbar fixed-top navbar-light">
<button id="retry-button" class="btn btn-success">Try again?</button>
Reset settings
</nav>
<div id="game-board" class="mb-3" data-row-num="{{ row_num }}" data-col-num="{{ col_num }}" data-win-size="{{ win_size }}">
<div>
<div class="game-cell" id="unique"
data-coordinate-x="172"
data-coordinate-y="273"></div>
</div>
</div>
Its also possible to get these values using the getAttribute method.
var elem = document.getElementById('unique');
var coordX = elem.getAttribute('data-coordinateX');
var coordY = elem.getAttribute('data-coordinateY');
Please, take a look at this page, it explains some aspects of data attributes:
https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes
Simply access your clicked game-cell by: (it will find the clicked coordinateX and coordinateY)
document.querySelectorAll('.game-cell').forEach((game) => {
game.addEventListener('click',function(event){
console.log(game.dataset.coordinateX);
console.log(game.dataset.coordinateY);
});
});
you must to get your element by class name or id(add an id)
than you can get its attributes like this
let gameCell = document.getElementById('game-cell-id');// id for example
gameCell.getAttribute('data-coordinate-x')

Django and JavaScript: filtering not working paused on exception

I am trying to filter a table by the room name of the records which are in each row. My table rows look like this:
<tr data-room="{{ record.room.room_name|lower|field_name_format}}">
So, when the user checks kitchen, rows related to kitchen shows up in the table and not rows related to other rooms.
And this is the code in the header of my HTML:
{% for room in user_related_rooms %}
document.querySelector('#{{room.room_name|lower|field_name_format}}').addEventListener('change',function (evt) {
updateTableView("{{room.room_name|lower|field_name_format}}", evt.target.checked);
});
{% endfor %}
function updateTableView(room_name, bVisible) {
var dataSelectorVal = "";
switch (room_name)
{
{% for room in user_related_rooms %}
case "{{room.room_name|lower|field_name_format}}":
dataSelectorVal = ".site-table tbody tr[data-room='{{room.room_name|lower|field_name_format}}']";
break;
{% endfor %}
}
$(".site-table tbody tr").has(dataSelectorVal).css('display', bVisible ? "" : "none");
}
Here is the code for the filter:
<!-- Filters -->
<div class="col-md-1">
<h1>Filters</h1>
<form>
<span> by room:</span>
<div class="side-filter-list">
<ul>
{% for room in user_related_rooms %}
<li class="flex-field">
<input type="checkbox" id="cb_{{room.room_name|lower|field_name_format}}" />
<label for="{{room.room_name}}">{{room.room_name}}</label>
</li>
{% endfor %}
</ul>
</div>
</form>
</div>
The browser pauses on the exception. I get error on this line, living_room being the first room in the loop (i.e. the first iteration of the loop):
document.querySelector( '#cb_living_room' ).addEventListener('change', function (evt) {
It seems the above line returns null whereas when I comment out the code and use the console to look for it, it finds it without complaining:
document.querySelector( '#cb_living_room')
Console gives me the output:
<input id="cb_living_room" type="checkbox">
What am I doing wrong? What is going on?

Fade out pop-up window on click of a button?

I've followed this tutorial to implement a pop-up email newsletter sign-up to add to my Shopify theme which uses fancybox.js & cookie.js. Everything works fine except when you enter an email address & click 'Sign Up' even though an additional tab opens to complete the Mailchimp sign up process, on the original shop tab, the email pop-up stays open as though nothing has changed.
I wondered if there is a way I could adapt the code so that on click of 'Sign Up' the new tab opens as normal but the email pop-up fades out so when the user goes back to the shop the pop-up has disappeared. I'm not great with JS so any help would be really appreciated!
My current code:
theme.liquid -
Liquid HTML:
{% if settings.popup_newsletter_enable %}
<div id="email-popup" style="display: none;" >
{% include 'popup-newsletter-form' %}
</div>
{% endif %}
JS:
{{ 'jquery.fancybox.js' | asset_url | script_tag }}
<script type="text/javascript">
(function($) {
// set a variable for the cookie check
var check_cookie = $.cookie('popup_box');
// check whether the cookie is already set for this visitor
if( check_cookie != 'active' ){
// if the cookie does not exist do the following:
// (1) set the cookie so it's there for future visits (including an expiration time in days)
$.cookie('popup_box', 'active', {
expires: 3,
path: '/'
});
// (2) trigger the fancybox pop up, specifying that it's inline
$( '#trigger' ).fancybox({
type: 'inline',
});
setTimeout(function () {
$('#trigger').eq(0).trigger('click'); // make the click event happen on load
}, 5000);
}
})(jQuery); // this is a noconflict wrapper for WP
</script>
popup-newsletter-form.liquid (snippet include):
Liquid HTML:
<!-- Mailchimp Form Integration -->
{% if settings.newsletter_form_action != blank %}
{% assign form_action = settings.newsletter_form_action %}
{% else %}
{% assign form_action = '#' %}
{% endif %}
<form action="{{ form_action }}" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" target="_blank" class="input-group">
<input type="email" value="{% if customer %}{{ customer.email }}{% endif %}" placeholder="{{ 'general.newsletter_form.newsletter_email' | t }}" name="EMAIL" id="mail" class="input-group-field" aria-label="{{ 'general.newsletter_form.newsletter_email' | t }}" autocorrect="off" autocapitalize="off">
<span class="input-group-btn">
<input type="submit" class="btn" name="subscribe" id="subscribe" value="{{ 'general.newsletter_form.submit' | t }}">
</span>
</form>
$('#pro_image').click(function(){
$("#pro_image").fancybox({
closeSpeed : 250,
closeEasing : 'swing',
closeOpacity : true,
closeMethod : 'zoomOut',
});
})
;
Try this one.
Usually they put js inside header, also possible to put it any where inside tag, but they say better to place in at the bottom of code ( inside ) to let all code receive by browser and the js execute.

Categories

Resources