Open new window in asp.net VB - asp.net

I'm a noob progammer that is working on something for our company. I'm working on a Quiz engine for training. I have some sample code that is about 90% built. I just need to tweak a few things. Here's what I'm working on.
THis is built in ASP.net with VB. I have a set of questions that I"m pulling from a database (using the built-in SQLDataSource binding). Currently what it does is pull the question, you select the answer, and click Next. It then pulls the next question in the list and so forth....till the end. The Database contains a column that indicates what the correct answer is. When you click next, it compairs your answer to the correct answer, stores it, then continues to the next question. At the end, it spits out your correct answers and incorrect answers.
However, this is what I want to do. When the user selects an answer and clicks next, it immediately opens up a small new window (not a pop-up, but a window on the same page) that immediately "grades" that question and in that window, displays whether it's correct..something like this:
If selected answer = correctAnswer then
"That is correct"
Else
"THat is not correct. The correct answer is B"
End if
The new window will only contain an "OK" button in the bottom corner. When the OK is pressed, it closes that new window and processes the rest of what the "next" button is programmed to do. Here is the button:
<asp:Button ID="buttonNext" runat="server" Text="Next" /> </td>
Here is the Questions.aspx.VB code to go along with that:
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles buttonNext.Click
' Save off previous answers
Dim dr As System.Data.DataRowView
dr = CType(questionDetails.DataItem, System.Data.DataRowView)
' Create Answer object to save values
Dim a As Answer = New Answer()
a.QuestionID = dr("QuestionOrder").ToString()
a.CorrectAnswer = dr("CorrectAnswer").ToString()
a.UserAnswer = answerDropDownList.SelectedValue.ToString()
Dim al As ArrayList
al = CType(Session("AnswerList"), ArrayList)
al.Add(a)
Session.Add("AnswerList", al)
If questionDetails.PageIndex = questionDetails.PageCount - 1 Then
' Go to evaluate answers
Response.Redirect("results.aspx")
Else
questionDetails.PageIndex += 1
End If
If questionDetails.PageIndex = questionDetails.PageCount - 1 Then
buttonNext.Text = "Finished"
End If
End Sub
If you are able to provide the code I need, that will be helpful. Thanks in advance for the help.
Tim

This should be fairly straight forward. As you have already retrieved the correct answer there is no need to do another call.
On your page you need to create a where you want the grading and OK button to live.
Something like this would suffice:
<div id="gradeWindow" runat="server" visible="false">
<asp:label id="gradeLabel" runat="server" text="" />
<asp:button id="gradeOK" runat="server" text="OK" onclick="gradeOK_Clicked" />
</div>
Then modify your function to look like this
Session.Add("AnswerList", al)
If String.Compare(a.UserAnswer, a.CorrectAnswer) = 0 then
gradeLabel.Text = "That is correct"
Else
gradeLabel.Text = "That is not correct. The correct answer is " + a.CorrectAnswer
EndIf
gradeWindow.Visible = true
End Sub
Protected Sub gradeOK_Clicked(ByVal sender As Object, ByVal e As System.EventArgs)
If questionDetails.PageIndex = questionDetails.PageCount - 1
Then
Response.Redirect("results.aspx")
Else
questionDetails.PageIndex += 1
End If
If questionDetails.PageIndex = questionDetails.PageCount - 1
Then
buttonNext.Text = "Finished"
End If
End Sub

Related

How to write a conditional that alerts a user if a text box is changed a second time

