I came up with the script to collapse a table
<script type="text/javascript">
var rowVisible = true;
function toggleDisplay(tbl) {
var tblRows = tbl.rows;
for (i = 0; i < tblRows.length; i++) {
if (tblRows[i].className != "headerRow") {
tblRows[i].style.display = (rowVisible) ? "none" : "";
}
}
rowVisible = !rowVisible;
}
</script>
<div class="datagrid"><table id="thread_1">
<thead><tr class="headerRow">
<th WIDTH="100">SLO</th>
It works fine but my problem is that I want to save the state when person leaves the website. I guess that the easiest way would be with cookie. I just haven't done something like this before. How can I do that?
If you don't need to support, let say IE7 you can use browser localStorage.
// Our flag to determine if rows are hidden or not
var rowsVisible = localStorage.getItem('rowsVisible'),
// Table handler
table = document.getElementById('table');
// "rowHidden" not exists in localStorage yet
if (rowsVisible === null) {
rowsVisible = true;
} else {
// localStorage return string
rowsVisible = rowsVisible === 'true' ? true : false;
}
toggleDisplay(table, rowsVisible ? '' : 'none');
document.getElementById('toggleBtn').addEventListener('click', function() {
toggleDisplay(table);
}, false);
function toggleDisplay(tbl) {
var tblRows = table.rows,
mode = rowsVisible ? '' : 'none';
for (i = 0; i < tblRows.length; i++) {
if (tblRows[i].className != "headerRow") {
tblRows[i].style.display = mode;
}
}
localStorage.setItem('rowsVisible', rowsVisible);
rowsVisible = !rowsVisible;
};
Demo: http://jsfiddle.net/SXAZ4/36/
Related
I have a search function on my table and it is only searching for the exact keyword. It will not display data which are not properly capitalized. How can I make it case insensitive so I can display those data even I typed all lowercase words? By the way I'm using ESLINT rules. Here is my javascript code:
myFunction () {
var searchText = document.getElementById('searchTerm').value
var targetTable = document.getElementById('myTable')
var targetTableColCount
for (var rowIndex = 0; rowIndex < targetTable.rows.length; rowIndex++) {
var rowData = ''
if (rowIndex === 0) {
targetTableColCount = targetTable.rows.item(rowIndex).cells.length
continue // do not execute further code for header row.
}
for (var colIndex = 0; colIndex < targetTableColCount; colIndex++) {
rowData += targetTable.rows.item(rowIndex).cells.item(colIndex).textContent
}
if (rowData.indexOf(searchText) === -1) {
targetTable.rows.item(rowIndex).style.display = 'none'
} else {
targetTable.rows.item(rowIndex).style.display = 'table-row'
}
}
}
You can use the toLowerCase string method.
if (rowData.toLowerCase().indexOf(searchText.toLowerCase()) === -1) {
targetTable.rows.item(rowIndex).style.display = 'none'
} else {
targetTable.rows.item(rowIndex).style.display = 'table-row'
}
It seems to me you're doing more work than necessary. If the intention is to show rows that have the search text, then use the textContent of the row rather than concatenating all the cell values, and also set the display to "none" or "", so the element adopts its default or inherited display without you having to program it. E.g.
function doSearch() {
var searchText = document.getElementById('i0').value.toLowerCase();
var table = document.getElementById('t0');
var row, rows = table.rows;
// Skip first row
for (var i=1, iLen=rows.length; i<iLen; i++) {
row = rows[i];
row.style.display = row.textContent.toLowerCase().indexOf(searchText) == -1? 'none' : '';
}
}
<table id="t0">
<tr><th>Index<th>name
<tr><td>0<td>Foo
<tr><td>1<td>Bar
</table>
Search text:<input id="i0">
<button onclick="doSearch()">Do search</button>
This part:
if (rowData.indexOf(searchText) === -1) {
targetTable.rows.item(rowIndex).style.display = 'none'
} else {
targetTable.rows.item(rowIndex).style.display = 'table-row'
}
Lets change it to:
if (isInsideInsensitive(rowData,searchText)) {
targetTable.rows.item(rowIndex).style.display = 'none'
} else {
targetTable.rows.item(rowIndex).style.display = 'table-row'
}
With additional function:
function isInsideInsensitive(a, b){
return a.toLowerCase().indexOf(b.toLowerCase()) != -1;
}
Take a look at the isInsideInsensitive function
I have set filter in Kendo grid but i have a problem when filter applied to grid, i missed value of my filter row.
After filter i missed my filter :
Now for this reason, i set my filter row again so bellow code :
function updateSearchFilters(grid, field, operator, value)
{
var newFilter = { field: field, operator: operator, value: value };
var dataSource = grid.dataSource;
var filters = null;
if ( dataSource.filter() != null)
{
filters = dataSource.filter().filters;
}
if ( filters == null )
{
filters = [newFilter];
}
else
{
var isNew = true;
var index = 0;
for(index=0; index < filters.length; index++)
{
if (filters[index].field == field)
{
isNew = false;
break;
}
}
if ( isNew)
{
filters.push(newFilter);
}
else
{
//alert(value);
if(value == '')
filters.splice(index,1);
//delete filters[index];
else
filters[index] = newFilter;
}
}
dataSource.filter(filters);
for (var i = 0; i < filters.length; i++) {
$('#gridId-filter-column-' + filters[i].field.toString()).val(filters[i].value.toString());
}
}
When i set the break point in this line $('#gridId-filter-column-' + filters[i].field.toString()).val(filters[i].value.toString()); it worked correct but
when i remove break point this line doesn't work.
you can set delay before run this line :
for (var i = 0; i < filters.length; i++) { $('#gridId-filter-column-' +filters[i].field.toString()).val(filters[i].value.toString()); }
Not sure what the problem is, also not a javascript coder at all. Can someone shed some light on what I am missing.
The main problem I am having is trying to make this a bit more dynamic based on the selection of a select input. if I comment out the first two variable entries and set the stropt variable to something static that would identify one of my div's then it works fine.
aChecked = false;
function checkByParent() {
var sel = document.getElementByID("me");
var stropt = sel.options[sel.selectedIndex].value;
//var stropt = 'test2';
var collection = document.getElementById(stropt).getElementsByTagName('INPUT');
if (aChecked === false) {
aChecked = true;
} else {
aChecked = false;
}
for (var x = 0; x < collection.length; x++) {
if (collection[x].type.toUpperCase() === 'CHECKBOX')
collection[x].checked = aChecked;
}
}
Here is my fiddle
http://jsfiddle.net/sasatek/b654V/2/
The problem is getElementByID, which is a mistake it should be getElementById
Like this
aChecked = false;
function checkByParent() {
// var sel = document.getElementByID("me");
var sel = document.getElementById("me");
var stropt = sel.options[sel.selectedIndex].value;
//var stropt = 'test2';
var collection = document.getElementById(stropt).getElementsByTagName('INPUT');
if (aChecked === false) {
aChecked = true;
} else {
aChecked = false;
}
for (var x = 0; x < collection.length; x++) {
if (collection[x].type.toUpperCase() === 'CHECKBOX')
collection[x].checked = aChecked;
}
}
Javascript & DOM api is written in CamelCase
function globalModelToggleClicked(modname)
{
var state = this.checked ? true : false;
var display = this.checked ? 'inline-block' : 'none';
var inputs = document.getElementsByTagName('input');
var input_l = inputs.length;
// check uncheck inputs checkboxes
while(input_l--)
{
var input = inputs[input_l];
if(input.getAttribute('class') == modname)
{
input.checked = state;
}
}
// show/ hide all colorings
var main = document.getElementById('main');
var divs = main.getElementsByTagName('div');
var divs_l = divs.length;
var regex = new RegExp(modname);
while(divs_l--)
{
var div = divs[divs_l];
if( regex.test(div.getAttribute('class'))
&& ( /hit/.test(div.getAttribute('class'))
|| /seqBorder/.test(div.getAttribute('class'))
)
)
{
div.style.display = display;
}
}
}
function localModelToggleClicked(modname)
{
var display = this.checked ? 'inline-block' : 'none';
// get parent fieldset
var fieldset = this.parentNode;
while(fieldset.nodeName != 'FIELDSET')
{
fieldset = fieldset.parentNode;
}
// show/ hide all colorings
var divs = fieldset.getElementsByTagName('div');
var divs_l = divs.length;
var regex = new RegExp(modname);
while(divs_l--)
{
var div = divs[divs_l];
if( regex.test(div.getAttribute('class'))
&& ( /hit/.test(div.getAttribute('class'))
|| /seqBorder/.test(div.getAttribute('class'))
)
)
{
div.style.display = display;
}
}
}
The two above functions toggle the div's visibility. They work perfectly in all browsers except IE(8) and I have no idea what is wrong. I have tried the debugger, which shows nothing. The functions are on an external script with other functions, which are working. When I alert inside the function everything seems in order. Can anyone help
?
The Problem was with the getAttribute('class') apparently IE does not accept this. So i use the className instead. Which works perfectly in all browsers.
Hey All I have this javascript function that actively searches a table I have on my web page. The function working in Mozilla and Chrome but not in IE. Can anyone help me tweak this so it will work in all browsers? here is the code:
function playerSearch(phrase, _name){
var words = phrase.value.toLowerCase().split(" ");
var table = document.getElementsByName(_name)[0];
var ele;
for (var r = 1; r < table.rows.length; r++){
ele = table.rows[r].innerHTML.replace(/<[^>]+>/g,"");
var displayStyle = 'none';
for (var i = 0; i < words.length; i++) {
if (ele.toLowerCase().indexOf(words[i])>=0)
displayStyle = '';
else {
displayStyle = 'none';
break;
}
}
table.rows[r].style.display = displayStyle;
}
}
Here is the function call from the html page:
<span id="filter" class="filter">Player Search:<input onkeyup="playerSearch(this, 'currentTable')" type="text"></span>
It sounds like IE is insisting on inserting a tBody dom element. try altering var table = document.getElementsByName(_name)[0]; to var table = document.getElementsByName(_name)[0].tBodies[0];
EDIT
After reading the comments below and doing a bit of googling it turns out that name is not a global attribute and not a valid attribute on tables according to the HTML4.01 specification (this is unchanged in the current draft of the HTML5 specification) this is unfortunatly one of the times when IEs javascript engine is being a stickler for the rules returning an array of 0 length when you do document.getElementsByName(_name) , and the other browser manufacturers are actually breaking the specification.
Here is my answer which works in all browsers. Separate function are given for IE, NetScape and all other browsers.
<script type="text/javascript" language="JavaScript">
var OtherBrowser = (document.getElementById);
var IE4 = (document.all);
var NS4 = (document.layers);
var win = window;
var n = 0;
function findInPage(str) {
var txt, i, found;
if (str == "") {
alert("Enter some thing to search");
return false;
}
else if (IE4) {
txt = win.document.body.createTextRange();
for (i = 0; i <= n && (found = txt.findText(str)) != false; i++) {
txt.moveStart("character", 1);
txt.moveEnd("textedit");
}
if (found) {
txt.moveStart("character", -1);
txt.findText(str);
txt.select();
txt.scrollIntoView();
n++;
}
else {
if (n > 0) {
n = 0;
findInPage(str);
}
else
alert("Sorry, we couldn't find.Try again");
}
}
else if (OtherBrowser) {
if (!win.find(str)) {
while (win.find(str, false, true, false, false, false, true))
n++;
}
else if (win.find(str)) {
n++;
}
}
if (NS4) {
if (!win.find(str)) {
while (win.find(str, false, true, false, false, false, true))
n++;
}
else if (win.find(str)) {
n++;
}
}
return false;
}
</script>
If you want to save yourself some trouble while applying some slick table functionality (including filters, which I think you're trying to achieve here), I suggest DataTables.
http://datatables.net/