How do I pull data from a javascript populated table? - c#

I am trying to pull data from my populated javascript table. How do I pull the value from a javascript row? I am using
for (var i = 0; i < rowCount; i++) {
var row = table.rows[i];
//This is where I am having trouble
var chkboxIndicator = row.cells[0].childNodes[1];
alert(chkboxIndicator);
//
if (chkboxIndicator == indicator && Checkbox.checked == false) {
table.deleteRow(i);
rowCount--;
i--;
}
}
which has an alert message of "undefined". I tried .value and .text as well and no progress. How do I get the text from the childNodes?

Since you're purportedly using jQuery, why not use it to get your checkboxes and simplify your life?
$("#mytableid tr").each(function() {
// find the checkbox (assuming you have only one; if not, use :eq(n))
var $checkbox = $("input:checkbox", this);
// if it's checked, delete this row
if ($checkbox.is(":checked"))
$(this).remove();
});
There are crazier ways to do it, but I thought that example would be illustrative. :)

Are you sure that chkboxIndicator is not null?
If it is null it will alert as undefined.
Try
for (var i = 0; i < rowCount; i++)
{
var row = table.rows[i];
// Add null check for row
if (row != null)
{
//This is where I am having trouble
// Add null check for cell
if (row.cells[0] != null)
{
var chkboxIndicator = row.cells[0].childNodes[1];
// Added null check for chkboxIndicator
if (chkboxIndicator != null)
{
alert(chkboxIndicator);
if (chkboxIndicator == indicator && Checkbox.checked == false)
{
table.deleteRow(i);
rowCount--;
i--;
}
}
else
{
alert('chkboxIndicator is NULL');
}
}
}
}

Depends on what your DOM actually looks like.
I suspect your problem is that childNodes[1] could be a text node.
You probably want to use a selector on the cell instead, such as:
$(row.cells[0]).find("input[type='checkbox']");

