Goal:
If you select "Dates", you can select the dropdownlist for Start date and end date.
If you select "All ... only" the start and end date will be grey colored in the background and you cannot click on the arrow down. These dropdownlists are disable.
Problem:
I don't know how to create it in frontend code.
Info:
*The dropdownlists are created in ASP.net MVC 4
*I'm using jquery 1.10 and bootstrap
<input id="aa" type="radio" name="searchselection" value="all" style="display: inline-block;" checked>
<label for="aa" style="width: 100px; display: inline-block; ">All ...only</label>
<input id="dates" type="radio" name="searchselection" value="dates" style="display: inline-block;">
<label for="dates" style="width: 100px; display: inline-block;">Dates</label>
#{
DateTime myDate = DateTime.Today;
List<SelectListItem> myListSelectListItem_YearStartDate = new List<SelectListItem>();
for (int i = 0; i < 10; i++) {
myListSelectListItem_YearStartDate.Add(new SelectListItem { Text = (myDate.Year - i).ToString(), Value = (i + 1).ToString(), Selected = DateTime.Today.Year == (myDate.Year - i) ? true : false });
}
}
#Html.DropDownList("YearStartDate", myListSelectListItem_YearStartDate)
You could try something like
$(document).on('change', 'input[type=radio][name=searchselection]', function() {
//func body
....
if(this.value == *your choices*){
//disable
$(YourDropdownSelector).attr('disabled', 'disabled');
}else {
//enable again
$(YourDropdownSelector).removeAttr('disabled');
}
});
This is fixed in the following jsfiddle
I've stripped out some of the unneeded HTML attributes (such as the style tags - styles are better applied in css) and also stubbed out the back end code generating the <select> in order to simplify the example and focus on the solution.
Let's look at what's happened:
<select class='js-date-selector' disabled='disabled'>
Firstly, each of your select elements has been edited to add the following two attributes. The class allows targeting from javascript (or JQuery) - note that the js- prefix is not essential, it's just a nice way of keeping your javascript class attributes separate from others. Also, a class is used instead of an id, this is generally best as it is easier to re-use, as we have to in this example.
The disabled attribute is how you mark-up an HTML element so it's greyed out. If you're going to mark 'all dates' as checked on page load and 'all dates' being checked means the selects should be disabled, then your HTML also needs to mark the selects as disabled on load.
Next is the bit that does the toggling:
$('.js-all-or-dates').on('click',function() {
var justClicked = $(this),
dateSelectors = $('.js-date-selector');
if (justClicked.attr('id') === 'aa') {
dateSelectors.attr('disabled', true);
}
else {
dateSelectors.attr('disabled', false);
}
});
Firstly, we bind a function to the click event for each of our .js-all-or-dates radio inputs.
Secondly, we assign variables, using justClicked = $(this) to store a jquery version the element that was just clicked and dateSelectors to store all of our select items, using the class mentioned above
Finally, we look at what was just clicked and if it has the ID of the 'all dates' radio input we set the disabled property on all the select elements.
Also, for good practice and smoother development: === is used for equality; $ function calls are minimised by assigning results to local variables; and the var statement contains comma separated declarations.
Related
I have a dynamically generated form with groups of checkboxes representing categories of companies. These eventually get plotted on a dynamic chart (not shown here). Each group of companies is in a div, and each div has a button called Only that should check all the checkboxes in its own category (div) and uncheck all the other checkboxes on the page.
Here's a Fiddle with all the code: https://jsfiddle.net/c2kn78a9/
The Only buttons have this code in them:
// Uncheck all checkboxes outside this div
$(this).closest("div").not(this).find('input[type=checkbox]').prop('checked', false).change();
// Check all checkboxes in this div
$(this).closest("div").find('input[type=checkbox]').prop('checked', true).change();
But it's not working. Any idea how to fix this?
Here's the code for the entire page.
<!-- This button is different than the other buttons -->
<button class="button-text" id="customize-button">Open User Settings</button>
<!-- Placeholder for dynamic form -->
<div id="company-selection-form"></div>
<script type="text/javascript">
function toMachineString(humanString) {
var machineString = humanString.replace(/\s+/g, '-').toLowerCase();
machineString = machineString.replace('&','');
return machineString;
}
// Setup the form
var categories = new Map([
['Tech Giants',['Alphabet','Amazon','Apple','Facebook','Microsoft']],
['Handset Manufacturers',['Apple','Samsung','Motorola','Sony']],
['Semiconductors', ['AMD','Intel','Nvidia']]
// ... more ...
]);
// Build company selection form inputs
let companySelectionHTML = '';
for (let category of categories) {
categoryName = category[0];
categoryList = category[1];
// Setup a div to differentiate each category of companies.
// Will be used for turning on/off categories en masse
companySelectionHTML += `<div id="${toMachineString(categoryName)}">\n`;
// Category heading
companySelectionHTML += `<h4>${categoryName}</h4>\n`;
// Only button
companySelectionHTML += `<button class="only" id="btn-only-${toMachineString(categoryName)}">Only</button>\n`;
categoryList.forEach(companyName => {
companySelectionHTML += `
<label class="checkbox-label">
<input id="x-${toMachineString(companyName)}" class="checkbox" type="checkbox" name="company" value="${companyName}" checked>
<label for="x-${toMachineString(companyName)}">${companyName}</label>
</label>`;
});
companySelectionHTML += '</div>\n</div>\n</div>\n';
}
// Append to DOM
const companySelectionId = document.getElementById('company-selection-form');
companySelectionId.insertAdjacentHTML('beforeend', companySelectionHTML);
// Make the ONLY buttons check all the checkboxes in their div and uncheck everything else
$(document).ready(function() {
$(document).on("click", ".only", function() {
// Uncheck all checkboxes outside this div
$(this).closest("div").not(this).find('input[type=checkbox]').prop('checked', false).change();
// Check all checkboxes in this div
$(this).closest("div").find('input[type=checkbox]').prop('checked', true).change();
});
});
</script>
Thanks!
Your .not(this) is trying to filter out the button element from the single closest div. You need to get all div's on the page and remove the closest div to "this" button.
From your JSFiddle like this:
var temp = $(this).closest("div");
$("div").not(temp).find('input[type=checkbox]').prop('checked', false).change();
OR (to avoid a new variable)
$("div").not($(this).closest("div")).find('input[type=checkbox]').prop('checked', false).change();
Matt G's solution works fine, it deselects all the checkboxes on the page.
I'd suggest to further refine it by first narrowing the selection to only your #company-selection-form
`$("#company-selection-form")
.find("div")
.not($(this)
.closest("div"))
.find('input[type=checkbox]')
.prop('checked', false)
.change();`
Nevertheless, allow me to suggest that you're maybe wasting your time learning this stuff. This programming paradigm is too problematic and anachronistic. It's slow, gets out of hand very quickly, and never brings anything but suffering. Even the slightest update to the UI can force you to revisit (after months sometimes), debug, and rewrite your code. It's never testable, no one would even bother to test this rigorously.
I mean, if your employer holds a gun to your head every day and you have to choose either to do it this way or die, you'd soon choose to die over this ordeal.
I am creating a form builder script. I have a select input where the user can select the form element they want to use, depending on their selection ("select", "checkbox" or "radio") another form field is displayed allowing users to input their options.
Users can create as many instances of form elements as they want, so each select input has a dynamically created id that corresponds to the id of the hidden form field. I then use jQuery to determine whether the "options" field should be hidden or not (triggered on change of the form elements select input).
Currently, for every instance, I have the following code addedabove the select input:
<script>
jQuery(document).ready(function($) {
var arr = ['select', 'checkbox', 'radio'];
var thisForm = 'select.input-type-118';
function showHideSelect() {
var val = $(thisForm + ' option:selected').val();
var selectOptions = $('#select-options-118')
if (arr.indexOf(val) >= 0) {
selectOptions.show();
} else {
selectOptions.hide();
}
}
showHideSelect();
$(thisForm).change(function() {
showHideSelect();
});
});
</script>
Where var thisForm and var selectOptions are added dynamically and refer to the select option below this script.
I'm wondering if there is a better way to do this rather than repeat several instances of this, at the moment, a users page cold look like this:
<script>
...
</script>
<select>
...
</select>
<textarea>
This is hidden depending on the select option
</textarea>
<script>
...
</script>
<select>
...
</select>
<textarea>
This is hidden depending on the select option
</textarea>
<script>
...
</script>
<select>
...
</select>
<textarea>
This is hidden depending on the select option
</textarea>
...etc...etc
My concern is that I don't think it's best practice to have so many instances of the same script, but I'm unsure how to write a global script that will allow me to show/hide the textarea on an individual basis.
I have shown a more accurate depiction of my workings on this jsfiddle here:
https://jsfiddle.net/46stb05y/4/
You can use Event Delegation Concepts. https://learn.jquery.com/events/event-delegation/
With this you can change your code to
$(document).on('change','select',function() { //common to all your select items
showHideSelect($(this)); // passing the select element which trigerred the change event
});
This will work even on the select items that are added dynamically
You must change your function to receive the element as the parameter.
function showHideSelect($selectElement) {
var val = $selectElement.val();
var selectOptionsId = $selectElement.attr('class').replace('input-type','select-options');
var selectOptions = $("#"+selectOptionsId);
if (arr.indexOf(val) >= 0) {
selectOptions.show();
} else {
selectOptions.hide();
}
}
Here is the Working JsFiddle
I am trying to select a radio button on a webpage using Javascript inside an Applescript. For this particular button, there is no element ID, so I'm no really sure how to select this radio button.
There's really no other identifying elements for this form (or that I see, at least).
Note: There's several radio buttons on this page, and the only unique identifier between them is the "value."
HTML:
<input type="radio" size="4" name="Level" value="p;29">
Javascript/Applescript:
do JavaScript "document.getElementById('p;29').checked = true;" in doc
If you have no other input elements, you can safely use
document.getElementsByTagName("input")[0]
Otherwise, you can do:
for (i=0; i<document.getElementsByTagName('input').length; i++) {
var myInput = document.getElementsByTagName('input')[i];
if (myInput.type == 'radio')
{
//myInput is the radio element. Do something with it
}
}
I ended up using the value and name fields to target the element and check it. Here is the working script:
do JavaScript "var elements = document.getElementsByName('Level');
for (i=0;i<elements.length;i++) {
if(elements[i].value == 'p;29') {
elements[i].checked = true;
}
}" in doc
I have a set of three radio buttons and they have mutual exclusion in them, as I implemented group name property, but the problem is, in the initial stage, none of the radio button is selected,
But when I select any of the radio button, then I cannot deselect the same, although mutual exclusion is in progress, but I want them to deselect as well.
My code aspx is:
<td>
<asp:RadioButton ID="AChk" runat="server" CssClass="itemRightAlign" GroupName="A"/>
</td>
<td>
<asp:RadioButton ID="DChk" runat="server" CssClass="itemRightAlign" GroupName="A"/>
</td>
<td>
<asp:RadioButton ID="WChk" runat="server" CssClass="itemRightAlign" GroupName="A"/>
</td>
You have both a code problem and a misunderstanding.
The misunderstanding is about how the mutual exclusion radio buttons work (or are supposed to work) (or are expected by the users to work).
The code problem is that in a mutually exclusion radio buttons group you need to initially select one of them.
So, I believe there are two ways of solving the problem:
Keep the radio buttons groud. Add a "none" button to the set, so that it works as if none of the other three are selected. And initially select this "none" button.
change the radio buttons to check boxes, so the user might select and deselect each of them. Then implement your own exclusion logic. I don't recommend this one.
You would need to use javascript...
doing binding in jquery, it's easier, and the name= should match your rendered groupname "name=" attribute...
var lastChecked = null;
$('input[name=A]').click(function(){
if (lastChecked == this) {
this.checked = false;
lastChecked = null;
}
lastChecked = this;
});
Use this to deselect:
var radios = document.getElementsByName('A');
for(var i=0; i<radios.length; i++)
{
radios[i].checked = false;
}
You can deselect a radio button by using the attribute ondblclick.
<input type="radio" name="RadioGroup1
" value="1" ondblclick="uncheckRadio();">
Apple</label>
When you double click on the radio button, just call a javascript function to set the checked property to false.
function uncheckRadio() {
var choice = document.form1.RadioGroup1;
for (i = 0; i < choice.length; i++) {
if ( choice[i].checked = true )
choice[i].checked = false;
}
}
Here is a similar implementation using the attribute ondblclickand jQuery. Also, this will allow you to include this functionality within controls with a dynamically generated client ID.
Code behind:
foreach (ListItem li in rbl.Items)
li.Attributes.Add("ondblclick", string.Format("clearCurrentRadioButtonSelection(\"{0}\")", rbl.UniqueID));
ASPX page
function clearCurrentRadioButtonSelection(controlName) {
var id = "input[name=" + controlName + "]";
$(id).each(function () {
$(this).attr('checked', false);
});
}
usual but I need to have different custom radio button images per button.
So Radio1 would have different images to Radio2.
Trying it out on the code below but it won't work so I must be doing something wrong?
Here's the code:
<label for="radio1">
<img src="radio1_unchecked.png" style="vertical-align:middle" />
<input name="radiogroup" type="radio" id="radio1" style="display:none;">
</label>
<label for="radio2">
<img src="radio2_unchecked.png" style="vertical-align:middle" />
<input name="radiogroup" type="radio" id="radio2" style="display:none;">
</label>
<script>
$(document).ready(function(){
var radio1checkedImage = "radio1_checked.png",
radio1uncheckedImage = "radio1_unchecked.png",
radio2checkedImage = "radio2_checked.png",
radio2uncheckedImage = "radio2_unchecked.png";
$('img').attr("src", radio1uncheckedImage);
$('#radio1, #radio2').change(function() {
var r;
r = $("#radio1");
r.prev().attr("src", r[0].checked ? radio1checkedImage : radio1uncheckedImage);
r = $("#radio2");
r.prev().attr("src", r[0].checked ? radio2checkedImage : radio2uncheckedImage);
});
});
</script>
Update: Here is the same code as above but without the multiple images.
As you can see it works. Can't the code be modified to have multiple images per radio?
You could use CSS to define which images goes with which radio button. Building on the JSBin example from my answer to you previous question, you can use JavaScript to add a classname (e.g. 'checked') to the parent of the checked radio (i.e. the <label>):
var radios = $('input:radio');
radios.change(function() {
radios.filter(':checked').parent().addClass('checked');
radios.filter(':not(:checked)').parent().removeClass('checked');
});
So, now that the <label> will have the 'checked' class if that radio is selected, you can use CSS to style it:
label {
/* regular styles */
}
label[for="radio1"].checked {
/* checked styles for #radio1's label */
}
label[for="radio2"].checked {
/* checked styles for #radio2's label */
}
Using CSS instead of <img> tags does mean you will need to use background-image, so be aware of that.
Live example: http://jsbin.com/ebapov/edit#javascript,html,live
Just in case, here is a more verbose version of the JavaScript posted above:
// Fetch the radio buttons (this is a jQuery collection):
var radios = $('input:radio');
radios.change(function() {
// Filter the radio inputs into 'checked' and 'unchecked':
var checkedInputs = radios.filter(':checked');
var uncheckedInputs = radios.filter(':not(:checked)');
// Get the 'checked' and 'unchecked' labels:
var checkedLabels = checkedInputs.parent();
var uncheckedLabels = uncheckedInputs.parent();
// Add the class "checked" to the checked labels:
checkedLabels.addClass('checked');
// ... and remove it from the unchecked labels:
uncheckedLabels.removeClass('checked');
});
Most of this code relies on the fact that jQuery functions can be chained. This means that when you call the parent() function on a jQuery collection, it will actually return a collection containing the parent of each of the elements in the original collection. If you then call addClass on that new collection, it will add a classname to each of those parents.
Most of jQuery's functions can be chained.
In addition my other answer, which uses CSS, let me offer an alternative solution.
Firstly; you want to keep track of which image goes with which radio button. Why not use an object literal?
var checkedImages = {
'radio1': "radio1_checked.png",
'radio2': "radio2_checked.png"
};
var uncheckedImage = "unchecked.png";
This way you can easily refer to the different URL's like, e.g.: checkedImages['radio2'].
The change event handler would look very similar. The only difference is what you do with the checkedLabels and the uncheckedLabels:
var radios = $('input:radio');
radios.change(function() {
var checkedLabels = radios.filter(':checked').parent();
var uncheckedLabels = radios.filter(':not(:checked)').parent();
uncheckedLabels.children('img').attr('src', uncheckedImage);
checkedLabels.each(function() {
var image = $(this).children('img');
var name = $(this).attr('for');
if (checkedImages[name] !== undefined) {
// We have checked image for this radio button, so set it:
image.attr('src', checkedImages[name]);
} else {
// We don't have checked image for this radio button.
image.attr('src', uncheckedImage);
}
});
});
The main differences:
We use children() to find the images.
We use each() to add more complicated logic for each of the unchecked label.
We check the selected <label>s for attribute (using .attr('for')) to find out which image we should apply.
In this example only the checked state has different images for the different radio's. If you need different unchecked images as well, you can easily apply the same principle.
Live example: http://jsbin.com/acalir/edit#javascript,html,live
P.S. don't forget to set the src to the unchecked images (in HTML), or do the following (in JS):
$('input:radio').change();
This fires the change event programmatically, which will cause the unchecked images to be applied.