ASP.net update DropDownList - c#

I'm adding a value database table then i want to show on DropDownList. This code working when page is loading. But when i add new value to db, dropdownlist doesn't update. I called after adding value but doesn't change. When i don't use !IsPostBack, dropdownlist updating but in this case DataValueField doesnt working.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
.............
listStudent.DataSource = dt;
listStudent.DataTextField = "st";
listStudent.DataValueField = "id";
listStudent.DataBind();
}

Well, you are free to put the DataTextField and the DataValue field in the markup.
(but does not matter one bit at all).
So, say we have this markup:
(drop down, and a button to add a new value).
<asp:DropDownList ID="cboHotels" runat="server"
DataValueField="HotelName" DataTextField="HotelName" AutoPostBack="True" Width="174px" >
</asp:DropDownList>
<asp:Button ID="cmdAdd" runat="server" Text="+" style="margin-left:10px"
OnClick="cmdAdd_Click"
OnClientClick="return AddHotel();" />
<asp:TextBox ID="txtHotelName" runat="server" ClientIDMode="Static" style="display:none"></asp:TextBox>
<script>
function AddHotel() {
myhotel = prompt("Enter New Hotel Name")
if (myhotel != null) {
document.getElementById('txtHotelName').value = myhotel
return true
}
else {
return false
}
}
</script>
So, we have that "+" button beside the drop to add a new row to the database.
So, our code to fill the drop down looks like this:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
LoadCombo();
}
public void LoadCombo()
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT HotelName from tblHotels ORDER BY HotelName",
new SqlConnection(Properties.Settings.Default.TEST4)))
{
cmdSQL.Connection.Open();
cboHotels.DataSource = cmdSQL.ExecuteReader();
cboHotels.DataBind();
// add a blank (no select row)
cboHotels.Items.Insert(0, new ListItem(""));
}
}
And our code to add a new row looks like this:
protected void cmdAdd_Click(object sender, EventArgs e)
{
// add a new hotel to table
using (SqlCommand cmdSQL =
new SqlCommand("INSERT into tblHotels (HotelName) Values(#Hotel)",
new SqlConnection(Properties.Settings.Default.AccessDB)))
{
cmdSQL.Connection.Open();
cmdSQL.Parameters.Add("#Hotel", SqlDbType.NVarChar).Value = txtHotelName.Text;
cmdSQL.ExecuteNonQuery();
}
LoadCombo(); // re-load combo to show new row
// lets be nice and select the row we just added
cboHotels.ClearSelection();
cboHotels.Items.FindByText(txtHotelName.Text).Selected = true;
}
And we get this:

Related

foreach by check on two control (dropdownlist and textbox)

