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.
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.
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.
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 series of checkboxes that I populate using a foreach loop (php). The code looks like this:
<input type="checkbox" name="artist_group[]" id="{{$fb_data['fbid']}}" class="input-hidden" data-name="{{$fb_data['name']}}" value="{{$fb_data['fbid']}}" style="display:none;" />
<label for="{{$fb_data['fbid']}}">
<img src="https://graph.facebook.com/{{$fb_data['fbid']}}/picture?width=200&height=200" width="140" height="140" alt="{{$fb_data['name']}}"/>
<article class="artistName">{{$fb_data['name']}}</article>
</label>
What I would like to do is check if any of the checkboxes are checked using javascript. However, I can't do this using the "getElementById" because I want each checkbox to have a unique id (so I can pull the data). I have the name of the checkbox group as an array, so I can send all of the checked boxes to my backend. Can I do the following?:
if (document.getElementByName('artist_group').checked) {
alert("checked");
}
Thank you for your help.
You have iterate over the checkboxes and test whether any of them is checked or not. Note that the method name is getElementsByName (Elements with s):
var boxes = document.getElementsByName('artist_group[]');
var checked = false;
for (var i = 0, l = boxes.length; i < l; i++) {
if (boxes[i].checked) {
checked = true;
break;
}
}
If you are not opposed to newer JavaScript methods, you can also use Array#some:
var checked = Array.prototype.some.call(boxes, function(input) {
return input.checked;
});
With jQuery, it's even simpler:
var checked = $('input[name="artist_group[]"]:checked').length > 0;
Since you tagged jQuery in your question as well, you can use jQuery's $.each.
Just select the elements by the class and not id.
$('.input-hidden').each(function() {
//this will iterate through all checkboxes
if ($(this).is(':checked')) {//Per #Felix's comment, this.checked is a more native way of doing it, I personally just prefer to use $(this) when I'm in jQuery context, to be consistent. Using this.checked is quicker though.
//this will apply just to the checked checkboxes
}
});
You can also get ONLY the selected checkboxes by:
$('input:checked').each(function() {
//this will only apply to selected checkboxes
});
Hope this helps!
As you also used the jQuery tag for your question: IF you're using jQuery anyway (don't just add it only for this task, that's an overkill!):
if ( ! $('input[name="artist_group"]').is(':not(:checked)') ) {
// all are selected
}
Need to populate a list of options with checkbox when a checkbox is clicked. let consider there are three checkbox when a checkbox is selected beneath that checkbox a list of options with checkbox should appear. if a checkbox is selected then beneath that and so on........
how to do this in javascript.....any help..........
If your lists are static, I would define them ahead of time in divs, and set the visibility to false. Then, in your OnClick methods of the checkboxes, simply set the visibility to true when necessary.
Since you asked a very generic question, I'll give a very generic answer.
Example: http://jsfiddle.net/NFs4K/3/
var container = document.getElementById('container'),
template = '<li>\
<input type="checkbox">\
</li>\
<li>\
<input type="checkbox">\
</li>\
<li>\
<input type="checkbox">\
</li>';
container.onchange = function(e) {
var event = e || window.event,
target = event.srcElement || event.target;
if( target.checked && target.parentNode.getElementsByTagName('ul').length === 0 ) {
var ul = document.createElement('ul');
ul.innerHTML = template;
target.parentNode.appendChild(ul);
} else {
var ul = target.parentNode.getElementsByTagName('ul')[0];
target.parentNode.removeChild(ul);
}
};
If you want a better answer, please ask a more detailed question.
EDIT: Removed the checkboxes variable. It wasn't being used.
EDIT: I updated so that it only appends the sub-list when checked, and only the first time it is checked.
EDIT: Updated to remove all nested levels when unchecked.