Select two dates simultaneously in a Textbox that uses TextMode"Date" - c#

I have a textbox that is used to filter data shown on a gridview. The Textbox is using TextMode="Date" so that when clicked, a mini calander is shown for the user to select a date and load the gridview accordingly.
<asp:TextBox ID="txtTime" runat="server" Width="100px" TextMode="Date" OnTextChanged="txtTime_TextChanged" AutoPostBack="True"></asp:TextBox>
The selected date is put in lblTIME and that label is used in an SQL statement to filter the gridview.
SqlCommand cmdSQL = new SqlCommand("SELECT * FROM Schedule.dbo WHERE Date = '" + lblTIME.Text + "'
ORDERY BY ASC");
GvSchedule.DataSource = MyRstP(cmdSQL);
GvSchedule.DataBind();
Is it possible for the user to select two dates from the calandar simulaneously? To be more specific: I want the user to select a day and then the following day is automatically selected as well and sent to a seperate label (ex. lblTomorrow). I believe the SQL Statement would look like this:
SqlCommand cmdSQL = new SqlCommand("SELECT * FROM Schedule.dbo WHERE Date = '" + lblTIME.Text + "'
AND '" + lblTomorrow.Text + "' ORDERY BY ASC");
GvSchedule.DataSource = MyRstP(cmdSQL);
GvSchedule.DataBind();

Ok, so I would for "easy" just set the 2nd date box to "always" the same date as the first box.
So, a user might select any old date, but then the 2nd box will default as same. That way they can easy select a single date, but if they need to change the 2nd date box, at least it will be "starting" from the same date.
So, we only need a "wee bit" of js code to make that 2nd date box follow the first (but, one is free to THEN change the 2nd date to whatever they want).
So, say this markup above the grid view (our results).
<div style="float: left">
<h3>Hotel Bookings</h3>
</div>
<div style="float: left; margin-left: 25px">
<h4>Start Date</h4>
<asp:TextBox ID="dtStart" runat="server" TextMode="Date" ClientIDMode="Static"
onchange="mychange()"></asp:TextBox>
</div>
<script>
function mychange() {
dtStart = $('#dtStart').val()
$('#dtEnd').val(dtStart)
}
</script>
<div style="float: left; margin-left: 20px">
<h4>End Date</h4>
<asp:TextBox ID="dtEnd" runat="server" TextMode="Date" ClientIDMode="Static" >
</asp:TextBox>
</div>
<div style="float: left; margin-left: 25px">
<br />
<asp:Button ID="cmdSearch" runat="server"
Text="Search" OnClick="cmdSearch_Click" CssClass="btn" />
</div>
<div style="clear:both"></div>
<br />
<br />
Ok, and right below above follows say our grid view results:
<asp:GridView ID="GridView1" runat="server" CssClass="table table-hover"
DataKeyNames="ID" AutoGenerateColumns="false" Width="60%">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" />
<asp:BoundField DataField="HotelName" HeaderText="Hotel Name" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="Province" HeaderText="Province" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:BoundField DataField="BookingDate" HeaderText="Booking Date"
ItemStyle-Width="110px" DataFormatString="{0:MM/dd/yyyy}" />
</Columns>
</asp:GridView>
And now all we need is the code for the "search" button, say this:
protected void cmdSearch_Click(object sender, EventArgs e)
{
String strSQL
= #"SELECT * FROM tblHotelsA
WHERE BookingDate BETWEEN #dtStart AND #dtEnd
ORDER BY HotelName";
SqlCommand cmdSQL = new SqlCommand(strSQL);
cmdSQL.Parameters.Add("#dtStart", SqlDbType.Date).Value = dtStart.Text;
cmdSQL.Parameters.Add("#dtEnd", SqlDbType.Date).Value = dtEnd.Text;
GridView1.DataSource = MyRstP(cmdSQL);
GridView1.DataBind();
}
DataTable MyRstP(SqlCommand cmdSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (cmdSQL)
{
cmdSQL.Connection = conn;
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
And now we get/see this:
Edit: user wants only/just next day
Ok, well, this might be a leap year (feb 28 or 29), or this might be the last day of the year, so to jump/add to next date, we need (should) use a date type.
So, this code will work:
<script>
function mychange() {
dtStart = new Date($('#dtStart').val())
dtEnd = dtStart
dtEnd.setDate(dtEnd.getDate() + 1)
$('#dtEnd').val(dtEnd.toISOString().split('T')[0])
}
</script>
And if you don't want the user to see (or change) the 2nd value, then just hide it with style
eg this:
<asp:TextBox ID="dtEnd" runat="server" TextMode="Date" ClientIDMode="Static"
style="display:none"
>
</asp:TextBox>
that way, user don't see it, but the post code can thus continue to work "as is"

Related

ItemDataBound in A Datalist in ASP.NET

After reading Formatting the DataList and Repeater Based Upon Data (C#) on Microsoft Website I found the following code sample.
protected void ItemDataBoundFormattingExample_ItemDataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
// Programmatically reference the ProductsRow instance bound
// to this DataListItem
Northwind.ProductsRow product =
(Northwind.ProductsRow)((System.Data.DataRowView)e.Item.DataItem).Row;
// See if the UnitPrice is not NULL and less than $20.00
if (!product.IsUnitPriceNull() && product.UnitPrice < 20)
{
// TODO: Highlight the product's name and price
}
}
}
However in the above I would like to know where Northwind.ProductsRow product is coming from. Is it from the Northwind database name or somewhere else.
this is a great question, and like some time travel movie, I REALLY WISH someone had and did explain how this works. You note that sometimes the "data source" of the datalist works, and sometimes it does not, and why is this so???
So, the data source comes from WHEN the control was "binded" or spoon fed the data source.
So, on page load, there is most likly some code that set-up and "binds" the data control. Or, it might be that a sqldatasource was dropped into the web page, but AGAIN, either way?
The page load will then trigger the row data bound event.
(ItemDataBound).
So, first BIG tip:
The e.Item.DataItem used IS ONLY available DURING the data bind process. That quite much means at data bind time and the ItemDataBound event.
So, WHEN you shove a data source INTO the GridView, Datalist, ListView, repeater etc controls? And use the data bound event (the name varies a wee bit, bu they all do the same thing), then the DataItemView is ONLY available DURING the row data bind process and hence you are 100% free to use that data source DURING the data bind event - BUT NOT AFTER!!!!!
After, binding has occured, you find that the the dataitem (and control datasoruce is NOW null!!!!). This is VERY different then desktop versions of such controls in .net (in desktop land, you actually can get/use/see the ACTUAL object used for each row!!! - and they persist!!!!
In web land, that data source is converted to a DataRowView.
However, what is the basic knowledge here?
Well, it means that your data control does NOT have to display or hide all of the columns from the database, but you ARE STILL FREE to use those additional columns for things like tax calculations, or for formatting controls based on OTHER columns that you have in the datasource BUT ARE NOT DISPLAYED!!!
And you see BOATLOADS of examples posted where people use hidden fields and all kinds of tricks, and they did that because they DID NOT KNOW the above!!!
Now, it not clear if you want to use a "datalist" control. They tend to be good for say one reocrd, or say several records in a "card like" view - not a table like layout.
So, for a table like layout, I suggest using ListView (most flexible), or for simple, and not too fancy, then use GridView.
But, DataList, listView, GridView, Repeater ? They all of this Row bound (or Item bound) event (they all are VERY close named).
And as noted, JUST like your question, in most cases this event can be used for addtional formatting.
Lets do this with a GridView - (since it easy).
So, say we have a grid of hotel names, but I want to highlight in say blue color ONLY hotels that are active. But I ALSO do NOT want to display the "active" column from the data base in that grid.
So, say this simple markup:
<style> .MyCenter {text-align:center;}</style>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" cssclass="table" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" ItemStyle-Width="120px" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="View" >
<HeaderStyle CssClass="MyCenter"/>
<ItemStyle CssClass="MyCenter" />
<ItemTemplate>
<asp:Button ID="bView" runat="server" Text="View" CssClass="btn" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Now, our code to load, we have this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid();
}
void LoadGrid()
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL = "SELECT * FROM tblHotelsA ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL,conn))
{
conn.Open();
DataTable rstData = new DataTable();
rstData.Load(cmdSQL.ExecuteReader());
GridView1.DataSource = rstData;
GridView1.DataBind();
}
}
}
And we now have this:
So, lets use the ItemDataBound event (RowdataBound for Gridview) to highlight the Hotel name and descrption ONLY for Hotels that are active. As noted, we do NOT display "Active" column in the gridview, but with Row data bound event, we still have use of the FULL row.
So, we can add this code to the Row data bound event.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// get the full data row used for binding
DataRowView OneRow = e.Row.DataItem as DataRowView;
// lets highlist the hotel name + description
if ((bool)OneRow["Active"])
{
e.Row.Cells[3].BackColor = System.Drawing.Color.LightSteelBlue;
e.Row.Cells[4].BackColor = System.Drawing.Color.LightSteelBlue;
}
// that button is not centered "vertical", so lets do that
Button btn = e.Row.FindControl("bView") as Button;
DataControlFieldCell g = btn.Parent as DataControlFieldCell;
g.Style.Add("vertical-align", "middle");
}
}
And now we we get this:
So, what about the view item click? For that we could use a datalist as you have, and we could then hide the grid, display the datalist, and we would be quite much on our way with a grid to edit items, then right?
Coffee break - I'll be back in a bit to add the view + datalist to see/view/edit one item.
Ok, part 2 - using a datalist to display above click
Ok, so lets drop in a data list - with a div area (to hide and show).
So, ok, now our data list we drop in.
<div id="MyEditArea" runat="server" style="width:44%;margin-left:35px;padding:8px;border:solid;display:none">
<asp:Datalist ID="DataList1" runat="server" DataKeyField="ID" >
<ItemTemplate>
<style>
.iForm label {display:inline-block;width:95px}
.iForm input {border-radius:8px;border-width:1px;margin-bottom:10px}
.iForm textarea {border-radius:8px;border-width:1px;margin-bottom:10px}
.iForm input[type=checkbox] {margin-right:6px}
</style>
<div style="float:left" class="iForm">
<label>HotelName</label>
<asp:TextBox ID="txtHotel" runat="server" Text='<%# Eval("HotelName") %>' width="280" /> <br />
<label>First Name</label>
<asp:TextBox ID="tFN" runat="server" Text='<%# Eval("FirstName") %>' Width="140" /> <br />
<label>Last Name</label>
<asp:TextBox ID="tLN" runat="server" Text='<%# Eval("LastName") %>' Width="140" /> <br />
<label>City</label>
<asp:TextBox ID="tCity" runat="server" Text='<%# Eval("City") %>' Width="140" /> <br />
<label>Province</label><asp:TextBox ID="tProvince" runat="server" Text='<%# Eval("Province") %>'
f="Province" Width="75"></asp:TextBox> <br />
</div>
<div style="float:left;margin-left:20px;width:420px " class="iForm">
<label>Description</label> <br />
<asp:TextBox ID="txtNotes" runat="server" Width="400" TextMode="MultiLine"
Height="150px" Text='<%# Eval("Description") %>' ></asp:TextBox> <br />
<asp:CheckBox ID="chkActive" Checked='<%# Eval("Active") %>' Text=" Active" runat="server" TextAlign="Right" />
<asp:CheckBox ID="chkBalcony" Checked='<%# Eval("Balcony") %>' Text=" Has Balcony" runat="server" TextAlign="Right" />
<asp:CheckBox ID="chkSmoking" Checked='<%# Eval("Smoking") %>' Text=" Smoking Area" runat="server" TextAlign="Right" />
</div>
<div style="clear:both"></div>
<div style="float:left" class="iForm">
<asp:Button ID="cmdSave" runat="server" Text="Save" CssClass="btn" />
<asp:Button ID="cmdCancel" runat="server" Text="Cancel" CssClass="btn" style="margin-left:10px" />
</ItemTemplate>
</asp:Datalist>
And now our button click for the grid view - to display that one data list control + data.
Hum, started writing some code routine, so lets clean this up a bit.
Ok, so we now have this to load + format the gridview.
void LoadGrid()
{
GridView1.DataSource = MyRst("SELECT * FROM tblHotelsA ORDER BY HotelName");
GridView1.DataBind();
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// get the full data row used for binding
DataRowView OneRow = e.Row.DataItem as DataRowView;
// lets highlist the hotel name + description
if ((bool)OneRow["Active"])
{
e.Row.Cells[3].BackColor = System.Drawing.Color.LightSteelBlue;
e.Row.Cells[4].BackColor = System.Drawing.Color.LightSteelBlue;
}
// button is not centered "vertical", so lets do that
Button btn = e.Row.FindControl("bView") as Button;
DataControlFieldCell g = btn.Parent as DataControlFieldCell;
g.Style.Add("vertical-align", "middle");
}
}
void CenterControl(Control c)
{
DataControlFieldCell g = c.Parent as DataControlFieldCell;
g.Style.Add("vertical-align", "middle");
}
public DataTable MyRst(string strSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
And for the button click on the grid, we have this now:
protected void bView_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
GridViewRow gRow = btn.NamingContainer as GridViewRow;
int? PKID = GridView1.DataKeys[gRow.RowIndex]["ID"] as int?;
// Now load our datalist
string strSQL = "SELECT * from tblHotelsA WHERE ID = " + PKID;
DataList1.DataSource = MyRst(strSQL);
DataList1.DataBind();
// hide grid, show edit area
GridView1.Style.Add("display", "none");
MyEditArea.Style.Add("display", "normal");
}
So, now when we click on a row, we hide grid, show our data list control, and we now see/have this:
And just like the grid view, lets highlight the hotelname and description as light grey. Once again, we now use the data list row data bound event.
Say, this:
Note how we don't use .cells for the data list, but have to use find control.
protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
{
if ( (e.Item.ItemType == ListItemType.Item) |
e.Item.ItemType == ListItemType.AlternatingItem)
{
DataRowView gData = e.Item.DataItem as DataRowView;
if ((bool)gData["Active"])
{
TextBox txtHotel = e.Item.FindControl("txtHotel") as TextBox;
txtHotel.BackColor = System.Drawing.Color.LightSteelBlue;
TextBox txtDescript = e.Item.FindControl("txtNotes") as TextBox;
txtDescript.BackColor = System.Drawing.Color.LightSteelBlue;
}
}
}
And, you do have to check for item, and "alternating" item.
But, now, when we click on a grid row, we get this:

