foreach by check on two control (dropdownlist and textbox) - c#

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.

Related

ASP.net update DropDownList

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:

asp:gridview filter using listbox cannot make multiple selection

I have this asp:gridview in which I show data using mySql stored procedure. I have this listbox named ddlstatus which I use to filter the data. I use viewstate to show data that are selected from the listbox. The problem is I want to make multiple selection on this listbox and show data for each selection made on it, but when it only shows data for the initial selection.
The below is the client side code:
<asp:Label ID="lblstat" Text="status" Visible="false" runat="server"></asp:Label>
<asp:ListBox ID="ddlstatus" runat="server" OnSelectedIndexChanged="DropDownChange" AutoPostBack="true" AppendDataBoundItems="true" SelectionMode="Multiple"></asp:ListBox>
<asp:GridView ID="gdvTM" runat="server" ControlStyle-Width="100%" AutoGenerateColumns="False" DataKeyNames="ID" OnRowDeleting="gdvTM_RowDeleting" PageSize="5" CssClass="cssgridview" AlternatingRowStyle-BackColor="#d5d8dc">
<Columns >
<asp:TemplateField HeaderText="Current Status">
<ItemTemplate >
<asp:Label ID="lblcstat" runat="server" Text='<%# Eval("status") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
The below is the server side code:
private void BindDropDownList()
{
PopulateDropDown(ddlstatus, lblstat.Text);
}
private void PopulateDropDown(ListBox ddl, string columnName)
{
ddl.Items.Clear();
ddl.DataSource = BindDropDown(columnName);
ddl.DataTextField = columnName;
ddl.DataValueField = columnName;
ddl.DataBind();
ddl.Items.Insert(0, new ListItem("Please select", "0"));
}
private void BindGrid()
{
DataTable dt = new DataTable();
String strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
MySqlConnection con = new MySqlConnection(strConnString);
MySqlDataAdapter sda = new MySqlDataAdapter();
MySqlCommand cmd = new MySqlCommand("GetTMData");
cmd.CommandType = CommandType.StoredProcedure;
string statusVal = null;
if (ViewState["stat"] != null && ViewState["stat"].ToString() != "0")
{
statusVal = ViewState["stat"].ToString();
}
cmd.Parameters.AddWithValue("statusVal", statusVal);
cmd.Connection = con;
sda.SelectCommand = cmd;
sda.Fill(dt);
gdvTM.DataSource = dt;
int i = dt.Rows.Count;
gdvTM.DataBind();
this.BindDropDownList();
TableCell cell = gdvTM.HeaderRow.Cells[0];
setDropdownselectedItem(ViewState["stat"] != null ? (string)ViewState["stat"] : string.Empty, ddlstatus);
}
private void setDropdownselectedItem(string selectedvalue, ListBox ddl)
{
if (!string.IsNullOrEmpty(selectedvalue))
{
ddl.Items.FindByValue(selectedvalue).Selected = true;
}
}
protected void DropDownChange(object sender, EventArgs e)
{
ListBox dropdown = (ListBox)sender;
string selectedValue = dropdown.SelectedItem.Value;
switch (dropdown.ID.ToLower())
{
case "ddlstatus":
ViewState["stat"] = selectedValue;
break;
}
this.BindGrid();
}
private DataTable BindDropDown(string columnName)
{
string username = uName.Text;
String strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
MySqlConnection con = new MySqlConnection(strConnString);
MySqlCommand cmd = new MySqlCommand("SELECT DISTINCT (" + columnName + ") FROM approved WHERE tm = #tm AND " + columnName + " IS NOT NULL", con);
MySqlDataAdapter sda = new MySqlDataAdapter(cmd);
cmd.Parameters.AddWithValue("#tm", username);
DataTable dt = new DataTable();
sda.Fill(dt);
return dt;
}
Below is the MySql stored procedure:
CREATE DEFINER=`root`#`localhost` PROCEDURE `GetTMData`(in statusVal varchar(45))
BEGIN
SELECT *
FROM approved
WHERE (statusVal IS NULL
OR status = statusVal)
order by date desc;
END
How can I make this happen? Thanks in advance.
Please make listbox multiple
<asp:ListBox id="ListBox1"
Rows="6"
Width="100px"
**SelectionMode="Multiple"**
runat="server">
<asp:ListItem Selected="True">Item 1</asp:ListItem>
<asp:ListItem>Item 2</asp:ListItem>
<asp:ListItem>Item 3</asp:ListItem>
<asp:ListItem>Item 4</asp:ListItem>
<asp:ListItem>Item 5</asp:ListItem>
<asp:ListItem>Item 6</asp:ListItem>
</asp:ListBox>
Then in server side
void SubmitBtn_Click(Object sender, EventArgs e)
{
Message.Text = "You chose: <br />";
// Iterate through the Items collection of the ListBox and
// display the selected items.
foreach (ListItem item in ListBox1.Items)
{
if(item.Selected)
{
Message.Text += item.Text + "<br />";
}
}
}
First of all, auto post back not allow you to select multiple items because upto select second item, the postback already happens by first selected item so,
You have to set AutoPostBack="false" for your list box,
<asp:ListBox ID="ddlstatus" runat="server" AutoPostBack="false" AppendDataBoundItems="true" SelectionMode="Multiple"></asp:ListBox>
For collecting multiple selected items we simply choose button for instance, you can collect those items wherever you want,
Then add one button that will call below code
<asp:Button ID="button1" runat="server" OnClick="button1_Click" Text="Click"/>
On above button event handler add below code,
protected void button1_Click(object sender, EventArgs e)
{
var selectedNames = ddlstatus.Items.Cast<ListItem>()
.Where(i => i.Selected)
.Select(i => i.Value)
.ToList();
string selectedValue = string.Join("','", selectedNames);
selectedValue = "'" + selectedValue + "'";
ViewState["stat"] = selectedValue;
}
Then the comma separated items in your ViewState will be used in your stored procedure parameter
string statusVal = null;
if (ViewState["stat"] != null && ViewState["stat"].ToString() != "0")
{
statusVal = ViewState["stat"].ToString();
}
cmd.Parameters.AddWithValue("statusVal", statusVal); //<= Now this string variable contains comma separated list box items values.
If you populate your list box on Page_Load then make sure that you should populate it into !Page.IsPostBack like
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//Populate your list box here
}
}
And your SP is
CREATE DEFINER=`root`#`localhost` PROCEDURE `GetTMData1`(in statusVal varchar(255))
BEGIN
IF statusVal = '\'\'' THEN
select * from approved;
ELSE
SET #sql = CONCAT('SELECT * FROM approved WHERE status IN (', statusVal, ')');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF ;
END
If you select multiple items from the dropdown then your SP's parameter data look like '\'apple\',\'banana\''. If not then it look like '\''.
There's a few issues that I could spot that may need to be addressed,
Ensure that the method BindDropDownList is only called on a non postback (page refresh), because your method PopulateDropDown is clearing the items on the list which means that viewstate cannot be restored in a postback, hence the probable reason why only one item is being selected.
I'm not 100% of the table schema, but the SQL provided does not seem to be able to query by more than one status properly, you should probably send a comma separated list of values, and in SQL turn them into a temp table so that you effectively search for items with multiple status (you should probably create a new question for this).
Do not use SelectedItem for multiple selections, instead you need to iterate your list items for those that are selected, and you don't need to use ViewState to pass it along (you probably did because of point 1. above). For example you could replace your method BindGrid and DropDownChange with:
private void BindGrid()
{
DataTable dt = new DataTable();
String strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
MySqlConnection con = new MySqlConnection(strConnString);
MySqlDataAdapter sda = new MySqlDataAdapter();
MySqlCommand cmd = new MySqlCommand("GetTMData");
cmd.CommandType = CommandType.StoredProcedure;
string statusVal = null;
foreach (ListItem item in ddlstatus.Items)
{
if(item.Selected)
{
if(statusVal.length > 0)
statusVal += ",";
statusVal += item.Value;
}
}
cmd.Parameters.AddWithValue("statusVal", statusVal);
cmd.Connection = con;
sda.SelectCommand = cmd;
sda.Fill(dt);
gdvTM.DataSource = dt;
gdvTM.DataBind();
}
protected void DropDownChange(object sender, EventArgs e)
{
this.BindGrid();
}

