jQuery & Django: how can I use jquery properly in this case - javascript

I'm having hard time with js and jquery executing events, I guess there is something I'm missing in my understanding of jquery.
Because I'm really new to this language, I'm confused and need some orientation if you can help me please.
what I need:
I have a form as a row, and a button that adds a new form everytime I click on it. also the new generated forms have different Ids and names.
Now every form contains two selects and need a change function to be excuted on it.
Where should I write this change function, so that every row have his own change function without getting confused with other rows.
EDIT :
<div id="myDIV1" style="display: inline">
<form action="/banque" method="POST" enctype="multipart/form-data" id="personForm" data-tiers-url="{% url 'ajax_load_tiers' %}" >{% csrf_token %}{{ form.non_field_errors }}
<table style ="border-collapse: separate;border-spacing: 15px;" id="id_forms_table">
<tr><td width="5%">N P</td><td width="8%">Date d'operation</td><td width="25%">Désignation</td><td width="10%">Type tiers</td><td width="10%">Tiers</td><td width="10%">Référence de Facture</td><td width="10%">Montant debit </td><td width="10%">Montant crédit</td></tr>
{% for form in formset %}
<tr style="border:1px solid black;" id="{{ form.prefix }}-row" class="dynamic-form" >
<td{% if forloop.first %} class="" {% endif %}><div class="col-xs-1"><b><p name="np1">1</p></b></div></td>
<td>
{% render_field form.dateOperation class="form-control" %}{{form.dateOperation1.errors}}
</td>
<td>{% render_field form.designation class="form-control" %}{{form..errors}}
</td>
<td>
{% render_field form.typeTiers class="form-control" %}{{form.typeTiers.errors}}
</td>
<td>
{% render_field form.tiers class="form-control" %}{{form.tiers.errors}}
</td>
<td>{% render_field form.numfacture class="form-control" %}{{form.numfacture.errors}}
</td>
<td>{% render_field form.montantdeb class="form-control" %}{{form.montantdeb.errors}}</td>
<td>{% render_field form.montantcred class="form-control" %}</td>
</tr>
{% endfor %}
<tr>
</tr>
</table>
{{ formset.management_form }}
<tr>
<!-- BUTTONS <td colspan="4">add property</td> -->
<td width="16%"><input type="submit" name="annuler" value="Annuler" class="btn btn-danger" style="float:right ;margin: 5px; margin-right: 35px"></td>
<td width="16%"><button value="" class="btn btn-success" style="float:right;margin: 5px;" onclick="verifier()">enregistrer</button></td>
</form>
<td><input type="submit" name="ajoutligne" value="Ajouter une ligne" class="btn btn-primary" id="add-row" style="background-color: #8C1944; border-color: #8C1944; float:right;margin: 5px;" onclick="test()"></td></tr>
</div>
On change of each added row by the button Ajouter une ligne , I need to execute the following change function:
$("#id_form-"+0+"-typeTiers").change(function () {
alert($('#id_form-'+0+'-typeTiers').attr('name'));
var url = $("#personForm").attr("data-tiers-url");
var typeID = $(this).val();
$.ajax({
url: url,
data: {
'tiers': typeID,
},
success: function(data) { // `data` is the return of the `load_cities` view function
alert(data);
var i=1;
var listeClt = $(data).clone(true).find('option[id=facvente],option[id=fadepenses],option[id=frs]').remove().end().html();
var listefactVentes= $(data).clone(true).find('option[id=clt],option[id=fadepenses],option[id=frs]').remove().end().html();
var listefrs = $(data).clone(true).find('option[id=facvente],option[id=fadepenses],option[id=clt],option[id=cnss]').remove().end().html();
var listefactDep= $(data).clone(true).find('option[id=clt],option[id=facvente],option[id=frs]').remove().end().html();
// var cnss= $(data).clone(true).find('select').remove().end().html();
if(listeClt!=0){
$("#id_form-"+0+"-tiers").html(listeClt);
$("#id_form-"+0+"-numfacture").html(listefactVentes);
}
else if(listefrs!=0){
$("#id_form-"+0+"-tiers").html(listefrs);
$("#id_form-"+0+"-numfacture").html(listefactDep);
}
else {
$("#id_form-"+0+"-tiers").html(data);
}
}
});
});
"#id_form-"+0+"-typeTiers" is the id of the first row select , "#id_form-"+0+"-tiers" is the Id of the select that will get populated after changing "#id_form-"+0+"-typeTiers" of the same row.
this jquery changes the first row correctly, but what about rows tha will be add after ? their fields will have as Ids 1 , 2 .. etc instead of 0 .
Any help would be great. Thank You in advance