If you want it to be fast too, use jOrder (http://github.com/danstocker/jorder).
Create a jOrder table with your data. Make sure to have a field 'checked' in it with true or false values, and put an index on that column and the ID:
var table = jOrder(data)
.index('id', ['ID'])
.index('checked', ['checked'], { grouped: true });
Then, you can rebuild your grid with the unchecked rows removed using table.where([{ 'checked': true }]) as the source.
But first, populate your grid with the data from the jOrder table. Use table.flat() to obtain the flat table.
When you build the grid, bind the record IDs to the checkboxes e.g. by $('#elem').data(). When a checkbox gets (un)checked, update the 'checked' value in the table:
var before = table.where([{ 'ID': 5 }])[0];
var after = table.where([{ 'ID': 5 }])[0];
after.checked = true;
table.update(before, after);
Note that you shouldn't do this for each item on an "(un)check all" event though. In that case just simply pass on table.flat() or set the 'checked' values in the buffer returned by it, and then issue a table.reindex() and THEN call table.where(...).

The block of code that I was missing was the following
var row = table.rows.item(i).cells;
var cellLength = row.length;
var cellVal = row.item(5).innerHTML;
Thanks for leading me in the right direction

Related

clear datagridview duplicate rows and keep unique rows

so when filling my datagridview I normally do something like
public void FillTable(CoBRAMetaField[] metaFields)
{
dataGridView.Rows.Clear();
// do something with metaFields
}
Important:
CoBRAMetaField is a object with a ID and other stuff
Each row in the grid holds a metafield object
My grid gets filled correctly (sorry, the language is german)
When I fill the grid another time I only want to remove the rows with metaFields that don't exist in the new metaFields array. I want this behaviour because when a user selected a value for this row I don't want it to get removed and created again because then the selected value is removed too.
I came up with this
public void FillTable(CoBRAMetaField[] metaFields)
{
for (int i = 0; i < dataGridView.Rows.Count; i++) // loop through the grid rows
{
double metaFieldID = (dataGridView.Rows[i].Cells[0].Tag as CoBRAMetaField).ID; // get the ID from the row metaField
if (metaFields.Any(field => field.ID == metaFieldID)) // Does it exist?
metaFields = metaFields.Where(field => field.ID != metaFieldID).ToArray(); // Remove it from the new array
else // it doesn't exist
dataGridView.Rows.Remove(dataGridView.Rows[i]); // remove the row
}
// Fill the grid with the remaining metaFields
}
The first run gets initialized correctly
the second run seems to crash, some fields remain empty
when I press the button on this row I get a nullpointer exception. I only get this error when using the "new code" so am I missing something? Is there something I didn't think about?
I will provide a full example here
At first create a DataGridView and Button on the form. Create a file for all required classes and take this snippet
https://pastebin.com/BFmr2ps9
After that fill the forms code with some test data
https://pastebin.com/Yz84Akkj
and now setup the DataGridView logic
https://pastebin.com/qH6kZKZv
I added
dataGridView.AllowDrop = false;
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.AllowUserToOrderColumns = false;
dataGridView.AllowUserToResizeRows = false;
if you just want to copy paste but you can also do it by the forms designer. Have a look at dataGridView.Rows.Clear(); this provides a working example. Comment it out and use the code above to test the incorrect example
The main problem is in the code for adding rows (taken from the link):
// Fill the grid with the remaining metaFields
for (int i = 0; i < metaFields.Length; i++)
{
MetaField currentMetaField = metaFields[i];
dataGridView.Rows.Add(currentMetaField.Name, null);
DataGridViewRow newRow = dataGridView.Rows[i]; // <-- Problem!
DataGridViewCell metaFieldCell = newRow.Cells[0];
metaFieldCell.Tag = currentMetaField;
(newRow.Cells[1] as DataGridViewAllocationCell).Initialize(releaseSetupData);
}
In the marked line you are assuming that the index of the added row is the same as i, which is true when you start with empty grid, bit not when the grid is updated and some old records are kept.
The proper way of handling it is to not assume the new row index - it is returned by the Add method:
int rowIndex = dataGridView.Rows.Add(currentMetaField.Name, null);
DataGridViewRow newRow = dataGridView.Rows[rowIndex];
This will solve the original issue from the question.
There is also a problem in the remove part of the code - the for loop will miss checking the rows next to the removed ones. Anytime you want to iterate some list and remove items during the iteration, use reverse for loop and RemoveAt:
for (int i = dataGridView.Rows.Count - 1; i >= 0; i--) // <--
{
double metaFieldID = (dataGridView.Rows[i].Cells[0].Tag as MetaField).ID;
if (metaFields.Any(field => field.ID == metaFieldID))
metaFields = metaFields.Where(field => field.ID != metaFieldID).ToArray();
else
dataGridView.Rows.RemoveAt(i); // <--
}
The removal code could further be improved (currently looks inefficient with these Any, Where + ToArray), but at least with the above changes it will work correctly.

Finding a cell in devexpress datagrid

I'm new to DevExpress GridControl.
I need to find a particular cell in the grid and then do something with it's value.
How do I go about this please?
In the grid's Loaded method, I tried using myGrid.FindRowByValue("ProductType","ABC"), but always gives a negative number.
Thanks.
Here is code you can try
for (int i = 0; i < gridView1.DataRowCount; i++) {
object b = gridView1.GetRowCellValue(i, "FieldName");
if (b != null && b.Equals(<someValue>)){
gridView1.FocusedRowHandle = i;
return;
}
}
you can go to this link for more details.
https://www.devexpress.com/Support/Center/Question/Details/Q132599/get-row-by-cell-value
Unlike XtraGrid, the DXGrid for WPF does not provide the DataRowCount property - that is why we suggested checking the GridControl's ItemsSource. On the other hand, our grid has the VisibleRowCount property, which will be useful in some scenarios.
To accomplish this task, iterate through visible grid rows manually as shown below.
void MoveFocusToLast(GridControl grid, string fieldName, object value) {
for (int i = grid.VisibleRowCount - 1; i >= 0; i--) {
var handle = grid.GetRowHandleByVisibleIndex(i);
var currentValue = grid.GetCellValue(handle, fieldName);
if (currentValue != null && currentValue.Equals(value)) {
grid.View.FocusedRowHandle = handle;
return;
}
}
}
Grid also provides the FindRowByValue method, which allows you to
find a row by a specific cell value. This method returns the handle of
the corresponding row, and you can make that row visible by setting
the FocusedRowHandle property or calling ScrollIntoView. I
have prepared a sample demonstrating this approach.
See Also:
Traversing Rows
Find Row
Get RowHandle from a cell value

How to get IDs of only checked rows of a datagridview

I have a datagridview that contains list of subjects populated from Subject table from database.Columns include
Select(checkbox),
SubjectId,
SubjectName,
SubjectGroup.
Now I want if a user Selects on any of the desired rows, the corresponding SubjectId's should be added to a List. I have made and inserted into the desired table in the database.
The problem is that the new column of checkboxes I have added to this datagridview is not being detected.
My code is:
foreach (DataGridViewRow row in gvSubjectsOpted.Rows)
{
if (Convert.ToBoolean(gvSubjectsOpted.SelectedRows[0].Cells["SelectId"].Value=true))
{
olist.Add(gvSubjectsOpted.SelectedRows[0].Cells["SubjectId"].Value.ToString());
}
}
Late to the party. I had the same issue with trying to get the checkbox column by name, use the index instead. Here is a linq example assuming the checkbox is column 0 and the stored values for TrueValue and FalseVale are true and false respectively.
var checkedRows = from DataGridViewRow r in gvSubjectsOpted.Rows
where Convert.ToBoolean(r.Cells[0].Value) == true
select r;
foreach (var row in checkedRows)
{
olist.Add(row.Cells["SubjectId"].Value.ToString());
}
I realise this is an old post but I came across it and didn't think it was really answered in an efficient way so I thought I would add my method.
I have a similar block in my windows app. I read the values from the grid when the user clicks a button, and I want to know which rows they checked. As the checkboxes are in Cell 0 and the data I want is in Cell 1, I use the following code. Note the cast: it is important as it allows us the use the Where clause and therefore just a single line of code to get the collection of data. I could use the name of the cells instead of magic index numbers but then it would not fit your app so I put numbers instead (you should use names)
var checkedRows = dataGridView
.Rows
.Cast<DataGridViewRow>()
.Where(x => x.Cells[0].Value.ToString() == "1")
.Select(x => x.Cells[1]);
Note that this will give you an IEnumerable of type DataGridViewCell. If you want you can either add something like .Value.ToString() to the select or do this when you use your collection.
You question is similar to another SO question.
Check the answer of this Datagridview checkboxcolumn value and functionality.
Try this
foreach(GridViewRow r in gvSubjectsOpted.Rows)
{
GridViewCheckBoxColumn c = r.cells[0].Controls[0] as GridViewCheckBoxColumn;
if(c.Checked)
{
//Do something.
}
}
private void button1_Click(object sender, EventArgs e)
{
string subjId;
List<string> lines = new List<string>();
for (int i = 0; i < gvSubjectsList.Rows.Count; i++)
{
bool Ischecked =Convert.ToBoolean(gvSubjectsList.Rows[i].Cells["Select"].Value);
if (Ischecked == true)
{
subjId = gvSubjectsList.Rows[i].Cells["SubjectId"].Value.ToString();
lines.Add(subjId);
}
}
comboBox1.DataSource = lines;
}
//the most important thing is to set 'true' and 'false' values against newly added checkboxcolumn instead of '0' and '1'...that is,
CBColumn.FalseValue = "false";
CBColumn.TrueValue = "true";

compare two cells on same row in datagrid

Using C# .NET 4.5, MS visual studio 2012, WPFs.
Hi, just got this code to finally work, it basically iterates through a datgrid via row.
be warned his may offend all the WPF wizards out there!
public IEnumerable<System.Windows.Controls.DataGridRow> GetDataGridRow(System.Windows.Controls.DataGrid grid)
{
var itemsource = grid.ItemsSource as System.Collections.IEnumerable;
paretogrid.UpdateLayout();
if (null == itemsource) yield return null;
foreach (var item in itemsource)
{
var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow; // null?
if (null != row) yield return row;
}
}
private void ShowArrows()
{
var rows = GetDataGridRow(paretogrid); // fetching null?
foreach (DataGridRow r in rows)
{
DataRowView rv = (DataRowView)r.Item;
}
}
So as you can see I iterate through the rows. Now what I want to do is compare a cell value at column index 2 with columns index 4 on every "row", then if true or false update column 5 accordingly. I can iterate through the columns which lets me go cell per cell but isn't what I am after e.g
foreach (DataGridColumn column in paretogrid.Columns)
So is it something like:
paretogrid.Columns[2].GetCellContent(something here) as textblock;
please see the following explanation below it will help clear up why you are seeing what you are seeing
Ok let me make it easier for you to understand TextBox for example if I did:
var myInt = (int)textBox1.text;
for example this would compile because I am implying that I want myInt to store an Int32 value, however :
var myInt = (int)textBox1;
would fail because you can not convert an Object, which is the TextBox to a Value does this make it easier to see where your initial error is an why you were getting it.
This also has nothing to do with WinForms vs WPF if basically something simple that I am sure many of us have done before because we forget to Append .Text to the end of the object when we are wanting to convert the Value that the object holds rather that the object itself
Turns out I over thought this. here's the solution I had,
var test1 = paretogrid.Columns[7].GetCellContent(paretogrid.Items[2]) as TextBlock;
int t1convert = Convert.ToInt32(test1.Text);
var test2 = paretogrid.Columns[8].GetCellContent(paretogrid.Items[2]) as TextBlock;
int t2convert = Convert.ToInt32(test2.Text);
if (t1convert == t2convert)
{
MessageBox.Show("it worked!");
}
Thanks for pointing this out #DJ KRAZE

Remove link text in Datagridview

I have a DataGridView which is populated from a list. I then Have defined a link column in the last column which is not DataBound saying View, how do I remove this link text if a condition is met. I have the below:
dgvReport.AutoGenerateColumns = false;
dgvReport.DataSource = queries;
//locals
Int32 lastColumnIndex = this.dgvReport.Columns.Count - 1;
//hide reads links for the null queries
for (int i=0; i < queries.Count; i++) {
if (queries[i].SomeID == null || queries[i].AnotherID == null) {
this.dgvReport.Rows[i].Cells[lastColumnIndex].Value = "";
}
}
This is not working and my column text still shows View. Any ideas?
Edit: lastColumnIndex is 24 which is indeed the last column index
You might try
View.PlainTextBehaviour = true;
It will remove the link and show it as plain text

Categories

Resources