How to turn this into a global javascript function effecting all values - javascript

This code loads via jQuery a page based onclick events of checkboxes.
function product_analysis(address, box) {
if (box.checked) {
$('#product_' + box.alt).load(address);
} else {
$('#product_' + box.alt).load('http://www.divethegap.com/update/blank2.html');
}
document.getElementById('product_quantity_PRI_' + box.alt).value = box.value;
};
With the onclick event looking as follows onclick="product_analysis('http://www.samedomain.blahblahblah', this)
What I need is that for all checkboxes that are already ticked on page load to have this function applied to them all. I am reasonably confident with javaScript but when it comes to objects and arrays I get lost.
Many Thanks,

You can use this code to find all the checkboxes that are currently checked:
$(':checkbox:checked')
If you then want to do something to all of them, you can use the each function like this:
$(':checkbox:checked').each(function() {
// alerts the checkbox for example
// "this" referes to the checkbox, one after the other
alert(this);
})
Or to do what you asked for ("for all checkboxes that are already ticked on page load to have this function applied to them all"):
$(':checkbox:checked').each(function() {
product_analysis("someaddress", this);
})
EDIT: To address the second issue (not a part of the original question, but to the comments below):
I will assume that you have fields like this in your markup. Use some meaningful IDs rather than my stupid examples of course.
<input type="checkbox" id="foo" />
<input type="checkbox" id="bar" />
<input type="checkbox" id="baz" />
Then you'll put the following in your JS:
var addresses = {
foo: 'some_address',
bar: 'some_other_address',
baz: 'yet_another_one'
};
$(':checkbox:checked').each(function() {
product_analysis(addresses[this.id], this);
})
That will invoke product_analysis with the address that corresponds to the ID of the checkbox.
EDIT (again):
There is actually a way to add meta-data directly to the html-tags that I wasn't aware of. You can add attributes prefixed by "data-" to your tag, like this:
<input type="checkbox" data-address="someaddress" data-foo="something else" data-bar="more data!" />
You can read more about it on John Resigs blog.

this is required script
$().ready(function(){
var box, address;
$(":checkbox").each(function(){
box = this;
if (box.checked) {
address = ""; //you can set address either in hidden fields or in metadata
$('#product_' + box.alt).load(address);
}
else {
$('#product_' + box.alt).load('http://www.divethegap.com/update/blank2.html');
}
document.getElementById('product_quantity_PRI_' + box.alt).value = box.value;
});
});

You need to check how many number of check is checked and then invoke your code.
var checkLength = checkObj.length;
for(var i = 0; i < checkLength ; i++) {
if(radioObj[i].checked) {
}
// here your code base on check box status
}

If you have a class called as "selected" when the check box are checked, you could do something like this
$('.selected').function(element){product_analysis(address, element)};

Thanks chaps for all your help here is I I got it. Jakob will probably consider this a hack but it is a data driven site and based on my limited technical knowledge can't be tasked with modifying a JS file every time we add a new product.
function product_analysis_global() {
$(':checkbox:checked').each(function() {
$('#product_' + this.alt).load(this.title);
});
}
function product_analysis(box) {
if (box.checked) {
$('#product_' + box.alt).load(box.title);
}
else {
$('#product_' + box.alt).load('http://www.divethegap.com/update/blank2.html');
}
document.getElementById('product_quantity_PRI_' + box.alt).value = box.value;
};

Related

How to add parameters in a function on a AddEventListener