How does Control.Enabled work?

I have spent several days looking at various resources and am getting more confused. I have several controls in a .aspx file: an edit button, a year dropdownlist, and four gridviews with textboxes and dropdownlists in them. The textboxes and dropdownlists in the gridviews start disabled. When the user clicks the edit button, they should enable. This works the first time, but they won't disable again. Here's the relevant code:
private void toggleEditMode()
{
editBtn.CssClass = editBtn.Attributes["mode"].ToString() == "edit" ? "btn btn-success" : "btn btn-primary";
editBtn.Text = editBtn.Attributes["mode"].ToString() == "edit" ? "<span class='glyphicon glyphicon-floppy-disk'></span> Save" : "<span class='glyphicon glyphicon-edit'></span> Edit";
editBtn.Attributes["mode"] = editBtn.Attributes["mode"].ToString() == "edit" ? "save" : "edit";
selectYear.Enabled = !selectYear.Enabled;
foreach (GridView gv in panels)
{
foreach (GridViewRow gvr in gv.Rows)
{
TextBox name = (TextBox)gvr.FindControl("nameTB");
DropDownList rating = (DropDownList)gvr.FindControl("ratingDDL");
name.Enabled = !name.Enabled;
rating.Enabled = !rating.
}
}
}
The edit button turns into the save button properly, and the year dropdownlist toggles correctly, but the textboxes and dropdownlists in the gridview won't disable. During debugging, I have discovered that the Enabled property of each textbox and DDL is false at the beginning of this method.
The textboxes and DDL's all start disabled, enable on the button click, and then won't disable, even though the button and year DDL toggle correctly.
My question is: how exactly does the Enabled property work? Any help is greatly appreciated.
EDIT: here is the markup:
<asp:LinkButton ID="editBtn" runat="server" ClientIDMode="Static" OnClick="ToggleEditMode" CssClass="btn btn-primary" mode="edit">
<span class="glyphicon glyphicon-edit"></span> Edit
</asp:LinkButton>
<div class="form-inline" role="form">
<fieldset>
<div class="form-group">
<label for="selectYear">Year: </label>
<asp:DropDownList ID="selectYear" runat="server" CssClass="form-control" AutoPostBack="true" ClientIDMode="Static"></asp:DropDownList>
</div>
</fieldset>
</div>
And here is the gridview:
<asp:GridView ID="jrSchools1a2aAdmin" runat="server" AutoGenerateColumns="false" GridLines="None" ClientIDMode="Static" OnRowCreated="BindRatings" CssClass="table table-striped table-bordered">
<Columns>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:TextBox ID="nameTB" runat="server" Text='<%# Eval("name") %>' ClientIDMode="Static" schoolID='<%# Eval("schoolID") %>' Enabled="false" CssClass="form-control"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Rating">
<ItemTemplate>
<asp:DropDownList ID="ratingDDL" runat="server" SelectedValue='<%# Eval("rating") %>' ClientIDMode="Static" Enabled="false" CssClass="form-control"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="students" HeaderText="Students" />
<asp:BoundField DataField="7_1" HeaderText="7-I" />
<asp:BoundField DataField="7_2" HeaderText="7-II" />
<asp:BoundField DataField="8_1" HeaderText="8-I" />
<asp:BoundField DataField="8_2" HeaderText="8-II" />
<asp:BoundField DataField="open" HeaderText="Open" />
<asp:BoundField DataField="score" HeaderText="Score" />
</Columns>
</asp:GridView>
ToggleEditMode checks if it should save or not, runs a SQL query if it should save, and calls toggleEditMode().
EDIT 2: Here is where toggleEditMode() is called. Sorry for the confusion. It's not called anywhere else.
protected void ToggleEditMode(object sender, EventArgs e)
{
if (editBtn.Attributes["mode"].ToString() == "save")
{
StringBuilder query = new StringBuilder();
List<SQLParameter> parameters = new List<SQLParameter>();
//Determine the year
int year;
int.TryParse(selectYear.SelectedItem.Value, out year);
parameters.Add(new SQLParameter("#year", year));
// Use a counter so we can enumerate parameter names
int i = 0;
foreach (GridView gv in panels)
{
foreach (GridViewRow gvr in gv.Rows)
{
TextBox name = (TextBox)gvr.FindControl("nameTB");
DropDownList rating = (DropDownList)gvr.FindControl("ratingDDL");
name.CssClass = "form-control green";
//SQL statements here
parameters.Add(new SQLParameter(String.Format("#name{0}", i), name.Text));
parameters.Add(new SQLParameter(String.Format("#schoolID{0}", i), name.Attributes["schoolID"].ToString()));
parameters.Add(new SQLParameter(String.Format("#rating{0}", i), rating.SelectedValue));
i++;
}
}
SqlConn.doQuery(query.ToString(), parameters);
//populateTables();
}
toggleEditMode();
}
Like #mjw mentioned in the comments, I was setting Enabled='false' in the markup. Due to the page life cycle, the controls were always rendering as Enabled='false'. If controls can be enabled/disabled based on conditions, this is best handled in the Page_Load function. However, ASP.NET has editing capabilities built into the GridView control, and these should be preferred over AJAX submissions for the inherent security benefits built into ASP.NET. Here are some links to get you started:
Making a column editable in an ASP.net GridView
https://learn.microsoft.com/en-us/previous-versions/dotnet/articles/ms972948(v=msdn.10)

