OnClick function on dynamic LinkButton? - asp.net

I'm creating dynamic LinkButton where I assign to it dynamically an ID now I would be able to write an onClick function where I get that ID but after trying to make something like that I had no result:
table.Append("<td><asp:LinkButton runat=""server"" class=""edit btn btn-sm btn-default"" ID=" & reader.GetString("id") & " OnClient=""Delete_User""><i class=""fa fa-trash-o"" aria-hidden=""true""></asp:LinkButton></i></a>")
While here is VB.NET code
Sub Delete_User(sender As Object, e As EventArgs)
Dim clickedBtn As LinkButton = CType(sender, LinkButton)
MsgBox(clickedBtn.ID)
End Sub

The LinkButton is a server control and you cannot render it with same way as you render plain HTML tags from code-behind, it will not work as expected. You need to provide HtmlTableCell instance and bind LinkButton control from there, assumed table is defined as HtmlTable:
' this is just a sample event
Protected Sub SomeEventHandler(sender As Object, e As EventArgs)
Dim table As HtmlTable = New HtmlTable()
Dim row As HtmlTableRow = New HtmlTableRow()
' set the data reader from database here
Dim cell As HtmlTableCell = New HtmlTableCell()
Dim linkbtn As LinkButton = New LinkButton()
linkbtn.ID = reader.GetString("id") ' setting control ID
linkbtn.Text = "Delete User" ' setting link text
linkbtn.CssClass = "edit btn btn-sm btn-default"
AddHandler lnkbutton.Click, AddressOf Delete_User ' assign event handler
' add the control to table cell ('td' element)
cell.Controls.Add(linkbtn)
row.Cells.Add(cell)
table.Rows.Add(row)
' other stuff
End Sub
Note that you should provide server-side click event with Click property which associated with OnClick event, not OnClient nor OnClientClick.
Additional note:
MsgBox cannot be used in ASP.NET because it belongs to WinForms, you need to provide JS alert() function to show message box with RegisterStartupScript or RegisterClientScriptBlock:
Sub Delete_User(sender As Object, e As EventArgs)
Dim clickedBtn As LinkButton = CType(sender, LinkButton)
Dim message As String = "alert('" & clickedBtn.ID & "');"
Page.ClientScript.RegisterClientScriptBlock(Me.[GetType](), "MsgBox", message, True)
End Sub
Related issues:
How to add linkbutton control to table cell dynamically
Creating a link button programmatically
How to add dynamically created buttons to a dynamically created table?

Related

Add click event to dynamic button inside calendar

I have a calendar control in my website (vb.net in asp.net)(the standard calendar control but I manipulated it and now it looks like outlook calendar)
The events are added to the calendar as dynamic buttons, and each button has uniqe ID which is the same even after postback.
This is my code to generate the button and add it to the appropiate cell in calendar:
Protected Sub Calendar1_DayRender(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DayRenderEventArgs) Handles Calendar1.DayRender
Dim nextDate As DateTime
If Not dsHearings Is Nothing Then
For Each dr As DataRow In dsHearings.Tables(0).Rows
nextDate = CType(dr(6), DateTime)
If nextDate = e.Day.Date Then
e.Cell.BackColor = System.Drawing.Color.LightGoldenrodYellow
Dim btn As New Button
btn.Text = Left(dr(7).ToString, 5) & "-" & "جلسة في ملف" & dr(1) & " " & dr(2) & " (" & dr(8) & ")"
btn.CssClass = "CalendarHearingEvent"
btn.BackColor = Drawing.Color.Red
btn.ToolTip = "جلسة في ملف" & dr(1) & " " & dr(2) & " (" & dr(8) & ")"
btn.ID = "btnHearings" & dr(9).ToString
btn.UseSubmitBehavior = True
AddHandler btn.Click, AddressOf Me.HearingButton_Click
Dim lbl As New Label
lbl.Text = "<br>"
e.Cell.Controls.Add(lbl)
e.Cell.Controls.Add(btn)
End If
Next
End If
And this is the Handling sub:
Private Sub HearingButton_Click(sender As Object, e As EventArgs)
End Sub
Everything is perfect, but the click event not firing
Please Help
I used LinkButton, and have set href property of link button to
lnkButton.Attributes("href") = e.SelectUrl
Code
lnkButton = New LinkButton()
lnkButton.CommandArgument = objScheduleDetail.SelectedDate
lnkButton.Text = <Write your text here>
lnkButton.ID = "lnkView" ' you can make it unique as well
lnkButton.Attributes("href") = e.SelectUrl
e.Cell.Controls.Add(lnkButton)
Now when this link button is clicked Calendar.SelectionChanged event is fired. and I use Calendar1.SelectedDate to get the date of the clicked button.
Protected Sub Calendar1_SelectionChanged(sender As Object, e As System.EventArgs) Handles Calendar1.SelectionChanged
Calendar1.SelectedDate ' date which is clicked.
End Sub
Thanks danish for your answer, but I need also to pass arguments. so I used your answer with extra code to meet the needs of my app.
The problem is that when a dynamic button inside calendar is clicked, it posts back the calendar event and not the button click event, so the app is not catching the button.
To bypass that, In my code behind I generated a linkbutton like this:
Dim btn As New LinkButton
btn.Text = "Text On LinkButton"
btn.CssClass = "CalendarEvent"
btn.ToolTip = "What ever"
btn.ID = "LinkButton1"
Dim str As String = "return EventonMyClientClick(" + dr(0).ToString + ");"
btn.OnClientClick = str
e.Cell.Controls.Add(btn)
This will generate a linkbutton inside calendar cell with OnClientClick pointing to a javascript function in HTML Code which goes like this:
<asp:LinkButton ID="LinkButton1" style="display:none;" runat="server" onclick="LinkButton1_Click">LinkButton</asp:LinkButton>
<asp:HiddenField ID="hdEventSentId" runat="server" />
<script>
function EventonMyClientClick(val) {
document.getElementById('<%=hdEventSentId.ClientID%>').value = val;
var btn = document.getElementById('<%=LinkButton1.ClientID%>');
btn.click();
}
</script>
As you see, The dynamic linkbutton passes my argument (dr(0).ToString) to eventonmyclientclick function. the function gets the argument, saves it in the hiddenfield and then perform a click event for the linkbutton1 linkbutton.
the page posts back and catches the linkbutton1 click event, which calls the code behind handler of the linkbutton that handles the argument saved in the hiddenfield:
Protected Sub LinkButton1_Click(sender As Object, e As EventArgs)
Try
Dim EventId As String = hdEventSentId.Value
....
Catch ex As Exception
End Try
End Sub
I hope this will help others seeking for a solution for the same problem.

