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.
Related
I work on asp.net web forms with c# I need to add checkbox column as last column on gridview
but i don't know how to add it
static string con =
"Data Source=DESKTOP-L558MLK\\AHMEDSALAHSQL;" +
"Initial Catalog=UnionCoop;" +
"User id=sa;" +
"Password=321;";
SqlConnection conn = new SqlConnection(con);
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridViewSearch.DataSource = GetDataForSearch();
GridViewSearch.DataBind();
}
}
public DataTable GetDataForSearch()
{
string response = string.Empty;
SqlCommand cmd = new SqlCommand();
DataTable dt = new DataTable();
try
{
conn.Open();
cmd.Connection = conn;
cmd.CommandText = "select top 10 datelogged AS EntredDatetime, Doc_type AS OrderType, Printer_name, BranchID AS BranchCode, id from Print_Report";
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = 50000;
SqlDataAdapter sda = new SqlDataAdapter(cmd);
sda.Fill(dt);
}
catch (Exception ex)
{
response = ex.Message;
}
finally
{
cmd.Dispose();
conn.Close();
}
return dt;
}
on aspx page
<asp:GridView ID="GridViewSearch" runat="server">
</asp:GridView>
GridViewSearch.DataSource = GetDataForSearch();
DataGridViewCheckBoxColumn checkColumn = new DataGridViewCheckBoxColumn();
checkColumn.Name = "X";
checkColumn.HeaderText = "X";
checkColumn.Width = 50;
checkColumn.ReadOnly = false;
checkColumn.FillWeight = 10; //if the datagridview is resized (on form resize) the checkbox won't take up too much; value is relative to the other columns' fill values
GridViewSearch.Columns.Add(checkColumn);
GridViewSearch.DataBind();
I get error on line below
GridViewSearch.Columns.Add(checkColumn);
argument 1 can't convert from system.windows.forms.datagridviewcheckbox to system.web.ui.webcontrol.databoundfield
so how to solve this issue please ?
Seems to me, that if you want say a button, or check box, or dropdown?
why not just add it to the markup.
So, say like this:
<div id="MyGridPick" runat="server" style="display:normal;width:40%">
<asp:Label ID="lblSel" runat="server" Text="" Font-Size="X-Large"></asp:Label>
<br />
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" cssclass="table table-hover" 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="Select" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox ID="chkSel" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
Then my code to load is this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid();
}
void LoadGrid()
{
SqlCommand cmdSQL =
new SqlCommand("SELECT * FROM tblHotelsA ORDER BY HotelName");
GridView1.DataSource = MyRstP(cmdSQL);
GridView1.DataBind();
}
Now, of course I get VERY tired of typing that connection string stuff over and over. So, I have a "genreal" routine like this:
public DataTable MyRstP(SqlCommand cmdSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
cmdSQL.Connection = conn;
using (cmdSQL)
{
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
And the result of running above:
So, kind of hard to make the case to "add" a check box control, when you can just drop one into the gridview.
Same goes for a button, maybe we want a button to "view" or edit the above row, or some such.
So, once again, just drop in a plain jane button, say like this:
<asp:TemplateField HeaderText="View" ItemStyle-HorizontalAlign="Center" >
<ItemTemplate>
<asp:Button ID="bView" runat="server" Text="View" CssClass="btn"
OnClick="bView_Click" />
</ItemTemplate>
</asp:TemplateField>
And now we have this:
And EVEN better?
Well, since that button (or check box) is a plain jane standard control?
then you can add standard events, like a click event, or whatever you want.
Say this code for the button click (shows how to get current row).
protected void bView_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
GridViewRow gRow = btn.NamingContainer as GridViewRow;
int PKID = (int)GridView1.DataKeys[gRow.RowIndex]["ID"];
SqlCommand cmdSQL =
new SqlCommand("SELECT * FROM tblHotelsA WHERE ID = #ID");
cmdSQL.Parameters.Add("#ID", SqlDbType.Int).Value = PKID;
DataTable dtHotel = MyRstP(cmdSQL);
General.FLoader(MyEditArea, dtHotel.Rows[0]);
MyGridPick.Style.Add("display", "none"); // hide grid
MyEditArea.Style.Add("display", "normal"); // show edit div area
}
And we now get/see this:
Edit: Process each checked/selected row.
this:
protected void cmdSelProcess_Click(object sender, EventArgs e)
{
// process all rows in GV with check box
String sPK = "";
List<int> MySelected = new List<int>();
foreach (GridViewRow gRow in GridView1.Rows)
{
CheckBox chkSel = (CheckBox)gRow.FindControl("chkSel");
if (chkSel.Checked)
{
int PK = (int)GridView1.DataKeys[gRow.RowIndex]["ID"];
// add pk value of row to our list
MySelected.Add(PK);
// Or we could process data based on current gRow
if (sPK != "")
sPK += ",";
sPK += PK.ToString();
Debug.Print(PK.ToString());
}
}
// at this point, we have a nice list of selected in MySelected
// or, maybe process as a data table
SqlCommand cmdSQL =
new SqlCommand($"SELECT * FROM tblHotelsA where ID IN({sPK})");
DataTable rstSelected = MyRstP(cmdSQL);
//
foreach (DataRow dr in rstSelected.Rows)
{
// do whatever
}
}
Datagridviewcheckboxcolumn is a Windows formx object. You are working in web forms. Please see the link below for information on the webforms check box field
CheckBoxField checkColumn = new CheckBoxField();
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:
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();
}
I have a GridView in a ASP.NET web application, in which I have added buttons in each row:
<asp:GridView ID="gridviewdatadosen" runat="server" AutoGenerateColumns="False" CssClass="table table-striped table-bordered table-hover" OnRowDataBound="gridviewdatadosen_RowDataBound" OnSelectedIndexChanged="gridviewdatadosen_SelectedIndexChanged" OnRowCommand="gridviewdatadosen_RowCommand">
<Columns>
<asp:BoundField DataField="NIK" HeaderText="NIK" SortExpression="NIK"></asp:BoundField>
<asp:BoundField DataField="NIDN" HeaderText="NIDN" SortExpression="NIDN"></asp:BoundField>
<asp:BoundField DataField="NAMA" HeaderText="NAMA" SortExpression="NAMA"></asp:BoundField>
<asp:BoundField DataField="Alamat" HeaderText="Alamat" SortExpression="Alamat"></asp:BoundField>
<asp:TemplateField ShowHeader="false">
<ItemTemplate>
<asp:Button ID="btnstatus" runat="server" Text="Aktif" CssClass="btn btn-primary" CommandName="aktifasi" CommandArgument='<%# Eval("NIK") %>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I fill the datagridview on the server side. I filled it with taking the data in the database.
DataTable dt = new DataTable();
DataTable dt1 = new DataTable();
SqlConnection conn = new SqlConnection(#"Data Source=localhost;Initial Catalog=SKRIPSI;User ID=sa;Password=sa");
conn.Open();
string ngisi = "SELECT [nik] as 'NIK' , [nidn] as 'NIDN', [nama] as 'NAMA', [alamat] as 'Alamat' FROM [dosen]";
SqlCommand comm = new SqlCommand(ngisi, conn);
dt.Load(comm.ExecuteReader());
conn.Close();
gridviewdatadosen.DataSource = dt;
gridviewdatadosen.DataBind();
int tmp = dt.Rows.Count;
after I fill the datagridview, I wanted to check the status of dosen whether he is active or not by select id and status of dosen.
conn.Open();
string check = "SELECT nik, status FROM [dosen]";
comm = new SqlCommand(check, conn);
dt1.Load(comm.ExecuteReader());
conn.Close();
I have tried to change the existing text on the button but did not succeed.
for (int i = 0; i < tmp; i++)
{
if (dt1.Rows[i][1].ToString() == "Aktif")//check the dosen aktif or not
{
for (int j = 0; j < tmp; j++)
{
if (dt.Rows[j][0].ToString() == dt1.Rows[i][0].ToString())// check nik where status = 'Aktif'
{
// I want to change the button in each row. if he 'Aktif' then the text in button will change to be 'aktif'
//do not know what to do
}
}
}
}
I want to change the button in each row. if he 'Aktif' then the text in button will change to be 'aktif'. help me to solve this problem. Sorry if my english or my explain is bad. Thank You
You can loop all the rows, find the Button and change the Text based on the values in dt1
foreach (GridViewRow row in GridView1.Rows)
{
//find the button in the row with findcontrol and cast back to a button
Button button = row.FindControl("btnstatus") as Button;
//check dt1 and set button text
button.Text = "Active";
}
Or you can do the same on the GridView databinding with the OnRowDataBound event.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//find the button in the row with findcontrol and cast back to a button
Button button = e.Row.FindControl("btnstatus") as Button;
//check dt1 and set button text
button.Text = "Active";
}
}
when i checked [checked box] data on my page (1) and then go on to next page (2) through paging(bottom button of pages like [1234]) and then checked data on page (2).
when i came back to page (1) then it remain unchecked as i don't checked anything!!!
all the things remains at its original positions. all are unchecked on both pages .
when coming from 1 page to page 2 (check-boxes of page 1 forget his value and get unchecked) and after when coming from page 2 to page 1 same thing happens.
sorry for my bad and rough English.
any suggestion??
If its a gridview or any repeater control try this
Gridview HTML
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False" AllowPaging="True"
PageSize="5" Width="324px" DataKeyNames="CategoryID"
OnPageIndexChanging="GridView1_PageIndexChanging">
<Columns>
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID" />
<asp:BoundField DataField="CategoryName" HeaderText="CategoryName" />
<asp:TemplateField HeaderText="Select">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
CS Codes
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
RememberOldValues();
GridView1.PageIndex = e.NewPageIndex;
BindData();
RePopulateValues();
}
And
private void RememberOldValues()
{
ArrayList categoryIDList = new ArrayList();
int index = -1;
foreach (GridViewRow row in GridView1.Rows)
{
index = (int) GridView1.DataKeys[row.RowIndex].Value;
bool result = ((CheckBox)row.FindControl("CheckBox1")).Checked;
// Check in the Session
if (Session[CHECKED_ITEMS] != null)
categoryIDList = (ArrayList)Session[CHECKED_ITEMS];
if (result)
{
if (!categoryIDList.Contains(index))
categoryIDList.Add(index);
}
else
categoryIDList.Remove(index);
}
if (categoryIDList != null && categoryIDList.Count > 0)
Session[CHECKED_ITEMS] = categoryIDList;
}
And
private void RePopulateValues()
{
ArrayList categoryIDList = (ArrayList)Session[CHECKED_ITEMS];
if (categoryIDList != null && categoryIDList.Count > 0)
{
foreach (GridViewRow row in GridView1.Rows)
{
int index = (int)GridView1.DataKeys[row.RowIndex].Value;
if (categoryIDList.Contains(index))
{
CheckBox myCheckBox = (CheckBox) row.FindControl("CheckBox1");
myCheckBox.Checked = true;
}
}
}
}
Bind Data Code
EDIT
/* QUERY */
private const string QUERY_SELECT_ALL_CATEGORIES = "SELECT * FROM Categories";
private void BindData()
{
SqlConnection myConnection = new SqlConnection(ConnectionString);
SqlDataAdapter ad = new SqlDataAdapter(QUERY_SELECT_ALL_CATEGORIES,
myConnection);
DataSet ds = new DataSet();
ad.Fill(ds, "Categories");
GridView1.DataSource = ds;
GridView1.DataBind();
}
For more details chk this Maintaining_State_of_CheckBoxes
When you are navigating from one page to another ,your page refreshes so it cant retain value for checkbox,If you want to do this you have to do it from code behind ,write code
Checkbox.Checked=True in !IsPostback according to your valid conditions.