I know what this error is generally from but I just can't find it in my code. I know it is the statement:
button.setAttribute("onclick", "makeUneditable(" + row_id + ")")
And I've included all the code so you can know what you're looking at. And just fyi {{row}} is a list that I pass in with Jinja2 and then convert to a string in javascript. But I am not sure what in that statement is illegal. Any ideas?
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script>
function makeEditable(row_id) {
row_id = String(row_id)
var row = document.getElementById(row_id);
row.setAttribute("contenteditable", "true")
var button = document.getElementById(row_id+"_button");
button.setAttribute("onclick", "makeUneditable(" + row_id + ")")
button.innerHTML = "Done Editing";
}
function makeUneditable(row_id) {
row_id = String(row_id)
console.log(row_id)
var row = document.getElementById(row_id);
row.setAttribute("contenteditable", "false")
}
</script>
</head>
<body>
<table class="TFtable" style="width:300px">
<thead>
{% for column_name in column_names %}
<th>{{column_name}}</th>
{% endfor %}
</thead>
{% for row in table %}
<script>
document.writeln('<tr id="' + String({{row}}) + '">');
</script>
{% for cell in row %}
<td>{{cell}}</td>
{% endfor %}
<td contenteditable="false">
<script>
document.writeln('<button id="' + String({{row}})+'_button"');
</script>
type="button" onclick="makeEditable({{row}})">Edit Connector</button>
</td>
</tr>
{% endfor %}
</table>
</body>
Use single quotes around your value when concatenating it:
button.setAttribute("onclick", "makeUneditable('" + row_id + "')")
Related
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 am new to Django and working on a eCommerce website and trying to improve cart functions.
I follow the course to use JavaScript to update the items in the cart like below code.
If I clicked the "add" or "remove" button on other page(like product list), it works fine.
However, when I tried to lick "remove" button on the cart page (where I can see all the products in the cart), it worked fine as the very first time, the item removed from the cart.
Afterward, I clicked the button, the page just refreshed. Then I clicked another time, it worked again. So it's like after the first item removed, I have to click two times to remove the item I want.
Below are my JavaScript Code, views.py, and my cart_home.html. Hope anyone could help get through this, I've been stuck for a week....
JavaScript
<script type="text/javascript">
$(document).ready(function(){
var productForm = $(".form-product-ajax") // id:#form-product-ajax
productForm.submit(function(event){
event.preventDefault();
console.log("Form is not sending");
var thisForm =$(this);
var actionEndpoint = thisForm.attr('data-endpoint');
var httpMethod = thisForm.attr('method');
var formData = thisForm.serialize();
$.ajax({
url: actionEndpoint,
method: httpMethod,
data: formData,
success: function (data) {
console.log("success");
console.log(data);
console.log("Added:",data.productAdded);
console.log("Removed:",data.productRemoved);
var submitSpan = thisForm.find(".submit-span")
if (data.productAdded) {
submitSpan.html('<button class="btn btn-danger btn-sm " type="submit" name="remove">Remove</button>')
} else {
submitSpan.html('<button class="btn btn-success btn-sm" type="submit" name="Add">Add to Cart</button>')
}
var navbarCount = $(".navbar-cart-count")
navbarCount.text(data.cartItemCount)
var currentPath = window.location.href
if (currentPath.indexOf("cart") != -1) {
refreshCart()
}
},
error: function (errorData) {
console.log("error");
console.log(errorData);
}
})
})
function refreshCart() {
console.log("in current cart");
var cartTable = $(".cart-table")
var cartBody = cartTable.find(".cart-body")
var productRows = cartBody.find(".cart-products")
var currentUrl = window.location.href
var refreshCartUrl ='api/carts'
var refreshCartMethod="GET";
var data={};
$.ajax({
url: refreshCartUrl,
method: refreshCartMethod,
data:data,
success:function(data) {
var hiddenCartItemRemoveForm = $(".cart-item-remove-form")
if (data.products.length>0) {
productRows.html("")
i = data.products.length
$.each(data.products,function (index,value) {
console.log(value);
var newCartItemRemove = hiddenCartItemRemoveForm.clone()
newCartItemRemove.css("display","none")
newCartItemRemove.find(".cart-item-product-id").val(value.id)
cartBody.prepend("<tr><th scope=\"row\">" + i +"</th><td><a href='" +value.url + "'>" + value.name +"</a>" + newCartItemRemove.html() + "</td><td>" + value.price + "</td></tr>")
i --
})
cartBody.find(".cart-subtotal").text(data.subtotal);
cartBody.find(".cart-tax").text(data.tax);
cartBody.find(".cart-total").text(data.total);
}else {
window.location.href = currentUrl;
}
},
error:function(errorData) {
console.log("error");
console.log(errorData);
}
})
}
})
</script>
Cart_home.html
{% extends "base.html" %}
{% block content %}
<h1>Cart</h1>
{% if cart.products.exists %}
<table class="table cart-table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Prodcut Name</th>
<th scope="col">Product Price</th>
</tr>
</thead>
<tbody class="cart-body">
{% for product in cart.products.all %}
<tr class='cart-products'>
<th scope="row">{{forloop.counter}}
<td>{{product.name}}
{% include "carts/snippets/remove-product.html" with product_id=product.id%} </th>
</td>
<td>${{product.price}}</td>
</tr>
{% endfor %}
<tr>
<th colspan='2'></th>
<td> <b>Subtotal : $</b><span class="cart-subtotal">{{cart.subtotal}}</span> </td>
</tr>
<tr>
<th colspan='2'></th>
<td> Tax : $<span class="cart-tax" >{{cart.tax}} </span></td>
</tr>
<tr>
<th colspan='2'></th>
<td> <b>Total : $</b><span class="cart-total">{{cart.total}} </span> </td>
</tr>
<tr>
<th colspan='2'></th>
<td> <a class="btn btn-success" href="{% url 'carts:checkout' %}">Checkout</a> </td>
</tr>
</tbody>
</table>
<div class="cart-item-remove-form" style='display:none'>
{% include "carts/snippets/remove-product.html" with product_id=product.id%}
</div>
{% else %}
<p class="lead">There is no porduct in your cart now! </p>
<p> <a class="btn btn-secondary" href="{% url 'products:list' %}">Go to check!</a> </p>
{% endif %}
{% endblock content %}
views.py
def cart_detail_api_view(request):
cart_obj, new_obj = Cart.objects.new_or_get(request)
products = [{
"ud":x.id,
"url":x.get_absolute_url(),
"name":x.name,
"price":x.price,
}
for x in cart_obj.products.all()]
cart_data ={"products":products,"subtotal":cart_obj.subtotal,"total":cart_obj.total,"tax":cart_obj.tax()}
return JsonResponse(cart_data)
def cart_update(request):
product_id = request.POST.get('product_id')
if product_id:
try:
product_obj = Product.objects.get(id=product_id)
except Product.DoesNotExist:
print("Show message to user, product does not exist")
raise("Producr does not exist")
return redirect("carts:home")
else:
cart_obj, new_obj = Cart.objects.new_or_get(request)
if product_obj in cart_obj.products.all():
cart_obj.products.remove(product_obj)
product_added = False
else:
cart_obj.products.add(product_obj) # cart_obj.products.add(1)
product_added = True
request.session['cart_items'] = cart_obj.products.count()
if request.is_ajax(): #Asynchronous JavaScript Anx XML / JSON(JaveScrtip Object Notation)
print("Ajax request")
json_data = {
"productAdded":product_added,
"productRemoved":not product_added,
"cartItemCount":cart_obj.products.count()
}
return JsonResponse(json_data)
return redirect("carts:home")
I wanted to make the disabled attribute false, but it doesn't work. here is my code.
here ins my base.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="{% static 'css/duty.css' %}">
<script src="{% static 'js/duty.js' %}"></script>
<title></title>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
here is my duty.html
{% extends 'base.html' %}
{% block content %}
<h1>duties and details for TA</h1>
<p>#student:{{ course.capacity }}</p>
<form>
<table border="2" bordercolor="black" width="800" height="500" cellspacing="0" cellpadding="5">
<tr>
<th>classification</th>
<th>times</th>
<th>teaching activity</th>
<th>Approx. hours/student</th>
</tr>
<tr>
<td rowspan="3">Lab</td>
<td rowspan="3"><label><input class="duty" type="text" disabled="disabled" value="{{ taDuty.labNumber }}"></label>
</td>
<td>preparation</td>
<td><label><input class="duty" type="text" disabled="disabled" value="{{ taDuty.preparationHour }}"></label></td>
</tr>
</table>
<button onclick="modification()">modify</button>
<button type="submit">save</button>
</form>
{% endblock %}
here is my duty.js
function modification() {
let node = document.getElementsByClassName('duty');
for (let i = 0; i < node.length; i++) {
node[i].disabled = false;
}
}
my javascript function can be called. I tried to add alert() and it works, but the disabled attributed can't be set false. I don't know why. Thank you for any help!
Have a look at this, to enable the input field you can't just set elm.disabled = false.
Try using removeAttribute()
function modification() {
let node = document.getElementsByClassName('duty');
for (let i = 0; i < node.length; i++) {
node[i].removeAttribute("disabled");
}
}
I have a grid with some items and I´d like to sum val_itemservico column from selected rows. My template sums all rows.
I´d like to sum val_itemservico column only for selected rows when I click on "Calcular" button. In this case, I need to know if ind_selecionado column is checked.
So, how can I do that?
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ORÇAMENTO</title>
</head>
<h2>ORÇAMENTO</h2>
<form class=" bd-form-20 " action="#" name="form-name" method="GET">
{% csrf_token %}
<label>Serviço: </label>{{filter.form.servico}}
<button type = "submit" >OK</button>
<br><br>
</form>
<tbody>
<div class=" bd-customhtml-29 bd-tagstyles bd-custom-table">
<div class="bd-container-inner bd-content-element">
<table id="table" border="1" rules="all" cellspacing="0" cellpadding="10"> <!--width="100%" border="0" cellspacing="0" cellpadding="2">-->
<tr>
<th>Selecionar</th>
<th>ID Item Serviço</th>
<th>Item Serviço</th>
<th>Valor Serviço</th>
<th>Serviço</th>
</tr>
{% for item in response.object_list %}
<tr>
<td> <input type="checkbox" id="item.ind_selecionado"></td>
<td>{{ item.id }}</td>
<td>{{ item.desc_itemservico }}</td>
<td>{{ item.val_itemservico }}</td>
<td>{{ item.servico_id}}</td>
</tr>
{% endfor %}
{% if response.object_list %}
Total: {{ response.object_list|length }}
{% endif %}
<br><br>
</table>
<br><br>
Valores:<br>
{% for item in response.object_list %}
{{item.val_itemservico}}<br>
{% endfor %}
<br><br>
<span id="sumV"></span>
<script>
var table = document.getElementById("table");
getSum();
function getSum()
{
var sumVal = 0;
for (var i = 1; i < table.rows.length; i++){
sumVal = sumVal + parseInt(table.rows[i].cells[3].innerHTML);
}
console.log("Sum: " + sumVal)
}
</script>
<br><br>
<button onclick="getSum();">Calcular</button>
</div>
</div>
</tbody>
</html>
You have to test for the value of the check input inside your loop that calculate the sum
for (var i = 1; i < table.rows.length; i++){
sumVal = sumVal + parseInt(table.rows[i].cells[3].innerHTML);
}
should be replaced by something like :
for (var i = 1; i < table.rows.length; i++){
if(table.rows[i].cells[1].childNodes[0].checked){
sumVal = sumVal + parseInt(table.rows[i].cells[3].innerHTML);
}
}
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>