Cannot Exit Telerik Radgrid Edit Mode after clicking btnInsert?

I'm having trouble exiting edit mode after performing an insert. Inserting isn't done through radgrid but passively through the code behind. I tried everything but I can't exit after completing the insert.
protected void btnInsertUpdate_Click(object sender, EventArgs e)
{
RadButton btnInsert = (RadButton)sender;
RadTextBox txtVisited = (RadTextBox)btnInsert.Parent.FindControl("txtVisited");
RadTextBox txtDays = (RadTextBox)btnInsert.Parent.FindControl("txtDays");
if (txtVisited.Text != "" & txtDays.Text != "" & !IsAsync)
{
string RECORD_UID = ds_01.InsertParameters["RECORD_UID"].DefaultValue;
string VISITED = txtVisited.Text;
string DAYS_ON_SITE = txtDays.Text;
DB db = new DB();
SqlCommand cmd = new SqlCommand();
db.ActiveDBConn = "dbConnection";
cmd.CommandText = "ACP_CANADA_INSERT_NEW_RECORD_DETAILS";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("UID", RECORD_UID);
cmd.Parameters.AddWithValue("VISITED", VISITED);
cmd.Parameters.AddWithValue("DAYS_ON_SITE", DAYS_ON_SITE);
db.SQLStatement = cmd;
db.NonQuery();
radgrid_1.MasterTableView.ClearEditItems();
}
}
<EditFormSettings EditFormType="Template" FormStyle-BackColor="#e1eaff" FormStyle-BorderColor="#006699" FormStyle-BorderWidth="10">
<FormTemplate>
<div style="padding: 10px;">
<div>
<telerik:RadLabel ID="lblVisited" runat="server" Text="Visited:"></telerik:RadLabel>
<telerik:RadTextBox ID="txtVisited" runat="server"></telerik:RadTextBox>
<br />
<br />
<telerik:RadLabel ID="lblDays" runat="server" Text="Days on Site:"></telerik:RadLabel>
<telerik:RadTextBox ID="txtDays" runat="server"></telerik:RadTextBox>
</div>
<br />
<br />
<telerik:RadButton id="btnInsertUpdate" runat="server" Text="Insert" OnClick="btnInsertUpdate_Click"></telerik:RadButton>
<telerik:RadButton id="btnCancel" text="Cancel" runat="server" causesvalidation="False" CommandName="Cancel"></telerik:RadButton>
</div>
</FormTemplate>
</EditFormSettings>
Adding the CommandName equal to "Cancel" gives me the behavior I'm looking for...Insert is performed to the database and I get to exit out of edit mode.
<telerik:RadButton id="btnInsert" runat="server" Text="Insert" OnClick="btnInsert_Click" CommandName="Cancel"></telerik:RadButton>

