ASP.NET Retrieve value from Checkbox onCheckChanged - asp.net

I am working on displaying a students timetable based on possible Module choices. (See Screenshot) Currently I am displaying all available modules in a gridview which the student can select by using check boxes. I have already created the insert query to insert their selection to the database. (2)
However, each time a check box is selected I want to retrieve the 'ModuleId' to add to a SELECT query which displays a timetable of their selected modules. (1)
So if a user selects 3 check boxes the 'ModuleId' from each row selected will be passed into the SELECT query.
Below is my method which enables the timetable for specific a ModuleId to be displayed:
public String[] getModulesAtCurrentSlot(int timeslotInt, String moduleID, String Day)
{
List<String> modulesList = new List<string>();
if (conn.State.ToString() == "Closed")
{
conn.Open();
}
SqlCommand newCmd = conn.CreateCommand();
newCmd.Connection = conn;
newCmd.CommandType = CommandType.Text;
newCmd.CommandText = "SELECT DISTINCT Module.ModuleCode,ClassType.ClassTypeName,Convert(time,Class.StartTime), Convert(time,Class.EndTime),Building.BuildingName,RoomCode.RoomCode,Class.Color" +
" FROM Class INNER JOIN Module ON Class.ModuleId = Module.ModuleId INNER JOIN RoomCode ON Class.RoomCodeId = RoomCode.RoomcodeId INNER JOIN Building ON RoomCode.BuildingId = Building.BuildingId INNER JOIN Days ON Class.DayId = Days.DayID INNER JOIN ClassType ON Class.ClassTypeId = ClassType.ClassTypeId WHERE " +
" Module.ModuleId = " + moduleID + " AND Convert(Date,StartTime) = '" + Day + "' AND " + timeslotInt.ToString() + " BETWEEN ClassScheduleStartTimeId and ClassScheduleEndTimeId";
SqlDataReader dr = newCmd.ExecuteReader();
while (dr.Read())
{
String current = "<div class='slot' " + (!dr.IsDBNull(6) ? "style=\"background-color: " + dr.GetString(6) + ";\"" : "") + ">";
current += "<div class='line1'>" + dr.GetString(0) + " " + dr.GetString(1) + "</div>";// +"<br />";
current += "<div class='line2'>" + dr.GetTimeSpan(2).ToString().TrimEnd('0').TrimEnd('0').TrimEnd(':') + " - " + dr.GetTimeSpan(3).ToString().TrimEnd('0').TrimEnd('0').TrimEnd(':') + "</div>";// +"<br />";
current += "<div class='line3'>" + dr.GetString(4) + " " + dr.GetString(5) + "</div>";
current += "</div>";
modulesList.Add(current);
}
conn.Close();
return modulesList.ToArray();
}
How would I pass all selected values (ModuleId) from the checkboxes to be used in my above select query as previously for displaying just one module I used
' Module.ModuleId = " + moduleID ' ?

To complete what you are trying to do efficiently and without big foreach loops you need to change the whole way your user inputs data in to the gridview.
I believe that you should be utilising the GridViews OnRowUpdating Event, When a row is updated, using this event you already have context of which row has changed. e.RowIndex - Gets the index of the row being updated
Utilising this event will require a bit of a redesign of your gridview fields, You will need to add a EditItemTemplate tag in each TemplateField Add a CommandFieldand using OnRowUpdating re-write your update event. Its to much information to post in a answer, This information should help you get started on using the GridView events to their full potential.
On a side note you should use paramerterized queries in your sql.
EDIT
Based on your clarification that you need to retrieve the moduleid for each checkbox, I am going to make a few assumptions so it might not work without some tweaks.
To start with try this:
<asp:TemplateField>
<ItemStyle HorizontalAlign="Center" Width="40px"></ItemStyle>
<ItemTemplate>
<asp:CheckBox ID="chkRow" runat="server" ToolTip='<%# Eval("ModuleId") %>' OnCheckedChanged="module_Changed" />
</ItemTemplate>
Using '<%# Eval("ModuleId") %>' Will populate the tooltip for the checkbox with the ModuleID value during the GridView.DataBind() function. Iam making the assumption that the column name is exactly "ModuleId"
Then in the code behind you can read the tooltip value of the checkbox like this:
protected void module_Changed(object sender, EventArgs e)
{
// Retrieve the check box ModuleId value to add to SELECT query
string moduleid = ((CheckBox)sender).ToolTip;
}
Now that when the gridview loads all the checkboxes have a tooltip that is populated with the ModuleID you can easily know which box is for which module by checking the tooltip.

Related