How to highlight search results in gridview using asp.net?

I am using a search box to sort my gridview according to the search text. I want to highlight the matching text in the gridview entered into the textbox.
This is my aspx page-
<table>
<tr>
<td>
<asp:TextBox ID="TextBox1" runat="server" Width="167px">
</asp:TextBox>
</td>
</tr>
<tr>
<td>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click"
Text="Submit" Width="116px" />
</td>
</tr>
<tr>
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</tr>
</table>
code behind
public void bind()
{
dt = g1.return_dt("select * from tbl1 where id is not null "
+ Session["Name"] + " order by compname ");
if (dt.Rows.Count > 0)
{
adsource = new PagedDataSource();
adsource.DataSource = dt.DefaultView;
adsource.PageSize = 10;
adsource.AllowPaging = true;
adsource.CurrentPageIndex = pos;
btnfirst.Enabled = !adsource.IsFirstPage;
btnprevious.Enabled = !adsource.IsFirstPage;
btnlast.Enabled = !adsource.IsLastPage;
btnnext.Enabled = !adsource.IsLastPage;
GridView1.DataSource = adsource;
GridView1.DataBind();
}
else
{
GridView1.DataSource = null;
GridView1.DataBind();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
if (TextBox1.Text != "")
{
Session["Name"] = string.Format("and compname like '%{0}%' or productcategory like '%{0}%' or country like '%{0}%'");
}
else
{
Session["Name"] = null;
}
}
Please guide me how can I do this.
You can do it in two ways:
Modify the text in the relevant columns of you data table. (Find the text in each column and add an span with css class surrounding that text.) Here is a sample:
foreach(DataRow dr in dt.Rows)
{
foreach(DataColumn dc in dt.Columns)
{
string s = Convert.ToString(dr[dc.ColumnName]);
s = s.Replace("Your Search Text","<span style='color:RED'>Your Search Text</span>");
dr[dc.ColumnName] = s;
}
}
You can use javascript for the same and let the browser do all the hardwork. (Refer this link for a sample.)
Hope this helps.

Toggle display the child DataList

I am try to toggle the display subnet data(childList). This codes below are working fine, but not able to toogle the display. When I click on the (+) sign, the ChildList dataList expands and displays the list subset data (Contact). However, I want to change the (+) to (-) when childList data expanded. And when user clicks on (-), it will collapse back (the child list disappear)
Any idea how to do this? an example code would be great since I am a newbie of ASP.NET.
<table width="595px">
<asp:DataList BackColor="#ffffff" id="DataList1" DataSourceID="dsCompanyList" runat="server" Width="100%" DataKeyField="Company">
<ItemTemplate>
<tr>
<td>
<asp:LinkButton ID="LinkButton1" runat="server" Text="+" CommandArgument='<%#Container.ItemIndex%>'
OnCommand="LinkButton1_Command"
></asp:LinkButton>
</td>
<td><%#Eval("Row")%></td>
<td><%#Eval("Company")%></td>
</tr>
<asp:Panel ID="pnlChildView" runat="server">
<asp:DataList ID="childList" runat="server" Width="100%">
<ItemTemplate>
<tr>
<td><%#Eval("FirstName")%></td>
<td><%#Eval("LastName")%></td>
</tr>
</ItemTemplate>
</asp:DataList>
</asp:Panel>
</ItemTemplate>
</asp:DataList>
</table>
Code Behind:
public partial class _CompanyList2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void LinkButton1_Command(object sender, CommandEventArgs e)
{
//pass index of item in command argument
int itemIndex = Convert.ToInt32(e.CommandArgument);
//depending on your needs bind the details on demand
//or preload during ItemDataBound
Panel childViewPanel = (Panel)DataList1.Items[itemIndex].FindControl("pnlChildView");
if (childViewPanel != null)
{
//toggle visibility of childViewPanel and bind child list if panel is visible
DataList childList = (DataList)childViewPanel.FindControl("childList");
if (childList != null)
{
//int keyValue = (int)DataList1.DataKeys[itemIndex];
string keyValue = (string)DataList1.DataKeys[itemIndex];
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["connApps"].ConnectionString))
{
con.Open();
using (SqlCommand cmd = new SqlCommand("SELECT FirstName, LastName FROM dbo.Import_CompanyContact WHERE REPLACE(Company, '''', '') = '" + keyValue + "'", con))
{
cmd.CommandType = CommandType.Text;
using (SqlDataReader dr = cmd.ExecuteReader())
{
childList.DataSource = dr;
childList.DataBind();
}
}
}
}
}
}
}