I have issue on doing the foreach part, I have multiple dropdownlist attach together with a textbox for filling quantity
But with my current code it will have issue with running all value in the foreach textbox first just until the next foreach of dropdownlist. Below is my code of now.
foreach (DropDownList dropDown in pnlDDLDispensary.Controls.OfType<DropDownList>()){foreach (TextBox textBox in pnltxtDispensaryQty.Controls.OfType<TextBox>()){ code here }}
My objective is want to insert each of the dropdownlist dispensary together with the quantity of that dispensary like example: (MedicineA with 5 quantity, MedicineB with 1 quantity). Is there anything like foreach( a in control && b in control)? Appreciate for help. Thanks~
protected void cmdDelete_ServerClick(object sender, EventArgs e)
{
GridToTable(); //This function havent done due to also having DataKeys cannot used like a method error
Button btnDelete = (Button)sender;
ListViewItem gRow = (ListViewItem)btnDelete.NamingContainer;
int disID = lvDispensary.DataKeys(gRow.DataItemIndex).Item("dispensaryID");
}
Result:
CS1955: Non-invocable member 'ListView.DataKeys' cannot be used like a method.
It not at all clear what kind of "system" or choice you have made to show the repeating drop down and text box.
As a general rule, if you need to "repeat" controls, then you use a listview, repeater, or even maybe a grid view.
so it will not matter if you have 1 or 15 row of repeating data (you don't care how many).
So, I might say have 1 or 8 hotels, and I have a combo box to rate the hotel.
So, hum, lets use the repeater.
So, we only need to drop/have one instance of the markup layout.
Say, like this:
<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
<ItemTemplate>
<asp:Label ID="lblH" runat="server" Text="Hotel Name" Font-Size="Medium">
</asp:Label>
<asp:TextBox ID="txtHotel" runat="server"
Text = '<%# Eval("HotelName") %>'
style="margin-left:20px" >
</asp:TextBox>
<asp:DropDownList ID="DropDownList1" runat="server"
style="margin-left:20px;width:120px"
DataValueField = "ID"
DataTextField = "Rating" >
</asp:DropDownList>
<br />
</ItemTemplate>
</asp:Repeater>
and our code behind is this:
DataTable rstRating = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadData();
}
void LoadData()
{
// set combo box source
rstRating =
MyRst("SELECT ID, Rating FROM tblRating ORDER BY ID");
DataTable rstData =
MyRst("SELECT * FROM tblHotelsA ORDER BY HotelName");
Repeater1.DataSource = rstData;
Repeater1.DataBind();
}
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item |
e.Item.ItemType == ListItemType.AlternatingItem)
{
DropDownList dl = (DropDownList)e.Item.FindControl("DropDownList1");
dl.DataSource = rstRating;
dl.DataBind();
dl.Items.Insert(0, new ListItem("Please Select", "0"));
}
}
and now we get this:
so, above works for 2 or 20 rows of data. We don't care how many rows.
but, now to do a for each on the repeating controls?
This:
protected void Button1_Click(object sender, EventArgs e)
{
foreach (RepeaterItem OneRow in Repeater1.Items)
{
TextBox txtHotel = (TextBox)OneRow.FindControl("txtHotel");
DropDownList cboRate = (DropDownList)OneRow.FindControl("DropDownList1");
Debug.Print("Hotel name = " + txtHotel.Text + " -- Rating = " +
cboRate.SelectedItem.Text);
}
}
And output is this:
So, for a "set" or "thing" of repeating data, then use some type of control such as a repeater.
I mean, for above, we could also use a listview, and that also is quite nice, say like this:
<div style="width:24%">
<asp:ListView ID="LVHotels" runat="server" DataKeyNames="ID" OnItemDataBound="LVHotels_ItemDataBound" >
<ItemTemplate>
<tr style="">
<td>
<asp:TextBox ID="txtHotel" runat="server"
Text = '<%# Eval("HotelName") %>'
style="margin-left:20px" >
</asp:TextBox>
</td>
<td>
<asp:DropDownList ID="DropDownList1" runat="server"
style="margin-left:20px;width:120px"
DataValueField = "ID"
DataTextField = "Rating" >
</asp:DropDownList>
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table id="itemPlaceholderContainer" runat="server" class="table table-bordered">
<tr runat="server" style="">
<th runat="server">Hotel Name</th>
<th runat="server">Rating</th>
</tr>
<tr id="itemPlaceholder" runat="server">
</tr>
</table>
</LayoutTemplate>
</asp:ListView>
</div>
Same code to bind, and we now have this:
And then once again, our for each code against that listview is much the same.
So, the idea here?
If you have repeating controls, then use some type of gridview, repeater, or listview.
that way, its all data driven, and once done, then 2 or 20 rows - it don't matter, and you can use for each against these containers that repeated the data for you.
Edit: User wants a List View example.
Ok, so markup for this is this:
<div style="width:30%">
<style>
.borderhide input {border:none;background-color:transparent}
.borderhide textarea {border:none;background-color:transparent}
</style>
<asp:ListView ID="LVHotels" runat="server" DataKeyNames="ID" OnItemDataBound="LVHotels_ItemDataBound" >
<ItemTemplate>
<tr style="">
<td><asp:TextBox ID="txtFirst" runat="server" Text='<%# Eval("FirstName") %>' width="80px"></asp:TextBox></td>
<td><asp:TextBox ID="txtLast" runat="server" Text='<%# Eval("LastName") %>' width="80px"></asp:TextBox></td>
<td><asp:TextBox ID="txtHotel" runat="server" Text='<%# Eval("HotelName") %>' width="110px"></asp:TextBox></td>
<td>
<asp:DropDownList ID="DropDownList1" runat="server"
style="width:120px"
DataValueField = "ID"
DataTextField = "Rating" >
</asp:DropDownList>
</td>
<td>
<button id="cmdDelete" runat="server" class="btn"
onserverclick="cmdDelete_ServerClick"
onclick="if (!confirm('Really delete')) {return false}" >
<span aria-hidden="true" class="glyphicon glyphicon-trash"></span>
</button>
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table id="itemPlaceholderContainer" runat="server" class="table table-bordered borderhide">
<tr runat="server" style="">
<th runat="server">First Name</th>
<th runat="server">Last Name</th>
<th runat="server">Hotel Name</th>
<th runat="server">Rating</th>
<th runat="server"></th>
</tr>
<tr id="itemPlaceholder" runat="server">
</tr>
<tfoot><tr><td>
<button id="cmdAddNew" runat="server" class="btn" onserverclick="cmdAddNew_ServerClick" >
<span aria-hidden="true" class="glyphicon glyphicon-plus-sign"> New</span>
</button>
</td></tr></tfoot>
</table>
</LayoutTemplate>
</asp:ListView>
</div>
<br />
<button id="cmdSave" runat="server" class="btn" onserverclick="cmdSave_ServerClick" >
<span aria-hidden="true" class="glyphicon glyphicon-floppy-saved"> Save</span>
</button>
<button id="cmdCancel" runat="server" class="btn" style="margin-left:15px" onserverclick="cmdCancel_ServerClick">
<span aria-hidden="true" class="glyphicon glyphicon-arrow-left"> Back/Cancel</span>
</button>
</div>
And our full code for this is this:
DataTable rstRating = new DataTable();
DataTable rstData = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadData();
Session["rstData"] = rstData;
Session["rstRating"] = rstRating;
}
else
{
rstData = (DataTable)Session["rstData"];
rstRating = (DataTable)Session["rstRating"];
}
}
void LoadData()
{
// set combo box source
rstRating = MyRst("SELECT ID, Rating FROM tblRating ORDER BY ID");
rstData = MyRst("SELECT * FROM tblHotelsA ORDER BY HotelName");
LVHotels.DataSource = rstData;
LVHotels.DataBind();
}
DataTable MyRst(string strSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
cmdSQL.Connection.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
protected void LVHotels_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
DropDownList dl = (DropDownList)e.Item.FindControl("DropDownList1");
dl.DataSource = rstRating;
dl.DataBind();
dl.Items.Insert(0, new ListItem("Please Select", "0"));
// now set to current data row
DataRowView OneRow = (DataRowView)e.Item.DataItem;
if (OneRow["Rating"] != null)
dl.SelectedValue = OneRow["Rating"].ToString();
}
}
protected void cmdSave_ServerClick(object sender, EventArgs e)
{
SaveAllData();
// data saved - move on to next page
// Response.Redirect("MyMain.aspx");
}
protected void cmdAddNew_ServerClick(object sender, EventArgs e)
{
DataRow NewRow = rstData.NewRow();
rstData.Rows.Add(NewRow);
// show this row
LVHotels.DataSource = rstData;
LVHotels.DataBind();
}
void SaveAllData()
{
GridToTable(); // move grid back to table
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL =
new SqlCommand("SELECT * FROM tblHotelsA WHERE ID = 0", conn))
{
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(cmdSQL);
SqlCommandBuilder daU = new SqlCommandBuilder(da);
da.Update(rstData);
// rstData.AcceptChanges()
}
}
}
protected void cmdCancel_ServerClick(object sender, EventArgs e)
{
// cancel without save - go back some place to other page
// Response.Redirect("MyMain.aspx");
}
void GridToTable()
{
// send LV rows back to our table.
foreach (ListViewItem rRow in LVHotels.Items)
{
int RecordPtr = rRow.DataItemIndex;
DataRow OneDataRow = rstData.Rows[RecordPtr];
OneDataRow["FirstName"] = ((TextBox)rRow.FindControl("txtFirst")).Text;
OneDataRow["LastName"] = ((TextBox)rRow.FindControl("txtLast")).Text;
OneDataRow["HotelName"] = ((TextBox)rRow.FindControl("txtHotel")).Text;
DropDownList dlRating = (DropDownList)rRow.FindControl("DropDownList1");
if (dlRating.SelectedIndex == 0)
OneDataRow["Rating"] = null;
else
OneDataRow["Rating"] = dlRating.SelectedItem.Value;
}
}
protected void cmdDelete_ServerClick(object sender, EventArgs e)
{
// we actully should saveAllData before we do this
// we might have added rows without save and thus
// pk not correctly valid
// so we need to actaully check deleted row status here.
HtmlButton btn = (HtmlButton)sender;
ListViewItem gRow = (ListViewItem)btn.NamingContainer;
int RowIndex = gRow.DataItemIndex;
int PK = (int)LVHotels.DataKeys[RowIndex]["ID"];
string strSQL = "DELETE FROM tblHotelsA WHERE ID = " + PK;
Debug.Print("will delete - future code");
}
And we now have get this:
So, you can:
Tab around - edit + change any row - including combo box
Add new rows
THEN hit save button, all edits, adding, edits and even delete(s) will now go back to sql server table.
The data bound event for the listview in above is what you are looking for.
Only part left out is delete button - but that should be easy.
Edit3: adding the delete button code
As noted, if we are to allow delete, then we STILL have to hit the save button, and the un-do changes button WILL still work!!! So, the user can add a few rows, delete a few rows - and then go "opps" wrong rows deleted. Since we not yet hit save, then we not actaully deleted the data. (and this means our un-do button can still work).
But, what this means? well in rstData, then rows of DELETED data WILL exist. We can feed rstData to the LV, and such rows don't show.
But, using for/each on the rstData? Then YES DELETED rows will show up!
And if the LV displays 5 rows, but we had 10 and deleted 5 of them?
Then as noted, we NOW cannot USE the LV "index" to peek into rstData anymore. But, we can still use Datakeys. BEYOND critial then that you set datakeys setting in the LV markup as I have done above.
So, first up, the delete button code. User might bounce around, edit some rows, maybe add. But then hits delete button.
So, this code is easy. (also note the JavaScript confirm prompt to confirm the delete button).
hence this:
Protected Sub cmdDelete_ServerClick(sender As Object, e As EventArgs)
' save any edits BACK to table before delete
' this ONLY delets from persited table - not SQL server.
GridToTable()
Dim btn As HtmlButton = sender
Dim gRow As ListViewItem = btn.NamingContainer
Dim PK As Integer = ListView1.DataKeys(gRow.DataItemIndex).Item("ID")
Dim OneDataRow As DataRow = rstData.Select("id = " & PK)(0)
OneDataRow.Delete()
DisplayUpdate()
End Sub
Note VERY close in above. We did not (and can't) use the LV index into our table, since rstData now can have more rows then the LV display. (LV is smart, only display rows that are not deleted).
So, in above, we dumped "index" from LV into rstData, and we now use PK value.
This also now means our GridToTable can't use the simple "index" into rstdata, and we MUST pull each row from rstData by PK value (we have to search/find the PK row based on PK).
So, GridToTable now has to be this:
Sub GridToTable()
' send grid rows back to persited table
For Each gRow As ListViewItem In ListView1.Items
' Get database PK value
Dim PK As Integer = ListView1.DataKeys(gRow.DataItemIndex).Item("ID")
Dim drT() As DataRow = rstData.Select("ID = " & PK, "", DataViewRowState.CurrentRows)
If drT.Length > 0 Then
Dim OneDataRow As DataRow
OneDataRow = drT(0)
OneDataRow.Item("FirstName") = CType(gRow.FindControl("txtFirst"), TextBox).Text
OneDataRow.Item("LastName") = CType(gRow.FindControl("txtLast"), TextBox).Text
OneDataRow.Item("City") = CType(gRow.FindControl("txtCity"), TextBox).Text
OneDataRow.Item("Description") = CType(gRow.FindControl("txtDescription"), TextBox).Text
OneDataRow.Item("Nights") = CType(gRow.FindControl("txtNights"), TextBox).Text
' combo box
Dim cboRank As DropDownList = gRow.FindControl("cboRank")
If cboRank.Text = "Select" Then
OneDataRow("Rating") = DBNull.Value
Else
OneDataRow("Rating") = cboRank.SelectedItem.Value
End If
End If
Next
End Sub
Note how we dumped "index" and now do search by PK. (note that datakeys by index WILL be ok, since LV only displays rows not deleted.
Edit4: Delete code - full code listing
As noted, I did post some vb code by mistake.
So, here is the full code listing:
DataTable rstRating = new DataTable();
DataTable rstData = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadData();
Session["rstData"] = rstData;
Session["rstRating"] = rstRating;
}
else
{
rstData = (DataTable)Session["rstData"];
rstRating = (DataTable)Session["rstRating"];
}
}
void LoadData()
{
// set combo box source
rstRating = MyRst("SELECT ID, Rating FROM tblRating ORDER BY ID");
rstData = MyRst("SELECT * FROM tblHotelsA ORDER BY HotelName");
LVHotels.DataSource = rstData;
LVHotels.DataBind();
}
DataTable MyRst(string strSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
cmdSQL.Connection.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
protected void LVHotels_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
DropDownList dl = (DropDownList)e.Item.FindControl("DropDownList1");
dl.DataSource = rstRating;
dl.DataBind();
dl.Items.Insert(0, new ListItem("Please Select", "0"));
// now set to current data row
DataRowView OneRow = (DataRowView)e.Item.DataItem;
if (OneRow["Rating"] != null)
dl.SelectedValue = OneRow["Rating"].ToString();
}
}
protected void cmdSave_ServerClick(object sender, EventArgs e)
{
SaveAllData();
// data saved - move on to next page
// Response.Redirect("MyMain.aspx");
}
protected void cmdAddNew_ServerClick(object sender, EventArgs e)
{
DataRow NewRow = rstData.NewRow();
rstData.Rows.Add(NewRow);
// show this row
LVHotels.DataSource = rstData;
LVHotels.DataBind();
}
void SaveAllData()
{
GridToTable(); // move grid back to table
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL =
new SqlCommand("SELECT * FROM tblHotelsA WHERE ID = 0", conn))
{
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(cmdSQL);
SqlCommandBuilder daU = new SqlCommandBuilder(da);
da.Update(rstData);
// rstData.AcceptChanges()
}
}
}
protected void cmdCancel_ServerClick(object sender, EventArgs e)
{
// cancel without save - go back some place to other page
// Response.Redirect("MyMain.aspx");
}
void GridToTable()
{
// send LV rows back to our table.
foreach (ListViewItem rRow in LVHotels.Items)
{
int PK = (int)LVHotels.DataKeys[rRow.DisplayIndex]["ID"];
// get row by PK
DataRow[] drT = rstData.Select("ID = " + PK,"", DataViewRowState.CurrentRows);
if (drT.Length > 0)
{
DataRow OneDataRow = drT[0];
OneDataRow["FirstName"] = ((TextBox)rRow.FindControl("txtFirst")).Text;
OneDataRow["LastName"] = ((TextBox)rRow.FindControl("txtLast")).Text;
OneDataRow["HotelName"] = ((TextBox)rRow.FindControl("txtHotel")).Text;
DropDownList dlRating = (DropDownList)rRow.FindControl("DropDownList1");
if (dlRating.SelectedIndex == 0)
OneDataRow["Rating"] = DBNull.Value;
else
OneDataRow["Rating"] = dlRating.SelectedItem.Value;
}
}
}
protected void cmdDelete_ServerClick(object sender, EventArgs e)
{
GridToTable();
HtmlButton btn = (HtmlButton)sender;
ListViewItem gRow = (ListViewItem)btn.NamingContainer;
int PK = (int)LVHotels.DataKeys[gRow.DataItemIndex]["ID"];
// get row by PK
DataRow[] drT = rstData.Select("ID = " + PK, "", DataViewRowState.CurrentRows);
drT[0].Delete();
LVHotels.DataSource = rstData;
LVHotels.DataBind();
}
protected void cmdUndo_ServerClick(object sender, EventArgs e)
{
LoadData();
Session["rstData"] = rstData;
}
And the results look like this:
Markup for the buttons was:
<br />
<button id="cmdSave" runat="server" class="btn" onserverclick="cmdSave_ServerClick" >
<span aria-hidden="true" class="glyphicon glyphicon-floppy-saved"> Save</span>
</button>
<button id="cmdCancel" runat="server" class="btn" style="margin-left:15px" onserverclick="cmdCancel_ServerClick" >
<span aria-hidden="true" class="glyphicon glyphicon-arrow-left"> Back/Cancel</span>
</button>
<button id="cmdUndo" runat="server" class="btn" style="margin-left:15px"
onserverclick="cmdUndo_ServerClick" >
<span aria-hidden="true" class="glyphicon glyphicon-refresh"> Undo Edits</span>
</button>
And I was going to add a bootstrap dialog for confirms - the built in browser ones look beyond ugly. But above should clear up the syntax for htis to work.