ASP.NET Pass multiple checkbox values into a SELECT query

I am working on displaying a students timetable based on possible Module choices. Each time a check box is selected I want to pass through the value selected "ModuleId" to use in a SELECT query to display the timetable for all modules selected. So if a user selects 3 check boxes the 'ModuleId' from each row selected will be passed into the SELECT query.
I don't know how to store each selected "ModuleId" and add it into my select query.
Below is how I retrieve the checked value:
<asp:TemplateField>
<ItemStyle HorizontalAlign="Center" Width="40px"></ItemStyle>
<ItemTemplate>
<asp:CheckBox ID="chkRow" runat="server" ToolTip='<%# Eval("ModuleId") %>' OnCheckedChanged="module_Changed" />
</ItemTemplate>
<asp:TemplateField>
Below is my method to display the value in a label (just for testing purposes):
protected void module_Changed(object sender, EventArgs e)
{
// Retrieve the check box ModuleId value to add to my SELECT query
string moduleid = ((CheckBox)sender).ToolTip;
}
Below is my method which contains the select query to display the timetable:
public String[] getModulesAtCurrentSlot(int timeslotInt, String moduleID, String Day)
{
List<String> modulesList = new List<string>();
if (conn.State.ToString() == "Closed")
{
conn.Open();
}
SqlCommand newCmd = conn.CreateCommand();
newCmd.Connection = conn;
newCmd.CommandType = CommandType.Text;
newCmd.CommandText = "SELECT DISTINCT Module.ModuleCode,ClassType.ClassTypeName,Convert(time,Class.StartTime), Convert(time,Class.EndTime),Building.BuildingName,RoomCode.RoomCode,Class.Color" +
" FROM Class INNER JOIN Module ON Class.ModuleId = Module.ModuleId INNER JOIN RoomCode ON Class.RoomCodeId = RoomCode.RoomcodeId INNER JOIN Building ON RoomCode.BuildingId = Building.BuildingId INNER JOIN Days ON Class.DayId = Days.DayID INNER JOIN ClassType ON Class.ClassTypeId = ClassType.ClassTypeId WHERE " +
" Module.ModuleId = " + moduleID + " AND Convert(Date,StartTime) = '" + Day + "' AND " + timeslotInt.ToString() + " BETWEEN ClassScheduleStartTimeId and ClassScheduleEndTimeId";
SqlDataReader dr = newCmd.ExecuteReader();
while (dr.Read())
{
String current = "<div class='slot' " + (!dr.IsDBNull(6) ? "style=\"background-color: " + dr.GetString(6) + ";\"" : "") + ">";
current += "<div class='line1'>" + dr.GetString(0) + " " + dr.GetString(1) + "</div>";// +"<br />";
current += "<div class='line2'>" + dr.GetTimeSpan(2).ToString().TrimEnd('0').TrimEnd('0').TrimEnd(':') + " - " + dr.GetTimeSpan(3).ToString().TrimEnd('0').TrimEnd('0').TrimEnd(':') + "</div>";// +"<br />";
current += "<div class='line3'>" + dr.GetString(4) + " " + dr.GetString(5) + "</div>";
current += "</div>";
modulesList.Add(current);
}
conn.Close();
return modulesList.ToArray();
}
On a previous page where the timetable is only displaying data for one ModuleId I've used the below query string to pass through the value.
String module_ID = "2";
if (Request.QueryString["module"] != null)
{
module_ID = Request.QueryString["module"];
}
else
{
Response.Write("Missing ?module=XX from url :(");
Response.End();// EndRequest;
}
DBAccess.cs screenshot:
Error screenshot:
If I understand correctly, you could have a session variable that contains a List of strings which holds all of the selected moduleID's
You could then use module_Changed event to add or remove moduleIDs from this List and then call getModulesAtCurrentSlot in a loop for each moduleid in the list and concatenate the returned string[]s into one longer string[] or List which you then display.
there may be some errors in the code below as I'm just doing it from memory but it should give you an idea!
protected void module_Changed(object sender, EventArgs e)
{
List<string> lst;
if( Session["lst"]!=null)
lst = (List<string>)Session["lst"];
else
Session.Add("lst", new List<string>());
// Retrieve the check box ModuleId value to add to my SELECT query
string moduleid = ((CheckBox)sender).ToolTip;
// add your own code to check if checkbox is checked or unchecked to see if you need to add or remove the ID from the list
// to add
if(lst.Contains(moduleid) == false)
lst.Add(moduleid);
// to remove - add your own code
List<string> lstResult = new List<string>();
foreach(var moduleID in lst)
{
lstResult.Add(getModulesAtCurrentSlot(timeslotInt, moduleID, Day));
}
// do something to display lstResult
// e.g. drag a Gridview control on your aspx page and bind the results list to it - this is just to give you a rough idea but you'll need to play around with it to get it to work as you want, and hopefully learn something in the process ;)
Gridview1.DataSource = lstResult;
Gridview1.Databind();
}

