I have generated a CheckBoxList which has more than one item using C#. Now I want to set a maximum number of checked item allowed in CheckBoxList. If user check more than maximum allowed item, there will be an alert or the other item will automatic uncheck to prevent user check over maximum number of item allowed.
The maximum number of checked item will be set up to ChecokBoxList in code-behind (C#) or using javascript do this, but the javascript is also should be generated in C# too.
I need some help to solve this issue.
Example Code:
CheckBoxList chkl = new CheckBoxList();
string[] items = {"item1", "item2", "item3", "item4", "item5"};
foreach (string item in items )
{
chkl.Items.Add(new ListItem(item));
}
chkl.MaximumCheck = 3;
After generated in code-behind, the CheckBoxList will only allow user to check only three items. If user check more than three item, other item will automatic uncheck or at least an alert will show to prevent user check more than three items.
I have a good solution for this issue:
In C# I will generate a CheckBoxList with 5 items using this code:
CheckBoxList chkl = new CheckBoxList();
string[] items = { "item1", "item2", "item3", "item4", "item5" };
foreach (string item in items)
{
chkl.Items.Add(new ListItem(item));
}
chkl.AutoPostBack = true;
chkl.CssClass = "3";
chkl.SelectedIndexChanged += new EventHandler(BoxChecked);
As you can see, the CheckBoxList has 5 item and the maximum checked item is seted via CssClass attribute of CheckBoxList, assumed there will be no CssClass needed in CheckBoxList. So that I will set the maximum checked item via this attribute to make it more clear. The key here is to add an EventHandler on CheckboxList, so that if user going to check more than the maximum item, other item will be disable.
The EventHander will be written as follow:
protected void BoxChecked(object sender, EventArgs e)
{
try
{
int maximumCheck = -1;
CheckBoxList CheckExpertiseList = (CheckBoxList)sender;
try {
maximumCheck = Convert.ToInt32(CheckExpertiseList.CssClass);
}
catch { }
if (maximumCheck > -1)
{
if (CheckExpertiseList.Items.Cast<ListItem>().Where(i => (i.Selected == true)).Count() == maximumCheck)
{
CheckExpertiseList.Items.Cast<ListItem>().Where(i => (i.Selected == false)).ToList().ConvertAll(i => i.Enabled = false).ToList();
}
else if (CheckExpertiseList.Items.Cast<ListItem>().Where(i => (i.Selected == true)).Count() == maximumCheck - 1)
CheckExpertiseList.Items.Cast<ListItem>().Where(i => (i.Selected == false)).ToList().ConvertAll(i => i.Enabled = true).ToList();
}
}
catch { }
}
EventHandler Event will check if the checkboxlist has over limit item checked it will disable other items, else it will reenable other item.
int x = 0;
foreach (var li in ListBox1.Items) {
if (li.Selected == true)
{
x = x + 1;
}
or like:
ListBox1.GetSelectedIndices().Length
In Javascript:
<script type="text/javascript" language="javascript">
function CheckCheck()
{
var chkBoxList=document.getElementById('<%=CheckBoxList1.ClientID %>'); var chkBoxCount=chkBoxList.getElementsByTagName("input");
var btn=document.getElementById('<%=btnSubmit.ClientID %>');
var i=0;
var tot=0;
for(i=0;i<chkBoxCount.length;i++)
{
if(chkBoxCount[i].checked)
{
tot=tot+1;
}
}
if(tot > 3)
{
alert('Cannot check more than 3 check boxes');
}
</script>
<form id="form1" runat="server">
<div>
<table>
<tr>
<td>
<asp:CheckBoxList ID="CheckBoxList1" runat="server" onclick="javascript:CheckCheck();">
<asp:ListItem>One</asp:ListItem>
<asp:ListItem>Two</asp:ListItem>
<asp:ListItem>Three</asp:ListItem>
<asp:ListItem>Four</asp:ListItem>
<asp:ListItem>Five</asp:ListItem>
</asp:CheckBoxList>
</td>
<td>
<asp:Button ID="btnSubmit" runat="server" Text="Submit" />
</td>
</tr>
</table>
First of all, I am thank you to Jeremy Thompson. He gave me a good idea for my issue. A little bit change and I have what I want. Solve my issue only using javascript.
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<script type="text/javascript" language="javascript">
function CheckCheck() {
var chkBoxCount = this.getElementsByTagName("input");
var max = parseInt(this.className);
var i = 0;
var tot = 0;
for (i = 0; i < chkBoxCount.length; i++) {
if (chkBoxCount[i].checked) {
tot = tot + 1;
}
}
if (tot > max) {
var k = 0;
for (i = 0; i < chkBoxCount.length; i++) {
if (chkBoxCount[i].checked) {
k++;
if (k > max) {
chkBoxCount[i].checked = false;
alert('Cannot check more than ' + max + ' check boxes');
}
}
}
}
}
</script>
<div>
<table>
<tr>
<td>
<asp:CheckBoxList ID="CheckBoxList1" runat="server" CssClass="3" onclick="javascript:CheckCheck.call(this);">
<asp:ListItem>One</asp:ListItem>
<asp:ListItem>Two</asp:ListItem>
<asp:ListItem>Three</asp:ListItem>
<asp:ListItem>Four</asp:ListItem>
<asp:ListItem>Five</asp:ListItem>
</asp:CheckBoxList>
</td>
<td>
<asp:Button ID="btnSubmit" runat="server" Text="Submit" />
</td>
</tr>
</table>
</div>
</form>
</body>
</html>
The javascript will automatic recognize what control is going to call it, and it also get the maximum check item via attribute CssClass of control. By doing this, I also prevent user check more than maximum item in CheckBoxList without doing some post-back.
private void cb_magia_SelectedIndexChanged(object sender, EventArgs e)
{
int maxNumber = 4;
int iSelectedIndex = cb_magia.SelectedIndex;
if (cb_magia.CheckedItems.Count > maxNumber)
{
cb_magia.SetItemCheckState(iSelectedIndex, CheckState.Unchecked);
MessageBox.Show("you had checked the maximum checkbox value allowed");
}
}
Related
This is my checkBoxList:
<asp:CheckBoxList ID="CheckBoxList1" runat="server" RepeatColumns="2" Style="float: left; font-size: large;"></asp:CheckBoxList><br />
When i select an item and press the button i gets an error System.IndexOutOfRangeException
I use this line to show selected item
System.Diagnostics.Debug.WriteLine(CheckBoxList1.SelectedValue[0])
Thank you!
EDIT
dobraKartaOdp.First() - string value;
zlaKartaOdp.First() - string value;
Random rnd = new Random();
for ( int i = 0; i< 20; i++)
{
if(rnd.Next(0,2) == 1 && dobraKartaOdp.Count != 0)
{
wyjKartaOdp.Add(dobraKartaOdp.First());
dobraKartaOdp.RemoveAt(0);
}
else if(rnd.Next(0, 2) == 0 && zlaKartaOdp.Count != 0)
{
wyjKartaOdp.Add(zlaKartaOdp.First());
zlaKartaOdp.RemoveAt(0);
}
else
{
i = i - 1;
}
}
CheckBoxList1.DataSource = wyjKartaOdp;
CheckBoxList1.DataBind();
This is my test
You have just declared a checkbox list.
You need to bind items to it or give it a datasource .
Its a checkbox list you need to iterate through every item and select those which are checked like ::
foreach (ListItem li in CheckBoxList1.Items)
{
if (li.Selected == true)
{
System.Diagnostics.Debug.WriteLine(li.value);
}
}
Im not sure what your output is but you should have the logic inside the button event in the code behind instead of the Page load. for example lets say you have 2 checkboxes and a button (make sure you put the onClick event on the button)
<fieldset style= 400px>
<asp:CheckBox ID="firstcheckbox" Text="firstcheckbox" runat="server"/>
<asp:CheckBox ID="secondcheckbox" Text="secondcheckbox" runat="server"/>
</fieldset>
<br/>
<asp:Button ID="Button1" runat="server" Text="submit" onClick="Button1_Click"/>
In your code behind make a a method for your submit button (remember the onClick event we have to use this button know or the code will crash)
so
protected void "Button1_Click (object sender,EventArgs e)
{
if(firstCheckbox.Checked)
{
//do something
}
if(secondCheckbox.Checked)
{
//do something
}
}
I have two checkboxlists CandidateName and Payment, and a dropdownlist. User can do multiple selections in checkboxlists and one selection at dropdownlist. I am populating those data of chechboxlists and dropdownlist to Panel nested inside UpdatePanel where gridview exist.. When I click on Add Button to open up Panel, all data is properly populating. When I tried to save multiple selected checkedboxlists through "for loop" at debugging, it is not going inside the loop to accumulate checked data with comma to save at database. Instead, after chekcing "if (cblPayment1.Items[j].Selected == true)", it skips over to another query statement. Please help me advise.
protected void btnAddNew_Click(object sender, EventArgs e)
{
try
{
string strcbl1 = string.Empty;
string strcbl2 = string.Empty;
compCon = new SqlConnection(strConnectionString);
compCon.Open();
for (int i = 0; i < cblCandidateName1.Items.Count-1; i++)
{
if (cblCandidateName1.Items[i].Selected ==true)
{
strcbl1 = strcbl1 + cblCandidateName1.Items[i].Value.ToString() + ",";
}
}
for (int j = 0; j < cblPayment1.Items.Count - 1; j++)
{
if (cblPayment1.Items[j].Selected == true)
{
strcbl2 += cblPayment1.Items[j].Value.ToString() + ",";
}
}
string InsertSchedule = "INSERT INTO ScheduleEmail(CANDIDATE_ID, PAYMENT_ID, TEMPLATE_ID)VALUES(#strCID, #strPID, #strCourseID)";
SqlCommand InsertScheduleCommand = new SqlCommand(InsertSchedule, compCon);
InsertScheduleCommand.Connection = compCon;
InsertScheduleCommand.Parameters.AddWithValue(#"strCID", strcbl1);
InsertScheduleCommand.Parameters.AddWithValue(#"strPID", strcbl2);
InsertScheduleCommand.Parameters.AddWithValue(#"strCourseID", strCourseID);
InsertScheduleCommand.ExecuteNonQuery();
compCon.Close();
}
catch (Exception ex)
{
ShowPopUpMsg("Data is failed to save in table. Please contact your system administrator \n" + ex.ToString());
}
finally
{
DispalyGridViewScheduleEmail();
compCon.Close();
}
}
THis is my HTML Code.
<!--Panel to add new record--><asp:Panel ID="panelAddNew" runat="server"
style="display:none; background-color:gray;" ForeColor="Black" Width="500" Height="550">
<asp:Panel ID="panelAddNewTitle" runat="server"
style="cursor:move;font-family:Tahoma;
padding:2px;" HorizontalAlign="Center" BackColor="Blue" ForeColor="White" Height="25">
<b>Add New</b></asp:Panel>
<table width="100%" style="padding:5px">
<tr>
<td colspan="3">
<asp:Label ID="lblStatus1" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td><b>Select Candidate Name(s)</b></td>
<td><b>:</b></td>
<td><asp:CheckBoxList ID="cblCandidateName1" runat="server" RepeatColumns="3" RepeatDirection="Horizontal" RepeatLayout="table">
</asp:CheckBoxList>
</td>
</tr>
<tr>
<td><b>Select Payments</b></td>
<td><b>:</b></td>
<td>
<asp:CheckBoxList ID="cblPayment1" runat="server" RepeatDirection="Horizontal" RepeatLayout="Table"></asp:CheckBoxList>
</td>
</tr>
<tr>
<td><b>Course Name</b></td>
<td><b>:</b></td>
<td> <asp:DropDownList ID="ddlCourseName" runat="server"> </asp:DropDownList>
</td>
</tr>
</table>
<br />
<div align="center">
<asp:Button ID="btnAddNew2" runat="server" Width="70" Text="Add" OnClick="btnAddNew_Click" ValidationGroup="add"/>
<asp:Button ID="btnCancel1" runat="server" Width="70" Text="Cancel" CausesValidation="false" OnClick="Cancel_Click" ValidationGroup="add"/>
</div>
</asp:Panel>
<!--End of Panel to add new record-->
Both of your for blocks will not be executed at the last item of cblCandidateName1.Items and cblPayment1.Items because of this condition:
for (int i = 0; i < cblCandidateName1.Items.Count-1; i++)
and
for (int j = 0; j < cblPayment1.Items.Count - 1; j++)
You need to change both of your for blocks to the following
for (int i = 0; i < cblCandidateName1.Items.Count; i++)
{
if (cblCandidateName1.Items[i].Selected ==true)
{
strcbl1 = strcbl1 + cblCandidateName1.Items[i].Value.ToString() + ",";
}
}
for (int j = 0; j < cblPayment1.Items.Count; j++)
{
if (cblPayment1.Items[j].Selected == true)
{
strcbl2 += cblPayment1.Items[j].Value.ToString() + ",";
}
}
UPDATE
It seems that cblPayment1.Items[j].Selected is always false even though you check some of the payment checkboxlist. The possible cause could be that you populate cblPayment1 items in Page_Load method but not inside if (!this.IsPostBack) block
protected void Page_Load(object sender, EventArgs e)
{
cblPayment1.DataSource = .... ;
cblPayment1.DataBind();
}
When you click the save button, Page_Load method will be executed first before btnAddNew_Click, so cblPayment1 will be repopulated and all of its items won't be selected when you reach btnAddNew_Click method. You need to change Page_Load code as the following
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
cblPayment1.DataSource = .... ;
cblPayment1.DataBind();
}
}
First of all try to not use string concatenation in a loop in a way you shown in question. It's bad habit and leads to performance problems at later time since every concatenation reallocates new memory for string and then copies it into that place.
And how about using some lambdas in this code?
It will be dramatically simplified like that:
strcbl1=string.Join(",", cblCandidateName1.Items.Where(x=>x.Selected));
strcbl2=string.Join(",", cblPayment1.Items.Where(x=>x.Selected));
First of all, try not to use string concatenation in a loop in a way you have shown in your question. It's a bad habit and leads to performance problems at a later time since every concatenation reallocates new memory for string and then copies it into that place.
And how about using some lambdas in this code? It will be dramatically simplified like that:
strcbl1 = string.Join(",", cblCandidateName1.Items.Where(x=>x.Selected));
strcbl2 = string.Join(",", cblPayment1.Items.Where(x=>x.Selected));
I have a asp:CheckBoxList which load items from database.
I want to write a script which shows no. of checked checkbox on each check.
My aspx page is as following :
<div id="rfd-demo-zone2" class="placeholderContent accordionEmpGroup-child-subGroup-container">
<asp:CheckBoxList ID="ckbList2DesignationUc" runat="Server" RepeatLayout="Flow" RepeatDirection="Horizontal" Width="100%" ></asp:CheckBoxList>
</div>
script :
<script type="text/javascript">
$('#ckbList2DesignationUc input:checked').each(function () {
alert('hi');
});
</script>
In the above script I am trying to get an alert, but it is not showing
Put script in document.ready to ensure the availability of html elements to script and use attribute contains selector to find the checkboxes of the checkboxlist.
<script type="text/javascript">
$(document).ready(function(){
$('[id*=ckbList2DesignationUc]:checked').each(function () {
alert('hi');
});
});
</script>
To fire event on change of checkbox
<script type="text/javascript">
$(document).ready(function(){
$('[id*=ckbList2DesignationUc]').change(function () {
alert(this.id);
});
});
</script>
Client side:
$('.CheckBoxList').each(function () {
var items = new Array();
$(this).find("input:checkbox").each(function () {
if ($(this).attr("checked") == true) {
items[items.length] = $(this).next().html();
}
});
$(this).parent().find('.txtList').val(items.toString());
});
Html MarkUp:
<asp:TextBox runat="server" ID="txtabc" CssClass="txtList txtformatcss" Width="160px" ViewStateMode="Disabled"></asp:TextBox>
<asp:CheckBoxList ID="chkabc" runat="server"
RepeatLayout="Flow" CssClass="CheckBoxList">
</asp:CheckBoxList>
Here CheckBoxList is class name which have given in checkboxlist control
Possible solution:
<div id="rfd-demo-zone2" class="placeholderContent accordionEmpGroup-child-subGroup-container">
<asp:CheckBoxList ID="ckbList2DesignationUc" runat="Server" RepeatLayout="Flow" RepeatDirection="Horizontal" Width="100%" >
</asp:CheckBoxList>
</div>
and access it:
$("#<%=ckbList2DesignationUc.ClientID %> input[type=checkbox]:checked").each(function() {
alert('checked');
});
Try below code :
Solution-1
Whenever you will check checkbox an alert will show you the values of checked items in checkboxes.
Javascript code :
< script type="text/javascript">
function itemClick(radioButton) {
var Control;
var selectedItems;
selectedItems = '';
Control = document.getElementById("<%=ckbList2DesignationUc.ClientID %>").getElementsByTagName("input");
for (var i = 0; i < Control.length; i++) {
if (Control[i].checked == true)
selectedItems += i.toString()+',';
}
alert(selectedItems);
}
</script>
ASPX Code :
protected void Page_Load(object sender, EventArgs e)
{
for (int index = 0; index < 10; index++)
{
ckbList2DesignationUc.Items.Add(new ListItem("Item" + index, index.ToString()));
}
foreach (ListItem Li in ckbList2DesignationUc.Items)
{
Li.Attributes.Add("onclick", "return itemClick()");
}
}
Required solution by using Jquery :
Solution -2
< script type="text/javascript">
$(document).ready(function () {
var selectedCheckBoxes = '';
$('#ckbList2DesignationUc').each(function () {
var items = new Array();
$(this).find("input:checkbox").each(function () {
$(this).click(function () {
selectedCheckBoxes += $(this).val() + ",";
alert(selectedCheckBoxes);
});
});
});
});
< /script>
< asp:CheckBoxList ID="ckbList2DesignationUc" runat="Server" RepeatLayout="Flow" RepeatDirection="Horizontal" Width="100%">
< /asp:CheckBoxList>
This may help you: you can use it in code behind file as well as inside the script tag enable AutoPostBack property of checkboxlist to true
protected void CheckBoxList1_SelectedIndexChanged(object sender, EventArgs e)
{
int i=0;
foreach (ListItem li in CheckBoxList1.Items)
{
if (li.Selected)
i++;
}
Response.Write(i);
}
I have two list boxes that I am trying to pass multiple values from one to the other.
asp.net code
<asp:UpdatePanel ID="userButtonPanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:LinkButton Text=">>" ID="lbtn_add" CssClass="button advButtons addRemButton"
runat="server" OnClick="addMappedUser_Click" />
<asp:LinkButton Text="<<" ID="lbtn_remove" CssClass="button advButtons addRemButton"
runat="server" OnClick="removeMappedUser_Click" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
<div>
<asp:Label ID="lbl_MappedUSers" Text="Mapped Users" runat="server" />
<asp:ListBox ID="listMappedUsers" runat="server" SelectionMode="Multiple" CssClass="listboxMappedUsers" />
</div>
</div>
</div>
<input id="cbUserList" type="hidden" runat="server" value="" />
<input id="cbUserRoleID" type="hidden" runat="server" value="" />
</ContentTemplate>
</asp:UpdatePanel>
On the click event of addMappedUser_Click I evaluate the listAllUsers listbox to see what items are selected and create a list of these items
protected void addMappedUser_Click(object sender, EventArgs e)
{
List<ListItem> selectedItems = listAllUsers.Items.Cast<ListItem>().Where(i => i.Selected).ToList();
List<AddedUsers> newusers = new List<AddedUsers>();
foreach (var item in selectedItems)
{
AddedUsers au = new AddedUsers();
au.UserID = item.Value;
au.UserName = item.Text;
newusers.Add(au);
}
MoveSelectedItems(newusers, listAllUsers);
}
Once that list is create it is then passed to the MoveSelectedItems Method
protected void MoveSelectedItems(List<AddedUsers> from, ListBox to)
{
if (from.Count == 0)
{
return;
}
SecurityUserRole sur = new SecurityUserRole();
ListItem item = new ListItem();
foreach (var i in from)
{
item.Value = i.UserID;
item.Text = i.UserName;
if (listAllUsers.Items.Contains(item))
{
listAllUsers.Items.Remove(item);
listMappedUsers.Items.Add(item);
}
sur.SecurityUserId = Convert.ToInt32(i.UserID);
sur.SecurityRoleId = Convert.ToInt32(RoleID);
MappedUser.Add(sur);
Session["MappedUser"] = MappedUser;
checkMappingButtons(listMappedUsers, listAllUsers);
editUserUpdatePanel.Update();
}
}
Where I am getting stuck is in the adding of the users to the second listbox (listMappedUsers.Items.Add)
When the I set a breakpoint I can see each value pass through (for example "201", "202", "203") however when the updatepanel updates the listbox will only have 203 listed three times.
Can someone help me understand what I am missing and why the last value is the only value appearing in the list box vs it's previous predecessors?
Thanks in advance,
In your last section of code, you will need to instantiate a new ListItem in your foreach. As it is now, you are editting the same item over and over in the foreach.
protected void MoveSelectedItems(List<AddedUsers> from, ListBox to)
{
if (from.Count == 0)
{
return;
}
SecurityUserRole sur = new SecurityUserRole();
ListItem item;
foreach (var i in from)
{
item = new ListItem();
item.Value = i.UserID;
item.Text = i.UserName;
if (listAllUsers.Items.Contains(item))
{
listAllUsers.Items.Remove(item);
listMappedUsers.Items.Add(item);
}
sur.SecurityUserId = Convert.ToInt32(i.UserID);
sur.SecurityRoleId = Convert.ToInt32(RoleID);
MappedUser.Add(sur);
Session["MappedUser"] = MappedUser;
checkMappingButtons(listMappedUsers, listAllUsers);
editUserUpdatePanel.Update();
}
}
Good Afternoon Developer,
this is my content in asp .net, I want the user can check only 2 checkbox,exceeding that alert box should pop up.
<body>
<form id="form1" runat="server">
<div>
<table width="100%">
<tr>
<td>
<asp:CheckBox id="q3a" runat="server" Text="Public" />
</td>
<td>
<asp:CheckBox id="q3b" runat="server" Text="void" />
</td>
<td>
<asp:CheckBox id="q3c" runat="server" Text="protected"/>
</td>
<td>
<asp:CheckBox id="q3d" runat="server" Text="return" />
</td>
</tr>
</table>
<asp:Button ID="btnSubmit" Text="submit" runat="server"/>
</div>
</form>
</body>
how can i write javascript for this, i have tried but can't find any way out, Pls help...
You should stop the user the instant they try and select a third option so that only two checked values can ever be submitted and avoid server side validation.
The client side onchange event should be hooked up to a function similar to this;
function validationCheck(checkbox) {
if(checkbox.checked) {
var count = 0;
count += document.getElementById('q3a').checked ? 1 : 0;
count += document.getElementById('q3b').checked ? 1 : 0;
count += document.getElementById('q3c').checked ? 1 : 0;
count += document.getElementById('q3d').checked ? 1 : 0;
if(count > 2) {
alert('You may only select two options.');
checkbox.checked = false;
}
}
}
The input should render with onchange="validationCheck(this);".
You could use JQuery:
$("input[type='checkbox']").change(function () {
var n = $("input:checkbox:checked").length;
if (n > 2) {
alert('2 are already selected!');
$(this).attr("checked", false);
}
});
If you really want to use JavaScript try this function:
function checkCondition(chkbox) {
var buttonGroup = document.getElementsByName("group");
var total = 0;
for (var i = 0; i < buttonGroup.length; i++) {
if (buttonGroup[i].checked) {
total++;
}
}
if (total > 2) {
alert('2 are already selected!');
chkbox.checked =false;
}
}
And also set onclick="checkCondition(this)" on your checkboxes and set their name attribute to the group value for example
agree with #Tim you can just write an on_click function for all checkboxes and then validate there if more then two chekboxes are selected and display error message when needed.
You could use jQuery to find all selected checkboxes:
var count = $("input:checked").length;
Then you have all you need.
But i would recommend to use the builtin ASP.NET-Validator Controls. You could use a CustomValidator for this purpose which would also work on clientside with an appropriate ClientValidationFunction.
You could add a client side onclick event for the check box and using jQuery you can check if the check box is checked. You can have a counter that should measure the threshold and then pop up the message if it exceeds.
$('.mycheckbox').click(function(){
var count = $("input:checked").length;
}
Note: Please add a classname property to all the checkboxes with same class name.