Select data from Gridview where there is multiple pages

In my gridview I have multiple pages.
I can select one or more items from Page 1 and save it in sql database.
However, If I select one item from Page 1 and another item from Page 2, system only save item from Page 1.
aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (Session["UserName"].ToString() != null)
{
SUserName.Text = Session["UserName"].ToString();
SUserEmail.Text = Session["Email"].ToString();
}
if (!Page.IsPostBack)
{
LoadUserSubSection();
CurrentDate();
this.SearchItems();
}
}
protected void RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes.Add("onmouseover", "MouseEvents(this, event)");
e.Row.Attributes.Add("onmouseout", "MouseEvents(this, event)");
}
//added in
GridViewRow gvr = e.Row;
if (gvr.RowType == DataControlRowType.DataRow)
{
CheckBox chkSelect = gvr.FindControl("chkSelect") as CheckBox;
if (chkSelect != null)
{
int StID = Convert.ToInt32(gvItemDesc.DataKeys[gvr.RowIndex]["StID"]);
chkSelect.Checked = this.StItemDescIDs.Contains(StID);
}
}
}
private void SearchItems()
{
using (SqlConnection con = new SqlConnection(cs))
{
using (SqlCommand cmd = new SqlCommand())
{
string sql = "SELECT [StID],[StNo],[StItemDesc],[CreatedBy] FROM [StationeryRequest].
[dbo].[tblStationeryItemlist]";
if (!string.IsNullOrEmpty(txtSearch.Text.Trim()))
{
sql += " WHERE StItemDesc LIKE #StItemDesc + '%'";
cmd.Parameters.AddWithValue("#StItemDesc", txtSearch.Text.Trim());
}
cmd.CommandText = sql;
cmd.Connection = con;
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
DataTable dt = new DataTable();
sda.Fill(dt);
gvItemDesc.DataSource = dt;
gvItemDesc.DataBind();
}
}
}
}
private List<int> StItemDescIDs
{
get
{
if (this.ViewState["StItemDescIDs"] == null)
{
this.ViewState["StItemDescIDs"] = new List<int>();
}
return this.ViewState["StItemDescIDs"] as List<int>;
}
}
protected void SelectDeselect(object sender, CommandEventArgs e)
{
foreach (GridViewRow gvr in gvItemDesc.Rows)
{
CheckBox chkSelect = gvr.FindControl("chkSelect") as CheckBox;
if (chkSelect != null)
{
chkSelect.Checked = e.CommandName.Equals("SelectAll");
}
}
}
protected void OnPaging(object sender, GridViewPageEventArgs e)
{
//added in
foreach (GridViewRow gvr in gvItemDesc.Rows)
{
CheckBox chkSelect = gvr.FindControl("chkSelect") as CheckBox;
if (chkSelect != null)
{
int StID = Convert.ToInt32(gvItemDesc.DataKeys[gvr.RowIndex]["StID"]);
if (chkSelect.Checked && !this.StItemDescIDs.Contains(StID))
{
this.StItemDescIDs.Add(StID);
}
else if (!chkSelect.Checked && this.StItemDescIDs.Contains(StID))
{
this.StItemDescIDs.Remove(StID);
}
}
}
gvItemDesc.PageIndex = e.NewPageIndex;
this.SearchItems();
}
protected void Search(object sender, EventArgs e)
{
this.SearchItems();
}
submit btn
protected void btnSubmit(object sender, EventArgs e)
{
object id;
//insert into Main Parent table -> tblStationeryRequest
string insertCmdtblStationeryRequest = "INSERT INTO tblStationeryRequest
(Department,RequestFor,UserName,Date,Email,Status) " +
"output inserted.StReqID " + //Get auto increment for StReqID
"VALUES (#Department,#RequestFor,#UserName,#Email,#Date,#Status)";
string Status = "Pending";
using (SqlConnection conn = new SqlConnection(cs))
{
conn.Open();
using (SqlCommand sqlcmd = new SqlCommand(insertCmdtblStationeryRequest, conn))
{
sqlcmd.Parameters.AddWithValue("#Department", ddlDept.SelectedItem.Text);
sqlcmd.Parameters.AddWithValue("#RequestFor", ddlName.SelectedItem.Text);
sqlcmd.Parameters.AddWithValue("#Date", lblCurrentDate.Text);
sqlcmd.Parameters.AddWithValue("#UserName", SUserName.Text);
sqlcmd.Parameters.AddWithValue("#Email", SUserEmail.Text);
sqlcmd.Parameters.AddWithValue("#Status", Status);
//get id from auto increment and will be used it in Child tables -> tblItemRequest,
tblSupplierRequest and so on.
//sqlcmd.ExecuteNonQuery();
id = sqlcmd.ExecuteScalar(); //the result is of Object type, cast it safely
}
}
Debug.WriteLine(id.ToString()); // Access it like this
string lblStID = "";
foreach (GridViewRow row in gvItemDesc.Rows)
{
CheckBox status = (row.Cells[1].FindControl("chkSelect") as CheckBox);
if (status.Checked)
{
if (lblStID != "")
{
lblStID += ",";
}
lblStID += (row.Cells[1].FindControl("chkSelect") as CheckBox).Text;
}
}
//In Page 1, can select one or more items
//However Page 1 one item and Page 2 one time, it only save from Page 1
string insertCmdtblRequestItemListID = "INSERT INTO tblRequestItemListID(StReqID, StID,
StItemDesc) select " + id.ToString() + ",StID,StItemDesc from tblStationeryItemlist where
StID in (" + lblStID + ")";
using (SqlConnection conn = new SqlConnection(cs))
{
conn.Open();
using (SqlCommand sqlcmd = new SqlCommand(insertCmdtblRequestItemListID, conn))
sqlcmd.ExecuteNonQuery();
}
.aspx
Here is my Gridview
< asp:GridView ID = "gvItemDesc" runat = "server" AutoGenerateColumns = "false"
AllowPaging = "true" DataKeyNames = "StID" OnPageIndexChanging = "OnPaging"
OnRowDataBound = "RowDataBound" Font - Size = "11pt" >
< Columns >
< asp:TemplateField >
< HeaderTemplate >
//no need use Check all function
< asp:CheckBox ID = "checkAll" runat = "server" Text = '<%#Eval("StID") %>' onclick
="checkAll(this);" />
</ HeaderTemplate >
< ItemTemplate >
< asp:CheckBox ID = "chkSelect" runat = "server" Text ='<%# Eval("StID") %>' onclick =
"Check_Click(this)" />
</ ItemTemplate >
</ asp:TemplateField >
< asp:BoundField DataField = "StID" HeaderText = "StID" ItemStyle - Width = "150"
SortExpression = "StID" Visible = "false" />
< asp:BoundField DataField = "StItemDesc" HeaderText = "Item Description" ItemStyle -
Width = "150" />
<asp:TemplateField HeaderText = "" >
</ asp:TemplateField >
< asp:TemplateField HeaderText = "" >
< ItemTemplate >
< asp:Label ID ="lblStItemDesc" runat = "server" Text = '<%# Eval("StItemDesc") %>'
Visible ="false" > </ asp:Label >
</ ItemTemplate >
</ asp:TemplateField >
</ Columns >
</ asp:GridView >
Ok, you have two approaches here.
First up, you can just during navigation, or filter, or paging have the user select data, and UPDATE the database (unless that's what you really want???).
What you want:
User can select any old row on the page. Maybe page around for fun, select a few more rows.
At that point, you THEN can process the rows selected and UPDATE the actual database.
So, we want to "separate" these two concepts to be crystal clear in your mind.
Next up:
We have two practical choices. We suffer a post back for the check box in the grid. I often use this, and it not all that bad.
If you REALLY want to avoid that post back, then on both paging event, and your final submit button, you have to "manage" that checked list.
Lets go with Mr. Easy. And if you really need the 2nd approach, then I can post a solution, but no need to do extra work when/if you don't need as such.
So, our simple grid - NOTE how the check box is un-bound - no data source.
So, our grid:
<asp:GridView ID="GVHotels" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table" AllowPaging="true"
OnPageIndexChanging="GVHotels_PageIndexChanging" OnRowDataBound="GVHotels_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" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="To Process" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox ID="chkSel" runat="server" CssClass="bigcheck"
OnCheckedChanged="chkSel_CheckedChanged"
AutoPostBack="true" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<PagerStyle CssClass="GridPager" />
</asp:GridView>
<asp:Button ID="cmdProcess" runat="server" Text="Process selected" CssClass="btn" OnClick="cmdProcess_Click" />
<br />
Code to fill grid:
List<int> MySelList = new List<int>();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadGrid();
ViewState["MySelect"] = MySelList;
}
else
MySelList = (List<int>)ViewState["MySelect"];
}
void LoadGrid()
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL = "SELECT * FROM tblHotels " +
"WHERE Description is not null " +
"ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
DataTable rst = new DataTable();
rst.Load(cmdSQL.ExecuteReader());
GVHotels.DataSource = rst;
GVHotels.DataBind();
}
}
}
and we now have this:
Ok, so now we need two extra routines.
The code to add/remove the selected check from the list (that we persisted).
That check box has auto post-back = true, and thus the code for that check box is this simple stub:
protected void chkSel_CheckedChanged(object sender, EventArgs e)
{
CheckBox chk = (CheckBox)sender;
GridViewRow gRow = (GridViewRow)chk.Parent.Parent;
int pkID = (int)GVHotels.DataKeys[gRow.RowIndex]["ID"];
if (chk.Checked)
{
// add to sel list
if (!MySelList.Contains(pkID))
MySelList.Add(pkID);
}
else
MySelList.Remove(pkID);
}
Ok, that will manage the selected check boxes for us.
Now, we also need to update the display (show which rows selected).
protected void GVHotels_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
CheckBox chk = (CheckBox)e.Row.FindControl("chkSel");
int pkID = (int)GVHotels.DataKeys[e.Row.RowIndex]["ID"];
chk.Checked = MySelList.Contains(pkID);
}
}
Ok, we are quite much done. The user is now free to page around - select any row they want for processing. And this trick works REALLY great for some types of reports or what not. You can present grid - let user pick/choose, and then say use that result for a filter for a report, a graph, or whatever.
So, now, when the user hits that above "process" button (could be for anything).
Let's update the Hotels "Active" column = true for the ones the user selected.
Our code for the "process" button thus could be this:
protected void cmdProcess_Click(object sender, EventArgs e)
{
if (MySelList.Count >0)
{
string sWhere = " ID in (" + string.Join(",", MySelList) + ")";
string strSQL = "UPDATE tblHotels SET Active = 1 WHERE " + sWhere;
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
using (SqlCommand cmdSQL = new SqlCommand(strSQL))
{
conn.Open();
cmdSQL.ExecuteNonQuery();
}
// Clear our select list
MySelList = new List<int>();
}
}
So, the above is nice, since we don't have to update the data base for this selecting process, and OFTEN that's not our goal anyway. However, as above shows, it rather easy to apply the list to some code to update the database.
Also NOTE VERY careful that I do not show, nor display the database PK id in that GV. I don't have to, since we have the DataKeys feature for that purpose. And VERY nice is that DataKeys is 100% automatic managed server side, and the key list is NOT exposed in the client side browser as plain text. (so, MUCH better for security). And since those datakeys are not based on user input - then I was able to use a simple string concatenation for the criteria. Had I used input, or even a exposed column from the GV, then we would open up to sql injection issues - but none exist in above, since we not using any displayed column from the GV.
As noted, if you REALLY can't have a post back, then we can move this code to the final submit button, but ALSO will have code in the pager event. However, I think since post-backs occur when the user has to page around then it not all that big of a deal to have a post-back for each check box event. As noted, you can always put JUST the grid in a update panel, but even then in most cases you find the above works just fine.
On the other hand, if you really WANT the data to be updated as you move aroud? then we can dump the MySel list code, and simply bind the check box to the database row. Then on paging we can update the database. The problem then becomes what happens if the user selects some rows/check box, and DOES NOT page? In other words, we almost for sure have a final button below the grid to continue? Right? So, we can update on paging, but you have to figure out what occures if they select, and don't page? And if there is some final button to hit, then again we back to my above working example anyway.

