I am new to OO JavaScript, and have tried writing a plugin which allows me so create multiple instances of "pretty selects" which can have custom html formatted within...
the issue im having is that when i add multiple instances on the page, one returns undefined or odd values....
Here is my JS
function selectify(options) {
var $elem = $(options.target),
$button = $elem.find('button');
open = false;
function getVal() {
return $elem.find('input:checked').val();
}
function setVal(val) {
$elem.find('.active').removeClass('active');
$elem.find('input[value="' + val + '"]').attr('checked','checked').parent().addClass('active');
}
function toggle() {
if(open) {
open = false;
$elem.removeClass('open');
$button.attr('aria-pressed','false');
} else {
open = true;
//$elem.find('.active input').focus();
$elem.addClass('open');
$button.attr('aria-pressed','true');
}
}
$button.attr('aria-pressed','false');
$elem.find('input:checked').parent().addClass('active')
$elem.find('label').click(function() {
setVal($(this).find('input').val());
if(open) toggle();
});
$button.click(function() {
toggle();
})
$(window).on('keydown', function(e) {
if(open) {
switch(e.keyCode) {
case 40:
//down
if(!$elem.find('.active').is('label:last-child')) setVal($elem.find('.active').next('label').find('input').val());
break;
case 38:
//up
if($elem.find('.active').index()>1) setVal($elem.find('.active').prev('label').find('input').val());
break;
case 27:
toggle();
break;
}
}
})
return {
getVal: getVal,
setVal: setVal,
open: open,
toggle: toggle
}
}
var x = new selectify({
target:'.target2'
});
var y = new selectify({
target:'.target'
});
and this is the html
<fieldset class="selectify target">
<button aria-label="open select">▼</button>
<!--legend>Donut Type</legend-->
<label>
<input type="radio" value="1" name="flavour" />
Red
</label>
<label>
<input type="radio" value="2" name="flavour" checked="checked" />
Blue
</label>
<label>
<input type="radio" value="3" name="flavour" />
Green
</label>
<label>
<input type="radio" value="4" name="flavour" />
Yellow
</label>
<label>
<input type="radio" value="5" name="flavour" />
Cat
</label>
</fieldset>
I have a working example on CodePen if that helps?
http://codepen.io/ben-walters/pen/fbIya
Thanks in advance guys and girls!
Related
I would like to have a little help on an enigma that I have.
I have a button that changes according to the number of input:checked
but I would like to add a condition which is: select of the checkboxes of the same class.
for example can I have 2 or more input.
<input class="banana" type="checkbox" value="Cavendish">
<input class="banana" type="checkbox" value="Goldfinger">
<input class="chocolato" type="checkbox" value="cocoa powder">
<input class="chocolato" type="checkbox" value="milk chocolate">
<input class="apple" type="checkbox" value="honneycrisp">
<input class="apple" type="checkbox" value="granny smith">
I can't use attribute name or value. it is not possible to modify the inputs.
the condition:
$('input[type="checkbox"]').click(function(){
if($('input[type="checkbox"]:checked').length >=2){
////////
if (my classes are the same) {
$('#btn').html("click me").prop('disabled', false);
} else {
$('#btn').html("too bad").prop('disabled', true);
}
//////
}
I try with
var checkClass = [];
$.each($("input[type="checkbox"]:checked"), function() {
checkClass.push($(this).attr('class'));
});
I don't know if I'm going the right way or if I'm complicating the code but a little help would be welcome. For the moment my attempts have been unsuccessful.
The following function will reference the first checkbox that's checked className and enable each checkbox that has said className whilst disabling all other checkboxes. Details are commented in Snippet.
// All checkboxes
const all = $(':checkbox');
// Any change event on any checkbox run function `matchCategory`
all.on('change', matchCategory);
function matchCategory() {
// All checked checkboxes
const checked = $(':checkbox:checked');
let category;
// if there is at least one checkbox checked...
if (checked.length > 0) {
// ...enable (.btn)...
$('.btn').removeClass('off');
// ...get the class of the first checked checkbox...
category = checked[0].className;
// ...disable ALL checkboxes...
all.attr('disabled', true);
// ...go through each checkbox...
all.each(function() {
// if THIS checkbox has the class defined as (category)...
if ($(this).is('.' + category)) {
// ...enable it
$(this).attr('disabled', false);
// Otherwise...
} else {
// ...disable and uncheck it
$(this).attr('disabled', true).prop('checked', false);
}
});
// Otherwise...
} else {
// ...enable ALL checkboxes...
all.attr('disabled', false);
// ...disable (.btn)
$('.btn').addClass('off');
}
return false;
}
.off {
pointer-events: none;
opacity: 0.4;
}
<input class="beverage" type="checkbox" value="Alcohol">
<label>🍸</label><br>
<input class="beverage" type="checkbox" value="Coffee">
<label>☕</label><br>
<input class="dessert" type="checkbox" value="cake">
<label>🍰</label><br>
<input class="dessert" type="checkbox" value="Ice Cream">
<label>🍨</label><br>
<input class="appetizer" type="checkbox" value="Salad">
<label>🥗</label><br>
<input class="appetizer" type="checkbox" value="Bread">
<label>🥖</label><br>
<button class='btn off' type='button '>Order</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
some thing like that ?
const
bt_restart = document.getElementById('bt-restart')
, chkbx_all = document.querySelectorAll('input[type=checkbox]')
;
var checked_class = ''
;
bt_restart.onclick = _ =>
{
checked_class = ''
chkbx_all.forEach(cbx=>
{
cbx.checked=cbx.disabled=false
cbx.closest('label').style = ''
})
}
chkbx_all.forEach(cbx=>
{
cbx.onclick = e =>
{
if (checked_class === '') checked_class = cbx.className
else if (checked_class != cbx.className )
{
cbx.checked = false
cbx.disabled = true
cbx.closest('label').style = 'color: grey'
}
}
})
<button id="bt-restart">restart</button> <br> <br>
<label> <input class="banana" type="checkbox" value="Cavendish" > a-Cavendish </label> <br>
<label> <input class="banana" type="checkbox" value="Goldfinger" > a-Goldfinger </label> <br>
<label> <input class="chocolato" type="checkbox" value="cocoa powder" > b-cocoa powder </label> <br>
<label> <input class="chocolato" type="checkbox" value="milk chocolate"> b-milk chocolate </label> <br>
<label> <input class="apple" type="checkbox" value="honneycrisp" > c-honneycrisp </label> <br>
<label> <input class="apple" type="checkbox" value="granny smith" > c-granny smith </label> <br>
In fact it's like a Matching Pairs card game
this answer is without global checked_group variable, and respecting epascarello message about data attribute see also usage.
Adding a repentance on uncheck elements
const
bt_restart = document.getElementById('bt-restart')
, chkbx_all = document.querySelectorAll('input[type=checkbox]')
;
function clearGame()
{
chkbx_all.forEach(cbx=>
{
cbx.checked = cbx.disabled = false
cbx.closest('label').style = ''
})
}
bt_restart.onclick = clearGame
chkbx_all.forEach(cbx=>
{
cbx.onclick = e =>
{
let checkedList = document.querySelectorAll('input[type=checkbox]:checked')
if (cbx.checked)
{
let checked_group = ''
checkedList.forEach(cEl=>{ if (cEl !== cbx) checked_group = cEl.dataset.group })
if (checked_group === '') checked_group = cbx.dataset.group
else if (checked_group !== cbx.dataset.group )
{
cbx.checked = false // you need to uncheck wrong group checkboxes for preserving checkedList
cbx.disabled = true
cbx.closest('label').style = 'color: grey'
}
}
else if (checkedList.length === 0) // case of cheked repentir
clearGame()
}
})
<button id="bt-restart">restart</button> <br> <br>
<label> <input data-group="banana" type="checkbox" value="Cavendish" > a-Cavendish </label> <br>
<label> <input data-group="banana" type="checkbox" value="Goldfinger" > a-Goldfinger </label> <br>
<label> <input data-group="chocolato" type="checkbox" value="cocoa powder" > b-cocoa powder </label> <br>
<label> <input data-group="chocolato" type="checkbox" value="milk chocolate"> b-milk chocolate </label> <br>
<label> <input data-group="apple" type="checkbox" value="honneycrisp" > c-honneycrisp </label> <br>
<label> <input data-group="apple" type="checkbox" value="granny smith" > c-granny smith </label> <br>
I have some radio inputs and I would like to call a JS function only in the case where the id3 radio is selected and becomes unselected.
I searched, but I found only solutions, where only checked/unchecked status is checked:
$("input:radio").change(function() {
if ($("#id3").is(":checked")) {
alert('checked');
} else {
alert('unchecked');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="radio" name="shipping_method" value="1" id="id1" data-refresh="5" class="">
<input type="radio" name="shipping_method" value="2" id="id2" data-refresh="5" class="">
<input type="radio" name="shipping_method" value="3" id="id3" data-refresh="5" class="">
You will need to keep track of when you last clicked it, to see if you need to say that it was unselected.
Plain JS
This is fairly simple to do in pure JavaScript. You can utilize the data-* attribute design to store the state of when an element was last checked.
let targetEl = document.getElementById('id3');
Array.from(document.querySelectorAll('input[type="radio"]')).forEach(radioEl => {
radioEl.addEventListener('change', function(e) {
if (e.target.id === targetEl.id && e.target.checked) {
alert(e.target.id + ' - checked');
e.target.setAttribute('data-waschecked', true);
} else if (targetEl.getAttribute('data-waschecked') === 'true') {
alert(targetEl.id + ' - unchecked');
targetEl.setAttribute('data-waschecked', false);
}
});
});
<input type="radio" name="shipping_method" value="1" id="id1" data-refresh="5">
<input type="radio" name="shipping_method" value="2" id="id2" data-refresh="5">
<input type="radio" name="shipping_method" value="3" id="id3" data-refresh="5">
jQuery
This advanced solution allows you to monitor multiple radio buttons. It is written mostly in jQuery.
const trackableIds = [ 'id1', 'id3' ];
$('input[type="radio"]').on('change', function(e) {
let $target = $(e.target),
isTrackable = trackableIds.includes($target.attr('id'));
if (isTrackable && $target.is(':checked')) {
alert($target.attr('id') + ' - checked');
$target.attr('data-waschecked', true);
}
trackableIds.filter(trackId => trackId !== $target.attr('id'))
.forEach(trackId => {
let $trackable = $('#' + trackId);
if ($trackable.attr('data-waschecked') === 'true') {
alert($trackable.attr('id') + ' - unchecked');
$trackable.attr('data-waschecked', false);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="radio" name="shipping_method" value="1" id="id1" data-refresh="5">
<input type="radio" name="shipping_method" value="2" id="id2" data-refresh="5">
<input type="radio" name="shipping_method" value="3" id="id3" data-refresh="5">
As a jQuery plugin
Nearly identical behavior to the jQuery above, but as a plugin. There are even custom callback function options for checking/unchecking.
(($) => {
$.fn.trackRadio = function(ids, opts) {
this.on('change', function(e) {
let $target = $(e.target), isTrackable = ids.includes($target.attr('id'));
if (isTrackable && $target.is(':checked')) {
opts.onCheckFn($target);
$target.attr('data-waschecked', true);
}
ids.filter(trackId => trackId !== $target.attr('id')).forEach(trackId => {
let $trackable = $('#' + trackId);
if ($trackable.attr('data-waschecked') === 'true') {
opts.onCheckFn($trackable);
$trackable.attr('data-waschecked', false);
}
});
});
}
})(jQuery);
$('input[type="radio"]').trackRadio(['id1', 'id3'], {
onCheckFn : function($radio) {
alert($radio.attr('id') + ' - checked');
},
onUncheckFn : function($radio) {
alert($radio.attr('id') + ' - unchecked');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="radio" name="shipping_method" value="1" id="id1" data-refresh="5">
<input type="radio" name="shipping_method" value="2" id="id2" data-refresh="5">
<input type="radio" name="shipping_method" value="3" id="id3" data-refresh="5">
What you can do is add a watcher variable to find out whether you are deselecting the radio button.
var isChecked = false;
$("input:radio").change(function () {
if ($("#id3").is(":checked")) {
isChecked = true;
} else {
if (isChecked) {
alert("Unchecked");
isChecked = false;
}
}
});
CodePen: https://codepen.io/ashfaq_haq/pen/LYYjLrv?editors=1010
I'm looking for a way to add another value into my input text. I have a read only input box, two radio buttons, and three checkboxes.
<div class="radios">
<label>
<input type="radio" value="non-exclusive" id="non-exclusive" name="packages"> Non-Exclusive
</label>
<label>
<input type="radio" name="extratreats" data-target="#extratreat"> Extra-Treats
</label>
</div>
<div id="extratreat" class="extratreat tab-pane collapse">
<label><h2>Extra Treats</h2></label>
<br />
<label><input id="treats" name="treats[]" value="Sweet Corner" type="checkbox" > Sweet Corner & Choco Fountain</label>
<label><input id="treats" name="treats[]" value="Popcorn Maker" type="checkbox" > Popcorn Maker</label>
<label><input id="treats" name="treats[]" value="Hotdog Roller" type="checkbox" > Hotdog Roller</label>
</div>
<div id="pricing">
<label><h2>Price</h2></label>
<br />
<input type="text" name="price-total" value="" autocomplete="off" readonly>
</div>
I've added a javascript to my radio button where if I click on non-exlusive the value of pricing will change to 279. But I don't know how to add more value to if I add from treats. For example the price of Sweet Corner is 2,500 and they also clicked on Non-Exlusive which has 279 as it's default value, how do I add 2,500 to the already specified 279?
Here's the script I tried using:
<script>
$(document).ready(function(){
$('[name=packages]').click(function() {
var val = $(this).val();
if (val == "non-exclusive") {
$('[name=price-total]').val('PHP 279');
} else if (val == "package1") {
$('[name=price-total]').val('PHP 300');
} else if (val == "package2") {
$('[name=price-total]').val('PHP 400');
}
});
$('[id=treats').click(function() {
var val1 = $(this).val();
var val = $('[name=price-total]').val();
if (val1 == "Sweet Corner") {
$('[name=price-total]').val(val.val+' 2500');
} else if (val1 == "package1") {
$('[name=price-total]').val('PHP 300');
} else if (val1 == "package2") {
$('[name=price-total]').val('PHP 400');
}
});
});
</script>
It gives me an "undefined value" if I click one of the checkboxes instead of adding it's value to the first value.
The problem was that you made a variable called val and then tried to access it with val.val + ' 2500' when it should have just been val + ' 2500'. val.val implies that there is a val object with a val property. Since there isn't, you got undefined.
You also have a syntax error with this:
$('[id=treats').click(function() {
As it should be:
$('[id=treats]').click(function() {
Also, I think that because of what your are testing, switch statements are more appropriate.
Lastly, you have multiple items with the same id, which isn't valid. After making them all unique, you should change your second click handler so that it accesses all the checkboxes by using the name attribute instead of id.
$(document).ready(function(){
$('[name=packages]').click(function() {
switch($(this).val()){
case "non-exclusive":
$('[name=price-total]').val('PHP 279');
break;
case "package1":
$('[name=price-total]').val('PHP 300');
break;
case "package2":
$('[name=price-total]').val('PHP 400');
break;
}
});
$('[name="treats[]"]').click(function() {
// Strip out non-numeric portion:
var val = $('[name="price-total"]').val().replace("PHP ", "");
switch($(this).val()){
case "Sweet Corner":
// Check to see if checkbox is checked...
if(this.checked){
// Must convert the value to a number and then you can do math
$('[name=price-total]').val("PHP " + (+val + 2500)); // <-- The problem was here
} else {
$('[name=price-total]').val("PHP 279");
}
break;
case "package1":
$('[name=price-total]').val('PHP 300');
break;
case "package2":
$('[name=price-total]').val('PHP 400');
break;
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="radios">
<label>
<input type="radio" value="non-exclusive" id="non-exclusive" name="packages"> Non-Exclusive
</label>
<label>
<input type="radio" name="extratreats" data-target="#extratreat"> Extra-Treats
</label>
</div>
<div id="extratreat" class="extratreat tab-pane collapse">
<label><h2>Extra Treats</h2></label>
<br />
<label><input id="treats1" name="treats[]" value="Sweet Corner" type="checkbox" > Sweet Corner & Choco Fountain</label>
<label><input id="treats2" name="treats[]" value="Popcorn Maker" type="checkbox" > Popcorn Maker</label>
<label><input id="treats3" name="treats[]" value="Hotdog Roller" type="checkbox" > Hotdog Roller</label>
</div>
<div id="pricing">
<label><h2>Price</h2></label>
<br />
<input type="text" name="price-total" value="" autocomplete="off" readonly>
</div>
This is what I have on the HTML side of things. I have a form with the id of products, a name of myForm, an action tag a method of get, and onsubmit returns the function validateForm(); I have a full fledged order form
<form id="products"name="myForm"action="FormProcessor.html"method="get"
onsubmit="return validateForm();">
<label for="payment">Payment Method?</label>
<input id="visa" name="credit_card" type="radio" value="Visa" />
<label for="visa">Visa</label>
<input id="masterCard" name="credit_card" type="radio"value="MasterCard" />
<label for="mastercard">MasterCard</label>
<input id="ae"name="credit_card"type="radio"value="American Express" />
<label for="americanexpress">American Express</label><br>
This is what I have on the js side of things, I am also trying to write it in vanilla js. I have not learned jQuery yet i am still new to programming. I am not sure why it is not alerting.
function validateForm() {
var p_form = document.getElementById("products");
p_form.addEventListener("submit", function(event) {
var payment_array = document.getElementsByName("credit_card");
for(var i = 0; i < payment_array.length; i++) {
if(payment_array[i].checked) {
selection_made = true;
break;
}
}
if(!selection_made) {
event.preventDefault();
alert("Payment Method must be selected.");
return false;
}
});}
Demo: http://jsfiddle.net/e4gfs67o/1/
Solution:
HTML:
<form id="products" name="myForm" action="FormProcessor.html" method="get">
<label for="payment">Payment Method?</label>
<input id="visa" name="credit_card" type="radio" value="Visa" />
<label for="visa">Visa</label>
<input id="masterCard" name="credit_card" type="radio" value="MasterCard" />
<label for="mastercard">MasterCard</label>
<input id="ae"name="credit_card" type="radio" value="American Express" />
<label for="americanexpress">American Express</label><br>
<button type='submit'>Submit</button>
</form>
Javascript:
var form = document.getElementById('products');
form.addEventListener('submit', function(event) {
var radios = document.getElementsByName('credit_card'),
len = radios.length,
i = 0,
selected = false;
for (; i < len; i++) {
if (radios[i].checked) {
selected = true;
break;
}
}
if (selected) {
return true;
} else {
event.preventDefault();
alert('Payment Method must be selected.');
return false;
}
});
I am trying to use radio buttons in html, but when I test out my code, what i want to happen isn't happening. I'm not sure if this is because of the radio buttons or the function i made.
here are the radio buttons, along with some other inputs I have:
<input type="text" id="num1">
+<input type="radio" name="group1" id="add" value="add">
-<input type="radio" name="group1" id="subtract" value="subtract">
*<input type="radio" name="group1" id="multiply" value="multiply">
/<input type="radio" name="group1" id="divide" value="divide">
<input type="text" id="num2">
<input type="text" id="answer" readonly>
<input type="button" value="Calculate" onClick="operation()"
And here is the function I made:
function operation() {
if (document.getElementById("add").checked) {
calculate0()
}
if (document.getElementById("subtract").checked) {
calculate1()
}
if (document.getElementById("multiply").checked) {
calculate2()
}
if (document.getElementById("divide").checked) {
calculate3()
Thanks!
here's a simple fiddle.
modify your script as follows:
function operation() {
var ans =document.getElementById("answer");
if (document.getElementById("add").checked) {
ans.value= calculate('add');
}
if (document.getElementById("subtract").checked) {
ans.value= calculate('subtract');
}
if (document.getElementById("multiply").checked) {
ans.value= calculate('multiply');
}
if (document.getElementById("divide").checked) {
ans.value= calculate('divide');
}
}
function calculate(action){
var num1 = document.getElementById("num1").value;
var num2 = document.getElementById("num2").value;
var result;
switch(action){
case 'add':
result= parseInt(num1)+parseInt(num2);
break;
case 'subtract':
result= num1-num2;
break;
case 'multiply':
result= num1*num2;
break;
case 'divide':
result= num1/num2;
break;
}
return result;
}
side note: now might be a good time to start closing the html tags