I need help in VB (no C# or Javascript, please -- I'm clueless with those languages)
I have also checked all the "questions that may already have your answer -- and those that were in VB didn't match my situation or were resolved by using AutoPostback,coding a textChanged event, or adding ontextchanged= to the textbox field --- I have all of these in my code already.
I can't seem to get the TextChanged event to fire despite setting the AutoPostBack to true.
Even after creating at submit button it still won't fire, what have I left out?
What I'm trying to accomplish:
I want the Finish Date to set to a date 30 days after the Start Date if and only if the user edits a start date.
Otherwise just display in the Finish Date whatever would have originally displayed there.
Both dates are allowed to be null in the database and both are defined as datetime.
In Default.aspx
<asp:FormView ID="FormView1" runat="server" DataKeyNames="MASTERID_Action"
DataSourceID="srcAction">
<EditItemTemplate>
MASTERID_Action:
<asp:Label ID="MASTERID_ActionLabel1" runat="server"
Text='<%# Eval("MASTERID_Action") %>' />
<br />
Action_StartDate:
<asp:TextBox ID="Action_StartDateTextBox" runat="server"
Text='<%# Bind("Action_StartDate") %>'
ontextchanged="Action_StartDateTextBox_TextChanged" AutoPostBack="True" /> <rjs:PopCalendar ID="StartDateCal" runat="server" Control="Action_STartDateTextBox" />
<br />
Action_FinishDate:
<asp:TextBox ID="Action_FinishDateTextBox" runat="server"
Text='<%# Eval("Action_FinishDate") %>' />
<br />
<asp:Button ID="SubmitButton1" runat="server" Text="Refresh"
onclick="SubmitButton1_Click" />
<asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True"
CommandName="Update" Text="Update" />
<asp:LinkButton ID="UpdateCancelButton" runat="server"
CausesValidation="False" CommandName="Cancel" Text="Cancel" />
</EditItemTemplate>
In Default.aspx.vb
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Action_StartDateTextBox_TextChanged(sender As Object, e As System.EventArgs)
Dim txtStartDate As TextBox = Me.FormView1.FindControl("Action_StartDateTextBox")
Dim txtFinishDate As TextBox = Me.FormView1.FindControl("Action_finishdatetextbox")
Dim strNewFinishDate As String
If txtFinishDate.Text = "" And txtStartDate.Text <> "" Then
strNewFinishDate = Convert.ToString(Convert.ToDateTime(txtStartDate).AddDays(30))
ElseIf txtFinishDate.Text <> "" Then
strNewFinishDate = txtFinishDate.Text
Else
strNewFinishDate = ""
End If
txtFinishDate.Text = strNewFinishDate
End Sub
Protected Sub SubmitButton1_Click(sender As Object, e As System.EventArgs)
Dim mytest As String
End Sub
End Class
16/01/2013 edit: had a typo in Protected Sub Action_StartDateTextBox_TextChanged ran the page but it still doesn't fire. Still need help with this, please.
17/01/2013 edit: My question is still unanswered, the response I did receive caused more errors. Please help.
I think you might have been deleted your controls after writing its corresponding events.If so, as a result it will remove all the handlers that you had specified with the events.
'---This is your code, by the way it seems to be missing its handler
... Action_StartDateTextBox_TextChanged(sender As Object, e As System.EventArgs)
try to add its handler like this,
'---Adding hanler
... Action_StartDateTextBox_TextChanged(sender As Object, e As System.EventArgs) Handles Action_StartDateTextBox.TextChanged
If you need more details regarding Event Handler, Just refer this.
No response on this, but I have to keep moving. So, I have chosen what is probably the smarter route -- to take care of my postbacks as client-side javascript. I would have accepted an answer of "asp.net can't do this. Javascript would make your life so much easier" for this issue....
Related
Please note: I do not necessarily need working code. I just don't know how to word what I am looking for to even find an answer on the web. I guess i'm just asking for a little guidance on what kind of control I would to use to accomplish my goal.
Basically when I go to a job site I will use different amounts and types of inventory. So one line item would consist of
Item Description
Quantity Used
UsedByTech
I'm collecting these via webform text box. I would like to have a button that says "Add" and then allows me to input another line item, and so on.
Then at some point a submit button on the form would gather those line items and input them in to a MSSQL databse.
I'm currently using ASP.Net framwork and webforms.
Can somone please tell me what kind of control would allow this a may be give me some hints about what to search for?
Ok, this is actually quite easy - but we let asp.net do most of the work for us.
So, we assume we have these two tables:
so, we have a table to list out the Job Sites
And then as per above, we have a table to list out the Job items for each site.
Ok, so we display the Job Sites.
Drop in a Gridview - build it using the wizards:
Now, blow out (delete) the data source from the page - don't need it.
Remove the DataSource setting for the Gridview
And lets drop in a plane jane button into that grid.
Thus, this markup - most of it was generated for me
<div style="padding:25px">
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table" Width="40%">
<Columns>
<asp:BoundField DataField="JobSite" HeaderText="JobSite" />
<asp:BoundField DataField="JobDate" HeaderText="JobDate" DataFormatString="{0:yyyy-MM-dd}" />
<asp:BoundField DataField="Foreman" HeaderText="Foreman" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="View">
<ItemTemplate>
<asp:Button ID="cmdView" runat="server" Text="View Job" CssClass="btn"
Onclick="cmdView_Click"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
And our code to load this grid is thus this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid
End If
End Sub
Sub LoadGrid()
GridView1.DataSource = MyRst("SELECT * from JobSites Order by JobDate")
GridView1.DataBind()
End Sub
Ok, we now have this:
Ok, so now we need to wire up that "view" button.
So, we grab the PK row value - jump to our edit items page;
Protected Sub cmdView_Click(sender As Object, e As EventArgs)
Dim btn As Button = sender
Dim gRow As GridViewRow = btn.Parent.Parent
' get PK database ID
Dim PK As Integer = GridView1.DataKeys(gRow.RowIndex).Item("ID")
' Now jump to our job add job items page
Session("JobID") = PK
Response.Redirect("JobAddItems.aspx")
End Sub
So, now we need to build our 2nd page.
I could use a repeater - but I used DataList - to display the ONE job.
I again used the wizards - then blow out the DataSource setting and item on that page.
We then drop in a gridview for the "many" items (the job items).
I now have this:
<br />
<div style="border:solid;border-color:black;width:20%">
<asp:DataList ID="DataList1" runat="server" DataKeyField="ID">
<ItemTemplate>
JobSite:
<asp:Label ID="JobSiteLabel" runat="server" Text='<%# Eval("JobSite") %>' Font-Size="Larger" Font-Bold="true" />
<br />
JobDate:
<asp:Label ID="JobDateLabel" runat="server" Text='<%# Eval("JobDate", "{0:yyyy-MM-dddd}") %>' />
<br />
Foreman:
<asp:Label ID="ForemanLabel" runat="server" Text='<%# Eval("Foreman") %>' />
<br />
Description:
<asp:Label ID="DescriptionLabel" runat="server" Text='<%# Eval("Description") %>' />
<br />
<br />
</ItemTemplate>
</asp:DataList>
<br />
</div>
<br />
<div style="float:left">
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table borderhide" Width="30%">
<Columns>
<asp:TemplateField HeaderText="Description">
<ItemTemplate>
<asp:TextBox id="txtDesc" runat="server" Text='<%# Eval("ItemDescription") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Qty">
<ItemTemplate>
<asp:TextBox id="txtQty" runat="server" Text='<%# Eval("Qty") %>' TextMode="Number" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Used By">
<ItemTemplate>
<asp:TextBox id="txtUsedBy" runat="server" Text='<%# Eval("UsedBy") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<div style="float:right">
<asp:Button ID="cmdAdd" runat="server" Text="Add Item" CssClass="btn" style="margin-top:-20px" />
</div>
</div>
<div style="clear:both"></div>
<asp:Button ID="cmdSave" runat="server" Text="Save" CssClass="btn" />
<asp:Button ID="cmdCancel" runat="server" Text="Cancel" CssClass="btn" style="margin-left:40px"/>
</div>
Ok, and the code to load this up is this:
We load up the main record - just for display, and then the GridView of child items.
Dim rstJobItems As New DataTable
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
ViewState("JobID") = Session("JobId")
LoadData()
Else
rstJobItems = ViewState("JobItems")
End If
End Sub
Sub LoadData()
DataList1.DataSource = MyRst("SELECT * from JobSites WHERE ID = " & ViewState("JobID"))
DataList1.DataBind()
rstJobItems = MyRst("SELECT * FROM JobItems where Job_ID = " & ViewState("JobID"))
GridView1.DataSource = rstJobItems
GridView1.DataBind()
ViewState("JobItems") = rstJobItems
End Sub
Ok, so now on the first page, when we click on a row, we jump to the 2nd page, and we see/have this:
So we need to wire up the button to add a new row.
That code looks like this:
Protected Sub cmdAdd_Click(sender As Object, e As EventArgs) Handles cmdAdd.Click
' user might have done some edits
GridToTable()
' create a new row
Dim NewRow As DataRow = rstJobItems.NewRow
NewRow("Job_id") = ViewState("JobID")
NewRow("Qty") = 0
rstJobItems.Rows.Add(NewRow)
GridView1.DataSource = rstJobItems
GridView1.DataBind()
End Sub
So, say in above, I click the add row, then you will see this:
(in fact I clicked it two times).
Ok, so you are free to tab around - edit data in that grid. You can edit/change existing rows, or add a new row and simple tab around and enter data.
So, now lets wire up the Save button. That save button has to allow and deal with editing rows - and also saving edits - all in ONE shot to the database.
The code for save button is thus this:
Protected Sub cmdSave_Click(sender As Object, e As EventArgs) Handles cmdSave.Click
GridToTable()
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand("SELECT * FROM JobItems WHERE ID = 0", conn)
Dim da As New SqlDataAdapter(cmdSQL)
Dim daU As New SqlCommandBuilder(da)
da.Update(rstJobItems)
End Using
End Using
' data add, and any edit now saved - return to our job site listing page
Response.Redirect("JobSites.aspx")
End Sub
So we send grid to table, and then in ONE database update, send the table back to the database.
Of course after we save, we return back to our first page with the grid now read to edit more.
So, the other routine used in above was sending the Grid (rows) back to the table.
That code is this:
Sub GridToTable()
For Each gRow As GridViewRow In GridView1.Rows
Dim OneRow As DataRow = rstJobItems.Rows(gRow.RowIndex)
OneRow("ItemDescription") = CType(gRow.FindControl("txtDesc"), TextBox).Text
OneRow("Qty") = CType(gRow.FindControl("txtQty"), TextBox).Text
OneRow("UsedBy") = CType(gRow.FindControl("txtUsedBy"), TextBox).Text
Next
End Sub
And of course the cancel button? Well, if you add some rows, or just edit the rows, and hit cancel? Well, we don't save - but just return to the previous page.
eg:
Protected Sub cmdCancel_Click(sender As Object, e As EventArgs) Handles cmdCancel.Click
Response.Redirect("JobSites.aspx")
End Sub
And last but not least, I have a "general" helper routine that simple returns a data table - and I used it several times in above. That routine kind of gives me a FoxPro or MS-Access like ability to get a data table with great ease (in place of typing that same code over and over).
That routine was this:
Public Function MyRst(strSQL As String) As DataTable
Dim rstData As New DataTable
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand(strSQL, conn)
conn.Open()
rstData.Load(cmdSQL.ExecuteReader)
End Using
End Using
Return rstData
End Function
So the above is quite much start to finish. It is of course quick code, and done rather fast/quick for stack overflow. But it is full of great ideas, and as noted, I let the wizards generate most of the markup. (but then remove the data source from the GV, and also the Data source item that gets created in the page.
So in summary:
I did not write most of that markup - I let the wizards generate most of it.
Note how SMALL and relative simple the code bits were. we broke up this into bite sized parts - thus each routine is not a lot of code.
We ALSO let .net built the sql update (and insert) commands for us. this eliminated BOAT LOADS of parameters, and BOATLOADS of work to wire that up. And it also MUCH better for performance, since ado.net is smart - for rows not changed - it don't send the updates to sql server.
Note also how ONE simple update method of
da.Update(rstJobItems)
Handles BOTH edits/updates, an inserts with one command. And we probably could/should drop in a delete row button - and the update would also handle that for us too!!!
So, there is a LOT of great ideas in above, but key concepts are:
Leverage as much as you can the wizards, and built in controls.
Leverage the ability of ado.net to update a table of edits in ONE shot back to the database - and as above shows, SAME single update also works for both inserts and updates at the same time.
I need an advice how to correct my code. I am using FindControl method to find TextBox inside Repeater. This is my markup:
<asp:Repeater ID="Repeater1">
HERE ARE SOME OTHER DATA
<ItemTemplate>
<asp:FormView ID="FormViewAddComment" runat="server"
DataSourceID="SqlDataSourceInsertComments" DefaultMode="Insert"
OnItemInserted="FormViewAddComment_ItemInserted"
OnItemInserting="FormViewAddComment_ItemInserting">
<InsertItemTemplate>
<asp:TextBox ID="txtAddComment" runat="server" CssClass="textbox"
Text='<%# Bind("CommentText") %>' Width="200px" />
<asp:Button ID="btnAddComment" runat="server" CssClass="button"
Text="Comment" CommandName="Insert" CausesValidation="false"/>
</InsertItemTemplate>
</asp:FormView>
</ItemTemplate>
</asp:Repeater>
And this is my code behind:
Protected Sub FormViewAddComment_ItemInserting(sender As Object, e As FormViewInsertEventArgs)
Dim FormView As FormView = DirectCast(Repeater1.FindControl("FormViewAddComment"), FormView)
Dim Comment As TextBox = DirectCast(FormView.FindControl("txtAddComment"), TextBox)
If Comment.Text = "" Then
Exit Sub
End If
End Sub
The Comment TextBox is not found and the code throws an Object reference error when it tries to access the Text property.
You can find the textbox inside it using ItemDataBound event.
Thanks
You are accessing "txtAddComment" which is there in FormView,then why are you finding FormView in Repeater and then again in textbox in that...you can directly find out it...
Protected Sub FormViewAddComment_ItemInserting(sender As Object, e As FormViewInsertEventArgs)
If (FormView1.CurrentMode == FormViewMode.Insert)
Dim Comment As TextBox = DirectCast(FormViewAddComment.FindControl("txtAddComment"), TextBox)
If Comment.Text = "" Then
Exit Sub
End If
End Sub
EDIT:-
My point is that you are writting the code in ItemInserting Event of FormView,so there you can directly find the FormView.I would suggest to use NamingContainer property in oredr to find the FormView which has trigged the event,by this way you can find the FormView then you can easily find the TextBox in it.
There is example of NamingContainer for Gridview Here
When an ASP.Net DetailsView data is first displayed, can you tell me how to populate the variable shown in this coding?
I already tried this in the code-behind file but was shown an error that:
Object reference not set to an instance of an object.
This is the coding:
Protected Sub DetailsViewDetails_DataBound(sender As Object, e As EventArgs) Handles DetailsViewDetails.DataBound
Dim txtOriginalRegistrationFee As TextBox
If DetailsViewDetails.CurrentMode = DetailsViewMode.Edit Then
txtOriginalRegistrationFee = FindControl("TextBoxRegistrationFee")
If String.IsNullOrEmpty(txtOriginalRegistrationFee.Text) = False Then
MsgBox(txtOriginalRegistrationFee)
End If
End If
End Sub
This is from the aspx file:
<asp:TemplateField HeaderText="RegistrationFee" SortExpression="RegistrationFee">
<EditItemTemplate>
<asp:TextBox ID="TextBoxRegistrationFee" runat="server" Text='<%# Eval("RegistrationFee") %>'></asp:TextBox>
</EditItemTemplate>
<InsertItemTemplate>
<asp:TextBox ID="TextBoxRegistrationFee" runat="server" Text='<%# Bind("RegistrationFee") %>'></asp:TextBox>
</InsertItemTemplate>
<ItemTemplate>
<asp:Label ID="LabelRegistrationFee" runat="server" Text='<%# Bind("RegistrationFee", "{0:c}") %>'></asp:Label>
</ItemTemplate>
<ItemStyle ForeColor="Blue" />
</asp:TemplateField>
* Update *
I tried using this coding updated based on your help but still get the "Object reference not set to an instance of an object." error when clicking the edit button of the DetailsView.
The FindControl function needs a control to search otherwise it will be searching the page (or content) level controls.
Try
txtOriginalRegistrationFee = DetailsViewDetails.FindControl("TextBoxRegistrationFee")
By the way your line with the MsgBox function will not work either. MsgBox is for windows forms and will not work on the web. You must use javascript for that type of functionality. Plus, that function takes a string, not a control.
I don't work in VB so bear with me.... The template is only rendered if your details view is in insert mode.
Dim txtOriginalRegistrationFee As TextBox
If DetailsViewDetails.CurrentMode = DetailsViewMode.Insert Then
txtOriginalRegistrationFee = FindControl("TextBoxRegistrationFee")
If String.IsNullOrEmpty(txtOriginalRegistrationFee.Text) = False Then
MsgBox(txtOriginalRegistrationFee)
End If
End If
Afternoon All,
I have two buttons on my web page that is used to lock and unlock a web page so that a user can lock the page and edit this without other users being able to access the record and then unlock this record so other users can edit this.
The problem i have is that the buttons doesnt work and im not to sure why. I am using image buttons but it looks like the event is not being triggered, i cant see the problem and its driving me crazy. Can some one please take a look at my code...
<asp:ImageButton ID="btnLock" runat="Server"
AlternateText="Click to lock record" ImageUrl="~/images/lock.png" />
<asp:ImageButton ID="btnUnlock" runat="Server"
AlternateText="Click to unlock record" ImageUrl="~/images/unlock.png" />
<asp:Label ID="lblUserName" runat="server" Font-Bold="True" Font-Size="Medium"
ForeColor="#CC3300"></asp:Label>
<asp:HiddenField ID="hdnIsLockedBy" runat="server" />
'VB Code for lock button...
Protected Sub btnLock_Click(sender As Object, e As System.EventArgs) Handles btnLock.Click
Dim lock As New WeeklyClass
'Check that the Loggedby field is set to null so the user can then lock the record
If String.IsNullOrEmpty(lock.LockedBy) Then
'lock and add the username
lock.LockedBy = User.Identity.Name
'global variable islockedby
hdnIsLockedBy.Value = User.Identity.Name
'AgendaID required as part of the stored procedure
lock.AgendaID = Integer.Parse(lblAgendaNumber.Text)
End If
'Save to the database using the Class DAL and the Stored Procedure
WeeklyClassDAL.LockWeeklyAgenda(lock)
'Display buttons as expected result
btnLock.Visible = False
btnUnlock.Visible = True
' Refreshes fields on the page
Response.Redirect("~/WeeklyAgenda.aspx?Edit=" & lblAgendaNumber.Text)
End Sub
'VB Code for unlock button...
Protected Sub btnUnlock_Click(sender As Object, e As System.EventArgs) Handles btnUnlock.Click
Dim unlock As New WeeklyClass
' Check to see if the system has a username
If hdnIsLockedBy.Value = User.Identity.Name Then
'set the lockedby field to null
unlock.LockedBy = hdnIsLockedBy.Value
'pass the relevent agendaid
unlock.AgendaID = Integer.Parse(lblAgendaNumber.Text)
End If
' save to the database using the Class DAL
WeeklyClassDAL.unLockWeeklyAgenda(unlock)
'Display buttons as expected result
btnLock.Visible = True
btnUnlock.Visible = False
' Refreshes fields on the page
Response.Redirect("~/WeeklyAgenda.aspx?Edit=" & lblAgendaNumber.Text)
End Sub
Any help is much appriechiated. I have been looking at this for ages and cant seem to find the issue.
Regards
Betty
You have not subscribed to the click event. Your control does not know that it has to call those functions when a user clicks them.
Subscribe to those events as follows:
<asp:ImageButton ID="btnLock" runat="Server"
AlternateText="Click to lock record" ImageUrl="~/images/lock.png"
OnClick="btnLock_Click" />
<asp:ImageButton ID="btnUnlock" runat="Server"
AlternateText="Click to unlock record" ImageUrl="~/images/unlock.png"
OnClick="btnUnloc_Click />
You need to specify the Click event in your buttons.
OnClick="Button1_Click"
So your buttons should be:
<asp:ImageButton
ID="btnLock"
runat="Server"
AlternateText="Click to lock record"
ImageUrl="~/images/lock.png"
OnClick="btnLock_Click" />
<asp:ImageButton
ID="btnUnlock"
runat="Server"
AlternateText="Click to unlock record"
ImageUrl="~/images/unlock.png"
OnClick="btnUnloc_Click />
You need to add autopostback="true" to the buttons:
<asp:ImageButton ID="btnLock" runat="Server" autopostback="true"
AlternateText="Click to lock record" ImageUrl="~/images/lock.png" />
Otherwise the code behind will not be triggered.
How do I enable a check_change for a checkbox in VB.
Here is what I have so far.
Code Behind:
Protected Sub CheckBoxCash_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles CheckBoxCash.CheckedChanged
Label1.Text = "Cash"
End Sub
Front end code:
<asp:Label ID="Label1" runat="server" Text="Empty"></asp:Label>
<asp:CheckBox ID="CheckBoxPoints" runat="server" Checked="True" />
It looks like you're not doing anything that specifically requires a postback here. In that case, I'd skip the postback entirely an do it more like this:
<asp:Label ID="Label1" runat="server" Text="Empty"></asp:Label>
<asp:CheckBox ID="CheckBoxPoints" runat="server" Checked="True" onclick="document.getElementById('Label1').value = 'Cash';" />
Of course, that's the simple version. Production code would also involve checking the label's clientid property in case these controls ever end up inside a naming container (like an asp:panel or gridview). I'd also look for a fallback for when javascript is not enabled, but in this case the Check_Changed server event depends on javascript to fire anyway.
I figured it out, I forgot to set the postback to true