Fetch value from database as selected in dropdownlist

I have a asp page in which i have a dropdown list. The complete list of values is binded in dropdown list from the database table "a". After selecting any value from that dropdown, i save it to database table "b". Now, in 2nd asp page, i want to have that dropdown list with selected value from table "b".
My aspx page:
<asp:DropDownList DataSource='<%# getBankTable() %>' ID="ddlBankName" DataValueField='BANK_ID'
DataTextField="BANK_DESC" SelectedValue='<%# Eval("BANK_ID") %>' AppendDataBoundItems="true"
runat="server">
</asp:DropDownList>
My .cs Page:
protected void Page_Load(object sender, EventArgs e)
{
string sql1 = "SELECT * FROM Master LEFT JOIN BANK ON Master.BANK_ID = Transaction.BANK_ID";
OracleDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
ddlBankName.Items.FindByValue(dr["BANK_ID"].ToString()).Selected = true;
}
}
public void getBankTable()
{
ddlBankName.Items.Clear();
ddlBankName.Items.Insert(0, new ListItem("Select", ""));
clsDataAccess cls = new clsDataAccess();
string sql = "SELECT BANK_ID,BANK_DESC FROM Master";
DataTable dt = cls.GetDataTable(sql);
ddlBankName.DataTextField = "BANK_DESC";
ddlBankName.DataValueField = "BANK_ID";
ddlBankName.DataSource = dt;
ddlBankName.DataBind();
}
I am not able to do that. Please help!!
Personally I think it would be best to populate the Dropdown in your CS and set the value there as well.
<asp:DropDownList ID="ddlBankName" DataValueField='BANK_ID' DataTextField="BANK_DESC" AppendDataBoundItems="true" runat="server">
</asp:DropDownList>
In your CS page:
protected void Page_Load(object sender, EventArgs e) {
//Only fill it once on page load:
if (!Page.IsPostBack) {
getBankTable();
string sql1 = "SELECT * FROM Master LEFT JOIN BANK ON Master.BANK_ID = Transaction.BANK_ID";
OracleDataReader dr = cmd.ExecuteReader();
while (dr.Read()) {
if (dr["BANK_ID"] != null)
{
ddlBankName.Items.FindByValue(dr["BANK_ID"].ToString()).Selected = true;
}
}
}
}
public void getBankTable() {
ddlBankName.Items.Clear();
ddlBankName.Items.Insert(0, new ListItem("Select", ""));
clsDataAccess cls = new clsDataAccess();
string sql = "SELECT BANK_ID,BANK_DESC FROM Master";
DataTable dt = cls.GetDataTable(sql);
ddlBankName.DataTextField = "BANK_DESC";
ddlBankName.DataValueField = "BANK_ID";
ddlBankName.DataSource = dt;
ddlBankName.DataBind();
}