Please look on this some samples. it may helps you
https://www.aspsnippets.com/Articles/Add-Insert-Remove-Delete-Table-Rows-dynamically-using-jQuery.aspx
https://www.tutorialrepublic.com/codelab.php?topic=faq&file=jquery-append-and-remove-table-row-dynamically

Related

Javascript/Django: change icon on dynamically created element based on query value or click

I have tried couple of ways to get icon to change on a button, that has been created with for loop on page load. Here is my element:
{% for i in data %}
<div class="accordion">
<div style="margin-left: -10px;">
<a href="#collapse{{ i }}", class="btn", role="button", data-bs-toggle="collapse" id="btn-collapse_{{ i }}">
<i class="material-icons" style="vertical-align: middle;">expand_more</i>
<label style="vertical-align: middle;">{{ i }}</label>
</a>
</div>
</div>
{% endfor %}
Here is my function to change the icon:
<script>
$(document).ready(function(){
$('#btn-collapse_{{ i }}').on('click', function () {
var thisElement = $(this);
var anchorElement = thisElement.find("i");
if(anchorElement.text() === "expand_less"){
anchorElement.text('expand_more');
} else {
thisElement.find("i").text("expand_less");
}
});
});
</script>
I've also tried changing the color in in another instance. Heres the element:
<tbody>
{% for i in data %}
<tr style="vertical-align: middle;">
<td>{{ i }}</td>
<td>{{ i.data1 }}</td>
<td>{{ i.data1 }}</td>
<td style="text-align: center;">
<button class="btn", id="btn-{{ i.data2 }}">
<i class="far fa-check-circle"></i>
</button>
</td>
<td style="text-align: center;">
<button class="btn", id="btn-{{ i.data3 }">
<i class="far fa-check-circle"></i>
</button>
</td>
</tr>
{% endfor %}
</tbody>
And here is the function:
<script>
$(document).ready(function(){
var data_button = document.getElementById("btn-{{ i.data2 }}");
if({{ i.data2 }} == 'None'){
data_button.style.color = "#858796";
}
else {
data_button.style.color = "#1cc88a";
}
});
</script>
Data that is being queried in second instance is either 'None' or date.
In your script you wrote {{ i }} outside of for loop. Use class instead of id because if you get an element with id it will get only the first child, while class receives all. And you don't need commas between your element attributes.
<a href="#collapse{{ i }}" class="btn" data-id="{{forloop.counter}}" role="button" data-bs-toggle="collapse" id="btn-collapse_{{ i }}">
<script>
$(document).ready(function(){
$('.btn').on('click', function () {
data_id = $(this[data-id])
var thisElement = $(this).filter('[data-card="'+data_id+'"]');
var anchorElement = thisElement.find("i");
if(anchorElement.text() === "expand_less"){
anchorElement.text('expand_more');
} else {
thisElement.find("i").text("expand_less");
}
});
});
</script>
I use jQuery. Please include it in your head tag
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
I had to modify the script enes islam provided, this is how I got it in the end:
<a href="#collapse{{ i }}" data-id_collapse="{{ forloop.counter }}" class="btn" role="button", data-bs-toggle="collapse" id="btn-collapse_{{ i }}">
<script>
$(document).ready(function(){
$('.btn').on('click', function () {
data_id = $(this).attr('data-id');
var thisElement = $(this).filter('[data-id=' +data_id+ ']');
var anchorElement = thisElement.find("i");
if(anchorElement.text() === "expand_less"){
anchorElement.text('expand_more');
} else {
anchorElement.text('expand_less');
}
});
});
</script>

Set input value for post from results of javascript function

