Toggle text in HTML table using JS with dynamic values - javascript

I'm using a datatable in Bootstrap to create a table which jinja2 will populate with values passed from Flask, example below:
Name
URL
google
www.google.com
reddit
www.reddit.com
{% for site in results %}
<tr>
<td>{{ site['sitename'] }}</td>
<td>{{ site['url'] }}</td>
</tr>
{% endfor %}
I also have site['new_url'] which is passed in results. I want to make the site['url'] clickable and have that toggle between site['url'] and site['new_url'] when clicked.
I'd like to implement using JS if possible or if there is another easier way I'm up for that too!
Any help is appreciated!

A Js solution:
{% for site in results %}
<tr>
<td>{{ site['sitename'] }}</td>
<td onclick="swapText()" id="target">{{ site['url'] }}</td>
</tr>
<script>
function swapText() {
var x = document.getElementById("target");
if (x.innerHTML === "{{ site['url'] }}") {
x.innerHTML = "{{ site['new_url'] }}";
} else {
x.innerHTML = "{{ site['url'] }}";
}
}
</script>
{% endfor %}

Related

Django link table row to view

new to coding. I'm creating an inventory table'with the django framework. I'd like to be able to click on a table row (which is a part) that will then parse that row/part information to a detail view. from what I understand table rows are inline elements and inline elements are psuedo code which current HTML does not allow for an anchor tag to be thrown in (bad practice?) so I need to use some javascript. Currently, the inventory view shows when I use runserver (http://127.0.0.1:8000/inventory/) but clicking on any row does nothing. Here is what I have so far;
inventory.html
{% extends "base.html" %}
{% block body %}
<br>
<table class="table table-hover">
<thead>
<tr>
<th>Part Number</th>
<th>Description</th>
<th>Location</th>
<th>Supplier</th>
<th>S.O.H</th>
</tr>
</thead>
<tbody>
{% for part in parts %}
<!-- need to make these table rows link to their respective parts
class="table_row" href="{{ selected_part.partnumber }}/detail">{{ selected_part.partnumber }}-->
<tr data-href="{% url 'detail' part.pk %}">
<td>{{ part.pk }}</td>
<td>{{ part.partnumber }}</td>
<td>{{ part.description }}</td>
<td>{{ part.location }}</td>
<td>{{ part.supplier }}</td>
<td>{{ part.stockonhand }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
urls.py
from django.urls import path
from .views import *
urlpatterns = [
path('inventory/', inventory_list, name='inventory'), # URL path for inventory_list view
path('<str:pk>/', part_information, name='detail'),
path('', index, name='index'),
]
custom.js
$('tr[data-href]').on("click", function() {
document.location = $(this).data('href');
});
base.html has <script src="/docs/4.4/dist/js/custom.js"></script> before the </body> tag.
I think the issues is in my javascript file. I'm pretty new to this and simplified explanations would be greatly appreciated
Use the below in your custom.js file. When the page is loaded then this function $(document).ready() gets executed initialising the tr on what to do 'On Click'
$(document).ready(function(){
$('table tr').click(function(){
window.location = $(this).data('href');
return false;
});
});

How to get child nodes in a <td> in javascript

I'm trying to get the child nodes from a table, multiply that and show that on a input field. I have tried using textContext but it only returns first value not the later ones.
My Javascript code is:
function add() {
console.log("this is working")
var x = parseInt(document.getElementById("id_quantity").value);
console.log(x, "value of x");
var y = document.getElementById("quantity").textContent;
document.getElementById("id_quantity_p1").value = x * y;
This is my HTML markup:
<div class="col-md-6 col-sm-8 col-12">
<form method="post" id="MaterialRequestForm" data-kit-url="{% url 'employee:ajax_load_kit' %}" onkeyup="add()"
data-product-url="{% url 'employee:ajax_load_product' %}"
novalidate>
{% csrf_token %}
{{ form|crispy }}
<button type="submit">Save</button>
<div id="products-table" class="col-md-12 col-sm-8 col-12 product-table-ajax">
</div>
</form>
</div>
And This is my table's HTML code:
{% for product in products %}
<tr>
<td>{{ product.id }}</td>
<td>{{ product.product_name }}</td>
{% for i in quantities %}
{% if forloop.counter == forloop.parentloop.counter %}
<td id="quantity">{{ i }}</td>
{% endif %}
{% endfor %}
{% endfor %}
In this <td id-"quantity" returns multiple values and I want first two of it.
They are in django HTML template
In this I want to enter quantity and I want that it should get multiplied by content Std Qty in column and get filled in "quantity p1", "quantity p2", "quantity p3". eg. quantitystdQty1=quantityP1, quantitystdQty[2]=quantityP2, quantity*stdQty[3]=quantityP3 etc. For that I need specific elements in my <td>. Please help!
I did that with a different way:
I attached different ID's with the form and then instead of fetching child of I assigned different ID's to all the and then used getElementByID:
{% for product in products %}
<tr>
<td>{{ product.id }}</td>
<td>{{ product.product_name }}</td>
{% for i in quantities %}
{% if forloop.counter == forloop.parentloop.counter %}
<td id="q{{ forloop.counter }}">{{ i }}</td>
{% endif %}
{% endfor %}
{% endfor %}
</tr>
And then changed my js accordingly:
function add() {
console.log("this is working")
var x = parseInt(document.getElementById("id_quantity").value);
console.log(x, "value of x");
var y =document.getElementById("q1").textContent;
var y1 =document.getElementById("q2").textContent;
var y2 =document.getElementById("q3").textContent;
var y3 =document.getElementById("q4").textContent;
var y4 =document.getElementById("q5").textContent;
document.getElementById("id_quantity_p1").value = x * y;
document.getElementById("id_quantity_p2").value = x * y1;
document.getElementById("id_quantity_p3").value = x * y2;
document.getElementById("id_quantity_p4").value = x * y3;
document.getElementById("id_quantity_p5").value = x * y4;
It will obviously only give you back the first one due to the fact that you are using a body.getElementById function, which only returns the very first element with the said id you look for.
For getting all the values you need, I suggest you could instead remake "id_quantity" into a class instead.
With that being done, use body.getElementsByClassName instead, write a loop that stores the data from every node of "id_quantity" and loop it back into the fields where you multiply them.
Here's a very quick example of what I mean
HTML:
<div id="container">
<div id="color-div">
<table>
<thead>
<th>1</th>
<th>2</th>
</thead>
<tbody>
<tr>
<td class="input">5</td>
<td class="output"></td>
</tr>
<tr>
<td class="input">7</td>
<td class="output"></td>
</tr>
<tr>
<td class="input">10</td>
<td class="output"></td>
</tr>
</tbody>
</table>
</div>
</div>
Javasript:
let arr = [];
const $input = document.getElementsByClassName("input");
const $output = document.getElementsByClassName("output");
for (let i = 0; i < $input.length; i += 1) {
arr.push($input[i].innerHTML);
}
for (let i = 0; i < $output.length; i += 1) {
$output[i].innerHTML = arr[i] * 5;
}

Django: How can I delete specific records out of tables by using a view, a template and confirm in JavaScript in a django-template?

I have a model named Actie in models.py.
The context I passed: {'actie': Actie.objects.all(), 'user': request.user}
This is my template I rendered by a view:
{% for actie in actie %}
{% if actie.actie_gebruiker.id == user.id %}
<tr onclick="window.location.href={{ actie.id }}">
<td>{{ actie.id }}</td>
<td>{{ actie.actie_naam }}</td>
<td>{{ actie.actie_status.status_naam }}</td>
<td>{{ actie.actie_aanmaakdatum|date:"d-m-y [ H:i ]" }}</td>
<td>{{ actie.actie_einddatum|date:"d-m-y" }}</td>
<td>{{ actie.actie_eindtijdstip|date:"[ H:i ]" }}</td>
<td>{{ actie.actie_gebruiker }}</td>
</tr>
<a id="verwijderenButton" href="" onclick="bevestigVerwijdering({{ actie_id }});"><img class="icontje"
src="{% static 'MyApp/verwijderen.png' %}"></a>
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
<script>
function bevestigVerwijdering(id) {
var actie_id = '{{ actie.id }}';
var antwoord = confirm("Weet u zeker dat u deze actie wilt verwijderen?");
if (antwoord == true) {
document.getElementById('verwijderenButton').href = 'verwijderen/' + id + '/';
alert(id);
alert(document.getElementById('verwijderenButton').href);
//window.location.href= 'verwijderen/' + id + '/';
}
}
</script>
Now what I want this code to do is that when I click on the image, that it deletes that specifc record out of the database.
It deletes nothing when I don't click on the first record but deletes the last record when I click on the first record.
This is my view:
def verwijderActie(request, id):
Actie.objects.filter(id=id).delete()
return HttpResponseRedirect('../../')
You are creating a list of elements with the same id, then, when you call the javascript function, it gets the first element with the called id.
I would make something like that:
{% for actie in actie %}
{% if actie.actie_gebruiker.id == user.id %}
<tr onclick="window.location.href={{ actie.id }}">
<td>{{ actie.id }}</td>
<td>{{ actie.actie_naam }}</td>
<td>{{ actie.actie_status.status_naam }}</td>
<td>{{ actie.actie_aanmaakdatum|date:"d-m-y [ H:i ]" }}</td>
<td>{{ actie.actie_einddatum|date:"d-m-y" }}</td>
<td>{{ actie.actie_eindtijdstip|date:"[ H:i ]" }}</td>
<td>{{ actie.actie_gebruiker }}</td>
</tr>
<a id="verwijderenButton_{{ actie.id }}" href="#" onclick="bevestigVerwijdering({{ actie.id }});return false;"><img class="icontje" src="{% static 'MyApp/verwijderen.png' %}"></a>
{% endif %}
{% endfor %}
<script>
function bevestigVerwijdering(id) {
var actie_id = id;
var antwoord = confirm("Weet u zeker dat u deze actie wilt verwijderen?");
if (antwoord == true) {
document.getElementById('verwijderenButton_'+id).href = 'verwijderen/' + id + '/';
alert(id);
alert(document.getElementById('verwijderenButton').href);
//window.location.href= 'verwijderen/' + id + '/';
}
}
</script>

How to get element id based on class name properly?

I am trying to get the id which is dynamically generated. I am using a class name to access it. If I click on the td item once, there is no alert. But when I click twice I will get the alert (for the first time). If I click on the second item, I get an alert two times. If on third, I get it three times and so on. What is the error?
My JavaScript code:
function myFunction() {
$('.task0').click(function() {
var x = $(this).data('id');
alert(x);
});
}
My HTML-Flask code:
<tbody>
{% set ns = namespace(num=1) %}
{% for task in tasklist %}
<tr>
<td>{{ ns.num }}</td>
<td class="task0" data-id="{{ task[0] }}"><a href="javascript:myFunction();" >{{ task[0] }}</a></td>
{% for i in range(1,task|count) %}
<td>{{ task[i] }}</td>
{% endfor %}
</tr>
{% set ns.num = ns.num+1 %}
{% endfor %}
</tbody>
You are calling the function twice. The .click you are using in jquery is already calls the function then your make the a tag call the JavaScript function as well. Remove the call to the function from the a tag
Every time you click on td you attach one more listener. you need to attach listner at once for all dynamically created elements.
remove javascript function call in your html part.
and change your javascript as below.
$(document).on(click, '.tasklink', function(e){
e.preventDefault();
var x = $(this).parents('td.task0').data('id');
alert(x);
})
<tbody>
{% set ns = namespace(num=1) %}
{% for task in tasklist %}
<tr>
<td>{{ ns.num }}</td>
<td class="task0" data-id="{{ task[0] }}"><a class="tasklink" href="#" >{{ task[0] }}</a></td>
{% for i in range(1,task|count) %}
<td>{{ task[i] }}</td>
{% endfor %}
</tr>
{% set ns.num = ns.num+1 %}
{% endfor %}
</tbody>

list all image button clicked change image

every one ,I am using django's template language with javascript to do "clicked image button change image" ,however,the result I got was only can change the last button.I do not know why what's wrong about the code , here is my
indext.html
{% extends 'base.html' %}
{% load static %}
{% block title %}
Homepage - {{ block.super }}
{% endblock title %}
{% block content %}
<script>
function setColor(e, btn, color) {
var target = e.target,
count = +target.dataset.count;
target.style.backgroundColor = count === 1 ? "#7FFF00" : '#FFFFFF';
target.dataset.count = count === 1 ? 0 : 1;
}
var img_array = [ src="{% static "img/published.png" %}" , src="{% static "img/draft.png" %}"];
i = 0;
{% for post in posts %}
function myFunction({{ post.model_number }}) {
i++;
document.getElementById("{{ post.model_number }}").src = img_array[i];
if (i == img_array.length - 1) {
i = -1;
}
}
{% endfor %}
</script>
<table class="table table-bordered">
<tr>
<td>產品編號</td><td>產品名稱</td><td>建立日期</td><td>產品圖片</td><td>最後修改日期</td><td>產品說明</td><td>建立者</td><td>修改者</td><td></td>
</tr>
{% for post in posts %}
<tr>
<td> {{ post.model_number }} </td>
<td>{{ post.name }}</td>
<td>{{ post.created }} </td>
<td> <img src="{% if post.image %} {{ post.image.url }}{% else %}{% static "img/no_image.png" %}{% endif %}" height="100" width="100"> </td>
<td>{{ post.modified }} </td>
<td>{{ post.feature }}</td>
<td>{{ post.user }}</td>
<td>{{ post.useredit }}</td>
{% for cp in post.cataloggroup.all %}
<td> {{cp }}</td>
{% endfor %}
<td><a href="{% url 'edit_thing' slug=post.slug %}"><input class="button0 button2" type="button" id="button" value="編輯" style="color:#fffff0" onclick="setColor(event, 'button', '#101010')"; data-count="1" /><a></td>
<td><button onclick="myFunction({{ post.model_number }})"><img id="{{ post.model_number }}" src="{% static "img/published.png" %}" width="50" height="30"></button></td>
</tr>
{% endfor %}
</table>
{% include "pagination.html" with page=posts %}
{% endblock content %}
and it will render the web
however, when I click the top button ,it will change the bottom button,I have to let every button clicked can change image
above image I clicked top button but changed the bottom button's image "published ---> draft"
I have to let every button clicked can changed it's own image,how can I do it?
It is due to the fact you have your myFunction() definintion inside a <script> tag that is entered into the HTML every iteration of your for loop in django.
This means the function is constantly being redefined and therefore myfunction functionality will always be that of the last iteration.
If you define myFunction() outside of your django loop and pass in the model number to the function (as below) then it should work as expected`
function myFunction(model_number) {
i++;
document.getElementById(model_number).src = img_array[i];
if (i == img_array.length - 1) {
i = -1;
}
}
ok,I solve the problem
index.html
<script>
...........
var img_array = [ src="{% static "img/published.png" %}" , src="{% static "img/draft.png" %}"];
i = 0;
{% for post in posts %}
function a{{ post.model_number }}() {
i++;
document.getElementById("{{ post.model_number }}").src = img_array[i];
if (i == img_array.length - 1) {
i = -1;
}
}
{% endfor %}
</script>
<table class="table table-bordered">
<tr>
{% for post in posts %}
<tr>
.........
<td><button onclick="a{{ post.model_number }}()"><img id="{{ post.model_number }}" src="{% static "img/published.png" %}" width="50" height="30"></button></td>
</tr>
{% endfor %}
</table>

Categories