I have an html table and i want to edit the contents of the table based on a button click.
My HTML code:
<form name="myform">
<table id="tblFollow" >
{% for key, value in result.iteritems() %}
<tr>
<td > {{ key }}</td>
<td> <div id="editableText" > {{ value }} </div></td>
</tr>
{% endfor %}
</tbody>
</table>
<h> {{ passvalue }} </h> <br>
<input type="button" onclick="changeContent()" value="Change content">
</form>
and my javascript is
function changeContent(){
var newstate = !editableText.isContentEditable
editableText.contentEditable = newstate
editableText.className = (newstate)
}
but the problem is when i click on the button only the first rown on the table is showing editable. otherthan that all the rows are immutable. Any help will be appreciated
You should use the class instead of id. Id's are meant to be unique.
<div class="editableText" > {{ value }} </div>
Then in your javascript, you need to loop over the selected elements:
function changeContent(){
var editables = document.getElementsByClassName('editableText');
for (var i = 0; i < editables.length; i++) {
var newstate = !editables[i].isContentEditable;
editables[i].contentEditable = newstate;
}
}
Related
In my template i'm using a formset to add a "Raum"-form dynamic.
In each row of my table, there is a button "delete row", so that i can delete the row again.
the java script code is as far as i can say is working quite well...
Adding and saving the forms works fine.
Also deleting with the java script code works fine.
Even when i delete the last row of the table, saving the forms works fine.
But when f.e. i add 3 rows (rooms), row1-row2 and row3, and i delete row 1 or row 2, i can not save my forms, because i think in view.py the is_valid method = false...
maybe i have to update some kind of index of my forms??? and how ??
any help is really apprecheated...
html template for adding rooms with the table and forms:
<table id="tableHeadToModify" class="table table-bordered">
<thead class="hg-rot schrift-weiss">
<tr>
<th colspan="2">Räume</th>
</tr>
{% for raum in raum_formset %}
{% if forloop.first %}
<tr>
<th>{{ raum.name.label_tag }}</th>
<th>{{ raum.name.label_tag }}</th>
</tr>
{% endif %}
{% endfor %}
</thead>
<tbody id="tableToModify">
{{raum_formset.management_form}}
{% for raum in raum_formset %}
<tr id="rowToClone">
<td> {{ raum.name }} </td>
<td><button type="button" value="Delete" onclick="deleteRow(this)"></td>
</tr>
{% endfor %}
</tbody>
</table>
<button id="add-form" type="button" class="btn btn-outline-danger btn-md">add room</button>
<script>
let container = document.querySelector("#form-container")
let addButton = document.querySelector("#add-form")
let totalForms = document.querySelector("#id_form-TOTAL_FORMS")
let rowCount = document.getElementById('tableToModify').rows.length-1;
addButton.addEventListener('click', addForm)
function addForm(e){
e.preventDefault()
let formRegex = RegExp(`form-(\\d){1}-`,'g')
rowCount = document.getElementById('tableToModify').rows.length-1;
var row = document.getElementById("rowToClone"); // find row to copy
var table = document.getElementById("tableToModify"); // find table to append to
var clone = row.cloneNode(true); // copy children too
table.appendChild(clone); // add new row to end of table
rowCount++
clone.innerHTML = clone.innerHTML.replace(formRegex, `form-${rowCount}-`)
totalForms.setAttribute('value', `${rowCount+1}`)
}
function deleteRow(r) {
var i = r.parentNode.parentNode.rowIndex;
var total = parseInt($('#id_form-TOTAL_FORMS').val());
if (total > 1) {
var i = r.parentNode.parentNode.rowIndex;
document.getElementById("tableHeadToModify").deleteRow(i);
totalForms.setAttribute('value', `${rowCount}`)
}
}
}
views.py
formset_raum = RaumFormSet(data=self.request.POST)
#wenn die Eingabe der Formen passt
if kunde_form.is_valid() and angebot_form.is_valid() \
and objekt_form.is_valid() \
and formset_raum.is_valid():<--- this isn't valid
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;
}
I am struggling to obtain the text within a table using jQuery.
I have a HTML page set up as followed.
{% for element in list %}
<button class="btn btn-primary add" id="{{forloop.counter}}">Add</button>
<table class="table" id="myTable">
<thead>
<tr><td><h3>General information for {{ element.id }}</h3></td></tr>
</thead>
<tbody>
<tr><td><label id='name-{{forloop.counter}}' class="label label-success" >{{ element.Name }}</label></td></tr>
<tr><td><label id='address-{{forloop.counter}}' class="label label-success" >{{ element.Address }}</label></td></tr>
<tr><td><label id='code-{{forloop.counter}}' class="label label-success" >{{ element.Code }}</label></td></tr>
</tbody>
</table>
{% endfor %}
<script>
$(".add").click(function(e) {
var id = $(this).attr('id');
var test = $("myTable tr td").each(function() {
var name = $(this).find('#name-'+id).text();
var address = $(this).find('#address-'+id).text();
var code = $(this).find('#code-'+id).text();
alert(name);
alert(address);
alert(code);
});
});
</script>
For every object in the list, there is a button and a table. his table contains several rows holding the list data. I wish to retrieve the text in the <tr> tags and submit them later using ajax.
What am I doing wrong?
You need to change this line
$("myTable tr td")
to
$("#myTable tbody tr td") //missing pound sign & your tds are inside tbody
I have a fruits form that has one FieldList object for the bananas:
bananas = FieldList(FormField(BananaForm))
In the frontend, initially, I add one of those fields to the FieldList
form.append_entry()
Now with Javascript I managed to create functions, that can dynamically add (plus button) or remove (minus button) the number of BananaForm fields that can be filled with information.
FielstList automatically creates ids for all of its fields. So to do dynamical adding with js, I duplicate the HTML code and set the field id += 1, like:
first field:
<tr>
<td><input id="bananas-0-originCountry" type="text" /></td>
</tr>
duplicated field with += 1:
<tr>
<td><input id="bananas-1-originCountry" type="text" /></td>
</tr>
When I name them accordingly like this and submitting the form, WTForms will automatically recognize the added fields in the backend (works fine).
So far so good, but here is my problem:
For a form to be valid, I have to add CSRF-fields to every WTForm. In the Jinja template I do this with:
{{ form.hidden_tag() }}
However, when I just copy the HTML with my js function, I'm missing the CSRF-fields (because until submitted, the backend form object doesn't know about the added FormFields). So how can I generate these CSRF-fields dynamically? (An Ajax Request? If yes, how?)
This should be a standard use case with forms and flask. I hope my description was understandable, if not please let me know. Any help appreciated!
UPDATE: Here is my code
JS-functions
function addBanana(){
// clone and insert banana node
var node = document.getElementById("fruitTable");
var trs = node.getElementsByTagName("tr");
var tr = trs[trs.length-2];
var tr2 = tr.cloneNode(true);
tr.parentNode.insertBefore(tr2, tr);
// in order to increment label and input field ids
function plusone(str){
return str.replace(
new RegExp("-(\\d+)-", "gi"),
function($0, $1){
var i = parseInt($1) + 1;
return "-" + i + "-";
}
);
}
// change inputs
var inputs = tr.getElementsByTagName("input");
for (var i = 0; i < inputs.length; i++){
inputs[i].setAttribute("id", plusone(inputs[i].getAttribute("id")));
}
var minusbutton =
['<td>',
'<button class="btn" type="button" onClick="removeBanana()"><i class="icon-black icon-minus"></i></button>',
'</td>'
].join('\n');
// only append at the first add
// second add automatically copies minus button
if (trs.length < 6){
tr.innerHTML += minusbutton
}
}
function removeBanana(){
var node = document.getElementById("fruitTable");
var trs = node.getElementsByTagName("tr");
var tr = trs[trs.length-2];
var trParent = tr.parentNode;
trParent.removeChild(tr);
}
Jinja Template:
<form method="POST" action="newsubmit">
{{ form.hidden_tag() }}
<table id="fruitTable" class="table">
{{ render_field(form.description) }}
<tr><td><h3>Bananas</h3></td></tr>
{% set counter = 0 %}
{% for banana in form.bananas %}
<tr>
{{ banana.hidden_tag() }}
{% set counter = counter + 1%}
{% for field in banana if field.widget.input_type != 'hidden' %}
{{ render_field_oneline(field) }}
{% endfor %}
{% if counter > 1 %}
<td>
<button class="btn" type="button" onClick="removeBanana()"><i class="icon-black icon-minus"></i></button>
</td>
{% endif %}
</tr>
{% endfor %}
<tr><td></td><td><button class="btn" type="button" onClick="addBanana()"><i class="icon-black icon-plus"></i></button></td></tr>
</table>
<input class="btn btn-primary" style="margin-left:300px;"type="submit" value="Submit" />
</form>
Jinja Template Macros:
{% macro render_field_oneline(field) %}
<td>{{ field.label }}</td>
<td>{{ field(**kwargs)|safe }}
{% if field.errors %}
<ul class=errors>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</td>
{% endmacro %}
{% macro render_field(field) %}
<tr>
{{ render_field_oneline(field) }}
</tr>
{% endmacro %}
I discovered how it works:
The CSRF-Tag can simply be copied. The id must be changed and incremented accordingly, but the hash may stay the same.
I didn't think it was possible to have many Fields with the same CSRF-Tag hash, but it actually does!
I'm trying to do a simple DOM transverse in an each loop. The issue is that jquery is selecting multiple instances of the specified class instead of the one I'm trying to select using $(this). This is my markup:
#foreach ($details as $i)
<tr>
<div class="ajax-tracking-check">
<input type="hidden" name="trans_id" value="{{ $i->transaction_id }}"/>
<input type="hidden" name="tracking" value="{{ $i->tracking_number }}"/>
<input type="hidden" name="carrier" value="{{ $i->shipping_carrier }}"/>
</div>
<td class="td-image">{{ HTML::image($i->image_url, 'item-image', array('class' => 'sir')) }}</td>
<td>{{ $i->item }}</td>
<td>${{ $i->price }}</td>
<td>{{ date('M d, Y',strtotime(Transaction::where('transaction_id', $i->transaction_id)->pluck('created_at'))) }}</td>
<td class="breh">
{{ $i->tracking_number }}
<!-- </br> -->
{{ $i->shipping_carrier }}
</td>
<td class="status"><h2>{{ $i->status }}</h2></td>
</tr>
#endforeach
I'm trying to select the class ".breh" with this line in my js:
var field = $(this).parent().find('td.breh');
This is the entire function:
$('.ajax-tracking-check').each(function() {
var number = $(this).find('input[name="tracking"]').val();
var trans_id = $(this).find('input[name="trans_id"]').val();
var carrier = $(this).find('input[name="carrier"]').val();
var field = $(this).parent().find('td.breh');
$.post(
'purchased/ajax/tracking/check',
{
trans_id: trans_id,
number: number,
carrier: carrier
},
function(data) {
if (number !== "1")
{
// field.text(data['city']+', '+data['state']);
field.addClass('red');
}
}
);
});
The first instance table row's var number is equal to 1 BUT the second row is equal to a random string. With my if statement, I'm trying to add the class "red" but it's added to both instances of "field".
The HTML is not valid.
Your ".ajax-tracking-check" DIV is not contained by a TD inside the table and because of that on the statement
var field = $(this).parent().find('td.breh');
The parent() is returning the BODY element and after that the find() returns all of the .breh element ocurrences.
You should wrap that DIV on a TD element (you can hide it with a display:none) and then the statement would be
var field = $(this).parents('tr').find('td.breh');
Note the plural of "parents()", this will go up in the parents chain until it finds the element TR not just one level as with the singular "parent()"