I have a datatable in my django template, I have a td element in the table as shown below
<td onclick="setColor('{{x.name}}')">{{x.name}}</td>`
I need this element to run the function 'setColor' everytime the webpage is loaded. I am unable to use onload here as oload is not valid for such elements, but I need to pass those parameters(because I am using a for loop here and this function gets called mutliple times in the loop with different {{x.id}}) which restricts me to only call this function from the exact td element. Is there a way that I could achieve this, so that the function gets called when the page loads and also the parameters are passed to the function?
I have used django filter to solve this issue. The html code is given below:
{% load filters.py %}
<td><span style="color:{{x.name|getNameColor}}">{{x.name}}</span></td>
I defined the getNameColor filter in my filters.py as shown below:
#register.filter(name='getNameColor')
def getNameColor(value):
if value == 'xxx':
return '#f19203'
elif value == 'yyy':
return '#b3a800'
elif value == 'zzz':
return '#f45c42'
elif value == 'uuu':
return '#44cc00'
Useful link: http://www.pfinn.net/custom-django-filter-tutorial.html
For who is searching a HTML/Javascript answer:
I had the same problem and found the solution in using custom attributes that I retrieve in the window.onload function. In my page I used the <tr> element, but this should work for a <td> also.
In the table:
<table>
<tr name="my_row" foo="value1"><td>value1</td></tr>
<tr name="my_row" foo="value2"><td>value2</td></tr>
</table>
In the window.onload function:
window.onload = function bar() {
var rows = document.getElementsByName("my_row")
for (row in rows) {
var foo = row.getAttribute("foo")
if (foo == "value1") {
// Do something
}
}
}
Related
I have a rest call in my application (spring based) to update the User's Active (boolean) status using Fetch API like below:
async function activateUser(obj) {
var fullURL = obj.getAttribute("href");
let response = await fetch(fullURL, {
method: 'POST'
});
let result = await response.json();
if (response.ok) {
alert(result.username + " Activated Successfully.. !!");
obj.parentElement.parentElement.cells[6].innerHTML = "true";
//getAllUsersApi(endpoint);
} else {
alert(response.status + "Error Occurred.. !!");
}
}
All works well.
Now, I am trying to update just that cell of my html table to true whose Initial value was false. I am updating the html table's cell by hard-coding the column number using (as you can see above too) - obj.parentElement.parentElement.cells[6].innerHTML = "true";. I was wondering if there is some way we can find the false in that row for that particular user and update that cell only. Prior to this I was reloading the entire table (the commented line in the JS code above), which nobody will prefer. I tried to find the solution here and here. But couldn't find the stating point for my situation.
From my rest call I am returning the User object so I was just wondering if I could search the table (on client side) just for that particular user and update that just one corresponding cell. In the table Id, Username and email are unique if that helps to find and replace false to true..
Summarized question: How can I update just one cell of my html table by utilizing the response from my REST call?
Since each ID is unique, you can add that to each row as an id="user id goes here" attribute. Then each cell can be given a class to specify it's purpose.
For example:
<table>
<tr id="user_{{ user ID }}">
<td class="user-name">{{ user name }}</td>
<td class="user-email">{{ user email address }}</td>
<td class="is-user-active">{{ user active status }}</td>
</tr>
</table>
Since the result is returning the username, I am guessing it can also return the ID, in which case your code would look like this:
if (response.ok) {
let isUserActive = document.querySelector(`#user_${result.id} .is-user-active`);
isUserActive.innerHTML = "true"
}
There is not really much magic to do. Instead of targetting cell 6, you would check find out the column number by finding the column header that has the title "Enabled". Replace this:
obj.parentElement.parentElement.cells[6].innerHTML = "true";
With:
let row = obj.closest("tr");
let titles = row.closest("table").querySelectorAll("th");
for (let cellNo = 0; cellNo < titles.length; cellNo++) {
if (titles[cellNo].textContent.includes("Enabled")) {
row.cells[cellNo].textContent = "true";
}
}
This is based on the information you have given in the question (not behind links) and in comments/chat.
My problem is the following:
I have created an array from a table I already have and stored the column I want into an array, and then stored it in the localStorage using JSON.stringify:
function createArray(){
var arrayPlayerName = [];
var count = 1;
while(count<=playerNum){
arrayPlayerName.push(document.getElementById('playertable').rows[count].cells[1].innerHTML);
count++;
}
localStorage.setItem("playerNameArray", JSON.stringify("arrayPlayerName"));
}
(playerNum is a variable with a fixed number used in other methods, and the "getElementById" works).
After that I want to show this data in another table in another HTML doc.
So, the following is my HTML code:
<table class="myTable">
<thead>
<tr class="row">
<th colspan="3">Array List</th>
</tr>
</thead>
</table>
And this is the script:
var storedPlayerArray = JSON.parse(localStorage.getItem("playerNameArray"));
tablegenerate (storedPlayerArray);
function tablegenerate (list) {
for(i=0; i<playerNum;i++){
var $formrow = '<tr><td>'+list[i]+'</td></tr>';
$('.myTable').append($formrow);
}
}
I am not sure what I'm doing wrong.. thanks in advance.
EDIT: I am calling the createArray function with a button, and I'm navigating to the second page with another button. The second page should load directly.
EDIT2: I have revised that the array is being stored and called properly on the second page, so the issue is now on the "tablegenerate" function.
EDIT
I think I found the problem try this:
var storedPlayerArray = JSON.parse(localStorage.getItem("playerNameArray"));
function tablegenerate (list) {
for(var i=0; i<list.length;i++){
var $formrow = $('<tr><td>'+list[i]+'</td></tr>');
$('.myTable').append($formrow);
}
}
$(document).ready(function(){
tablegenerate (storedPlayerArray);
})
You have an issue in your createArray function.. You are running JSON.stringify on a string instead of the array you want to store.
Change this:
localStorage.setItem("playerNameArray", JSON.stringify("arrayPlayerName"));
To this:
localStorage.setItem("playerNameArray", JSON.stringify(arrayPlayerName));
OK everybody, I hope you can help me. I have a problem with JQuery or better with the each selector of JQuery.
I have an example table, where I want to filter for special values which I entered before. Those values I got from my input field , store them in a variable, split the data an create an JQuery Object.
Well and then I think I have a problem with the selection, marked in the code section.
<p>
<input id="testyear" size="4" type="text">
<input value="Werte" onclick="getvalue()" type="button">
</p>
<script>
function getvalue() {
var wert = $('#testyear').val();
$("#years").find("tr").hide();
var data = this.value.split(" ");
// create jQuery Object
var jQueryObject = $("#years").find("tr");
// i think here is my error, i want to display only the object which are equal or better stored in my variable “wert”.
$.each(data, function (){
//jQueryObject = jQueryObject.filter(wert);
jQueryObject == wert;
});
jQueryObject.show();
};
<!--Example Table-->
<table id="years">
<tbody>
<tr>
<td>1997</td>
<td class="century">20</td>
</tr>
<tr>
<td>2001</td>
<td class="century">21</td>
</tr>
</tbody>
</table>
I expect, that when I enter 1997 in the inpt field, the whole tr which contains 1997 will be displayed. I know it is simple but I have no idea so thanks for your help.
Use a filter on the TR's after initially hiding them all.
e.g.
getvalue = function() {
var wert = $('#testyear').val();
// create jQuery Object
$("#years tr").hide().filter(function() {
return ~~$("td", this).first().text() >= wert;
}).show();
};
JSFiddle: https://jsfiddle.net/TrueBlueAussie/h8Lejfac/
Notes:
The ~~ is a little conversion to integer trick
You seem to have extra code you do not need in the example
Just get filter to return true for each item you want to keep and false for the rest
When using jQuery, avoid using inline event handlers (like onclick=). Use jQuery event handlers instead. See below:
e.g.
$('#wert').click(function() {
var wert = $('#testyear').val();
// create jQuery Object
$("#years tr").hide().filter(function() {
return ~~$("td", this).first().text() >= wert;
}).show();
});
JSFiddle: https://jsfiddle.net/TrueBlueAussie/h8Lejfac/1/
I think your problem is not in each() method (not selector). Your problem is here:
var data = this.value.split(" ");
this is not defined (you are not in an object scope). I think you need this:
var data = wert.split(" ");
-----------^^^^
You've obtain the value of wert in the last line.
I am very new in JavaScript and I have the following problem to solve.
I have a table that contains this td cell:
<td class= "dateToConvert" width = "8.33%">
<%=salDettaglio.getDataCreazione() != null ? salDettaglio.getDataCreazione() : "" %>
</td>
This retrieve a String from an object and show it into the cell
The problem is the retrieved string represent a date having the following horrible form: 20131204 and I have to convert it into the following form: 2013-12-04.
So I am thinking to create a JavaScript that do this work when the value is retrieved.
My problem is: how can I do to automatically call the JavaScript before to show the value into the td cell? (So I show the modified output in the desidered form)
EDIT 1:
So I have create thid JavaScript function into my page:
function convertData() {
var tds = document.querySelectorAll('.dateToConvert');
[].slice.call(tds).forEach(function(td) {
td.innerText = td.innerText.replace(/(\d{4})(\d{2})(\d{2})/, '$1-$2-$3');
});
}
But it don't work because it never enter in this function (I see it using FireBug JavaScript debugger). Why? What am I missing? Maybe have I to call it explicitly in some way in my td cell?
Of course it is better to fix backend method to make it return proper format. But since you have no control over it try to use something like this:
var tds = document.querySelectorAll('.dateToConvert');
[].slice.call(tds).forEach(function(td) {
td.textContent = td.textContent.replace(/(\d{4})(\d{2})(\d{2})/, '$1-$2-$3');
});
Check the demo below.
var tds = document.querySelectorAll('.dateToConvert');
[].slice.call(tds).forEach(function(td) {
td.textContent = td.textContent.replace(/(\d{4})(\d{2})(\d{2})/, '$1-$2-$3');
});
<table>
<tr>
<td class= "dateToConvert" width = "8.33%">
20131204
</td>
<td class= "dateToConvert" width = "8.33%">
20140408
</td>
</tr>
</table>
I've got a table with a load of auto complete boxes in it which look like so...
<richui:autoComplete style="width:500px" name="objSelect[${newRow-1}].id" value= "" action="${createLinkTo('dir': 'object/searchAJAX')}" forceSelection = "true" maxResultsDisplayed="20" minQueryLength ="3" onItemSelect="updateHiddenInput(id,${newRow-1})" />
I've got it to call a function called updateHiddenInput when a user selects a value passing in the id selected as well as the row the autocomplete is on (this function then updates a hidden field in the same row, using the values passed in, with the ID). The function looks like so: -
function updateHiddenInput(id, num){
var objID = "objectID[" + num + "].id";
$(document.getElementById(objID)).val(id);
}
Everything works until I add a new row within my table, this pushes everything down one row and stops the autocomplete from updating the right rows hidden field (as its still referencing the old row).
Currently I have another piece of code that goes through and renames all the fields when a new row is inserted, but I have no idea how to update the autocomplete so that it passes through the right row number, anyone know how I can alter this?
The only other alternative I could think of would be to just pass through the object itself as well as the ID I can then locate the hidden based off the object, but I can't work out how to do this, any suggestions gratefully received! :S
I've tried changing
onItemSelect="updateHiddenInput(id,${newRow-1})"
to
onItemSelect="updateHiddenInput(id,this)"
Theoretically so I can just pass through the autocomplete object and from there just traverse the page to find the hidden field I want to update. However when I then attempt to use that object in my function, for example with something like: -
var mynumber = $(myobject).closest('td').find('input').val();
I always get an "undefined" returned when I try to alert back the value...
If I just put in an alert(myobject) in the function it returns AutoComplete instance0 autoLook[0].id but if I've inserted new lines the id value doesn't change (i.e the objects id is now autoLook[3].id but it still shows [0], which I think could be part of the problem but I've got now idea how I can update this value...
I notice when looking in firebug at the html there is a /script linked to the autocomplete which could be the problem as this doesn't get updated when new lines are added and I can see multiple references to the old/original id value (see below) so maybe the passing through of this isn't passing the current objects values through...?
<script type="text/javascript">
var autoCompleteDataSource = new YAHOO.util.XHRDataSource("/Framework/object/searchAJAX");
autoCompleteDataSource.responseType = YAHOO.util.XHRDataSource.TYPE_XML;
autoCompleteDataSource.responseSchema = {
resultNode : "result",
fields : [
{ key: "name" },
{ key: "id" }
]
};
;
autoComplete = new YAHOO.widget.AutoComplete('autoLook[0].id','ad186a42e45d14d5cde8281514f877e42', autoCompleteDataSource);
autoComplete.queryDelay = 0;
autoComplete.prehighlightClassName = 'yui-ac-prehighlight';
autoComplete.useShadow = false;
autoComplete.minQueryLength = 3;
autoComplete.typeAhead = false;
autoComplete.forceSelection = true;
autoComplete.maxResultsDisplayed = 20;
autoComplete.shadow = false;
var itemSelectHandler = function(sType, args) {
var autoCompleteInstance = args[0];
var selectedItem = args[1];
var data = args[2];
var id = data[1];
updateHiddenInput(id,this) };
autoComplete.itemSelectEvent.subscribe(itemSelectHandler);
</script>
My thanks so far to user1690588 for all his help thus far! :)
On further digging I'm convinced that my issues is down to the line autoComplete = new YAHOO.widget.AutoComplete('autoLook[0].id','a5b57b386a2d1c283068b796834050186', autoCompleteDataSource); specifically the part where its inputting autoLook[].id and if I could change this I'd then be ok, but this line is auto generated and I've got no idea how to update it, anyone have any similar experience?
I have not much idea about your gsp page but I tried it on my side:
My gsp:
<!DOCTYPE html>
<html>
<head>
<resource:autoComplete skin="default"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
var counter = ${list.size()};
function asd() {
jQuery.ajax({
url: " ${createLink(controller: 'oauthCallBack', action: 'testAuto')}",
data: "idx=" + counter++,
success: function (data) {
jQuery("#tableId").append("<tr><td>" + data + "</td></tr>");
}
});
}
function updateHiddenInput(id, tg) {
jQuery(tg).val(id);
}
</script>
</head>
<body>
<g:form>
<table id="tableId">
<g:each in="${list}" var="vr" status="idx">
<tr>
<td>
<richui:autoComplete name="name" id="uniqueId${idx}" action="${createLinkTo('dir': 'oauthCallBack/test')}" onItemSelect="updateHiddenInput(id, someId${idx})"/>
<g:hiddenField name="someName" id="someId${idx}" value=""/>
</td>
</tr>
</g:each>
</table>
</g:form>
<button onclick="asd()">Add</button>
</body>
</html>
My action:
def testAuto() {
render template: 'addNew', model: [idx: params.idx]
}
My template(addNew):
<richui:autoComplete name="name" id="uniqueId${idx}" action="${createLinkTo('dir': 'oauthCallBack/test')}"
onItemSelect="updateHiddenInput(id, someId${idx})"/>
<g:hiddenField name="someName" id="someId${idx}" value=""/>
Try this..,.
EDIT.....................................................................................
I supposed that you have successfully updated all the input field names. Then you can edit hidden field like:
View:
<tr class="dummyClass">
<td>
<richui:autoComplete name="name[${idx}]" id="uniqueId[${idx}]" action="${createLinkTo('dir': 'oauthCallBack/test')}" onItemSelect="updateHiddenInput(id, this)"/>
<g:hiddenField name="someName[${idx}]" id="someId[${idx}]" value=""/>
</td>
</tr>
jQuery:
function updateHiddenInput(id, tg) {
jQuery(tg._elTextbox).closest("tr.dummyClass").find("input[type=hidden]").val(id);
}
EDIT.....................................................................................
Why you need to change the 'id'? Changing name is sufficient to send values in order. And you can update the hidden field without id as above edit.
If you still need to change the id then you can change it by cloning the tr and then use regex. See this answer for full working example.