I'm trying to create a Web mapping application with some layers, the idea it's that I have some checkboxes and when I click them the layer is added or removed (I have already done that) but there are a lot of layers and of course a lot of code, I realize that with a function I can do the work, but after hours and hours of work it still doesn't work and I'm ready to give up:
function turnon(idlayer, layer) {
var local = document.getElementById(layer);//verify whick checkbox is the one for the layer
if (local.checked == true) {
map.addOverlay(layer);//an OpenLayers method to add the layer to the map
} else {
map.removeOverlay(layer);
}
}
var wmsSector=document.getElementById('sector')//This is the checkbox
wmsSector.addEventListener("click", turnon);
The thing its that I don't know how to add the parameter on the addEventListener Handler I have tried this:
wmsSector.addEventListener("click",turnon('wmsSector',sector))
I appreciate any help you can give me, because right now the application works but I believe it can be more elegant.
I would be more generic in attaching the listeners so that the checkbox provides the id or name of the overlay to attach, e.g.
// For testing
var map = {
addOverlay: function(layer) {
console.log(layer + ' added');
},
removeOverlay: function(layer) {
console.log(layer + ' removed');
}
};
// Toggle layer on or off
function toggleLayer(evt) {
this.checked? map.addOverlay(this.value) : map.removeOverlay(this.value);
}
// Add listener to each layer checkbox
window.onload = function() {
[].forEach.call(document.querySelectorAll('.layerToggle'), function(node) {
node.addEventListener('click', toggleLayer, false);
});
}
<label for="wmsSector"><input type="checkbox" id="wmsSector" value="wmsSector" class="layerToggle"> WMS Sector</label><br>
<label for="vegetation"><input type="checkbox" id="vegetation" value="vegetation" class="layerToggle"> Vegetation</label><br>
<label for="adminBoundaries"><input type="checkbox" id="adminBoundaries" value="adminBoundaries" class="layerToggle"> Admin Boundaries</label>
I've used the value attribute, but you could also use a data-
* attribute, say data-mapLayer="wmsSector" or similar.
Use an anonymous function,
wmsSector.addEventListener("click",function(){
turnon('wmsSector',sector);
})

Multiple conditions on single checkbox

I wanted to have a single checkbox in a form but i need to implement multiple scenarios but not sure if this is possible using a single checkbox or if i need radio buttons . Please advise
box shown and checked: Accepted / yes
(hidden)Box shown and not checked: Declined / no
Box not shown: Not Shown / blank
not sure if this is possible using a single checkbox
box shown and checked: Accepted / yes
(hidden)Box shown and not checked: Declined / no
Box not shown: Not Shown / blank
if the requirements 1/2/3 can be met using a single checkbox .The reason i ask is a single checkbox can hold only one value and if there is a way i can alter the value in Jquery dynamically still satisfying all the requirements.
Yes, it is possible. You can create an object having properties set to selectors :checked, :not(:checked, :hidden), :hidden; with corresponding values set to yes, no, blank. Set variable at change event handler using for..in loop, .is()
var obj = {
":checked": "yes",
":not(:checked, :hidden)": "no",
":hidden": "blank"
};
var curr;
$(":checkbox").change(function() {
for (var prop in obj) {
if ($(this).is(prop)) {
curr = obj[prop]; break;
}
}
// do stuff with `curr`
console.log(curr);
});
// check `:hidden`
$(":checkbox").prop("hidden", true)
.change() // `curr` should log `blank`
.prop("hidden", false);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<input type="checkbox" />
I have created one sample onchange function where you can handle mutiple events
codepen URL for reference:
http://codepen.io/nagasai/pen/xOGNYW
<input type="checkbox" id="checkTest" onchange="myFunction()">
<input type="text" id="myText" value="checked">
#myText
{
display:none;
}
function myFunction() {
if (document.getElementById("checkTest").checked) {
document.getElementById("myText").style.display = "block";
} else {
document.getElementById("myText").style.display = "none";
}
}

Changing aria-label based on the binding of css style

I have a checkbox that i have an aria-label for but i am not sure of how to change this aria-label text to reflect whether the checkbox is checked or not for the user. Is it possible to control the aria-label text in the same function for rendering the css?
Function for checking and unchecking box:
checkbox = ko.pureComputed(function () {
var checked = checked(),
uncheck = uncheck(),
checkedIcon = 'icon_check',
uncheckedIcon = 'no_check',
if (checked) {
//Can i add in here what the aria-label text should be?
return checkedIcon;
}
if (uncheck) {
return uncheckedIcon;
}
});
You could do something like this if you would like to change the attribute based on check-box value.
HTML:
<input type="checkbox" data-bind="checked:Mycheckbox,attr:{'aria-label':MyAriaLabel}" >
VM:
$(function () {
var MainViewModel = function () {
var self = this;
self.MyAriaLabel = ko.observable('aria-lebel');
self.Mycheckbox = ko.observable();
self.Mycheckbox.subscribe(function(newVal){
self.MyAriaLabel(newVal?'Something' : 'Something else');
})
}
ko.applyBindings(new MainViewModel());
})
Example : http://jsfiddle.net/GSvnh/5129/
You could, but it sounds like you're making this more complex than it has to be. Rather than manually setting an aria-label, you can use the native API of the checkbox input type. If your html is an actual checkbox input, like:
<input id="check1" name="field-name" type="checkbox">
then when it's checked off, it should automatically get the "checked" attribute, which screenreaders should be able to pick up on. If that fails, you can use aria-checked to supplement it.
var isChecked = element.getAttribute('checked')
element.setAttribute('aria-checked', isChecked)
If you're not using normal input type="checkbox" markup for whatever reason, you can add role="checkbox" to your markup to help the browser treat it as such.
Bonus: you can even use the native check behavior to handle your css, in some cases, via something like this:
[type="checkbox"] { background-image: url('uncheckedIcon.png'); }
[type="checkbox"]:checked { background-image: url('checkedIcon.png'); }