What I am trying to do is create a conditional statement that will alert the user if a text box is changed after initially filling that field.
For instance if they enter their name into the text box and then at a later point enter a different name into that text box, I want it to alert the user.
Below is my code of both the text box control as well as a .textchanged event.
Text Box Control:
<div class="txtSearch">
<asp:TextBox ID="txtSearchOC" runat="server" Width="250px" Text="" AutoPostBack="True" TabIndex="13" Font-Bold="True"
ForeColor="#822402" BorderColor="#822402" AutoCompleteType="Disabled" ClientIDMode="Static" />
</div>
.textChanged Event Code:
Protected Sub txtSearchOC_TextChanged(sender As Object, e As EventArgs) Handles txtSearchOC.TextChanged
Dim searchOCText As String = txtSearchOC.Text
Dim isTheSame As Boolean = False
If searchOCText = txtSearchOC.Text Then
isTheSame = True
End If
If isTheSame = True AndAlso searchOCText <> txtSearchOC.Text Then
Call txtSearchOC_Warning()
End If
End Sub
My thought process was to store the first name in a variable called "searchOCText" and then have a boolean that would hold true if searchOCText = txtSearchOC.Text, I would then use that boolean value to test if the text in the text box had changed, but I'm not terribly sure where to go from here as I am pretty new to programming.
So far I have tested the procedure "txtSearchOC_Warning()" and on its own it works and displays the message I am wanting to display. However when I try to call it from the TexChanged procedure nothing happens and I am at a loss as to why. So I am left to believe that the problem lies within my conditional and that I need to start digging there.
Any and all help would be greatly appreciated.
It's better to use JS to perform this validation since it's more efficient and doesn't require a PostBack to trigger. Check the following simple script:
<script>
let oldVal=document.getElementById("<%=txtSearchOC.ClientID%>").value;
function checkChange(val) {
if(oldVal!="")//To check if this change is a first time change
{
alert("The input value has changed to: " + val);
}
oldVal=val;
}
</script>
And your Text Box definition will be:
<asp:TextBox ID="txtSearchOC" runat="server"
onClientClick="checkChange(this.value)" AutoPostBack="false" ...
The problem with your approach is that searchOCText will be always equal to txtSearchOC after the PostBack. Line Dim searchOCText As String = txtSearchOC.Text
If you still want to use this approach you may store searchOCText in a Session like this:
Try
If Session("searchOCText").ToString()= txtSearchOC.Text Then
isTheSame = True
End If
Catch
End Try
Session("searchOCText")=txtSearchOC.Text
Looks like your code has some small mistakes:
TextChanged raised on programmatically setting value and any typing, every stroke. Better to use the LostFocus event.
Variable isTheSame is redundant (always True) because the event raises after text changing.
Actually, your message will never be shown when changing the user contents or not, because you compare user input with the same user input (inequality searchOCText <> txtSearchOC.Text always be False).
I think it is the simplest solution.
Public Class ExtTextBox
Inherits TextBox
Private LastUserInput As String
Protected Sub ExtTextBox_LostFocus(sender As Object, e As EventArgs) Handles Me.LostFocus
Select Case True
Case LastUserInput Is Nothing
LastUserInput = Text
Case Text <> LastUserInput
If MsgBox("Apply change?", MsgBoxStyle.YesNo Or MsgBoxStyle.Question) = MsgBoxResult.Yes Then
LastUserInput = Text
Else
Text = LastUserInput
End If
End Select
End Sub
End Class
Variable LastUserInput (initially Nothing) stores user input.
The first branch of Select Case stores the first user input in LastUserInput.
The second branch updates stored input or restored text according to user decision where the user points to any other element after any edit excluding the first one. You can put any code into the second branch to process new input.

Sql table check

