I have two mutually exclusive checkboxes; that being so, I'd like each one to automatically reflect the opposite state of the other when a change is made: if checkboxA is checked, checkboxB should be, if checked, unchecked (etc., I'm sure you know what I mean).
I'm creating the checkboxes in my code-behind like so:
ckbxPaymentForSelf = new CheckBox();
ckbxPaymentForSelf.Text = "myself";
ckbxPaymentForSelf.ID = "ckbxPaymentForSelf";
this.Controls.Add(ckbxPaymentForSelf);
ckbxPaymentForSomeoneElse = new CheckBox();
ckbxPaymentForSomeoneElse.Text = "someone else";
ckbxPaymentForSomeoneElse.ID = "ckbxPaymentForSomeoneElse";
this.Controls.Add(ckbxPaymentForSomeoneElse);
Based on this, I thought maybe I could use the checkbox's Name property and set them both to the same value, something like "ckbxsSelfOrSomeoneElse" but there is no "Name" property on Checkbox available to me.
I could write some jQuery like so (pseudoscript):
$(document).on("change", '[id$=ckbxPaymentForSelf]', function () {
var ckd = this.checked;
if (ckd) // check ckbxPaymentForSomeoneElse and uncheck if it it's checked
else // check ckbxPaymentForSomeoneElse and check if it it's unchecked
});
$(document).on("change", '[id$=ckbxPaymentForSomeoneElse]', function () {
var ckd = this.checked;
if (ckd) // check ckbxPaymentForSelf and uncheck if it it's checked
else // check ckbxPaymentForSelf and check if it it's unchecked
});
...but am wondering if there is a more obvious or elegant solution to this, as this is indubitably a common requirement.
UPDATE
I tried 's answer:
$(document).on("click", '[id$=ckbxPaymentForSelf]', function () {
alert('reached onclick for ckbxpaymentforself');
$('#ckbxPaymentForSomeoneElse').prop('checked', !this.checked);
});
$(document).on("click", '[id$=ckbxPaymentForSomeoneElse]', function () {
alert('reached onclick for ckbxpaymentforsomeoneelse');
$('#ckbxPaymentForSelf').prop('checked', !this.checked);
});
...but, illogically (it seems to me and, obviously, him), it doesn't work. The strange/suspicious thing is that the alert messages are showing twice! I have to click them twice to dismiss them. Why would that be, and could that be the/a problem? I did notice that the jQuery appears twice in the "View Source" although, of course, it is in only one place in the actual source code (at the bottom of the .asxc file).
UPDATE 2
As wilusdaman suggested (make it an answer, Wilus, and I'll accept it as such), the elegantest way is to use radiobuttons instead. All that is needed is this:
rbPaymentForSelf = new RadioButton();
rbPaymentForSelf.Text = "myself";
rbPaymentForSelf.ID = "rbPaymentForSelf";
rbPaymentForSelf.GroupName = "SelfOfSomeoneElse";
this.Controls.Add(rbPaymentForSelf);
String checkboxPaymentForSomeoneElseText = "someone else";
rbPaymentForSomeoneElse = new RadioButton();
rbPaymentForSomeoneElse.Text = checkboxPaymentForSomeoneElseText;
rbPaymentForSomeoneElse.ID = "rbPaymentForSomeoneElse";
rbPaymentForSomeoneElse.GroupName = "SelfOfSomeoneElse";
this.Controls.Add(rbPaymentForSomeoneElse);
...and this jQuery, relatedly, then acts:
/* If user selects "payment for self" (they are seeking payment for themselves, as opposed to someone else), omit (invisibilize) sections 2 and 3 on the form */
$(document).on("change", '[id$=rbPaymentForSelf]', function () {
if (this.checked) {
$('[id$=panelSection2]').slideUp();
$('[id$=panelSection3]').slideUp();
$('[id$=_MailStopRow]').slideDown();
$('[id$=_AddressRows]').slideUp();
}
});
/* If user selects "payment for someone else" (they are seeking payment for someone else, as opposed to themselves), make sections 2 and 3 on the form visible */
$(document).on("change", '[id$=rbPaymentForSomeoneElse]', function () {
if (this.checked) {
$('[id$=panelSection2]').slideDown();
$('[id$=panelSection3]').slideDown();
$('[id$=_MailStopRow]').slideUp();
$('[id$=_AddressRows]').slideDown();
}
});
However, the sections that should show if the user selects "someone else" do not display the first time the user (me for now) selects the "someone else" radio button - subsequently, it does work, though...
i am able to achieve using javascript as below:
<body>
<input type="checkbox" id="one" name="one" onchange="check1()"/>
<input type="checkbox" id="two" name="two" onchange="check2()"/>
<script>
function check1()
{
if(one.checked)
{
document.getElementById("two").checked = false;
}
else
{
document.getElementById("two").checked = true;
}
}
function check2()
{
if(two.checked)
{
document.getElementById("one").checked = false;
}
else
{
document.getElementById("one").checked = true;
}
}
</script>
</body>
This can be used for each instance you have in your project, you never need to worry about mixing the logic in for each selector you wish to target. Super reusable!
Since the click event happens on the client side, heres some jQuery to fit your requirements:
$.fn.dependantCheckbox = function() {
"use strict";
var $targ = $(this);
function syncSelection(group, action) {
$targ.each(function() {
if ($(this).data('checkbox-group') === group) {
$(this).prop('checked', action);
}
});
};
$('input[type="checkbox"][data-checkbox-group]').on('change', function() {
var groupSelection = $(this).data('checkbox-group');
var isChecked = $(this).prop('checked');
syncSelection(groupSelection, isChecked);
});
}
$('input[type="checkbox"][data-checkbox-group]').dependantCheckbox();
http://codepen.io/nicholasabrams/pen/mJqyqG
I believe using a client side MVC framework is a much better elegant solution.
Eg, in AngularJs, you can bind your view (two checkboxes) to your model, and every time when you change your model, your view will be updated by framework.
In addition, I believe you can also use observationCollection to do the same on the server side (https://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx).
While this is elegent you will face an issue because the change event will fire for both. This would be a cartesian product as the two will start a war. the code would change the state of the other going forever, or at least causing unwanted results. Using click would be a better solution.
$(document).on("change", '#ckbxPaymentForSelf', function () {
$('#ckbxPaymentForSomeoneElse').prop('checked', !this.checked);
});
$(document).on("change", '#ckbxPaymentForSomeoneElse', function () {
$('#ckbxPaymentForSelf').prop('checked', !this.checked);
});
I suggest the following. Note the labels and use of the class vs the id to assign the event handler:
$(document).on("click", '.ckbxPaymentForSelf', function () {
$('#ckbxPaymentForSomeoneElse').prop('checked', !this.checked);
});
$(document).on("click", '.ckbxPaymentForSomeoneElse', function () {
$('#ckbxPaymentForSelf').prop('checked', !this.checked);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="ckbxPaymentForSelf" class="ckbxPaymentForSelf" type="checkbox" checked/>
<label class="ckbxPaymentForSelf" for="ckbxPaymentForSelf">Payment For Self</label></br>
<input id="ckbxPaymentForSomeoneElse" class="ckbxPaymentForSomeoneElse" type="checkbox" />
<label class="ckbxPaymentForSomeoneElse" for="ckbxPaymentForSomeoneElse">Payment For Someone Else</label></br>
Note: When creating the controls server side you may want to set the
ClientIdMode="Static"
or script this way:
$('#<%= ckbxPaymentForSomeoneElse.ClientID %>').prop('checked', !this.checked);
in the script to be sure your control is referenced
I have a page containing a jQuery ui tab control. That is working just fine.
The issue I have is saving the selected tab between PostBacks occuring from a DropDownList, without (offcourse) disabling those PostBacks.
I have following code on my aspx page and I receive no Javascript errors whatsoever:
<script>
var selected_tab = 1;
$(document).ready(function () {
var tabs = $("#rapportentabs").tabs({
activate: function (e, i) {
selected_tab = i.index;
}
});
selected_tab = $("[id$=selected_tab]").val() != "" ? parseInt($("[id$=selected_tab]").val()) : 0;
tabs.tabs("option", "active", selected_tab);
$("form").submit(function () {
$("[id$=selected_tab]").val(selected_tab);
});
});
</script>
<div id="rapportentabs">//containing the tabs itself</Div>
<asp:HiddenField ID="selected_tab" runat="server" />
I have following in my code behind:
protected void Page_Load(object sender, EventArgs e)
{
selected_tab.Value = Request.Form[selected_tab.UniqueID];
}
I've finally found a solution which seems to work perfectly
Just change the javascript part using direct reference to objects and use i.newTab.index() instead of i.index
The correct script should read as:
<script>
var selected_tab = 1;
$(document).ready(function () {
var tabs = $("#rapportentabs").tabs({
activate: function (e, i) {
selected_tab = i.newTab.index();
$("#selected_tab").val(selected_tab);
}
});
selected_tab = $("#selected_tab").val() != "" ? parseInt($("#selected_tab").val()) : 0;
tabs.tabs("option", "active", selected_tab);
$("form").submit(function () {
$("#selected_tab").val(selected_tab);
});
});
</script>
One option is to save the selected_tab in a localstorage and then restore it when the page loads - this will have a side affect of saving the selected tab not only when you post but also when you close the tab and reopen it.
Another option, much better IMHO, is to post the form with Ajax and this way you will not get a page refreshed at all - but this will mean you have to update whatever page changes, which may be lots of work if you have lots of server side rendering code.
I'm trying to populate a SELECT using jQuery and after it's populated set the value i want.
I'm working with ASP.NET MVC 5.
The problem is the value doesn't get set
Here's my code:
$(document).ready(function () {
//DropDownLists Initialization
ListCategories(); //Populates the dropdownlist
PreviousCategory(); //Sets DropDownList value to previous state (posted value)
});
function PreviousCategory() {
var previousCategory = $("#PreviousCategory").val();
if (previousCategory != null && previousCategory != '') {
$("#IdCategory").val(previousCategory);
}
}
$("#PreviousCategory") is a hidden input wich gets it's value server-side after a postback with the next code:
#if (ViewBag.Category!=null)
{
#Html.Hidden("PreviousCategory",(object)ViewBag.Category);
}
Both functions work separately, the DropDownList gets populated flawlessly, but the value doesn't get set.
If i trigger PreviousCategory() from another event (for example a button click), the value gets set perfectly.
I didn't think it was necessary to post ListCategories() code since it works well and you can just assume it fills the dropdownlist, though if anyone find it necessary let me know and i'll edit the post.
EDIT:
Here is ListCategories() code:
function ListCategories(){
_idOrganigrama = $("#IdOrganigrama").val()
_idTipoPedido = $("#IdTipoPedido").val()
data = { idOrganigrama: _idOrganigrama, idTipoPedido: _idTipoPedido }
$.post("ListCategories/", data, function (categoryList) {
$("#IdCategoria").empty();
$(categoryList).each(function () {
$("<option />", {
val: this.Id,
text: this.Descripcion
}).appendTo($("#IdCategory"));
});
});
}
By the way...$("#IdCategory") is the select.
The problem seems to be in the ListCategories where you might be using a async function like ajax to fetch data from server and populate the select.
So use a callback based solution like this
$(document).ready(function () {
//DropDownLists Initialization
ListCategories(PreviousCategory); //Populates the dropdownlist
//Sets DropDownList value to previous state (posted value) after the values are loaded
});
function PreviousCategory() {
var previousCategory = $("#PreviousCategory").val();
if (previousCategory != null && previousCategory != '') {
$("#IdCategoria").val(previousCategory);
}
}
function ListCategories(callback) {
//your ajax request to populate the select
$.ajax({}).done(function () {
//populate the select
//then at the last call the callback method which will set the value
callback()
})
};
Using jQuery I'm trying to get the id of control, which I clicked (radiobutton). I read this question and tried almost everything from there:
alert($(this).get(0).id);
alert($(this).id);
alert($(this).attr('id'));
alert(this.id);
But I'm always getting: Undefined
I just don't understand what I'm doing wrong.
UPDATED:
Radiobuttons is generated dynamically in code behind by C#:
controlToReturn = new RadioButton
{
ID = controlId
};
((RadioButton)controlToReturn).Text = text;
((RadioButton)controlToReturn).Checked = Convert.ToBoolean(Convert.ToInt32(value));
((RadioButton)controlToReturn).GroupName = groupName;
((RadioButton)controlToReturn).CssClass = cssClass;
((RadioButton)controlToReturn).Attributes.Add("runat", "server");
((RadioButton)controlToReturn).Attributes.Add("onclick", "Show();");
and function in ASPX:
<script type="text/javascript" language="javascript">
function Show() {
if ($(this).cheked = true) {
console.log(this);
alert($(this).get(0).id);
alert($(this).id);
alert($(this).attr('id'));
alert(this.id);
}
}
</script>
I know radiobutton has id, I checked generated HTML.
Your problem is this has no context within your function and is in fact the window itself.
You would need to modify both the output html to provide context as an argument:
((RadioButton)controlToReturn).Attributes.Add("onclick", "Show(this);");
and change the function Show:
function Show(el) {
/* for jQuery use $(el) */
if(el.checked) {
alert(el.id);
}
}
C#:
((RadioButton)controlToReturn).Attributes.Add("onclick", "Show(this);");
JavaScript:
function Show(radio) {
if (radio.checked) {
alert(radio.id);
}
}
To attach a click-listener and alert the ID, your code would look something like this:
$(function () {
$("input[type='radio']").on("click", function () {
alert(this.id);
});
});
A working demo: http://jsfiddle.net/SSBnV/1/
I have the following JS code which shows/hides buttons (had to be done this way, and please don't say do it another way).
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequestHandle);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequestHandle);
function beginRequestHandle(sender, Args) {
document.getElementById("ltInstructions").style.visibility = "hidden";
document.getElementById("btnSubmit").style.visibility = "hidden";
document.getElementById("btnToExcel").style.visibility = "hidden";
}
function endRequestHandle(sender, Args) {
if(<%=resultsCount %> > 0)
{
document.getElementById("ltInstructions").style.visibility = "visible";
document.getElementById("btnSubmit").style.visibility = "visible";
document.getElementById("btnToExcel").style.visibility = "visible";
}
else
{
document.getElementById("results").innerHTML = "<br><b><center><font size=20>No results found, please try again.</b></font></center>";
}
}
The problem is <%=resultsCount %> which gets initialized to 0 in the code behind and then later updated in Timer_Tick method. The Js above always picks it up as 0.
How to make the JS pick it up as the correct value?
Use asp:hiddenfield instead and change its value in Timer_Tick, You will get updated value for it.
In HTML
<asp:HiddenField id="resultsCount" runat="server" Value="String" />
In Javascript
resultsCount = document.getElementById('<%= resultsCount.ClientID %>').value;
Try looking at the source of the webpage in your browser. You have to write the timer in JavaScript, because <%=resultsCount %> is evaluated once only and therefore, all the client sees is
if (0 > 0) {
...
}
You can implement a timer in JavaScript using the setInterval and clearInterval methods. Define a function update() that should be called whenever something needs to be updated and then do
var updateInterval
function update() {
if(condition) {
/* update stuff */
} else {
/* no more updates needed */
clearInterval(updateInterval) /* stop updating */
}
}
updateInterval = setInterval(update, 1000) /* call update() every 1000 ms, that is every second */