how to change gridview paging when have search result

I have gridview and some textbox that user can search .
when user search I updated gridview but when changed pageing I bind gridview again and I lost search result .
how can I change gridview paging without call DataBind Again?
I used this for Paging:
protected void grv_Data_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
grv_Data.PageIndex = e.NewPageIndex;
TicketDataBinding();
}
and my search method is :
protected void btn_search_Click(object sender, EventArgs e){
using (var ticket = new BLL.Ticket())
{
grv_Data.DataSource = tit.SelectList( fromDate, toDate);
grv_Data.DataBind();
}}
sorry I forgot asp.net webform and I dont know how do this ?
I've included two examples of binding data to a GridView where paging still works on filtered data. I hope it helps you.
1.You can do this completely in .ASPX:
<form id="form1" runat="server">
<asp:TextBox ID="txtEmailAddress" runat="server"></asp:TextBox>
<asp:Button runat="server" Text="Search" />
<asp:GridView ID="GridView1" runat="server" DataSourceID="sqlDS" AllowPaging="true" PageSize="5" AutoGenerateColumns="true">
<Columns>
<asp:BoundField DataField="EmailType" />
<asp:BoundField DataField="EmailAddress" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="sqlDS"
runat="server"
ConnectionString="<%$ ConnectionStrings:conn %>"
SelectCommand="SELECT EmailType, EmailAddress FROM EmailNotifications WHERE EmailAddress LIKE #EmailAddressParam + '%'">
<SelectParameters>
<asp:ControlParameter ControlID="txtEmailAddress" DbType="String" Name="EmailAddressParam" DefaultValue="%" />
</SelectParameters>
</asp:SqlDataSource>
</form>
2.Or in code behind:
public partial class PagingAndSearchingInGridView : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.GetData();
}
private void GetData()
{
string emailAddress = txtEmailAddress.Text;
DataTable table = !Page.IsPostBack ? GetEmails() : GetEmails(emailAddress);
GridView1.DataSource = table;
GridView1.DataBind();
}
private DataTable GetEmails(string emailAddress = "%")
{
var table = new DataTable();
string connectionString = ConfigurationManager.ConnectionStrings["conn"].ConnectionString;
using (var connection = new SqlConnection(connectionString))
{
using (var command = new SqlCommand("SELECT EmailType, EmailAddress FROM EmailNotifications WHERE EmailAddress LIKE #EmailAddressParam + '%'", connection))
{
command.Parameters.AddWithValue("#EmailAddressParam", emailAddress);
using (var a = new SqlDataAdapter(command))
{
connection.Open();
a.Fill(table);
connection.Close();
}
}
}
return table;
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
this.GetData();
}
}
While the pageIndex changed event, you can check whether the search button is already clicked or not. When clicking the search button you can set a hiddenfield value to 1 or something like that.
protected void grv_Data_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
grv_Data.PageIndex = e.NewPageIndex;
if(status==1) //Search button is already clicked, means the grid contains searched result
{
grv_Data.DataSource = tit.SelectList( fromDate, toDate);
}
else
{
//Search button is not clicked .. means the grid contains all records.
TicketDataBinding();
}
}