I have a table with the following fields ID IDuser IDpc FROM TO.
obviously a PC cannot be used during the same time period by more than one user. how do i place a constraint on entries so that incorrect entries are prevented?
I use sql Server 2016 (management studio) with asp.net
ok, as noted, I though the part about multiple users using the same PC had to do with multi-user databases!
I now see that you are booking a PC to be used, and you don't want booking collisions.
Ok, there is a VERY neat condition to test/check for a booking collision.
It looks like this:
A collision occurs when:
RequestStartDate <= EndDate
and
RequestEndDate >= StartDate
And if the values include date + time, then the above still works just fine.
The above condition will find ANY kind of overlap (so a date/time in the middle) or any parts that overlap.
As I suggested in comments? You could get/have the data base not allow you to add that row (you would have to use a table trigger).
However, then what?
What this REALLY suggests? You don't write out the record and expect a database failue. Worse yet, you really want to give the user some nice feed back.
So, your booking page would ask for the room, and then the start/end time (with date). You use the above condition, and if record(s) are returned, then you tell the user they can't book the room. However, if no matches occur, then you add that row to the database.
This kind of problem actually seems quite difficult, but it turns out with the above simple condition, is is remarkable simple.
Lets do this simple example as a asp.net webforms.
So, drop in a list box, two text boxes (start/end) and a book button.
So, the markup looks like this:
<div style="margin-left:40px">
<h2>Book a work station</h2>
<div style="float:left">
<h3>Select a work station</h3>
<asp:ListBox ID="lstCompter" runat="server"
DataTextField="Computer" DataValueField="ID" Height="151px" Width="294px"></asp:ListBox>
</div>
<div style="float:left;margin-left:20px">
<div style="float:left">
<h3>Start Time</h3>
<asp:TextBox ID="txtStart" runat="server" TextMode="DateTimeLocal"></asp:TextBox>
</div>
<div style="float:left;margin-left:20px">
<h3>End Time</h3>
<asp:TextBox ID="txtEnd" runat="server" TextMode="DateTimeLocal"></asp:TextBox>
</div>
<div style="clear:both;float:left;margin-top:40px">
<asp:Button ID="cmdBook" runat="server" Text="Book Room" />
</div>
<div style="clear:both;float:left">
<br />
<asp:Label ID="lblMsg" runat="server" Text=""></asp:Label>
</div>
</div>
</div>
I tossed in a few divs to lay this out.
Ok, now the code to load up the listbox was this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadData()
End If
End Sub
Sub LoadData()
Using cmdSQL As New SqlCommand("SELECT ID, Computer from Computers ORDER BY Computer",
New SqlConnection(My.Settings.TEST4))
cmdSQL.Connection.Open()
lstCompter.DataSource = cmdSQL.ExecuteReader
lstCompter.DataBind()
End Using
End Sub
And now we get this:
Note that if you drop in that textbox and in the property sheet choose DateTimeLocal as the format, then without any extra code, you get that way cool date = time picker for free.
Now, lets write the code to check for if we can book.
The user selects a room, and then the start/end times (that could be for 1 hour, or one 1 week - it don't matter.
So, now our book button code looks like this:
Protected Sub cmdBook_Click(sender As Object, e As EventArgs) Handles cmdBook.Click
Dim strSQL As String
strSQL = "SELECT * FROM Bookings WHERE IDPc = #IDpc " &
"AND #RequestStart <= [TO] " &
"AND #RequestEnd >= [From] "
Using cmdSQL As New SqlCommand(strSQL, New SqlConnection(My.Settings.TEST4))
cmdSQL.Parameters.Add("IDpc", SqlDbType.Int).Value = lstCompter.SelectedItem.Value
cmdSQL.Parameters.Add("#RequestStart", SqlDbType.DateTime).Value = txtStart.Text
cmdSQL.Parameters.Add("#RequestEnd", SqlDbType.DateTime).Value = txtEnd.Text
cmdSQL.Connection.Open()
Dim rstBooking As New DataTable
rstBooking.Load(cmdSQL.ExecuteReader)
If rstBooking.Rows.Count > 0 Then
' booking not allowed - show message
lblMsg.Text = "Computer station already booked - try differnt date/time"
Else
' add this booking
Dim da As New SqlDataAdapter(cmdSQL)
Dim daupdate As New SqlCommandBuilder(da)
Dim OneRow As DataRow = rstBooking.Rows.Add
OneRow("IDpc") = lstCompter.SelectedValue
OneRow("IDUser") = LogOnID
OneRow("From") = txtStart.Text
OneRow("To") = txtEnd.Text
da.Update(rstBooking)
lblMsg.Text = "Room booked!"
End If
End Using
End Sub
Note how simple this becomes. In about the SAME time it took me to write this post? I in fact have a real working booking page. It would need more love an care then a quick dirty example like above, but all in all, it is remarkable that the above works.
our Computers (table) to book for the list box was this:
And then the booking table of course is this:
And that is quite much it. You can see we query the database, and if we find a match (collision), then we NEVER even try to add the row, and we give a user that message.
But, if now rows are found, then we add the row to the database.
So, it will look like this:
It is times like this that one realizes how amazing simple this was in asp.net.
Enjoy!
FYI: both "to" and "from" are SQL words - you have to use [To] and [From] (brackets around) those words, since SQL server will get confused - those column names are what we call reserved words - and "FROM" is part of regular sql syntax, so just remember to use those [] around the sql.

ASP:NET - GridVIEW - DropDownList selectedvalue

I am new at this forum though I have passed many years looking for answers into it. Now,I will like your help to solve an issue. I am following this link to make my own DropDown List in my Grid and works fine until this line:
ddlCities.Items.FindByValue(country).Selected = True
here,I have got error:
Object reference not set to an instance of an object.
but my code is right in affected fields:
this is relevant code in Code Behind:
Protected Sub RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow AndAlso grdLinea.EditIndex = e.Row.RowIndex;
Dim ddlCities As DropDownList = DirectCast(e.Row.FindControl("ddlFacturarA"), DropDownList)
' Create the command with the sproc name and add the parameter required'
ddlCities.DataSource = GetData("select UPPER(DSCA_ZONA)as Zona from tb_personal where dsca_Zona <> 'NULL'group by dsca_zona order by dsca_zona")
ddlCities.DataTextField = "Zona"
ddlCities.DataValueField = "Zona"
ddlCities.DataBind()
'Add Default Item in the DropDownList
'ddlCountries.Items.Insert(0, New ListItem("Please select"))
Dim country As String = Trim(CType(e.Row.FindControl("lblFacturarA"), Label).Text)
ddlCities.Items.FindByValue(country).Selected = True
End If
End Sub
and this is affected code in design mode:
<EditItemTemplate >
<asp:label ID="lblFacturarA" Value ='<%# Eval("facturar_a")%>' Visible ="false" runat="server" />
<asp:DropDownList
ID="ddlFacturarA"
CssClass="txt"
runat="server"
AutoPostBack="True" ValidationGroup="rfNewLineEmpty">
</asp:DropDownList>
<asp:RequiredFieldValidator
ID="rfNewLineFacturarA"
runat="server"
ErrorMessage="Obligatorio"
ValidationGroup="rfNewLine"
SetFocusOnError="True"
ControlToValidate="ddlFacturarA">
</asp:RequiredFieldValidator>
</EditItemTemplate>
I know I am new at ASP.NET and maybe I am loosing something by the way, but I have been round this code for two days and don't see light.
can you tell me something about reason for this error?
please,let me know if you need more detailed information to solve this.
thanks in advance
If you are sure that error is on line ddlCities.Items.FindByValue(country).Selected = True and country item is in dropdown list, I suggest you double check that is there white space or upper/lower case difference in dropdown list item and country variable.
because FindByValue finds exact item and it is case sensitive.
You should try changin query to RTRIM(LTRIM(UPPER(DSCA_ZONA))) as Zona
and
ddlCities.Items.FindByValue(country.ToUpper()).Selected = True
Sorry for delay as I been outside, i think i've solved in this way
Dim country As String = Trim(CType(e.Row.FindControl("lblFacturarA"), Label).Text)
ddlCities.Items.Insert(0, country)
and now it's working fine, Do you think this is a valid way?
many thanks!!!

Clear Textboxes

Morning All,
I would like to have a cancel button on my web page that essentially i would like to clear form field and themn redirect users to the home page.
I have 7 txt boxes that i will need to clear before the page redirects. I have done some searching on the internets and have tried to put the following sample into my page with no luck....
With this code i get an error on the X = "" line. I get a message 'Value of type string cannt be converted to system.we.UI.control'
Protected Sub btnCancel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnCancel.Click
Dim x As Control
For Each x In Me.Controls
If TypeOf x Is TextBox Then
x = " "
End If
Next
End Sub
And i have also tried the below which also produces a Compilation Error.
For Each c As Control In Me.Controls
If TypeOf c Is TextBox Then
DirectCast(c, TextBox).Text = ""
End If
Next
Can anyone help me with resolving this issue?
Regards
Betty
Try this:
Dim x As Control
For Each x In Me.Controls
If TypeOf x Is TextBox Then
Dim txt as TextBox = x
txt.Text = ""
End If
Next
Explanation:
You tried to set a string to a Control-variable and of course the compiler does not know how to to this.
The version I gave will set the Text-property of each TextBox to the empty-String
You can use html code to reset all field of current form you are working with
use follwoing code to reset all fields
<input type="reset" value="Clear" onclick="redirectFunction()" />
and in redirectFunction write following javascript code:
function redirectFunction()
{
window.location="destination.aspx";
}
using above code you can redirect to destination page.

Telerik radGrid - possible to do use AllowAutomaticUpdates when Datasource = a dataset?

I am setting the datasource of my radGrid to a dataset (that I have stored in session).
I have enabled AllowAutomaticUpdates and EnableViewState, implemented NeedDataSource, set DatakeyNames, etc. (see code below)
However, when I press the Edit button and make a change and press the Update link, the record does not update and leave Edit Mode.....it just stays in edit mode, and no error of any kind occurs.
So, the question is....does anyone know if radGrid with EnableViewstate even supports AutomaticUpdates, so the changes in the grid will be automatically pushed into the dataset to which it is bound?
One would think you could read the documentation, but I have been unable to find a definitive answer.
Thanks
<telerik:Radgrid id="grid" runat="server" AllowPaging="True" AllowSorting="True" AllowAutomaticUpdates="true"
AutoGenerateEditColumn="True" GridLines="None" >
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
Dim data As New DataGateway
Dim ds As DataSet = data.GetEmployeesByProgram(Year:=2009, ProgramName:="Long Term Incentive Stock Program")
Dim dt As DataTable = ds.Tables(0)
ds.Tables(0).PrimaryKey = New DataColumn() {dt.Columns("EmployeeNum"), dt.Columns("ProgramName"), dt.Columns("Year")}
Session("datasource") = ds
With Me.grid
.AllowAutomaticUpdates = True
.AutoGenerateColumns = True
.AllowSorting = True
.AutoGenerateEditColumn = True
.EnableViewState = True 'IS REQUIRED!!!
Me.grid.MasterTableView.AllowAutomaticUpdates = True
Me.grid.MasterTableView.EditMode = GridEditMode.InPlace
End With
End If
End Sub
Private Sub grid_NeedDataSource(ByVal source As Object, ByVal e As Telerik.Web.UI.GridNeedDataSourceEventArgs) Handles grid.NeedDataSource
Debug.WriteLine("NeedDataSource: " & e.RebindReason.ToString)
Dim ds As DataSet = CType(Session("datasource"), DataSet)
Me.grid.MasterTableView.DataKeyNames = New String() {"EmployeeNum", "ProgramName", "Year"}
Me.grid.DataSource = ds
End Sub
In short, there is one key issue at play here:
The "automatic" operations are only supported when you're using a Data Source control to bind the grid. That includes the ObjectDataSource, so you can use your DAL with the ODS and then support auto upserts/updates/deletes.
When binding directly to a data table, you must handle the updates manually. That's because it is the data source controls- not the RadGrid- that are providing the "auto" logic for CRUD operations. Fortunately, it's not hard to handle update manually if that's the path you prefer. Check out some of the demos on Telerik.com for examples:
http://demos.telerik.com/aspnet-ajax/grid/examples/dataediting/editmodes/defaultcs.aspx
You can also use the RadGrid with ViewState disabled if you want to. The best way to do that is to use the Grid's support for client-side databinding (though that does require that you expose your DAL via a Service Layer). Check out the demos for that approach here:
http://demos.telerik.com/aspnet-ajax/grid/examples/client/insertupdatedelete/defaultcs.aspx
Hope that helps!
-Todd
Your question has already been answered in the Telerik forums:
http://www.telerik.com/community/forums/aspnet/grid/is-it-possible-to-do-automaticupdates-to-a-dataset.aspx

Resources