Multiple Images upload with different titles

My Requirement is. I will be uploading 3-4 images at a time through FileUpload. Each Image will have its own Title, Descriptions etc.
Now my issue is that, whenever uploading I have given a title column for the images. But when I upload 3-4 Images the title and description is going same for all the images.
Here Is my HTML for the Image Uploading via FileUpload.
<tr>
<td style="vertical-align: top;">
<asp:label cssclass="control-label" id="Label1" runat="server">Image Title</asp:label>
</td>
<td>
<div class="control-group">
<div class="controls">
<asp:textbox id="txtImagetitle" cssclass="form-control" runat="server" validationgroup="AddNew"></asp:textbox>
<asp:requiredfieldvalidator cssclass="error-class" id="RequiredFieldValidator1" runat="server"
controltovalidate="txtImagetitle" errormessage="Please add the image title" validationgroup="AddNew"></asp:requiredfieldvalidator>
</div>
</div>
</td>
</tr>
<tr>
<td style="vertical-align: top;">
<asp:label cssclass="control-label" id="Label2" runat="server">Image description</asp:label>
</td>
<td>
<div class="control-group">
<div class="controls">
<asp:textbox id="txtImagedesc" cssclass="form-control" runat="server" validationgroup="AddNew"></asp:textbox>
<asp:requiredfieldvalidator cssclass="error-class" id="RequiredFieldValidator2" runat="server"
controltovalidate="txtImagedesc" errormessage="Please add the image description"
validationgroup="AddNew"></asp:requiredfieldvalidator>
</div>
</div>
</td>
</tr>
<tr>
<td style="vertical-align: top;">
<asp:label cssclass="control-label" id="Label3" runat="server">Image upload</asp:label>
</td>
<td>
<div class="control-group">
<div class="controls">
<asp:fileupload id="FileUpload1" runat="server" allowmultiple="true" />
<asp:requiredfieldvalidator cssclass="error-class" id="RequiredFieldValidator3" runat="server"
controltovalidate="FileUpload1" errormessage="Please add the gallery date" validationgroup="AddNew"></asp:requiredfieldvalidator>
</div>
</div>
</td>
</tr>
Please suggest what to do in this case when uploading multiple images how to set different titles for different Images.
UPDATED CODE BEHIND
protected void btnSubmit_Click(object sender, EventArgs e)
{
if (Request.QueryString.Count > 0)
{
foreach (var file in FileUpload1.PostedFiles)
{
string filename = Path.GetFileName(file.FileName);
file.SaveAs(Server.MapPath("/GalleryImages/" + filename));
using (SqlConnection conn = new SqlConnection(conString))
if (Request.QueryString["Id"] != null)
{
string Id = Request.QueryString["Id"];
SqlCommand cmd = new SqlCommand();
cmd.CommandText = " Update tbl_galleries_stack SET gallery_id=#gallery_id,img_title=#img_title,img_desc=#img_desc,img_path=#img_path, IsDefault=#IsDefault Where Id=#Id";
cmd.Parameters.AddWithValue("#Id", Id);
cmd.Parameters.AddWithValue("#gallery_id", ddlgallery.SelectedValue);
cmd.Parameters.AddWithValue("#img_title", txtImagetitle.Text);
cmd.Parameters.AddWithValue("#img_desc", txtImagedesc.Text);
cmd.Parameters.AddWithValue("#img_path", filename);
cmd.Parameters.AddWithValue("#IsDefault", chkDefault.Checked);
cmd.Connection = conn;
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
ScriptManager.RegisterStartupScript(this, this.GetType(), "alert", "alert('Gallery updated sucessfully');window.location ='csrgalleriesstack.aspx';", true);
}
}
}
else
{
foreach (var file in FileUpload1.PostedFiles)
{
string filename = Path.GetFileName(file.FileName);
file.SaveAs(Server.MapPath("/GalleryImages/" + filename));
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DefaultCSRConnection"].ConnectionString);
using (SqlCommand cmd = conn.CreateCommand())
{
conn.Open();
SqlCommand cmd1 = new SqlCommand("Insert into tbl_galleries_stack (gallery_id,img_title,img_desc,img_path,IsDefault) values(#gallery_id,#img_title, #img_desc, #img_path,#IsDefault)", conn);
cmd1.Parameters.Add("#gallery_id", SqlDbType.Int).Value = ddlgallery.SelectedValue;
cmd1.Parameters.Add("#img_title", SqlDbType.NVarChar).Value = txtImagetitle.Text;
cmd1.Parameters.Add("#img_desc", SqlDbType.NVarChar).Value = txtImagedesc.Text;
cmd1.Parameters.Add("#img_path", SqlDbType.NVarChar).Value = filename;
cmd1.Parameters.Add("#IsDefault", SqlDbType.Bit).Value = chkDefault.Checked;
cmd1.ExecuteNonQuery();
conn.Close();
ScriptManager.RegisterStartupScript(this, this.GetType(), "alert", "alert('Gallery added sucessfully');window.location ='csrgalleriesstack.aspx';", true);
}
}
}
}
There is no way you can give different title / description as you have given no option to provide it. Period.
You are forced to use multiple fileupload controls. This is also tricky because asp:FileUpload controls wont maintain their state after postback.
So, the solution I can see is a two-part one. Create two panels and hide the second panel at page load
Part 1
Place a label and textbox and button like this in the first panel in your page.
When the user enters a value, say 10, and fires EnterButton_click close Panel1 and open Panel2.
Part 2
On Panel 2, place a GridView like this
<asp:GridView ID="ImagesGrid" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField HeaderText="Sl No">
<ItemTemplate><%# Container.DisplayIndex + 1 %></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Title">
<ItemTemplate>
<asp:TextBox ID="txtTitle" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Description">
<ItemTemplate>
<asp:TextBox ID="txtDescription" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="File">
<ItemTemplate>
<asp:FileUpload ID="flUpload" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="SaveButton" Text="Save" runat="server" OnClick="SaveButton_Click"/>
Now on the Enter buttons click event on Panel 1, write this.
// the idea is to create an empty gridview with number of rows client selected
protected void EnterButton_Click(object sender, EventArgs e)
{
//in this, 10 has been entered
var imageCount = Convert.ToInt32(txtImageCount.Text);
//var list = new List<string>();
//for (int i = 0; i < imageCount; i++)
//{
// list.Add(string.Empty);
//}
var list = new List<string>(10);
list.AddRange(Enumerable.Repeat(String.Empty, imageCount));
ImagesGrid.DataSource = list;
ImagesGrid.DataBind();
//TO DO: hide panel1 and make panel2 visible
}
So on clicking enter, you will get an empty gridview with ten rows.
Now fill the rows in the GridView, do validation and hit Save. On Save Button click event, you can access the WebControls like this.
protected void SaveButton_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in ImagesGrid.Rows)
{
var title = row.FindControl("txtTitle") as TextBox;
var description = row.FindControl("txtDescription") as TextBox;
var imageFile = row.FindControl("flUpload") as FileUpload;
string filename = Path.GetFileName(imageFile.FileName);
imageFile.SaveAs(Server.MapPath("/GalleryImages/" + filename));
//TO DO: write save routine
}
}
It looks like you only have one set of inputs tied to a single file upload with multiple turned on.
You will either want to turn off multiple and allow the user to add reported sets of those images, or have the editing of title, etc happen in a gridview with the upload.
You could also support a"holding cell " where they upload and then must enter that information before you actually save it to your data store.

