loadComplete: function(data) {
$("tr.jqgrow:odd").addClass('myAltRowClass');
var i, groups = $(this).jqGrid("getGridParam", "groupingView").groups,
l = groups.length,
idSelectorPrefix = "#" + this.id + "ghead_2_";
for (i = 0; i < l; i++) {
if (groups[i].cnt === 1) {
$(idSelectorPrefix + i).hide();
}
}
//var gd=jQuery("#master")[0];
//gd.grid.footers
// alert("YES");
//});
//var element = $('#master>tbody>tr>td>div');
//element.each(function (i) {
// alert(i);
// $(this).closest('div').find(".RCSummaryFooter1").text("check");
//});
},
/*-----------this is from jqgird---- */
tr class="ui-widget-content jqfoot ui-row-ltr" role="row" jqfootlevel="1">
<tr id="masterghead_1_3" class="ui-widget-content jqgroup ui-row-ltr masterghead_1" role="row">
<tr id="masterghead_2_4" class="ui-widget-content jqgroup ui-row-ltr masterghead_2" role="row" style="display: none;">
<tr class="ui-widget-content jqfoot ui-row-ltr" role="row" jqfootlevel="2">
<td aria-describedby="master_HD" style="">
<div class="RCSummaryFooter1">Total </div>
</td>
Dear sir,
I am hiding the second level group text if only one record existed. this is from the ID (masterghead_2_4) I need to hide the summary as well. How could I access the tr since there is no Id for this tr (jqfootlevel="2") I have three groupings. This is the second level which I need to hide. I need to change the text of the summary as well. At the moment it is displaying word "Total" for all three summary levels. I need to change the text as 'Accounts Total', Activity total and Cost/Rvnu Total respectively. Thanks in Advance.
Please understand it is because of this site only I was managed to do all these work I have done so far. I am a Informix guy and new to this subject. If any one have ideas please share it
I managed solve the issue. But if some one has better way of doing please let me know.
The first issue was to hide the group headings and summary totals if the count ==1.
I need to hide two groups if in the event count ==1
loadComplete: function() {
/* --Hiding cost/revenue and Activity summary Values ---*/
$('tbody tr').each(function(n,opts) {
if(opts.getAttribute('jqfootlevel')=='2' && opts.cells[2].innerText ==1){
opts.style.display='none';
}
if(opts.getAttribute('jqfootlevel')=='1' && opts.cells[2].innerText ==1){
opts.style.display='none';
}
});
jqfootlevel is one of the attributes representing summary value tr (no id is available in this tr)
The following code segment I copied from Mr. Oleg's answer. This is to hide the Group header. In this case I am hiding only one Group header. (group 2- Cost/Rvnue Group)
/* --This is hiding Cost/Revenue Group header if total =1 --*/
var i, groups = $(this).jqGrid("getGridParam", "groupingView").groups,
l = groups.length,
idSelectorPrefix = "#" + this.id + "ghead_2_";
for (i = 0; i < l; i++) {
if (groups[i].cnt === 1) {
$(idSelectorPrefix + i).hide();
}
}
Following code will change the Total word as given below. So that it will display as
Cst/Rvnu Total
Activity Total
Accounts Total
for(var i=0;i<3;i++){
var element = $('tr[jqfootlevel='+i+']');
switch(i){
case 0:
var txt="Accounts Total";
break;
case 1:
var txt="Activity Total";
break;
case 2:
var txt="Cst/Rvnu Total";
break;
}
element.each(function (n,opts) {
opts.cells[0].innerHTML=txt;
opts.cells[0].style.color='tomato';
if(i<2){
opts.cells[2].innerHTML="";
}
});
Related
I am trying to change the class name to an element when its value goes down
My view in the blade is a foreach
#foreach ($scaduti as $item )
<tr>
<td>{{$item->name}}</td>
<td>{{$item->lotto}}</td>
<td>{{carbon\Carbon::createFromFormat('Y-m-d', $item->data_di_scadenza)->format('d-m-Y')}}</td>
<td>{{$item->sector->settore}}</td>
<td>{{$item->sector->scaffale}}</td>
<td id="changecolor">{{$item->sector->quantita_rimanente - $item->sector->quantita_bloccata}}</td>
<td>{{$item->sector->quantita_bloccata}}</td>
</tr>
#endforeach
I want to add a class to the td with id "changecolor"
My script is:
var x = document.getElementById("changecolor").innerHTML;
var i;
for (i = 0; i < x.length; i++) {
if(x[i] <= 20){
document.getElementById('changecolor').className= 'changetored';
}
}
The color is applied only to the first element of the foreach and ignoring all the others.
I want to apply it to all foreach results that respect the if
Sorry for my bad English.
The problem is, as many users said, on id univocity. How to easly solve that? Let's say you have an id on $item that is a progressive number from 0 to ...
In this case you could do something like:
#foreach ($scaduti as $item )
<tr>
<td>{{$item->name}}</td>
<td>{{$item->lotto}}</td>
<td>{{carbon\Carbon::createFromFormat('Y-m-d', $item->data_di_scadenza)->format('d-m-Y')}}</td>
<td>{{$item->sector->settore}}</td>
<td>{{$item->sector->scaffale}}</td>
<td id="{{ $item->id }}">{{$item->sector->quantita_rimanente - $item->sector->quantita_bloccata}}</td>
<td>{{$item->sector->quantita_bloccata}}</td>
</tr>
#endforeach
Then the script becames:
var i;
for (i = 0; i < length of scaduti; i++) {
var x = document.getElementById(i).innerHTML;
if(x[i] <= 20){
document.getElementById(i).className= 'changetored';
}
}
document.getElementById will always give you a single element. Most of the time the first element that it finds.
Instead of giving each element same id give them same name like
<td name="changecolor">{{$item->sector->quantita_rimanente - $item->sector->quantita_bloccata}}</td>
then use : document.getElementsByName("changecolor")
This will give all the elements with name 'changecolor'.
You can loop through these elements and do the thing you want.
Your modified code will look something like this:
var x = document.getElementsByName("changecolor");
var i;
for (i = 0; i < x.length; i++) {
if(x[i].innerHTML <= 20){
x[i].className = "changetored";
}
}
This is happening because you are using the id attribute more than once. An id should only appear once on a page. There are a couple ways to solve this problem:
change the id to a class='changecolor', then iterate through all of the elements with the changecolor class.
loop through the s of the and change the color of the 6th
I would suggest looking up document.querySelector to help in this.
I just started using DataTables and everything works fine when creating the table.
When I display 5, 24, 47 rows in my table, DataTables behaves as I would expect.
But I have this table that has around 700 rows and I get the error in Google Chrome,
"VM9075 dataTables.min.js:24Uncaught TypeError: Cannot set property '_DT_CellIndex' of undefined "
and in IE 9,
"SCRIPT5007: Unable to set value of the property '_DT_CellIndex': object is null or undefined
jquery-1.10.2.min.js, line 4 character 2367"
I don't have jQuery included twice btw.
I'm not sure how to proceed from here.
I tried to use the unminified version of the .js file to debug it more myself but i kept getting an "ext" method or property is undefined and couldn't fix that either.
Any help is appreciated!
I figured it out
The biggest issue was not knowing exactly what this error actually meant.
In my case it meant "the number of every <td> element in your table that is a child of a <tr> element doesn't match the number of <th> elements that are a child of the <thead> element."
My table was being generated by the server, and some of the <tr> elements had 27 <td> children (which was filling the whole width of the table up, but some of the <tr> elements only had 3, 4, or 5, ... <td> child elements which isn't a valid table.
I solved it by adding empty <td> elements in my table for the <tr> elements that lacked the correct number of <td> elements
var makeTableValidObject = {
thisWasCalled: 0,
makeTableValid: function() {
var tableToWorkOn = document.getElementById("table1");
//check the number of columns in the <thead> tag
//thead //tr //th elements
var numberOfColumnsInHeadTag = tableToWorkOn.children[1].children[0].children.length;
var numberOf_trElementsToValidate = tableToWorkOn.children[2].children.length;
//now go through each <tr> in the <tbody> and see if they all match the length of the thead columns
//tbody //all trs//all tds elements
//tableToWorkOn.children[2].children.children);
for(var i = 0; i < numberOf_trElementsToValidate; i++) {
//row my row make sure the columns have the correct number of elements
var tdColumnArray = tableToWorkOn.children[2].children[i].children
var trElementToAppendToIfNeeded = tableToWorkOn.children[2].children[i];
if(tdColumnArray.length != numberOfColumnsInHeadTag) {
//since they don't match up, make them valid
if(tdColumnArray.length < numberOfColumnsInHeadTag) {
//add the necessary number of blank <td> tags to the <tr> element to make this <tr> valid
var tdColumnArrayLength = tdColumnArray.length;
for(var j = 0; j < (numberOfColumnsInHeadTag - tdColumnArrayLength); j++) {
var blank_tdElement = document.createElement("td");
blank_tdElement.id = "validating_tdId" + i + "_" + j;
trElementToAppendToIfNeeded.appendChild(blank_tdElement);
}
}
else {
//TODO: remove <td> tags to make this <tr> valid if necessary
}
}
}
}
};
Edit 1:
It has been awhile and this question is still getting a bunch of views. I have since updated the code.
I replaced the first line of code with the second line to be more general
var numberOfColumnsInHeadTag = tableToWorkOn.children[1].children[0].children.length;
var numberOfColumnsInHeadTag = tableToWorkOn.querySelectorAll('thead')[0].querySelectorAll('th');
Pretty much where ever in the prior code you see the children.children I replaced that with the querySelectorAll(...) Function.
It uses css selectors which makes it amazingly powerful.
stay blessed
Ran into this same issue and implemented this same solution (essentially) in jquery based on Coty's. Hope this helps someone. :)
$( '.table' ).each(function( i ) {
var worktable = $(this);
var num_head_columns = worktable.find('thead tr th').length;
var rows_to_validate = worktable.find('tbody tr');
rows_to_validate.each( function (i) {
var row_columns = $(this).find('td').length;
for (i = $(this).find('td').length; i < num_head_columns; i++) {
$(this).append('<td class="hidden"></td>');
}
});
});
As answered by Coty, the problem lies in the mismatch of td elements generated in the header and body of table.
I'd like to highlight one of the reasons why it can occur (For .Net Users).
If Page numbers are being displayed at the end of gridview, they can disrupt table structure.
Remove AllowPaging="true" from your gridview to solve this.
And no worries because Datatable handles Paging.
you always keep four column but sometimes you will receive or append null td or only one td, td count always match with total column so when you does not have record then make td as following.
<th>No</th>
<th>Name</th>
<th>place</th>
<th>Price</th>
----------------------------------------
<td colspan="4">Data not found.</td>
<td style="display: none;"></td>
<td style="display: none;"></td>
<td style="display: none;"></td>
this error can also be triggered if you try to set options for the responsive extension for more columns than you have.
$( '.table' ).each(function( i ) {
var worktable = $(this);
var num_head_columns = worktable.find('thead tr th').length;
var rows_to_validate = worktable.find('tbody tr');
rows_to_validate.each( function (i) {
var row_columns = $(this).find('td').length;
for (i = $(this).find('td').length; i < num_head_columns; i++) {
$(this).append('<td class="hidden"></td>');
}
});
});
I have 2 tables on my page, #seats and #wings.
Now I have to check which td inside table#seats contains a special title, then check what the value of its attr "seq" is, and finally add a class to the corresponding td intable#wings.
<table id="seats">
<tr>
<td title="" seq="1">Info</td>
<td title="Exit Row Seat" seq="2">Info</td>
<td title="" seq="3">Info</td>
</tr>
</table>
My Code so far:
$("table#seats tr td[title*='Exit Row Seat']").each(function () {
var count = $(this).attr("seq");
$("table#wings tr td:nth-child(" + count + ")").addClass('exitRow');
});
My Problem is, that I get all of the td's back, not only those with the title tag I am looking for. What do I do wrong?
Then you need to iterate all td and then read the attribute:
$("table#seats tr td").each(function () {
if($(this).attr('title') == "Exit Row Seat") {
var count = $(this).attr("seq");
$(this).addClass('exitRow');
}
});
My solution at the end:
for (var i = 0; i < allSeatTables.length; i++) {
$("td[title*='Exit']", allSeatTables[i]).each(function () {
var count = $(this).attr("seq");
$(("td:eq(" + count + ")"), allWingRow[i]).addClass("exitRow");
});
}
I have a a and I would like to sort my list alphabetically (I don't want caps to matter) according to a class named "name". How would I do this?
<ul class="column">
<li>
<table>
<tr>
<td class="name" >Name of Item</td>
</tr>
<tr>
<td>Content</td>
</tr>
<tr>
<td>morecontent</td>
<td>morecontent</td>
</tr>
</table>
</li>
<li>
<table>
<tr>
<td class="name" >Another name of item</td>
</tr>
<tr>
<td>Content</td>
</tr>
<tr>
<td>morecontent</td>
<td>morecontent</td>
</tr>
</table>
</li>
</ul>
Thanks
Using jQuery, this should do it:
function sort() {
$($('ul.column>li').get().reverse()).each(function(outer) {
var sorting = this;
$($('ul.column>li').get().reverse()).each(function(inner) {
if($('td.name', this).text().localeCompare($('td.name', sorting).text()) > 0) {
this.parentNode.insertBefore(sorting.parentNode.removeChild(sorting), this);
}
});
});
}
The above is a little dense though, so if you want to understand what's going on, let's break it down line-by-line:
function sort() {
//get each <li> which is a child of <ul class="column">
//for each element in the results, execute a function
//also, we reversed the order (e.g. start at the bottom and go up
$($('ul.column>li').get().reverse()).each(function(outer) {
//this is the current <li> we're running against
var sorting = this;
//get the same set of elements again in their current state,
//so we can figure out where to put this one
$($('ul.column>li').get().reverse()).each(function(inner) {
//get the inner text of the <td class="name">
//for the item we're trying to replace,
//and for the current item in the inner loop
//use localeCompare to compare the two strings alphabetically
if($('td.name', this).text().localeCompare($('td.name', sorting).text()) > 0) {
//if the one we're trying to sort goes after the current one
//alphabetically, remove it from its current position
//and insert it after the current one
this.parentNode.insertBefore(sorting.parentNode.removeChild(sorting), this);
}
});
});
}
We can make it a little more reusable by passing in the selector for the list and the key:
sort('ul.column>li', 'td.name');
function sort(list, key) {
$($(list).get().reverse()).each(function(outer) {
var sorting = this;
$($(list).get().reverse()).each(function(inner) {
if($(key, this).text().localeCompare($(key, sorting).text()) > 0) {
this.parentNode.insertBefore(sorting.parentNode.removeChild(sorting), this);
}
});
});
}
Do keep in mind this requires jQuery, so you'll need a reference to it in your <head>:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
And this function should be called at some point in the page after the list is written in the HTML.
Mine answer is longer :p but work.
function SortLIs() {
var ColumnUL = $("ul.column");
var Columns = $(ColumnUL).children("li");
var ColumnNames = new Array();
var Columns_byName = new Array();
var Columns_Count = Columns.length;
for(var i = 0; i < Columns_Count; i++) {
var aColumn = Columns[i];
var aTD = $(aColumn).find(".name");
var aTDName = aTD.text();
ColumnNames.push(aTDName);
Columns_byName[aTDName] = aColumn;
$(aColumn).remove();
}
ColumnNames.sort(function(a, b){
return (a > b) - (a < b);
});
for(var i = 0; i < Columns_Count; i++) {
var aName = ColumnNames[i];
ColumnUL.append(Columns_byName[aName]);
}
}
EDIT: I saw you said that you are not good at JS. So here is the bigger picture for you.
(1) Add The following code to the header of the HTML. This will use jQuery library.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
(2) Add the 'sortLIs' code just right after the above code
<script>
<!--
function SortILs() {
...
}
-->
</script>
(3.1) If you want the sorting to begin at the load time. Add this right after the above code.
<script>
<!--
$(document).ready(function(){
SortILs();
});
-->
</script>
(3.2) Otherwise, you call the function from an event.
Hope this helps.
Here's another approach, stealing ideas from the other answers given so far (also requiring jQuery):
function sort(elementSelector, valueSelector, ascending) {
var sign = ascending ? -1 : 1;
var elements = jQuery(elementSelector);
elements.each(function() {
this.sortKey = jQuery(valueSelector, this).text();
});
var sorted = elements.get();
sorted.sort(function(a, b) {
var keyA = a.sortKey;
var keyB = b.sortKey;
return sign * ((keyA < keyB) - (keyA > keyB));
});
elements.parent().append(sorted);
}
sort('.column>li', '.name', true)
Just seconding the jQuery response above, have a look at this tutorial:
http://www.shopdev.co.uk/blog/sortable-lists-using-jquery-ui/
For semantics, you might be better off also placing the classname inside the actual <li> tag.
The use of a table inside a list aside though, you may want to post an example page to help further.
I have a table with one column and about ten rows. The first column has rows with text as row headers, "header 1", "header 2". The second column contains fields for the user to type data (textboxes and checkboxes).
I want to have a button at the top labelled "Add New...", and have it create a third column, with the same fields as the first column. If the user clicks it again, it will create another blank column with fields (as in the second column).
Does anyone know of an effective way to manipulate the DOM to achieve this?
I'm experimenting with div's and TABLES but i'm on my third day of doing this, and it feels harder than it should be.
Amusing exercise. Thanks to AviewAnew's hint, I could do it.
function AddColumn(tableId)
{
var table = document.getElementById(tableId);
if (table == undefined) return;
var rowNb = table.rows.length;
// Take care of header
var bAddNames = (table.tHead.rows[0].cells.length % 2 == 1);
var newcell = table.rows[0].cells[bAddNames ? 1 : 0].cloneNode(true);
table.rows[0].appendChild(newcell);
// Add the remainder of the column
for(var i = 1; i < rowNb; i++)
{
newcell = table.rows[i].cells[0].cloneNode(bAddNames);
table.rows[i].appendChild(newcell);
}
}
with following HTML:
<input type="button" id="BSO" value="Add" onclick="javascript:AddColumn('TSO')"/>
<table border="1" id="TSO">
<thead>
<tr><th>Fields</th><th>Data</th></tr>
</thead>
<tbody>
<tr><td>Doh</td><td>10</td></tr>
<tr><td>Toh</td><td>20</td></tr>
<tr><td>Foo</td><td>30</td></tr>
<tr><td>Bar</td><td>42</td></tr>
<tr><td>Ga</td><td>50</td></tr>
<tr><td>Bu</td><td>666</td></tr>
<tr><td>Zo</td><td>70</td></tr>
<tr><td>Meu</td><td>80</td></tr>
</tbody>
</table>
Something along the lines of
function(table)
{
for(var i=0;i<table.rows.length;i++)
{
newcell = table.rows[i].cells[0].cloneNode(true);
table.rows[i].appendChild(newcell);
}
}