Is there a way to add rows to a gridview using JavaScript? Right now I have the GridView's onclick method set to sortTrGrid(gridviewname) with the sortTrGrid method structured as below. I can get the rows in the tables set in the proper order, however nothing changes on the web page.
function sortTrGrid(sender) {
var table = document.getElementById(sender.id);
var rows = new Array(table.rows);
for (var i = 0; i < table.rows; i++) {
rows[i] = table.rows[i];
}
for (var i = table.rows; i > 0; i--) {
table.deleteRow(document.getElementById(i));
table.rows[i] = rows[i];
}
}//end GridSort
Assuming your page contains all the rows from your data source (no-paging) and you want to order the GridView rows on the client to increase performance (without hitting the server), you can do the following:
(This code allows sorting numbers and text and sorting in ascending and descending mode when clicking the GridView headers)
If you want to check the full working example, I just uploaded to my GitHub site
Screenshot
Unordered
First click - ASC order
Second click - DESC order
Binding the GridView
<asp:LinqDataSource runat="server" ID="lds"
ContextTypeName="WebForms_1.DataAccess.PubsDataContext"
TableName="jobs"
EntityTypeName="WebForms_1.DataAccess.jobs">
</asp:LinqDataSource>
<asp:GridView runat="server" ID="gv" DataSourceID="lds" DataKeyNames="job_id">
</asp:GridView>
jQuery code
<script type="text/javascript">
$(function () {
var $gv = $("table[id$=gv]");
var $headers = $("th", $gv);
var $rows = $("> tbody > tr:not(:has(table, th))", $gv);
$rows.addClass("grid-rows");
$headers.addClass("grid-headers");
$headers.toggle(function (e) {
sortGrid($(this), 0);
}, function (e) {
sortGrid($(this), 1);
});
function sortGrid(row, direction) {
var colIndex = $(row).parent().children().index($(row));
var $rowsArray = $.makeArray($rows);
var $sortedArray = $rowsArray.sort(function (o, n) {
var $currentCell = $("td:nth-child(" + (colIndex + 1) + ")", $(o));
var $nextCell = $("td:nth-child(" + (colIndex + 1) + ")", $(n));
var currentValue = parseFloat($currentCell.text()) ? parseFloat($currentCell.text()) : $currentCell.text();
var nextValue = parseFloat($nextCell.text()) ? parseFloat($nextCell.text()) : $nextCell.text();
if (direction == 0) {
return currentValue < nextValue ? -1 : 1;
}
else {
return currentValue > nextValue ? -1 : 1;
}
});
$("> tbody > tr:not(:has(table, th))", $gv).remove();
$("tbody", $gv).append($sortedArray);
}
});
</script>
Related
I'm trying to put pagination function into my table and taking this post "Simple pagination in javascript" for reference.
https://codepen.io/duongvu/pen/eewdPG?editors=1111
It's supposed to input the data from my array into the table's class. However it doesn't work in my case.
It freezes and can not proceed when clicking on <next>
Try this out #Duong Vu
for (var i = 0; i < records_per_page; i++)
{
col[i].innerText = content[i + (page-1) * records_per_page].number;
}
function changePage(page) {
var btn_next = document.getElementById("btn_next");
var btn_prev = document.getElementById("btn_prev");
var col = document.getElementsByClassName("no");
var colName = document.getElementsByClassName("name");
var colDetails = document.getElementsByClassName("info");
var page_span = document.getElementById("page");
if (page < 1) page = 1;
if (page > numPages()) page = numPages();
for (var i = (page - 1) * records_per_page; i < (page * records_per_page); i++) {
col[i % records_per_page].innerText = content[i] ? content[i].number : '';
colName[i % records_per_page].innerText = content[i] ? content[i].name : '';
colDetails[i % records_per_page].innerText = content[i] ? content[i].detail : '';
}
}
You are printing only numbers thats why it was not printing any other result. And as you have only 4 rows, so you need to use col[i % records_per_page] to print inside the table data on page changes.
Here is updated codepen.
I have used asp:drowdownlist on dataviewwebpart and is bind with source spdatasource1.
It have multiple duplicate items. How could I delete those duplicate item
asp:DropDownList runat="server" id="DropDownList1" DataValueField="ID" DataTextField="ProgramMaster" DataSourceID="spdatasource1" AutoPostBack="False" AppendDataBoundItems="True" ToolTip="Select a Program from the list"/>
Also, It is showing items in following formation ID;#ProgramName. How can I get programName only.
Well I use JQuery to remove duplicates item from asp:dropdownlist and here's the code if in-case somebody might need it. The code works in four part, Get the value from Dropdown, strip off the Duplicates and get the value in usable form, Remove the existing value from Dropdown and last set or append the values back to the dropdown list.
<script type="text/javascript">
$(document).ready(function(){
var handles= [];
$('#DropDownList1 option').each(function() {
var Prog1 = $(this).attr('text');
if(Prog1 != 'All'){
var Prog2 = Prog1.split(';#');
handles.push('All');
handles.push(Prog2[1]);
}
//Remove The existed Dropdownlist value
$("select#DropDownList1 option[value='" + $(this).val() + "']").remove();
//$(this).val().remove();
});
//Removing the Duplicates
var individual = [];
for (var i = 0; i<handles.length; i++) {
if((jQuery.inArray(handles[i], individual )) == -1)
{
individual .push(handles[i]);
}
}
//Inserting or setting the value from array individual to the dropdownlist.
var sel = document.getElementById('DropDownList1');
for(var i = 0; i < individual.length; i++) {
var opt = document.createElement('option');
opt.innerHTML = individual[i];
opt.value = individual[i];
sel.appendChild(opt);
}
});
</script>
P.S if the given ID didn't work fine for dropdown, get the ID from IE debugging tool which will be in form ctl00_PlaceHolderMain_g_a0a2fb36_2203_4d2e_bcd4_6f42243b880f_DropDownList1
you can do this with jquery
var usedNames = {};
$("select[name='company'] > option").each(function () {
if(usedNames[this.text]) {
$(this).remove();
} else {
usedNames[this.text] = this.value;
}
});
or with server side code try this
void RemoveDuplicateItems(DropDownList ddl)
{
for (int i = 0; i < ddl.Items.Count; i++)
{
ddl.SelectedIndex = i;
string str = ddl.SelectedItem.ToString();
for (int counter = i + 1; counter < ddl.Items.Count; counter++)
{
ddl.SelectedIndex = counter;
string compareStr = ddl.SelectedItem.ToString();
if (str == compareStr)
{
ddl.Items.RemoveAt(counter);
counter = counter - 1;
}
} } }
I have a gridview that is being rendered as follows
<table cellspacing="0" cellpadding="4" rules="cols" id="ContentPlaceHolder1_ucstockcount1_GridView1" style="color:Black;background-color:White;border-color:#DEDFDE;border-width:1px;border-style:None;width:100%;border-collapse:collapse;">
<tr style="color:White;background-color:#6B696B;font-weight:bold;">
<th scope="col">Sr.no</th><th scope="col">Style</th><th scope="col">Stk Last Mon</th><th scope="col">Stk Received</th><th scope="col">Stk This Mon</th><th scope="col">Change</th><th scope="col">Price</th><th scope="col">Value</th>
</tr><tr style="background-color:#F7F7DE;">
<td>1</td><td>T1-34H</td><td>0</td><td>0</td><td>
<input name="ctl00$ContentPlaceHolder1$ucstockcount1$GridView1$ctl02$TextBox2" type="text" id="ContentPlaceHolder1_ucstockcount1_GridView1_TextBox2_0" onblur="updatevals("ContentPlaceHolder1_ucstockcount1_GridView1_TextBox2_0",0,0,5.00,"ContentPlaceHolder1_ucstockcount1_GridView1_Label1_0","ContentPlaceHolder1_ucstockcount1_GridView1_Label2_0")" />
</td><td>
<span id="ContentPlaceHolder1_ucstockcount1_GridView1_Label1_0">0</span>
</td><td>5.00</td><td>
<span id="ContentPlaceHolder1_ucstockcount1_GridView1_Label2_0">0</span>
</td>
</tr><tr style="background-color:White;">
<td>2</td><td>T1-43B</td><td>0</td><td>0</td><td>
<input name="ctl00$ContentPlaceHolder1$ucstockcount1$GridView1$ctl03$TextBox2" type="text" id="ContentPlaceHolder1_ucstockcount1_GridView1_TextBox2_1" onblur="updatevals("ContentPlaceHolder1_ucstockcount1_GridView1_TextBox2_1",0,0,5.00,"ContentPlaceHolder1_ucstockcount1_GridView1_Label1_1","ContentPlaceHolder1_ucstockcount1_GridView1_Label2_1")" />
</td><td>
<span id="ContentPlaceHolder1_ucstockcount1_GridView1_Label1_1">0</span>
</td><td>5.00</td><td>
<span id="ContentPlaceHolder1_ucstockcount1_GridView1_Label2_1">0</span>
</td>
</tr>
I use the following code to extract values at client side.
function updatea(grid) {
$('#' + grid + ' tr').each(function (i) {
var style = "";
var lastmon = 0;
var received = 0;
var thismon = 0;
var change = 0;
var price = 0;
var value = 0;
$(this).children('td').each(function (j) {
if (j == 2) {
style = $(this).html();
} else if (j == 3) {
lastmon = $(this).html();
} else if (j == 4) {
received = $(this).html();
} else if (j == 5) {
thismon = $(this).children('input').val().trim();
alert(thismon);
}
// else if (j == 6) {
// change = $(this).children('span').val().trim();
// alert(change);
// }
// alert($(this).html());
});
});
}
Till 4th column I am able to get values as required but when i need to extract the value of a textbox that is inside the 5th column I get error TypeError: $(...).children(...).val(...) is undefined
I have taken the code from Traverse html table using jQuery
please help. Thankx
Two problems, the index starts from 0 so column with index 4 has input element, second the first row does not have input element
function updatea(grid) {
//start processing from row 1
$('#' + grid + ' tr').slice(1).each(function (i) {
var style = "";
var lastmon = 0;
var received = 0;
var thismon = 0;
var change = 0;
var price = 0;
var value = 0;
$(this).children('td').each(function (j) {
if (j == 1) {
style = $(this).html();
} else if (j == 2) {
lastmon = $(this).html();
} else if (j == 3) {
received = $(this).html();
//column 5 has index 4
} else if (j == 4) {
thismon = $(this).children('input').val().trim();
alert(thismon);
}
});
});
}
Demo: Fiddle
The index in each() is zero based, and the fifth TD doesn't have an input, the fourth has:
} else if (j == 4) {
thismon = $(this).children('input').val().trim();
alert(thismon);
}
You can make selections easier this way
$('#' + grid + ' tr').slice(1).each(function (i) {
var style = $('td:eq(1)', this).html();
var lastmon = $('td:eq(2)', this).html();
var received = $('td:eq(3)', this).html();
var thismon = $('td:eq(4) input', this).val();
}
+1 to #arun-p-johny for .slice(1)
Sometimes val() function didn't work for me in some conditions. You may test attr('value') instead of val() or you can change children() to $($(this).find('input')).val().trim() or $(this+'input').val().trim() or $(this).children().val().trim()
So I don't really remember right now but sometimes the returning object is not DOM Object.
Finally you can test $($(this).children('input')).val().trim().
As you can see there are too much moves to find anything. I just focused the main problem, so you need to test these and if any of them don't work, just tell me.
But I think the main problem is returning value is not DOM object. So it tries to reach non object and it gives error.
Currently when you add some values in the 4 textboxes identified by "Special" it outputs in a concatenated string. How would I break that up into a table where I could print it out in a table nicely.
$add.click(function() {
var elem = document.createElement("div");
var dmenu = document.getElementById("days");
var dmenuvalue = dmenu.options[dmenu.selectedIndex].text;
var regex = /^\d+(?:\.\d{0,2})$/;
if (dmenuvalue != "temp" && $name.val().indexOf("%") == -1 && ($origprice.val().indexOf("%") == -1 && regex.test($origprice.val())) && ($specprice.val().indexOf("%") == -1 && regex.test($specprice.val()))) {
var name = dmenuvalue + "%" + $name.val() + "%" + $origprice.val() + "%" + $specprice.val();
$(elem).text(name);
var dailyDeal = [
dmenuvalue,
$name.val(),
$origprice.val(),
$specprice.val()
];
dailyDeals.push(dailyDeal);
for (i = 0; i < 4; i++) {
$('<input type="hidden">').attr({
'name': 'name[' + ctr + '][' + i + ']',
'value': dailyDeal[i]
}).appendTo(elem);
}
$('<a>').attr({
'href': '#'
}).text("X").click(function() {
$(elem).remove();
//ctr--;
return false;
}).appendTo(elem);
$list.append(elem);
ctr++;
document.getElementById("dailydeals").innerHTML = '';
return false;
} else {
document.getElementById("dailydeals").innerHTML = '*Please complete all required fields above.';
return false;
}
});
The code is below:
http://jsfiddle.net/protron/xGhnv/4/
Full solution on JSFiddle:
http://jsfiddle.net/protron/xGhnv/9/
Basically what I did was:
In the HTML I replaced the <div> called list for a new <table>:
<table id="tableDailyDeals"></table>
In the Javascript instead of calling $(elem).text(... I create a new table row (<tr>) in the table just defined:
var $tr = $('<tr>').appendTo('#tableDailyDeals');
Then besides adding the input-hidden for each dailyDeal attribute (for 0 to 3) I also create a table cell (<td>) and inside it a new <span> with the text you already have in your array named dailyDeal (the span is optional, but as I also put the input-hidden in the same td I think is better this way):
var $td = $('<td>').appendTo($tr);
$('<span>').text(dailyDeal[i]).appendTo($td);
Then just add another table cell (<td>) for the row remover link:
var $tdRemoveRow = $('<td>').appendTo($tr);
The rest is just some css styling and minor details.
jqGrid has column named Posted. It can be positioned in different positions depending how grid is configured by customer but is always prssent.
I need to change background color of rows if Posted column has value True
I tried colmodel below but alert(rdata.Posted) displays always undefined.
How to change backgound color of row if Posted column in this row has value true ?
I looked into lot of Oleg and other solutions for changing background color but they are using hard coded column number.
colModel: [
{"cellattr":function(rowId, tv, rawObject, cm, rdata) {
if (rdata.Posted)
return 'class="jqgrid-readonlycolumn"';
return '';
}
,"label":"Klient","name":"Klient_nimi","classes":null,"hidden":false},
{"label":null,"name":"Posted","editable":true,"width":0,
"classes":null,"hidden":true}],
...
Update
In update2 Oleg recommends to use rowattr. I need to hide inlined delete button and custom post button in actions column also. I'm usijng code below in loadComplete. How to implement this using rowattr ?
var LoadCompleteHandler = function () {
var iCol = getColumnIndexByName($grid, 'Kinnitatud'),
postedDateCol = getColumnIndexByName($grid, 'Kinkuup'),
cRows = $grid[0].rows.length,
iRow,
row,
className,
isPosted,
mycell,
mycelldata,
i, count,
cm = $grid.jqGrid('getGridParam', 'colModel'),
l,
iActionsCol = getColumnIndexByName($grid, '_actions');
l = cm.length;
if (iCol > 0 || postedDateCol > 0) {
for (iRow = 0; iRow < cRows; iRow = iRow + 1) {
row = $grid[0].rows[iRow];
className = row.className;
isPosted = false;
if ($.inArray('jqgrow', className.split(' ')) > 0) { // $(row).hasClass('jqgrow')
if (iCol > 0) {
isPosted = $(row.cells[iCol]).find(">div>input:checked").length > 0;
}
if (postedDateCol > 0) {
mycell = row.cells[postedDateCol];
mycelldata = mycell.textContent || mycell.innerText;
isPosted = mycelldata.replace(/^\s+/g, "").replace(/\s+$/g, "") !== "";
}
if (isPosted) {
if ($.inArray('jqgrid-postedrow', className.split(' ')) === -1) {
row.className = className + ' jqgrid-postedrow';
$(row.cells[iActionsCol]).find(">div>div.ui-inline-del").hide();
$(row.cells[iActionsCol]).find(">div>div.ui-inline-post").hide();
}
}
}
}
}
The main ideas to change the background color of the row you will find here and here. I recommend you to read this answer which discussed different advantages and disadvantages of different approaches.
To get column index from the column name you can use following simple function:
var getColumnIndexByName = function(grid, columnName) {
var cm = grid.jqGrid('getGridParam','colModel'),i=0,l=cm.length;
for (; i<l; i++) {
if (cm[i].name===columnName) {
return i; // return the index
}
}
return -1;
};
The function getColumnIndexByName($("#list"), 'MyColumnName') will get you the index in colModel of the 'MyColumnName' column.
To change the background color you can follow the example
loadComplete: function() {
$("tr.jqgrow:odd").addClass('myAltRowClass');
}
from the answer, but instead of ':odd' filter you can write the filter yourself using jQuery.filter. Inside of the filter you can use :nth-child() to access the data from the corresponding <td> element (see here)
UPDATED: You can do the following (very close to the code from the another answer):
loadComplete: function() {
var iCol = getColumnIndexByName($(this),'closed'),
cRows = this.rows.length, iRow, row, className;
for (iRow=0; iRow<cRows; iRow++) {
row = this.rows[iRow];
className = row.className;
if ($.inArray('jqgrow', className.split(' ')) > 0) {
var x = $(row.cells[iCol]).children("input:checked");
if (x.length>0) {
if ($.inArray('myAltRowClass', className.split(' ')) === -1) {
row.className = className + ' myAltRowClass';
}
}
}
}
}
The corresponding demo is here. You will see the following:
By the way if the 'Closed' column will be hidden everything will continue to work as before.
UPDATED 2: The answer describe how to use rowattr callback to simplify the solution and to have the best performance (in case of gridview: true).
I think the answer is right here: http://www.trirand.net/forum/default.aspx?g=posts&m=2678
Let me know if this is wat you need.
Best Regards.
Apolo