Perform a SQL query search based on one or both user inputs and populate a grid view with the results

I am working on a small search form that has two text fields: One that allows users to search for a job list (which is basically a wish list--don't know why they want to call it a "job list" but whatever) by entering in part of or a full email address or someone's first and/or last name (This textbox is called SearchName). This field is required and if it is blank when the user hits "Search," an error message appears telling them so. The second textbox is optional, and it allows users to enter in a city or a state to help narrow their search down even more (this textbox is called SearchLocation).
I have a function (called getJobLists()) that is used by the search button to get results.
As it is right now, the part of the function that returns results based on what is entered into the SearchName field works perfectly. However, I cannot get any results for SearchLocation. When I enter a valid email or name into SearchName, then enter a valid city or state into SearchLocation, I get no results. However, if I enter in anything invalid (i.e. a city that is not associated with the entered email or name) the "no results found" message does appear.
I have tested both SQL queries in my search function in SQL Server Management Studio and they do work perfectly.
I have a try-catch inside the search function, but no error is being shown, not even in the console.
This is the code behind:
protected void Page_Load(object sender, System.EventArgs e)
{
// CHECK IF THE WISHLIST SEARCH ENABLED
StoreSettingsManager settings = AbleContext.Current.Store.Settings;
if (!settings.WishlistSearchEnabled)
{
Response.Redirect(AbleCommerce.Code.NavigationHelper.GetHomeUrl());
return;
}
}
protected void getJobLists()
{
try
{
if (SearchName.Text != "")
{//if SearchName.Text is not blank
if (SearchLocation.Text != "")
{//check to see if SearchLocation.Text is not blank either
string sqlSelect = "SELECT (FirstName +' '+ LastName) AS 'FullName', UserName, (Address1 + ', ' +City + ', ' + Province) AS 'Address' FROM ac_Users INNER JOIN ac_Wishlists ON ac_Wishlists.UserId = ac_Users.UserId INNER JOIN ac_Addresses ON ac_Addresses.UserId = ac_Wishlists.UserId WHERE IsBilling ='true' AND (UserName LIKE '%'+#UserName+'%' OR (FirstName + LastName) LIKE '%'+#UserName+'%') AND ((City + Province) LIKE '%'+#Location+'%')";
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["AbleCommerce"].ToString()))
{
SqlCommand cmd = new SqlCommand(sqlSelect, cn);
cmd.Parameters.AddWithValue("#UserName", String.Format("%{0}%", SearchName.Text));
cmd.Parameters.AddWithValue("#Location", String.Format("%{0}%", SearchLocation.Text));
cmd.CommandType = CommandType.Text;
cn.Open();
DataSet ds = new DataSet();
DataTable jobsListsTbl = ds.Tables.Add("jobsListsTbl");
jobsListsTbl.Columns.Add("User", Type.GetType("System.String"));
jobsListsTbl.Columns.Add("PrimaryAddress", Type.GetType("System.String"));
using (IDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
DataRow dr = jobsListsTbl.NewRow();
dr["User"] = reader["Name"];
dr["PrimaryAddress"] = reader["Address"];
jobsListsTbl.Rows.Add(dr);
}
}
WishlistGrid.DataSource = ds;
WishlistGrid.DataMember = "jobsListsTbl";
WishlistGrid.DataBind();
}
}//end of if(SearchLocation.Text !='')
else
{//if SearchLocation.Text is blank, then go with this code instead
string sqlSelect2 = "SELECT (FirstName +' '+ LastName) AS 'FullName', UserName, (Address1 + ', ' +City + ', ' + Province) AS 'Address' FROM ac_Users INNER JOIN ac_Wishlists ON ac_Wishlists.UserId = ac_Users.UserId INNER JOIN ac_Addresses ON ac_Addresses.UserId = ac_Wishlists.UserId WHERE IsBilling ='true' AND (UserName LIKE '%'+#UserName+'%' OR (FirstName + LastName) LIKE '%'+#UserName+'%')";
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["AbleCommerce"].ToString()))
{
SqlCommand cmd = new SqlCommand(sqlSelect2, cn);
cmd.Parameters.AddWithValue("#UserName", String.Format("%{0}%", SearchName.Text));
cmd.CommandType = CommandType.Text;
cn.Open();
DataSet ds = new DataSet();
DataTable jobsListsTbl2 = ds.Tables.Add("jobsListsTbl2");
jobsListsTbl2.Columns.Add("User", Type.GetType("System.String"));
jobsListsTbl2.Columns.Add("PrimaryAddress", Type.GetType("System.String"));
using (IDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
DataRow dr = jobsListsTbl2.NewRow();
dr["User"] = reader["UserName"];
dr["PrimaryAddress"] = reader["Address"];
jobsListsTbl2.Rows.Add(dr);
}
}
WishlistGrid.DataSource = ds;
WishlistGrid.DataMember = "jobsListsTbl2";
WishlistGrid.DataBind();
}
}//end if SearchLocation.Text is empty
}//end of if SearchName.Text !==''
}
catch (Exception x)
{
errors5.Text += "ERROR: " + x.Message.ToString() + "<br />";
}
}
protected void SearchButton_Click(object sender, EventArgs e)
{
WishlistGrid.Visible = true;
getJobLists();
}
And this is the designer code for the search form (Note: the NavigateUrl is not set for the hyperlink yet. I will set it once everything is displaying properly for the search results):
<div id="findWishlistPage" class="mainContentWrapper">
<div class="section">
<div class="introDiv">
<div class="pageHeader">
<h1>Find a Job List</h1>
</div>
<div class="content">
<asp:label id="errors" runat="server" text=""></asp:label>
<asp:label id="errors2" runat="server" text=""></asp:label>
<asp:label id="errors3" runat="server" text=""></asp:label>
<asp:label id="errors4" runat="server" text=""></asp:label>
<asp:label id="errors5" runat="server" text=""></asp:label>
<asp:UpdatePanel ID="Searchajax" runat="server">
<ContentTemplate>
<asp:Panel ID="SearchPanel" runat="server" EnableViewState="false" DefaultButton="SearchButton">
<asp:ValidationSummary ID="ValidationSummary1" runat="server" EnableViewState="false" />
<table class="inputForm">
<tr>
<th class="rowHeader">
<asp:Label ID="SearchNameLabel" runat="server" Text="Name or E-mail:" AssociatedControlID="SearchName" EnableViewState="false"></asp:Label>
</th>
<td>
<asp:Textbox id="SearchName" runat="server" onfocus="this.select()" Width="200px" EnableViewState="false"></asp:Textbox>
<asp:RequiredFieldValidator ID="SearchNameValdiator" runat="server" ControlToValidate="SearchName"
Text="*" ErrorMessage="Name or email address is required." EnableViewState="false"></asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<th class="rowHeader">
<asp:Label ID="SearchLocationLabel" runat="server" Text="City or State (optional):" EnableViewState="false"></asp:Label>
</th>
<td>
<asp:TextBox id="SearchLocation" runat="server" onfocus="this.select()" Width="140px" EnableViewState="false"></asp:TextBox>
<asp:LinkButton ID="SearchButton" runat="server" CssClass="button linkButton" Text="Search" OnClick="SearchButton_Click" EnableViewState="false" />
</td>
</tr>
</table><br />
<asp:GridView ID="WishlistGrid" runat="server" AllowPaging="True"
AutoGenerateColumns="False" ShowHeader="true"
SkinID="PagedList" Visible="false" EnableViewState="false">
<Columns>
<asp:TemplateField HeaderText="Name">
<HeaderStyle CssClass="wishlistName" />
<ItemStyle CssClass="wishlistName" />
<ItemTemplate>
<asp:HyperLink ID="WishlistLink" runat="server" >
<%#Eval("User")%>
</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Location">
<HeaderStyle CssClass="wishlistLocation" />
<ItemStyle CssClass="wishlistLocation" />
<ItemTemplate>
<asp:Label ID="Location" runat="server" Text='<%#Eval("PrimaryAddress")%>'></asp:Label>
<%--'<%#GetLocation(Eval("User.PrimaryAddress"))%>'--%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
<asp:Localize ID="EmptySearchResult" runat="server" Text="There were no job lists matching your search criteria."></asp:Localize>
</EmptyDataTemplate>
</asp:GridView>
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</div>
</div>
Can anyone please tell me what I'm missing or doing wrong?
Okay, I finally solved the issue. Apparently, it was a variable naming issue I kept overlooking. But now it all works okay! :)

Categories

Resources