How to delete row from gridview's RowDataBound event - asp.net

I am trying to delete a row from a gridview (based on a condition) and then add than row to another gridview inside of the "master" gridview's RowDataBound event. Originally I did not know that in order to call .DeleteRow(i) you needed to have an "ondelete" event handler. However, since all the gridview's .DeleteRow method does is call this event handler, I am confused as to how to use it. Can someone please help point me in the right direction?
Protected Sub grdProduct_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles grdProduct.RowDataBound
' Grey out expired products
Dim row As GridViewRow
row = e.Row
Dim incomingDate As String
Dim incomingStatus As String = ""
incomingDate = row.Cells(3).Text.ToString()
incomingStatus = row.Cells(5).Text.ToString()
If (e.Row.RowType <> DataControlRowType.DataRow) Then
Exit Sub
End If
Try
Dim expDate As Date = incomingDate
If (expDate < DateTime.Today Or incomingStatus.Equals("D")) Then
'Create object for RowValues
Dim RowValues As Object() = {"", "", "", "", "", ""}
'Create counter to prevent out of bounds exception
Dim i As Integer = row.Cells.Count
'Fill row values appropriately
For index As Integer = 0 To i - 1
RowValues(index) = row.Cells(index).Text
Next
'create new data row
dProdRow = dProdtable.Rows.Add(RowValues)
dProdtable.AcceptChanges()
grdProduct.DeleteRow(e.Row.RowIndex)
End If
Catch ex As Exception
End Try
End Sub
Protected Sub grdProduct_Delete(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles grdProduct.RowDeleting
'Not sure what to do here
End Sub

The best way to do this is to manipulate this at the datasource level rather than manipulating the UI components themselves.
For example:
if(!IsPostback)
{
DataTable one = ...
DataTable two = ...
var removeRows = (from c in one.AsEnumerable()
where c.Field<DateTime>("incomingDate")< incomingDate ||
c.Field<string>("incomingStatus")=="D"
select c).ToList();
for(var item in removeRows)
{
two.ImportRow(item);
}
//now delete from initial table
foreach(var item in removeRows)
{
one.Rows.Remove(item);
}
//Now bind both grids
grid1.DataSource=one;
grid1.DataBind();
grid2.DataSource=two;
grid2.DataBind();
}
Update - Sample toy program in VB.NET Hopefully you can adapt it to your situation.
Sub Main
Dim one As New DataTable()
one.Columns.Add("one", GetType(Integer))
For i As Integer = 0 To 9
Dim r As DataRow = one.NewRow()
r.ItemArray = New Object() {i}
one.Rows.Add(r)
Next
Dim two As New DataTable()
two.Columns.Add("one", GetType(Integer))
For i As Integer = 0 To 9
Dim r As DataRow = two.NewRow()
r.ItemArray = New Object() {i}
two.Rows.Add(r)
Next
Dim removeRows = (From c In one.AsEnumerable() Where c.Field(Of Integer)("one") = 5).ToList()
For Each item As DataRow In removeRows
two.ImportRow(item)
Next
For Each item As DataRow In removeRows
one.Rows.Remove(item)
Next
End Sub
I just realized that you are using VB.NET. You should be able to translate the above from C# to VB.NET. The general idea is there, anyway.

Related

declare dataview using object

I have a object in previous code and it is bind on datagrid. Now I need to add sort the column. I search the web to convert the dataTable from datasource. But I got an error'DataTable must be set prior to using DataView.'
Does anyone tell me how to do it? Thanks in advance.
there is the code to bind the datagrid:
Dim thisOrder as New co.Orders(123)
dgrdOrders.DataSource=thisOrder
dgrdOrders.DataBind()
there is my code:
Private Sub dgrdOrders_SortCommand(source As Object, e As DataGridSortCommandEventArgs) Handles dgrdOrders.SortCommand
Dim dataTable As DataTable = TryCast(dgrdOrders.DataSource, DataTable)
Dim dv As New DataView(dataTable)
dv.Sort = e.SortExpression
dgrdOrders.DataSource = dv
dgrdOrders.DataBind()
End Sub
Finally I found the way to sort it:
Private Sub dgrdOrders_SortCommand(source As Object, e As DataGridSortCommandEventArgs) Handles dgrdOrders.SortCommand
Dim lstOrders As New List(Of co.Order)
For Each objOrder As co.Order In thisOrder
lstOrders.Add(objOrder)
Next
Select Case e.SortExpression
Case "Type"
lstOrders = lstOrders.OrderBy(Function(x) x.Type).ToList
Case "Region"
lstOrders = lstOrders.OrderBy(Function(x) x.Region).ToList
End Select
dgrdOrders.DataSource = lstOrders
dgrdOrders.DataBind()
End Sub

Add conditional dropdownlist items in ASPX Application (VB)

I have a GridView with a asp:dropdownlist
I am able to add dropdown values using rowdatabound.
However what I need to do, is add specific dropdown list values base on the contents of another cell in that row.
So for example if Row(1) and Cell(2) = MAR001, I want the Dropdown values Four, Five and Six
However if Row(1) and Cell(2) <> MAR001, I want the dropdown values One, Two and Three.
Here is my attempt using a loop, however it doesn't target the dropdown values correctly.
Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
For i As Integer = 0 To GridView1.Rows.Count - 1
Dim Name As String = GridView1.Rows(i).Cells(2).Text
If Name = "MAR001" Then
Dim ddl As DropDownList = e.Row.FindControl("ddlQuantity")
Dim numbers As New List(Of String)()
numbers.Add("Four")
numbers.Add("Five ")
numbers.Add("Six")
ddl.DataSource = numbers
ddl.DataBind()
Else
Dim ddl As DropDownList = e.Row.FindControl("ddlQuantity")
Dim numbers As New List(Of String)()
numbers.Add("One")
numbers.Add("Two")
numbers.Add("Three")
ddl.DataSource = numbers
ddl.DataBind()
End If
Next
Else
End If
End Sub
Any help much appreciated.
Not sure if this is what you need, but try finding the textbox first and get the text value of that.
Edit: i just realized you're looping the rows. you don't have to do that - this is the RowDataBound event, so this code happens for every row.
If e.Row.RowType = DataControlRowType.DataRow Then
Dim ddl As DropDownList = e.Row.FindControl("ddlQuantity")
Dim numbers As New List(Of String)()
Dim customerid As String = (e.Row.Cells(2).Text)
If customerid = "MAR001" Then
numbers.Add("Four")
numbers.Add("Five ")
numbers.Add("Six")
Else
numbers.Add("One")
numbers.Add("Two")
numbers.Add("Three")
End If
ddl.DataSource = numbers
ddl.DataBind()
End If

add new row in gridview

UPDATE
from this i bind gridview
Public Function uplif() As DataTable
Dim dt As New DataTable()
gridvieew1.Visible = True
Try
dt.Columns.AddRange(New DataColumn(1) {New DataColumn("ID", GetType(Integer)),
New DataColumn("Name", GetType(String))}
Dim Content As String = Request.Form(textbox1.UniqueID)
For Each row As String In Content .Split(ControlChars.Lf)
If Not String.IsNullOrEmpty(row) Then
dt.Rows.Add()
Dim i As Integer = 0
For Each cell As String In row.Split(ControlChars.Tab)
If i > 1 Then
labelmessage.Text = "More than 2 columns not Allowed !!"
textbox1.Text = ""
Else
If cell.Trim() = "" Then
cell = "0"
End If
dt.Rows(dt.Rows.Count - 1)(i) = cell
i += 1
End If
Next
End If
Next
gridvieew1.DataSource = dt
gridvieew1.DataBind()
Catch Ex As Exception
labelmessage.CssClass = "alertNo"
labelmessage.Text = Ex.Message
End Try
Return dt
End Function
Protected Sub PasteToGridView(sender As Object, e As EventArgs)
uplif()
End Sub
now when i try to add new row like this
Private Sub AddNewRowToGrid()
Dim dt As DataTable = uplif()
Dim NewRow As DataRow = dt.NewRow()
dt.Rows.Add(NewRow)
gridvieew1.DataSource = dt
gridvieew1.DataBind()
End Sub
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
AddNewRowToGrid()
End Sub
this shows same output like add new row and replace previous data which is already in gridview and also this shows an error
Object reference not set to an instance of an object.
after click on add new row
ID Name
where as i want like this
ID Name
1 abc
2 def
(here new empty row when click on button )
As was pointed out in a comment to your post, the problem is in these two lines:
Dim dt As New DataTable()
...
gridview1.DataSource = dt
That creates a brand new DataTable and binds the grid view to it. You don't copy data over, and you don't alter the existing gridview's table.
The correct fix here would be to get the DataTable from the gridview's DataSource and make any changes you need to to that. Don't create a new DataTable.
Get the already assigned DataSource and then add the Row. Do not add columns as it will be already present in your datasource
Private Sub AddNewRowToGrid()
Dim dt As gridview1.DataSource
Dim NewRow As DataRow = dt.NewRow()
dt.Rows.Add(NewRow)
gridview1.DataSource = dt
gridview1.DataBind()
End Sub
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
AddNewRowToGrid()
End Sub

My dynamically created ImageButtons won't fire up the click event

I need to create a table whose first column is an image button that deletes the whole row when clicked (actually it deletes a database row then reloads the HTML table).
The table and the buttons display as expected, but when I click a button, nothing happens.
To make each button clickable, I used AddHandler.
deletion is the sub that handles the clicks, it will get the button's ID (which contains the database table id for the row the user wants to delete) then calls a stored procedure with the ID as parameter and finally reloads the HTML table. I didn't implement it yet but the debugger can't reach it.
The VB code is as follows
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Request.Cookies("myuser") Is Nothing OrElse Request.Cookies("myuser")("isconnected") <> "1" Then
Response.Redirect("/Default.aspx")
Else
N_User = CInt(Request.Cookies("myuser")("N_User"))
Dim dbc As DBConnection
dbc = New DBConnection("192.168.1.45", "CorpDB", "someuser", "xxxxxxx")
Dim dt As DataTable
Try
dt = dbc.getQueryData("select lastname, isnull(firstname,'') from itc where N_User=" & CStr(N_User))
If dt.Rows.Count > 0 Then
End If
Catch ex As Exception
' do nothing for now
End Try
End If
FillTable()
End Sub
Protected Sub deletion(sender As Object, e As ImageClickEventArgs)
' confirm deletion
' Run a stored procedure to delete the comment row
FillTable()
End Sub
Private Sub FillTable()
Dim dbc As DBConnection
Dim dt As DataTable
Dim tr As TableRow
Dim tc As TableCell
Dim ibutton As ImageButton
Dim sqlquery As String
If PickProject.SelectedValue = "" Then
Exit Sub
End If
sqlquery = "select N_follow, Name=isnull(isnull(lastname + ' ','') + Nom, 'Anon'), Date=convert(varchar,DFollow,103), Stage=isnull(FreeField1,''), [Text]=isnull(dbo.RTFtoText(txt),'') from AF_FOLLOW a left outer join USERS u on u.N_User = a.N_User_Create where Numero=" & PickProject.SelectedValue & "order by DFollow desc"
dbc = New DBConnection("192.168.1.45", "CorpDB", "someuser", "xxxxxxx")
Try
dt = dbc.getQueryData(sqlquery)
Catch ex As Exception
' Show something,
Exit Sub
End Try
If dt.Rows.Count > 0 Then
CommentTable.Rows.Clear()
For Each row As DataRow In dt.Rows
' Create a new row
tr = New TableRow
' column #1 : delete button
tc = New TableCell
tc.CssClass = "SelectDel"
ibutton = New ImageButton()
ibutton.ID = "ibutton_" & row.Item("N_follow")
ibutton.ImageUrl = "img/remove_icon.png"
AddHandler ibutton.Click, AddressOf deletion
tc.Controls.Add(ibutton)
tr.Cells.Add(tc)
' Column #2 : Date
tc = New TableCell
tc.Text = row.Item("Date")
tr.Cells.Add(tc)
' Column #3 : Stage
tc = New TableCell
tc.Text = row.Item("Stage")
tr.Cells.Add(tc)
' Column #4 : name
tc = New TableCell
tc.Text = row.Item("Name")
tr.Cells.Add(tc)
' Column #5 : Comment
tc = New TableCell
tc.Text = row.Item("Text")
tr.Cells.Add(tc)
' Add the created row to the table
CommentTable.Rows.Add(tr)
Next
CommentTable.Visible = True
Else
End If
End Sub
For some reason, it's Page_Load that gets triggered when I click a button. But I got the same behavior with a DropDownList, first Page_Load gets fired up, then PickProject_SelectedIndexChanged and the event handler works as intended.
I googled and searched StackOverflow a lot , but none of the solutions suggested seems to work.
What did I miss ?

ASP.net/jQuery: JSTree, selecting Node, can't seem to get ID

Currently, I'm using an AJAX Handler to populate the JSTree:
$(function () {
$("#jstree").jstree({
"json_data": {
"ajax": {
"url": "AJAXHandler.aspx?action=GetMenu"
}
},
"plugins": ["themes", "json_data", "dnd"]
})
.bind("move_node.jstree", function (node, ref, position, is_copy, is_prepared, skip_check) {
console.log(node); });
});
The handler actually makes a database call, loops through the menu items, creates a JSON object that is serialized, sent back, and rendered:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Select Case Request("action")
Case "GetMenu"
GetMasterMenu()
Case "UpdateMenuHiearchy"
UpdateMenuHiearchy()
End Select
End Sub
Private Sub GetMasterMenu()
Dim dt As DataTable = GetMenu()
Dim nodesList As New List(Of JsTreeNode)()
PopulateNodes(dt, nodesList)
Dim ser As New JavaScriptSerializer()
Dim res As String = ser.Serialize(nodesList)
Response.ContentType = "application/json"
Response.Write(res)
Response.[End]()
End Sub
Private Sub PopulateNodes(ByRef dt As DataTable, ByVal nodes As List(Of JsTreeNode))
Dim parents() As DataRow = dt.Select("PARENT_MENU_ID = 0")
'Root Nodes
For Each dr As DataRow In parents
Dim node As New JsTreeNode()
node.attributes = New Attributes()
node.attributes.id = dr("APPLICATION_MENU_ID").ToString
node.attributes.rel = "root" & dr("APPLICATION_MENU_ID").ToString
node.data = New Data()
node.data.title = dr("DESCRIPTION")
node.state = "open"
'Check for Children
Dim strSQL As New StringBuilder
With strSQL
.Append(" SELECT * FROM APPLICATION_MENU WHERE PARENT_MENU_ID = " & dr("APPLICATION_MENU_ID") & "")
End With
Dim dtChildren As DataTable = DatabaseManager.Query(strSQL.ToString)
If dtChildren.Rows.Count > 0 And dtChildren IsNot Nothing Then
For Each drChild As DataRow In dtChildren.Rows
AddChildNodes(dt, dr("APPLICATION_MENU_ID"), node)
Next
End If
node.attributes.mdata = "{draggable : true}"
nodes.Add(node)
Next
End Sub
Private Sub AddChildNodes(ByRef dt As DataTable, ByVal parentID As Integer, ByVal node As JsTreeNode)
Dim strSQL As New StringBuilder
With strSQL
.Append(" SELECT * FROM APPLICATION_MENU WHERE PARENT_MENU_ID = " & parentID.ToString & "")
End With
Dim dtChildren As DataTable = DatabaseManager.Query(strSQL.ToString)
node.children = New List(Of JsTreeNode)()
For Each drChild As DataRow In dtChildren.Rows
Dim cnode As New JsTreeNode()
cnode.attributes = New Attributes()
cnode.attributes.id = drChild("APPLICATION_MENU_ID").ToString
node.attributes.rel = "folder"
cnode.data = New Data()
cnode.data.title = drChild("DESCRIPTION")
cnode.attributes.mdata = "{draggable : true }"
strSQL = New StringBuilder
With strSQL
.Append(" SELECT * FROM APPLICATION_MENU WHERE PARENT_MENU_ID = " & drChild("APPLICATION_MENU_ID") & "")
End With
Dim dtChildren2 As DataTable = DatabaseManager.Query(strSQL.ToString)
If dtChildren.Rows.Count > 0 And dtChildren IsNot Nothing Then
AddChildNodes(dt, drChild("APPLICATION_MENU_ID"), cnode)
End If
node.children.Add(cnode)
Next
End Sub
The idea here is to bind the move_node to a function that will hit the handler and update the database as to where I moved the object. I've been able to create the bind to do that. The problem, however, is that I can't seem to obtain the ID. I'm setting it in the attributes in the population of the JSON object, but when I do a watch on the NODE and REF objects via console.log, the id field is empty.
What gives? Any ideas? Am I missing something vital?
After fiddling with it once again, I found the answer:
cnode.attributes
node.attributes
It must be name specific underneath, these must be cnode.attr and node.attr to work.
You are indeed correct-
JSTree V1+ uses the jquery bindings,etc.. Therefore you need to use the attr to obtain the objects attributes - also on a side note, IE7- are case sensitive with the node data, eg:
$("#node").attr("id")!=$("#node").attr("ID")

Resources