Selected value on a DropDownList inside of a repeater

I'm adding a dropdwonlist inside of my repeater. Now I need to set a selected value for my dropdownlist.. but I'm not being very successful..
private void PhysicianSource()
{
DataSet ds = new DataSet();
DataTable dt = ds.Tables.Add("Source");
dt.Columns.Add("ID", Type.GetType("System.String"));
dt.Columns.Add("Desc", Type.GetType("System.String"));
Provider oProvider = new Provider();
List<ProviderLabel> lstprovider = oProvider.RetrievePhysicianList();
foreach (ProviderLabel item in lstprovider)
{
DataRow dr = dt.NewRow();
dr[0] = item.ProviderCode.ID.ToString();
dr[1] = item.Name.ToString();
dt.Rows.Add(dr);
}
drpPhysicianCode.DataSource = ds;
drpPhysicianCode.DataMember = "Source";
drpPhysicianCode.DataTextField = "ID";
drpPhysicianCode.DataValueField = "ID";
drpPhysicianCode.DataBind();
}
asp.net
<asp:Repeater ID="rptrPatientList" runat="server" >
<HeaderTemplate></HeaderTemplate>
<ItemTemplate>
<tr>
<td class="style2">
<asp:DropDownList ID="DropDownList1"
DataTextField="ID" runat="server"
DataValueField="Desc"
SelectedValue='<%# Eval("Code") %>'
DataSource="ds">
</asp:DropDownList>
</td>
</td>
</tr>
nothing happens on my codes.. help me guys I'm just a beginner on this.. thank you very much..
Hi Ian Ace its better to modify your code a little bit
<asp:Repeater ID="rptProductList" runat="server" OnItemDataBound="rptProductList_ItemDataBound">
<ItemTemplate>
<asp:DropDownList runat="server" ID="MyRepeater" AutoPostBack="true" OnSelectedIndexChanged="DropDownList_SelectedIndexChanged" >
</asp:DropDownList>
</ItemTemplate>
</asp:Repeater>
Now the code behind should be
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
fillRepeater();
}
}
}
protected void rptProductList_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
DropDownList MyDropDown= (DropDownList)e.Item.FindControl("MyRepeater");
if (MyDropDown!= null)
{
MyDropDown.DataSource = fillDropDown(MyDropDown);
MyDropDown.DataBind();
}
}
}
private DataSet fillDropDown(DropDownList dropDown)
{
// get your collection and return.
}
protected void DropDownList_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList MyDropDown= (DropDownList)sender;
string item = MyDropDown.SelectedValue;
}
hope the above example helps.
Try setting the selected value after data binding
Don't set the list contents with every postback. Check for Page.IsPostBack(). Note that this only works if you have ViewState enabled.
//Declare Class Scoped DataSet and DataTable variables
DataSet ds;
DataTable dt;
//Bind repeater and DataSource method
private void PhysicianSource()
{
ds = new DataSet();
dt = ds.Tables.Add("Source");
dt.Columns.Add("ID", Type.GetType("System.String"));
dt.Columns.Add("Desc", Type.GetType("System.String"));
Provider oProvider = new Provider();
List<ProviderLabel> lstprovider = oProvider.RetrievePhysicianList();
foreach (ProviderLabel item in lstprovider)
{
DataRow dr = dt.NewRow();
dr[0] = item.ProviderCode.ID.ToString();
dr[1] = item.Name.ToString();
dt.Rows.Add(dr);
}
drpPhysicianCode.DataSource = ds;
drpPhysicianCode.DataMember = "Source";
drpPhysicianCode.DataTextField = "ID";
drpPhysicianCode.DataValueField = "ID";
drpPhysicianCode.DataBind();
}
//Repeater Item Data Bound event in which we would find Controls to be bound
//and set DataSource and SelectedValue
protected void rptrPatientList_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
DropDownList DropDownList1 = e.Item.FindControl("DropDownList1") as DropDownList;
if (DropDownList1 != null)
{
DropDownList1.DataSource = dt;
DropDownList1.DataBind();
DropDownList1.SelectedValue = // DataBinder Eval 'Code' //;
}
}
}
<asp:Repeater ID="rptrPatientList" runat="server" OnItemDataBound="rptrPatientList_ItemDataBound">
<HeaderTemplate></HeaderTemplate>
<ItemTemplate>
<tr>
<td class="style2">
<asp:DropDownList ID="DropDownList1"
DataTextField="ID" runat="server"
DataValueField="Desc"
SelectedValue='<%# Eval("Code") %>'
DataSource="ds">
</asp:DropDownList>
</td>
</td>
</tr>
The problem occurs because the binding of dropdown occurs after that of repeater control. You can use HTML5 custom attributes, to set your dropdown value into a custom attribute, and then setting it as selected value after the dropdown is databinded. I have binded the dropdown using asp:ObjectDataSource
ASPX
<asp:Repeater ID="rptrPatientList" runat="server" >
<HeaderTemplate></HeaderTemplate>
<ItemTemplate>
<tr>
<td class="style2">
<asp:DropDownList ID="DropDownList1"
DataTextField="ID" runat="server"
DataValueField="Desc"
SetValue='<%# Eval("Code") %>' datasourceid="dsCategory"
datatextfield="ID" datavaluefield="desc" DataMember = "Source" onprerender="DropDownDataBinding">
</asp:DropDownList>
<asp:ObjectDataSource ID="dsCategory" runat="server" SelectMethod="PhysicianSource" TypeName="WebApplication.WebForm1" />
</td>
</td>
</tr>
CodeBehind
protected void DropDownDataBinding(object sender, EventArgs e) //Method to set the selected value on Category dropdown inside repeater
{
DropDownList sel = (DropDownList)sender;
sel.Value = sel.Attributes["SetValue"];
ListItem li = new ListItem("<< Select >>", "");
sel.Items.Insert(0,li);
}
protected DataSet PhysicianSource()
{
DataSet ds = new DataSet();
DataTable dt = ds.Tables.Add("Source");
dt.Columns.Add("ID", Type.GetType("System.String"));
dt.Columns.Add("Desc", Type.GetType("System.String"));
Provider oProvider = new Provider();
List<ProviderLabel> lstprovider = oProvider.RetrievePhysicianList();
foreach (ProviderLabel item in lstprovider)
{
DataRow dr = dt.NewRow();
dr[0] = item.ProviderCode.ID.ToString();
dr[1] = item.Name.ToString();
dt.Rows.Add(dr);
}
return ds;
}

Categories