Blank Items in CheckBoxList (Remove blank items)

I have a rather irritating and silly problem. I have a checkbox list on a asp page that I populate from a database. I am able to populate it, the problem lies when I do a specific check that checks if the users are active or not, it displays only the ones that are active but then leaves huge blanks in my control of where the original not active users were displayed.
I have pictures of before and after I implement that specific if statement:
here is the code for populating and checking:
this.AddMultipleUsers.Items.Clear();
foreach (GetAllLoginUsersResult result in from a in this.db.GetAllLoginUsers(null)
orderby a.FirstName
select a)
{
ListItem item = new ListItem();
string str = Membership.GetUser(result.UserId).ToString();
item.Text = result.FirstName.Trim() + " " + result.Surname.Trim() + " (" + str + ")";
if (!result.IsApproved)
{
item.Text = item.Text + " (Not Active)";
//item.Attributes.Add("style", "display:none;"); before
}
item.Value = result.UserId.ToString();
this.AddMultipleUsers.Items.Add(item);
}
in the first image, the checkboxlist is fully populated. Before link to code^
in the second after I un-comment this line //item.Attributes.Add("style", "display:none;");
then checkboxlist is the same size as the first image but, there is large spaces between
the users that are active, when you scroll down you see them randomly.
I want to remove the blank items within the checkbox list and make the other valid entries to be moved up like a normally populated checkbox list
Thank you
simply add a where condition to your select statement:
this.AddMultipleUsers.Items.Clear();
foreach (GetAllLoginUsersResult result in from a in this.db.GetAllLoginUsers(null)
orderby a.FirstName
where a.IsApproved==true
select a)
{
ListItem item = new ListItem();
string str = Membership.GetUser(result.UserId).ToString();
item.Text = result.FirstName.Trim() + " " + result.Surname.Trim() + " (" + str + ")";
item.Value = result.UserId.ToString();
this.AddMultipleUsers.Items.Add(item);
}
now you are only cycling through the active users, and no longer need to hide the inactive ones.

asp.net GridView and Checkboxes Dynamic Bind

I am having a little issue that I don't seem to understand the best way to approach.
I have a GridView that get automatic column generations based on the query I run. The GridView will contain (Name) (Description) (Edit) (Delete) (View) (Admin).
Now because the Edit, Delete, View... are bit's in the database when the query returns the results and binds the data with the GridView I get these grayed out Checkboxes with checked if True or Unchecked if False.
Now because I didn't create those disabled checkboxes are they really a checkbox or are the something that's just display like that... If they are really a checkboxes how do I access them and enable or disable them? I tried looping through each cell in grid but when I say cell.text it gives me empty string back... What would be the best way to approach this or am I misunderstanding the DataBind of a bit fields?
Thanks all for your help.
UPDATED
string sSQLAccess = "SELECT ap.n_Name 'App', a.b_Edit 'Edit', a.b_Delete 'Delete', a.b_View 'View' " + Environment.NewLine
+ "FROM tbl_Actions a " + Environment.NewLine
+ "JOIN tbl_Applications ap ON ap.u_ID = a.u_ApplicationID" + Environment.NewLine
+ "JOIN tbl_Roles r ON r.u_ID = a.u_RoleID" + Environment.NewLine
+ "WHERE a.b_Deleted = 0" + Environment.NewLine
+ "AND ap.b_Deleted = 0 " + Environment.NewLine
+ "AND r.b_Deleted = 0 " + Environment.NewLine
+ "AND a.u_RoleID = '" + Request.QueryString["ID"] + "'" + Environment.NewLine;
grdAccess.DataSource = vwAccess;
grdAccess.DataBind();
The checkbox will not be enabled unless the gridview is in edit mode - you would need to define an edit template for the gridview.

ASP.Net add image to radiobuttonlist items on load