Grab SelectedValue of Dropdownlist in Gridview

Creating a list of users that haven't updated their job title in a Gridview. I want the list to have a dropdown filled with all the possible title selections and a button next to the dropdown. Then a person can come in and change the title in the dropdown hit the button and its updated and removed from the list.
I have all of this the way I want it to look but I'm trying to figure out how to pass the SelectedValue of the dropdown box in that row to the code behind OnClick. As you can see below the closest I can get is pass the row number in the CommandArgument. Any suggestions how I can get the SelectedValue of the dropdown of that specific row to the OnClick?
EDIT: Maybe I should be using OnRowCommand instead of OnClick?
Looks like this currently:
John Doe | DropdownList Button
Jane Doe | DropdownList Button
Joe Doe | DropdownList Button
Jeff Doe | DropdownList Button
ASPX
<asp:GridView runat="server" ID="TitleView" OnRowDataBound="TitleView_RowDataBound" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="Fullname" HeaderText="Fullname" />
<asp:TemplateField>
<ItemTemplate>
<div class="input-append"><asp:DropDownList CssClass="span5" ID="TitleList" runat="server">
</asp:DropDownList>
<asp:Button ID="lbnView" runat="server" Text="Update" CssClass="btn btn-primary" OnClick="btn_Clicked"
CommandArgument='<%# ((GridViewRow)Container).RowIndex %>'></asp:Button></div>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code Behind
public void bindTitleView()
{
using (SqlConnection conn = new SqlConnection(""))
{
SqlCommand cmd = new SqlCommand(#"SELECT U.First + ' ' + U.Last as Fullname, U.UserID, T.Name FROM Employees U LEFT JOIN Titles T ON U.Title = T.ID WHERE U.Active = '1' AND U.Title = '92' ORDER BY Fullname ASC", conn);
conn.Open();
SqlDataAdapter adp = new SqlDataAdapter(cmd);
DataSet myDataSet = new DataSet();
adp.Fill(myDataSet);
TitleView.DataSource = myDataSet;
TitleView.DataBind();
}
}
protected void TitleView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl = (DropDownList)e.Row.FindControl("TitleList");
using (SqlConnection conn = new SqlConnection(""))
{
SqlCommand cmd = new SqlCommand(#"SELECT ID, Name FROM Titles ORDER BY Name ASC", conn);
conn.Open();
SqlDataAdapter adp = new SqlDataAdapter(cmd);
DataTable myDataSet = new DataTable();
adp.Fill(myDataSet);
ddl.DataSource = myDataSet;
ddl.DataTextField = "Name";
ddl.DataValueField = "ID";
ddl.DataBind();
}
}
}
protected void btn_Clicked(object sender, EventArgs e)
{
String rowid = ((Button)sender).CommandArgument;
}
SOLUTION: The answer I approved below worked for me once I added !IsPostBack to the Page_Load
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
bindTitleView();
}
You can do like that:
protected void btn_Clicked(object sender, EventArgs e)
{
int line = ((GridViewRow)((Button)sender).Parent.Parent).RowIndex;
DropDownList drp = ((DropDownList)TitleView.Rows[line].FindControl("TitleList"));
//Continue the method
}
In your btn_click write the following code
protected void btn_Clicked(object sender, EventArgs e)
{
Button Sample = sender as Button;
GridViewRow row = Sample.NamingContainer as GridViewRow;
DropDownList drp = row.FindControl("TitleList") as DropDownList;
//Now use drp.SelectedValue
}
}
Let me know if this isnt what you are looking for.

Categories