I have an ASP.NET HTML website in which I want to update my SQLDataSource SELECT command using a drop-down menu. The user can select to sort by Date, Duration or Player, and the GridView will update showing the new, sorted results from my mdf database. I'm really not sure at all how to approach this as I am fairly new to ASP.NET. I could just do with some pointers on how to go about it, and what method to use. I can google tutorials, the problem is knowing what to google. Any advice greatly appreciated :)
My code:
<form id="form1" runat="server">
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="RunsData">
<Columns>
<asp:BoundField DataField="PlayerId" HeaderText="PlayerId" SortExpression="PlayerId" />
<asp:BoundField DataField="Duration" HeaderText="Duration" SortExpression="Duration" />
<asp:BoundField DataField="VersionId" HeaderText="VersionId" SortExpression="VersionId" />
<asp:BoundField DataField="DateUploaded" HeaderText="DateUploaded" SortExpression="DateUploaded" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="RunsData" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionString %>" SelectCommand="SELECT [PlayerId], [Duration], [VersionId], [DateUploaded] FROM [Run] ORDER BY [Duration]"></asp:SqlDataSource>
</form>
<div>
<label class="label" for="version">Version: </label>
<select name="version" id="version">
<option value="lev1">Level 1</option>
<option value="lev1to3">Level 1-3</option>
<option value="lev8">Level 8</option>
<option value="lev17">Level 17</option>
</select>
<label class="label" for="sortby">Sort By: </label>
<select name="sortby" id="sortby">
<option value="duration">Duration</option>
<option value="date">Date</option>
<option value="player">Player</option>
</select>
</div>
</div>
Ok, first up, I would think it is better to have the filters at the top (above) the grid, and not below? (just a idea).
and in fact, even better idea would be to drop in the two combo boxes RIGHT into the grid heading - even better!!!
but, lets take this one step at a time.
First up, I recommend we dump (remove) the data source in the web page. The can be handy, wizards generate them - thank you much - all good. However, EVEN when I often use a wizard to create the GV, I THEN blow out the data source, and use code. And when is a GOOD idea to use code to fill the GV?
Why of course when you want to filter it!!!
So, lets do this:
Delete/remove the Sqldata source - we not going to use it.
Remove this from GV - DataSourceID="RunsData"
Also, you clear used the wizards to create and setup that GV, but then now use select html? Why not use DropDown lists? The wizards not only can build them for you (like the GV, they also have a rich .net event model. And you can shove, drive the dropdown list just like the GV (they are data source friendly).
So, we going to assume this markup now:
<div style="float:left">
<label class="label" for="version">Version: </label>
<asp:DropDownList ID="cboVersion" runat="server" Width="150px">
<asp:ListItem></asp:ListItem>
<asp:ListItem Value="1">Level 1</asp:ListItem>
<asp:ListItem Value="1-3">Level 1-3</asp:ListItem>
<asp:ListItem Value="8">Level 8</asp:ListItem>
<asp:ListItem Value="17">Level 17</asp:ListItem>
</asp:DropDownList>
</div>
<div style="float:left;padding-left:25px">
<label class="label" for="sortby">Sort By:</label>
<asp:DropDownList ID="cboSortBy" runat="server" Width="150px">
<asp:ListItem></asp:ListItem>
<asp:ListItem Value="duration">Duration</asp:ListItem>
<asp:ListItem Value="DateUploaded">Date</asp:ListItem>
<asp:ListItem>Player</asp:ListItem>
</asp:DropDownList>
</div>
<div style="clear:both;height:10px"></div> <%-- Start new line for grid --%>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="RunsData">
<Columns>
<asp:BoundField DataField="PlayerId" HeaderText="PlayerId" />
<asp:BoundField DataField="Duration" HeaderText="Duration" />
<asp:BoundField DataField="VersionId" HeaderText="VersionId" />
<asp:BoundField DataField="DateUploaded" HeaderText="DateUploaded" />
</Columns>
</asp:GridView>
</form>
So, note that just like GV the dropdown list as a edit items option, like this:
And then you get this:
Also, when you want level say 1-3 is that column a number type?
And as noted, I put the filters tat the top of the grid. Since your placing the filers below the grid? You have to explain that goal - not seen filters on the bottom of a grid in about 20 years now - maybe some desktop apps? But SUPER rare. Since that choice is SUPER RARE? Then you may well have a good reason, but I placed the filter at the top. In fact, we would/could consider placing the dropdowns in the header of the GV (and that is allowed!!!). But, hey, one step at a time.
I also don't grasp, see the need for two forms on the page? (again, might be a reason, but you better have one heck of a good and great reason for that choice).
So, we now have this:
<div style="float:left">
<label class="label" for="version">Version: </label>
<asp:DropDownList ID="cboVersion" runat="server" Width="150px" AutoPostBack="true">
<asp:ListItem></asp:ListItem>
<asp:ListItem Value="1">Level 1</asp:ListItem>
<asp:ListItem Value="1,3">Level 1-3</asp:ListItem>
<asp:ListItem Value="8">Level 8</asp:ListItem>
<asp:ListItem Value="17">Level 17</asp:ListItem>
</asp:DropDownList>
</div>
<div style="float:left;padding-left:25px">
<label class="label" for="sortby">Sort By:</label>
<asp:DropDownList ID="cboSortBy" runat="server" Width="150px" AutoPostBack="true" >
<asp:ListItem></asp:ListItem>
<asp:ListItem Value="duration">Duration</asp:ListItem>
<asp:ListItem Value="DateUploaded">Date</asp:ListItem>
<asp:ListItem>Player</asp:ListItem>
</asp:DropDownList>
</div>
<div style="clear:both;height:10px"></div> <%-- Start new line for grid --%>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
Width="30%" CssClass="table">
<Columns>
<asp:BoundField DataField="PlayerId" HeaderText="PlayerId" />
<asp:BoundField DataField="Duration" HeaderText="Duration" />
<asp:BoundField DataField="VersionId" HeaderText="VersionId" />
<asp:BoundField DataField="DateUploaded" HeaderText="DateUploaded" />
</Columns>
</asp:GridView>
Note careful we added/allow/have a BLANK choice for the two combo boxes.
Ok, so now our code to load up the grid like 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()
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand("SELECT PlayerId, Duration, VersionId, DateUploaded FROM [Run]", conn)
' add filter
Dim strWhere As String = ""
If cboVersion.Text <> "" Then
If InStr(cboVersion.SelectedItem.Value, "-") = 0 Then
' one value
cmdSQL.CommandText &= " WHERE VersionID = #id"
cmdSQL.Parameters.Add("#id", SqlDbType.Int).Value = cboVersion.SelectedItem.Value
Else
' we have range
Dim MyRnage() As String = Split(cboVersion.SelectedItem.Value, "-")
cmdSQL.CommandText &= " WHERE VersionID is between #lower and #upper"
cmdSQL.Parameters.Add("#lower", SqlDbType.Int).Value = MyRnage(0)
cmdSQL.Parameters.Add("#upper", SqlDbType.Int).Value = MyRnage(1)
End If
End If
' add order by
If cboSortBy.Text = "" Then
cmdSQL.CommandText &= " ORDER BY Duration"
Else
cmdSQL.CommandText &= " ORDER BY " & cboSortBy.SelectedItem.Value
End If
Dim rstData As New DataTable
conn.Open
rstData.Load(cmdSQL.ExecuteReader)
GridView1.DataSource = rstData
GridView1.DataBind()
End Using
End Using
End Sub
Since we have auto post-back, then for both the sort by combo, filter by, then we have two event stubs here.
Protected Sub cboVersion_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboVersion.SelectedIndexChanged
loadgrid()
End Sub
Protected Sub cboSortBy_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboSortBy.SelectedIndexChanged
loadgrid()
End Sub
Edit:
The follow up question was where did TEST4 come from? Why of course it is my own setting.
From VS menu, project->"my project"->settings.
There we go to settings, and then do this:
So then in above hit the [...] and you get the connection string builder.
I mean, you can manually edit web config, but that's kind of human torture, and using the above settings is oh so much easy. So for application settings, you can use the above to create settings for your application. Say company name, or connection strings, or whatever. Those settings are placed in web.config for you. So, you not limited to just connection strings, but all kinds of constants settings such as company name, maybe company address etc.
I am trying to build a three level left navigation for my application using asp.net repeater and html list
I have three nested repeater with a linkbutton inside
when i click the linkbutton the list class should be active ( i have css for this active class).I am not good in Jquery
below is my code ( now i used only two repeater),Kindly help me how can i do this?
<ul class="nav nav-list mb-xl show-bg-active">
<asp:repeater ID="rep1" runat="server" DataSourceID="SqlDataSource1">
<ItemTemplate>
<li class="">
<asp:LinkButton ID="LinkButton1" runat="server" Text='<%# Eval("Menu") %>'></asp:LinkButton>
<asp:repeater ID="rep2" runat="server" DataSourceID="SqlDataSource1">
<ItemTemplate>
<ul>
<li>
<asp:LinkButton ID="LinkButton2" CommandArgument="id" runat="server" Text='<%# Eval("Menu") %>'></asp:LinkButton>
</li> </ul>
</ItemTemplate>
</asp:repeater>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:KTCWEBConnectionString %>" SelectCommand="SELECT NAVIAGATE_1.Menu FROM NAVIAGATE INNER JOIN NAVIAGATE AS NAVIAGATE_1 ON NAVIAGATE.ID = NAVIAGATE_1.ParentID WHERE (NAVIAGATE.Menu = #menu)">
<SelectParameters>
<asp:ControlParameter ControlID="LinkButton1" Name="menu" PropertyName="text" />
</SelectParameters>
</asp:SqlDataSource>
</li>
</ItemTemplate>
</asp:repeater>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:KTCWEBConnectionString %>" SelectCommand="SELECT DISTINCT Menu, ParentID, ID FROM NAVIAGATE WHERE (NOT (ParentID IS NULL)) AND (ParentID = 2)"></asp:SqlDataSource>
</ul>
So it's been a while since I've done ASP.Net controls but...
Your inner lists would need to bind the Enabled property to something in your Controller. Then when something is clicked you just set that binding to false. This should in turn disable all those buttons and if your css is written correctly (tier2:disabled) it should pick it up correctly.
That said, if this is a new application, stop using ASP.NET controls, it should have been killed a long time ago. HTML + CSS + ReactJs or KnockoutJs is the way to go now-a-days!
I have been trying to apply Eval on textbox which its mode is TextMode="Date". The date is not loading in to the text box and this is because the textmode. It seems to be that the Eval format is not working at all. When I remove the textmode it works. I have been trying several on variations and non of them have worked.
Here is some of them:
<asp:TextBox ID="birthdayTB" runat="server" Text='<%# Convert.ToDateTime(Eval("Birthday")).ToString("d") %>' TextMode="Date"></asp:TextBox>
<asp:TextBox ID="birthdayTB" runat="server" Text='<%# Eval("Birthday", "{0:dd-MM-yyyy}") %>' TextMode="Date"></asp:TextBox>
<asp:TextBox ID="birthdayTB" runat="server" Text='<%# Eval("Birthday", "{0:d}") %>' TextMode="Date"></asp:TextBox>
How can I make this work?
Thank you.
Use on code behind
birthdayTB.Text = Convert.ToDateTime(Birthday).ToString("dd-MM-yyyy");
I am using a range validation in asp for a date range...
<EditItemTemplate>
<asp:RequiredFieldValidator ID="RequiredFieldValidatordtmStartDateEdit" runat="server" ErrorMessage="Start Date is required" ControlToValidate="dtmStartDateEdit"></asp:RequiredFieldValidator>
<asp:RangeValidator ID="RangeValidatordtmStartDateEdit" runat="server" Type="String" ErrorMessage="Range is +/- 1 year" ControlToValidate="dtmStartDateEdit" MaximumValue="DATETIME.Today.ADDYEARS(1).ToShortDateString()" MinimumValue="DATETIME.Today.ADDYEARS(-1).ToShortDateString()"></asp:RangeValidator>
<ajaxToolkit:CalendarExtender ID="CalendarExtenderStartDateEdit" runat="server" TargetControlID="dtmStartDateEdit"></ajaxToolkit:CalendarExtender>
<asp:TextBox ID="dtmStartDateEdit" runat="server">
</asp:TextBox>
</EditItemTemplate>
The error I get is that the Maximum cannot be smaller than the minimum.
Add type attribute , and I wonder ToShortDateString() returns String or use Type = Date if not.
<asp:RangeValidator ID="RangeValidatordtmCloseDateAdd" runat="server"
ErrorMessage="Range is +/- 1 year" ControlToValidate="dtmCloseDateAdd"
MaximumValue="DATETIME.Today.ADDYEARS(1).ToShortDateString()"
MinimumValue="DATETIME.Today.ADDYEARS(-1).ToShortDateString()"
Type = "String">
</asp:RangeValidator>
What I did was extract the Max and Min statements and placed them in the PageLoad event for each RangeValidator. It works fine.
I have a program that dynamically creates various text boxes / drop down lists. I am trying to figure out how to validate these fields only when one is changed. Basically if someone entered a date in the text box then I need the program to validate that the drop down list was changed or vice versa. If there are no changes to both fields then it should not validate. Any help would be extremely appreciated. Here is the code:
<asp:TemplateField HeaderText="ValidatedDate" SortExpression="ValidatedDate">
<EditItemTemplate>
<asp:TextBox ID="txtValDate" Width="100px" MaxLength="10" runat="server" AutoPostBack="true"
Text='<%# Bind("ValidatedDate","{0:MM/dd/yyyy}") %>'></asp:TextBox>
<asp:RegularExpressionValidator ValidationGroup="g1" ID="RegularExpressionValidator10"
runat="server" ControlToValidate="txtValDate" Display="None" ErrorMessage="Validated Date: ##/##/####"
ValidationExpression="\d{1,2}/\d{1,2}/\d{4}"></asp:RegularExpressionValidator>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblValidatedDate" runat="server" Text='<%# Bind("ValidatedDate","{0:MM/dd/yyyy}")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ProductStatus" SortExpression="ProductStatusDescription">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList4" runat="server" DataSourceID="SqlDataSource6" AutoPostBack="true"
DataTextField="StatusDescription" DataValueField="StatusID" SelectedValue='<%# Bind("Status") %>'>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblProductStatus" runat="server" Text='<%# Bind("ProductStatusDescription")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
My apologies, the code can be a bit confusing without the correct context.
ebyrob, thank you for your help. I figured it out however and it works beautifully. Here is the code that fixed it all:
protected void AddError(string errorMessage)
{
cstValidate.IsValid = false;
cstValidate.ErrorMessage = errorMessage;
cstValidate.EnableClientScript = false;
}
protected void GridView2_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
TextBox txtValidatedDate = GridView2.Rows[e.RowIndex].FindControl("txtValDate") as TextBox;
DropDownList ddlStatusCompare = GridView2.Rows[e.RowIndex].FindControl("dropdownlist4") as DropDownList;
if (txtValidatedDate.Text == string.Empty && ddlStatusCompare.SelectedValue == "1")
{
AddError("Please enter a Validated Date");
e.Cancel = true;
}
else if (txtValidatedDate.Text != string.Empty && ddlStatusCompare.SelectedValue == "0"
|| txtValidatedDate.Text != string.Empty && ddlStatusCompare.SelectedValue == "99")
{
AddError("Please remove the Validated Date");
e.Cancel = true;
}
if (!e.Cancel)
Helpers.LogChanges(GridView2, e, _employeeID, "SaleProducts");
}