I have a RadioButtonList that is bound to a datatable. Within the datatable, a column exist with urls of images and another column with the description.
The following is what I am doing right now (not working though):
foreach ( acryliccolor scurrent in ssmacryliccolor )
{
DataRow dr = dt.NewRow();
dr["TEXT"] = "<img src=\"\\colorswatches\\" + scurrent.SwatchURL + "\" alt=\"\" border=\"0\" /><span style=\"margin-right:21px;\"></span>" + scurrent.Color;
dr["VALUE"] = "ID|SC_" + scurrent.ID.ToString() + ";CSID|" + current.ID.ToString() + ";JS|radiosimple(this)";
dt.Rows.Add(dr);
}
this.rblAcrylicColors.DataSource = dt;
this.rblAcrylicColors.DataTextField = "TEXT";
this.rblAcrylicColors.DataValueField = "VALUE";
this.rblAcrylicColors.DataBind();
How do I add the image next to the description for each radiobutton item?
Have you tried dynamically adding items to the radiobuttonlist.Items collection?
this.rblAcrylicColors.Items.Add(String.Format("<img src={0} />", "url"));
Also have you checked the html output from what you are currently trying? Is the img tag there?

Gridview filtering using textbox in asp.net

i want to know as how to search or filter records in a gridview dynamically based on the character(s) entered on a textbox. What is the best way to achieve this? Any sample codes or examples will be really helpful.
The trick here is to make databind only when the text change on the search box, but you must always set the datasource select command code. So you add a text box, and a button that say, submit, and you have the following:
OnPageLoad ->
if(SearchContron.Text.Length > 0)
SqlDataSource1.SelectCommand = "SELECT * FROM TABLE WHERE Desc LIKE N'%" + SearchContron.Text +"%'"
else
SqlDataSource1.SelectCommand = "SELECT * FROM TABLE "
and
OnSubmitButtonClick -> GridView.DataBind()
If you do it other way, the paging and editing and other commands will fail. You can also make it more advanced if you get the text from the text box and break it in many words and search each one as separate on the same sql command.
Its simple,
Look here for a basic tutorial on adding Ajax control to page.
1) Add the text box as well as the grid view into same update panel
2) In the text box's key press event, you can set the data source of gird and invoke databind command.
Note that when the key press will be fired, it will cause the complete page life cycle to be executed at server side. Hence, you will have to check whether the post back is async or not in your Page Load even handler.
A trick to reduce the number of database queries being fired is to set a timer when the user presses a key with a timeout of say...500ms and do the databinding of gridview in timer's tick event. If you do this, database will be queried only when the user has stopped typing something.
Thanks,
Vamyip
To bind gridview data write the following code
private void GridData()
{
string conString = ConfigurationManager.ConnectionStrings["MyCon"].ToString();
SqlConnection sqlcon = new SqlConnection(conString);
SqlCommand sqlcmd;
SqlDataAdapter da;
DataTable dt = new DataTable();
String query;
if (txtsearch.Text == "")
{
query = "select PersonID,LastName,FirstName from Person";
}
else
{
query = "select PersonID,LastName,FirstName from Person where PersonID like '" + txtsearch.Text + "%' or LastName like '" + txtsearch.Text + "%' or FirstName like '" + txtsearch.Text + "%'";
}
sqlcmd = new SqlCommand(query, sqlcon);
sqlcon.Open();
da = new SqlDataAdapter(sqlcmd);
dt.Clear();
da.Fill(dt);
if (dt.Rows.Count > 0)
{
grdsearch.DataSource = dt;
grdsearch.DataBind();
}
else
{
grdsearch.DataBind();
Label1.Text = "No Records Found";
}
sqlcon.Close();
}
In page load event
if (!IsPostBack)
{
GridData();
}
for search button click event call GridData() method and
for clear button click event write following code
txtsearch.Text = "";
GridData();
Label1.Text = "";
Unless you have a specific need to do this on the server, why not perform the filtering on the client? A solution like DataTables is fast and user-friendly.
If you do other way to working search filtering condition for grid view header part. it is easy to use implement in your code. This is concepts used without database but i was using data table in linq. i hope to this code use full.
DataTable dt = (DataTable)Session["ProductTable"];
var query = from t in dt.AsEnumerable()
where t.Field<string>("ProducId").StartsWith(txtProductId.Text.ToString().Trim())
|| t.Field<string>("ProducId").Contains(txtProductId.Text.ToString().Trim())
select t;
Here is a sample program.
implement the onclick of search button like this:
protected void searchButton_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(searchTextBox.Text))
{
SqlDataSource1.SelectCommand = "SELECT id,name,address, datetime FROM nirmaan.[seller] where id <>0" +
" ORDER BY [name], [id]";
}
else
{
SqlDataSource1.SelectCommand = "SELECT id,name,address, datetime FROM nirmaan.[seller] where id <>0" +
"and "+DropDownList1.SelectedValue+" LIKE '%" + searchTextBox.Text + "%' ORDER BY [name], [id]";
}
GridView1.DataBind();
}

Resources