I have an HTML page with a search function that returns a table of search results. For each row of the table, there is a drop-down for the amount to donate and a Donate button. I would like to post the value from the row upon clicking Donate, but am unable to figure it out.
I have the confirm alert working with all the correct row information on click, but I am unable to set the hidden input value from within that function. So I made a second function results() and tried to set the value from that, but it's not working. If I just set it with some text (document.getElementById('donation').value = "some_text"), that works fine. But I would like to set the data from the row in which the button was clicked and set it as a value for POST.
This is my code:
{% extends "layout.html" %}
{% block title %}
Donate
{% endblock %}
{% block main %}
<form action="/donate" method="post">
<div class="form-group">
<input autocomplete="off" autofocus class="form-control" name="name"
placeholder="What animal would you like to support?" type="text" size="40">
</div>
<button id="search" class="btn btn-primary" type="submit" name="search">Search</button>
</form>
<br>
<table class="table" id="sponsor_table">
<thead class="thead-light">
<tr>
<th scope="col">Scientific Name</th>
<th scope="col">English Name</th>
<th scope="col">Red List Category</th>
<th scope="col">Donation</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{% for animal in animals %}
<tr>
<th scope="row">{{ animal.canonicalName }}</th>
<td>{{ animal.vernacularName }}</td>
<td>{{ animal.redlistCategory }}</td>
<td> <select id="price" name="price" onChange="calc();">
<option value="">Amount</option>
<option value="25">$25.00</option>
<option value="50">$50.00</option>
<option value="100">$100.00</option>
<option value="200">$200.00</option>
<option value="500">$500.00</option>
<option value="1000">$1000.00</option>
</select>
</td>
<form action="/donate" method="post">
<td><input name="donation" type="hidden" value="">
<button id="donation" class="btn btn-primary" name="donation" value="Donate" >Donate</button></td>
</form>
</tr>
{% endfor %}
</table>
<script type="text/javascript">
$(document).ready(function () {
// code to read selected table row cell data (values).
$("#donation").on('click',function(){
// get the current row
var currentRow=$(this).closest("tr");
var col1=currentRow.find("td:eq(0)").text(); // get current row 1st TD value
var col2=currentRow.find("td:eq(1)").text(); // get current row 2nd TD
var col3=currentRow.find("td:eq(2) option:selected").text(); // get current row 3rd TD
var col4=currentRow.find("td:eq(3)").text(); // get current row 3rd TD
confirm("Would you like to support the " + col2 + " " + col1 + " population with a donation of " + col3 + "?");
});
});
function results()
{
var rowId = event.target.parentNode.parentNode.id;
var data = document.getElementById(rowId).querySelectorAll(".row-data");
var species = data[0].innerHTML;
var name = data[1].innerHTML;
var category = data[2].innerHTML;
var amount = data[3].innerHTML;
return species;
} ;
document.getElementById('donation').value = results();
</script>
{% endblock %}
SOLVED:
<form action="/donate" method="post">
<td><input name="donation" type="hidden" id="test" value="">
<button id="donation" class="btn btn-primary" name="donation" value="Donate" >Donate</button></td>
</form>
</tr>
{% endfor %}
</table>
<script type="text/javascript">
$(document).ready(function () {
// code to read selected table row cell data (values).
$("#donation").on('click',function(){
// get the current row
var currentRow=$(this).closest("tr");
var col1=currentRow.find("td:eq(0)").text(); // get current row 1st TD value
var col2=currentRow.find("td:eq(1)").text(); // get current row 2nd TD
var col3=currentRow.find("td:eq(2) option:selected").text(); // get current row 3rd TD
var col4=currentRow.find("td:eq(3)").text(); // get current row 3rd TD
confirm("Would you like to support the " + col2 + " " + col1 + " population with a donation of " + col3 + "?");
document.getElementById('test').value = [col1, col2, col3];
});
});

i want to count the number of correct answers in jS or jquery