Optimizing code to define variables only once, code only works when the vars are in change function and for the code outside change I redefine?

Pretty sure I know the solution... would write .on('change','load', function(){}
correct? <-- Tested didn't work? so I am up to your solutions :)
Sushanth -- && adeneo both came up with great solutions, this is a good lesson in optimizing code... It's gonna be hard to choose which answer to go with, but I know this is going to help me rethink how I write... I dont know what I do without this forum, id have to learn this stuff in college.
This is purely a question out of curiosity and bettering my skills, as well as giving you guys a chance to display your knowledge on jQuery. Also to prevent any sloppy writing.
I have a radio based switch box, the markup looks like this, the id's and on/off values are generated by the values in my array with PHP...
<span class="toggle-bg">//This color is the background of the toggle, I need jQuery to change this color based on the state on/off
<input type="radio" value="on" id="_moon_page_header_area1" name="_moon_page_header_area">//this is my on value generated by the array
<input type="hidden" value="_moon_page_header_area" class="switch-id-value">// I create this input because I have multiple checkboxes that have the ID _moon_ARRAYVALUE_area1
<input type="radio" value="off" id="_moon_page_header_area2" name="_moon_page_header_area">// off value
<input type="hidden" value="_moon_page_header_area" class="switch-id-value">//_moon_ARRAYVALUE_area2
<span class="switch"></span>// the switch button that changes
</span>
Hope that makes sense and the comments are clear
Here is the jQuery
var value = $('.toggle-bg input.switch-id-value').val()
var moon1 = $('#'+value+'1').is(':checked');
var moon2 = $('#'+value+'2').is(':checked');
var static_slide = $('._moon_staticarea_height');
var toggle = $('.toggle-bg');
if(moon1){
toggle.css({'background-color': '#46b692'});
static_slide.hide()
} else
if (moon2){
toggle.css({'background-color': '#333'});
static_slide.show()
}
$('.toggle-bg').change(function () {
var value = $('.toggle-bg input.switch-id-value').val()
var moon1 = $('#'+value+'1').is(':checked');
var moon2 = $('#'+value+'2').is(':checked');
var static_slide = $('._moon_staticarea_height');
var toggle = $('.toggle-bg');
if(moon1){
toggle.css({'background-color': '#46b692'});
static_slide.slideUp()
} else
if (moon2){
toggle.css({'background-color': '#333'});
static_slide.slideDown()
}
});
it looks longer than it really is, its just repeating it self, one is on load so that it gives the correct color on load of the page, and then inside the change function we need to change colors..
How do I write it so I only have to use variables one time (so its cleaner) is there a better way to optimize it... Just NOW thinking after writing this I could put it in one function .on('load', 'change', function() {}
I just now thought of that, but I wrote all this so I am going to see what others think...
You'd do that by having the function in the change event handler, and on the end you chain on a trigger('change') to make it work on pageload :
$('.toggle-bg').on('change', function () {
var value = $('.toggle-bg input.switch-id-value').val(),
moon1 = $('#' + value + '1').is(':checked'),
slider = $('._moon_staticarea_height'),
toggle = $('.toggle-bg');
toggle.css('background-color', (moon1 ? '#46b692' : '#333'));
slider[moon1?'slideUp':'slideDown']();
}).trigger('change');
As radiobuttons can't be unchecked, it's either moon1 or moon2, which means checking one of them should be enough.
.on('change','load',
supposed to be
// Remove the comma separator if you want to bind the same handler to
// multiple events.
.on('change load',
And you can remove the one separately written out and enclose it in a function (if multiple instances of the class toggle-bg)
or just trigger the change event.(If there is a single instance of a class)
This will just run the same functionality when the page loads.
var toggle = $('.toggle-bg');
toggle.change(function () {
var value = $('input.switch-id-value', this).val(),
moon1 = $('#' + value + '1').is(':checked'),
moon2 = $('#' + value + '2').is(':checked'),
static_slide = $('._moon_staticarea_height');
if (moon1) {
toggle.css({
'background-color': '#46b692'
});
static_slide.slideUp()
} else if (moon2) {
toggle.css({
'background-color': '#333'
});
static_slide.slideDown()
}
}).change();

Using custom jQuery radio buttons with CakePHP Form Helper

I'm using a custom jQuery plugin to convert radio buttons to actual images, and it works with basic checkboxes, but when using Cake's built-in input form helper, it acts more as a checkbox by not unchecking the already clicked options. Not only that, but it isn't populating $this->data (or sending anything when the form is submitted).
The js looks like this:
//##############################
// jQuery Custom Radio-buttons and Checkbox; basically it's styling/theming for Checkbox and Radiobutton elements in forms
// By Dharmavirsinh Jhala - dharmavir#gmail.com
// Date of Release: 13th March 10
// Version: 0.8
/*
USAGE:
$(document).ready(function(){
$(":radio").behaveLikeCheckbox();
}
*/
$(document).ready(function() {
$("#bananas").dgStyle();
var elmHeight = "15"; // should be specified based on image size
// Extend JQuery Functionality For Custom Radio Button Functionality
jQuery.fn.extend({
dgStyle: function()
{
// Initialize with initial load time control state
$.each($(this), function(){
var elm = $(this).children().get(0);
elmType = $(elm).attr("type");
$(this).data('type',elmType);
$(this).data('checked',$(elm).attr("checked"));
$(this).dgClear();
});
$(this).mouseup(function() {
$(this).dgHandle();
});
},
dgClear: function()
{
if($(this).data("checked") == true)
{
$(this).addClass("checked");
}
else
{
$(this).removeClass("checked");
}
},
dgHandle: function()
{
var elm = $(this).children().get(0);
if($(this).data("checked") == true)
$(elm).dgUncheck(this);
else
$(elm).dgCheck(this);
if($(this).data('type') == 'radio')
{
$.each($("input[name='"+$(elm).attr("name")+"']"),function()
{
if(elm!=this)
$(this).dgUncheck(-1);
});
}
},
dgCheck: function(div)
{
$(this).attr("checked",true);
$(div).data('checked',true).addClass('checked');
},
dgUncheck: function(div)
{
$(this).attr("checked",false);
if(div != -1)
$(div).data('checked',false).css({
backgroundPosition:"center 0"
});
else
$(this).parent().data("checked",false).removeClass("checked");
}
});
The PHP/Html looks like this:
<span id="bananas-cat" class="cat">
<?= $this->Form->radio('bananas',array(),array('legend' => false, 'id' => 'bananas', 'name' => 'category')); ?>
<label for="bananas">Bananas</label>
</span>
While it upon first inspection may look correct, when clicked, nothing gets passed within $this->data and it acts like a checkbox and doesn't unselect the value when I add an additional radio checkbox.
Although the radio functionality does work without CakePHP's html form helper like so:
<span id="animals-cat" class="cat">
<input type="radio" name="category" id="animals" />
<label for="animals">Animals</label>
</span>
If anyone can help me out here, I would be forever indebted. I've been trying to solve this for way too long now that I'm considering just scrapping the whole idea to begin with.
What I would suggest is see and compare the HTML output of example and one being generated by CakPHP, try to make it similar to example so that you can get your custom-radio-buttons working.
But if you can not do that I would highly recommend to override those helpers by some parameters so that you can get the exact HTML as an output and Javascript should work flawlessly.
Let me know if that does not work for you.

Categories

Resources