Responding to dynamically created async postback buttons

When my ASP page is loaded I am reading data from a SQL database into a list of objects, then looping through this list and creating dynamic placeholders, updatepanels, textboxs and buttons which are then added to a main placeholder. Each updatepanel is set to conditional and the unique button is added to the scriptmanager. I tried to create async triggers dynamically but found this is not possible. Below is my code:
Dim plcComments As New PlaceHolder()
plcComments.ID = "plcComments" + Link.ID.ToString()
Dim updComments As New UpdatePanel()
updComments.ID = "updComments" + Link.ID.ToString()
updComments.UpdateMode = UpdatePanelUpdateMode.Conditional
Dim txtComment As New TextBox()
txtComment.ID = "txtComment" + Link.ID.ToString()
txtComment.Text = "txtComment " + Link.ID.ToString() 'Example text
updComments.ContentTemplateContainer.Controls.Add(txtComment)
Dim btnComment As New Button()
btnComment.ID = "btnComment" + Link.ID.ToString()
btnComment.Text = "btnComment" + Link.ID.ToString()
updComments.ContentTemplateContainer.Controls.Add(btnComment)
ScriptManager1.RegisterAsyncPostBackControl(btnComment)
plcComments.Controls.Add(updComments)
In a normal circumstance I understand you would have code behind for each button that acts a trigger. As these buttons are created dynamically with unique names, how can I react to each button when it is pressed?
After looking into the AddHandler function I came up with this dirty method:
AddHandler btnComment.Click, AddressOf Me.Button_Handler
This latches to each button as it is created, points back at the same sub routine, and creates the controls within the subroutine based upon the sender.
Protected Sub Button_Handler(sender As Object, e As EventArgs)
Dim Comment_ID As String = DirectCast(sender, Button).ID.ToString.Remove(0, 3)
Dim txtComment As TextBox = Me.FindControl("txt" & Comment_ID)
Dim plcComment As PlaceHolder = Me.FindControl("plc" & Comment_ID)
Dim updComment As UpdatePanel = Me.FindControl("upd" & Comment_ID)
End Sub
Probably not the cleanest or best way to do it but it works.

Make reference to a Button in a repeater?