I want to count the number of correct answers and display it.i tried many ways but couldn't go through.will appreciate if anybody can help me .Thanks in advance.
{% extends 'base.html' %}
{% block title%}Quiz{% endblock title %}
{% block content %}
<div class=" text-danger mt-5 text-center">
<!-- <h2><b id="count">Timer</b></h2> -->
<h3>+++Quiz on Indian Politics+++</h3>
<hr>
</div>
<div class="pt-5">
{% for item in obj %}
<table>
<tr>
<h2>Q{{item.id}}. {{item.question}}</h2><br>
</tr>
<tr>
<input type="radio" class="rd" name="{{item.id}}" id="opt1" value="{{item.opt1}}"> {{item.opt1}}</input><br>
</tr>
<tr>
<input type="radio" class="rd" name="{{item.id}}" id="opt2" value="{{item.op2}}"> {{item.opt2}}</input><br>
</tr>
<tr>
<input type="radio" class="rd" name="{{item.id}}" id="opt3" value="{{item.opt3}}"> {{item.opt3}}</input><br>
</tr>
<tr>
<input type="radio" class="rd" name="{{item.id}}" id="opt4" value="{{item.opt4}}"> {{item.opt4}}</input><br>
</tr>
<tr>
<label id="lb" class="rd" name="{{item.id}}" value="{{item.cor_ans}}" style='display:none;color:green'><b>The correct answer is: {{item.cor_ans}}</b></label>
</tr>
<tr>
</tr>
</table>
<hr> {% endfor %}
<div class="pt-4">
<button type="submit" class="btn btn-success" id="btn">Submit</button>
</div>
<div class="pt-3">
<b id="counter"></b>
<b id="ans"></b>
</div>
</div>
{% endblock content %}
{% block scripts %}
<script>
const rad = document.getElementsByClassName('rd')
const input = document.getElementsByTagName('input')
const bt = document.getElementById('btn')
const label = document.getElementsByTagName('label')
const counter = document.getElementById('counter')
var score = 0;
bt.onclick = function() {}
// JQuery code
$(document).ready(function() {
$('#btn').click(function() {
$('.rd').show();
$('.rd').attr("disabled", true);
});
});
// # javascript code
bt.addEventListener('click', function() {
for (i = 0; i < input.length; i++) {
if (input[i].type === 'radio') {
if (input[i].checked) {
document.getElementById('ans').innerHTML += "Q" + input[i].name + " The Answer you selected is: " + input[i].value + "<br>";
}
}
}
})
// var interval = setInterval(function(){
// document.getElementById('count').innerHTML=count;
// count--;
// if (count === 0){
// clearInterval(interval);
// document.getElementById('count').innerHTML='Done';
// alert("You're out of time!");
// }
// }, 1000);
// document.getElementsByClassName('counter').innerHTML = cnt;
// console.log(label[j].innerHTML.replace("<b>The correct answer is: ","").replace("</b>",""))
//
// if(label[j].innerHTML.replace("<b>The correct answer is: ","").replace("</b>","") == input[i].value){
// console.log("Hello")
// }
</script>
{% endblock scripts %}

Updating my database with the changed elements in a table

I'm making an address book of a company's tech support contacts and the admin gets access to all addresses in a form of a table. In this table, he can add, delete and make changes to data in the same page.
I have set up the add and delete functions successfully, but I struggle a lot with the edit. I'm using node, express, mongodb and vanilla javascript.
I'm still a newbie in web developement and there is are words I may use wrong, so sorry in advance!
(Excuse my french, but most of the words mean the same in english.)
My HTML
<div>
<input id="edit" type="button" value="Editer" onclick="return edit()">
<input id="valider" type="hidden" value="Valider" onclick="return valider()">
</div>
<table id='myTable'>
<thead>
<tr class="header">
<th>Nom de l'entreprise</th>
<th>Téléphone 1</th>
<th>Téléphone 2</th>
<th>Mail</th>
</tr>
</thead>
<tbody>
<% companies.forEach(function(company){ %> //I loop through my db
<tr class="compName">
<td hidden id='_id' > <%= company._id %> </td>
<td> <input id="name" class="readonly" type="text" value=" <%= company.name %>" readonly style="border: none" onblur="change(this)"> </td>
<td> <input id="phone" class="readonly" type="text" value=" <%= company.phone %>" readonly style="border: none" onblur="change(this)"> </td>
<td> <input id="phone2" class="readonly" type="text" value=" <%= company.phone2 %>" readonly style="border: none" onblur="change(this)"> </td>
<td> <input id="mail" class="readonly" type="text" value=" <%= company.mail %>" readonly style="border: none" onblur="change(this)"> </td>
</tr>
<% }) %>
</tbody>
</table>
My Script
<script>
function edit() {
var editComp = document.getElementsByClassName("readonly");
var edit = document.getElementById('edit').type = 'hidden'; //get the edit button and hide it
var valider = document.getElementById('valider').type = 'button'; //then unhide the validate button so I can use it
for (var i = 0; i < editComp.length; i++) { //remove the readonly for each td so I can edit it
editComp[i].removeAttribute('readonly');
editComp[i].setAttribute("style", "border: 1px solid red;");
};
}
function valider() {
var editComp = document.getElementsByClassName("readonly");
var edit = document.getElementById('edit').type = 'button'; //unhide the edit button
var valider = document.getElementById('valider').type = 'hidden' //hide my validate button
for (var i = 0; i < editComp.length; i++) { //put back the readonly for each td so its uneditable
editComp[i].setAttribute('readonly', true);
editComp[i].setAttribute("style", "border: none;");
};
}
function change(element) { //when the input gets unfocused, I assume that's because changes happened
var setChanged = element.setAttribute("class", "readonly changed"); //I mark all changed element
/*I want to udapte my database with the changed elements
I was thing of getting the hidden company._id and the id of the changed element so I can update them specifically*/
}
</script>
So I was think of getting the col[0] of the changed row, which is the _id of my changed element, so I can target it for updating in my database, but I don't know how I should do it.
Thanks!