I have a form with a button control in a repeater, and I am trying to reference it in my code so that I can disable and enable it where appropriate but it isn't recognized.
I tried something that looked like this:
Sub btnClickPrev(ByVal sender As Object, ByVal e As EventArgs)
'Get the reference of the clicked button.
Dim button As Button = CType(sender, Button)
'Get the command argument
Dim commandArgument As String = button.CommandArgument
'Get the Repeater Item reference
Dim item As RepeaterItem = CType(button.NamingContainer, RepeaterItem)
'Get the repeater item index
Dim index As Integer = item.ItemIndex
item.Enabled = false
End Sub
But item.enabled didn't work like btnPrev.enabled=false would
And this is what I have in my button form control:
asp:Button ID="btnPrev" Text="Previous" OnClick="btnClickPrev" CommandArgument = '1' runat="server"
Any help would be appreciated. thank you
Problem is, RepeaterItem doesn't have any Enable property that you are trying to change. Instead, loop through all controls inside RepeaterItem and disable them like this:
Sub btnClickPrev(ByVal sender As Object, ByVal e As EventArgs)
'Get the reference of the clicked button.
Dim button As Button = CType(sender, Button)
'Get the Repeater Item reference
Dim item As RepeaterItem = CType(button.NamingContainer, RepeaterItem)
For Each con In item.Controls
'Disable button
If TypeOf con Is Button Then
CType(con, Button).Enabled = False
End If
'Disable other controls if you want
If TypeOf con Is CheckBox Then
CType(con, CheckBox).Enabled = False
End If
Next
'item.Enabled = False 'Wouldn't work
End Sub

ASP.NET 2.0 dynamically add OnSelectedIndexChanged

I have a DropDownList() that is rendered in my codebehind and populated by myView
Dim ddl As New DropDownList()
ddl.ID = "ddlV_" & dtrw("col_id") & "_" & fixDisplayName(dtrw("display_name"))
ddl.DataSource = myView
ddl.DataTextField = "DDLTEXT"
ddl.DataValueField = "DDLVALUE"
ddl.AutoPostBack="true"
ddl.DataBind()
I would like to add OnSelectedIndexChanged ="do_this_when_changed" attribute to the above dropdown list.
I do understand that Web server controls are also created on the server and they require a runat="server" attribute to work.
Can this be done for this list control?
You can add an event handler programmatically with AddHandler:
Dim ddl As New DropDownList()
' ... '
AddHandler ddl.SelectedIndexChanged, AddressOf do_this_when_changed
In this class:
Private Sub do_this_when_changed(sender As Object, e As EventArgs)
Dim ddl = DirectCast(sender, DropDownList) ' here it is'
End Sub
You can do it using this event...
ddl.SelectedIndexChanged

Gridview - Cannot get updated cell value for RowUpdating

I am using ItemTemplate & EditTemplate for editing the gridview. (ASP.net + VB).
I click EDIT button then I can check/uncheck those checkbox and amend the textbox value.
When click UPDATE button, it will fire the RowUpdating Event, But I found that when I get the value for update statement, it still get the value before editing, not updated value.
How can I get the latest & updated value ? Thanks.
Joe
The following is the VB code:
Protected Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e As GridViewUpdateEventArgs)
'Update the values.
Dim row = Gridview1.Rows(e.RowIndex)
Dim Col1_SL = CType(Gridview1.Rows(e.RowIndex).FindControl("cb1_SL"), CheckBox)
Dim Col1_VL = CType(Gridview1.Rows(e.RowIndex).FindControl("cb1_VL"), CheckBox)
Dim Col1_ML = CType(Gridview1.Rows(e.RowIndex).FindControl("cb1_ML"), CheckBox)
Dim Col1_PH = CType(Gridview1.Rows(e.RowIndex).FindControl("cb1_PH"), CheckBox)
Dim Col1_APH = CType(Gridview1.Rows(e.RowIndex).FindControl("cb1_APH"), CheckBox)
Dim Col1_TOIL = CType(Gridview1.Rows(e.RowIndex).FindControl("cb1_TOIL"), CheckBox)
Dim Col1_Others = CType(Gridview1.Rows(e.RowIndex).FindControl("tb1_Others"), TextBox)
Dim Col1_RosterKey = CType(Gridview1.Rows(e.RowIndex).FindControl("lb1_rosterkey"), Label)
Using conn As New System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings("hris_shiftdutyConnectionString").ConnectionString)
conn.Open()
cmd.Connection = conn
sql = "SET DATEFORMAT dmy;UPDATE troster SET SL='" & Convert.ToInt32(Col1_SL.Checked) & "' where roster_key='" & Col1_RosterKey.Text & "';"
cmd.CommandText = Sql
reader = cmd.ExecuteReader()
conn.Close()
reader.Close()
End Using
'Reset the edit index.
Gridview1.EditIndex = -1
'Bind data to the GridView control.
BindData()
End Sub
The most likely reason will be this.
You are calling BindData() on Page_Load without using !IsPostBack
Protected Sub Page_Load Handles Me.Load
If Not IsPostBack
' Bind Grid only at the first load
' Do not load Grid again at Postbacks
BindData()
End If
End Sub
You have 2 options:
There is a separate RowUpdated method that is fired after updates have been performed by the data source that is bound to the grid view. This method will contain the new values for edits and inserts.
The RowUpdating method should have a parameter of type GridViewEventArgs. This will have a property called NewValues that contains the new values. In your example this was the variable e.

Resources