Getting existing HTML in TR Body to Clear

I have a Jquery/Ajax call which updates cart details. At the moment I can't get the existing HTML in the cart-body(tablebody) to clear. The actual ajax request works and all items are added to cart but the original HTML entries stay. The particular code is here:
if (data.products.length > 0 ) {
productRows.html("")
$(cartBody).empty()
Jquery Function
function refreshCart() {
console.log("in current cart")
var cartTable = $(".cart-table")
var cartBody = cartTable.find(".cart-body")
var productRows = cartBody.find(".cart-product")
var cartTotal = cartTable.find(".cart-total-sec")
var productQuantity = cartTable.find(".cart-item-quanity")
var currentUrl = window.location.href
var refreshCartUrl = '/api/cart/'
var refreshCartMethod = "GET";
var data = {};
$.ajax({
url: refreshCartUrl,
method: refreshCartMethod,
data: data,
success: function(data) {
console.log("success")
console.log(data)
if (data.products.length > 0 ) {
productRows.html("")
$(cartBody).empty()
$.each(data.products, function(index, value) {
console.log(value)
console.log(data.count)
cartBody.append("<tr><td>" + value.quantity + " x" + "</td><td>"+ value.name + "</td><td>" + "£" + value.price + "</td></tr>")
})
cartTotal.find(".cart-total").text(data.total)
console.log(data.total)
} else {
window.location.href = currentUrl
}
},
error: function(errorData) {
console.log("error")
console.log(errorData)
}
})
}
HTML Form:
<div>
<h4>This is your shopping cart</h4>
<table class="cart-table">
<tr>These are the items in your basket and their respective totals</tr><br>
<tbody class="cart-body">
{% for item in cart.items %}
<form method="POST" action='{% url "shopping-cart-remove" %}'>
{% csrf_token %}
<tr class="cart-product"><span class="cart-item-quanity">{{ item.quantity }}</span> x {{ item.product.name }} = {{ item.subtotal }}</tr>
<input type="hidden" name='id' value='{{ item.product.id }}'>
<span class='remove-span'><button>remove</button><br></span>
</form>
</tbody>
{% endfor %}
<tr class="cart-total-sec"><td class="cart-price">{{ cart.total }}</td></tr>
</div>
Any help is really appreciated.
First you are making mistake, as i can see there's form in table, on refreshing you will lose that form so i guess you should append items in form not in .cart-body.
And for emptying html use cartBody.html(""); and you don't have to use productRows.html("") at all.
The issue as pointed out by Ultrazz008, was that the HTML was incorrectly formatted. For reference:
<table class="cart-table">
<tbody class="cart-body">
<form method="POST" class='form-product-ajax' action='{% url "shopping-cart-remove" %}' data-endpoint='{% url "shopping-cart-remove" %}'>
{% csrf_token %} {% for item in cart.items %}
<tr class=cart-product>
<td>{{ item.quantity}} x {{ item.product.name }} {{ item.subtotal }}
<input type="hidden" name='id' value='{{ item.product.id }}'>
<button class='remove-btn'>remove</button>
</td>
{% endfor %}
</tr>
</form>
</tbody>
<tr class="cart-total-sec">
<td class="cart-price">{{ cart.total }}</td>
</tr>
</table>

Categories