How can I toggle an element's attributes using pure JavaScript? - javascript

Most of the similar questions that arose as I wrote this one were like this (where the user wishes to toggle an element's class using pure JS) or this (where the user wishes wishes to toggle other attributes using jQuery)
My question is a mixture of the two. I am aware that the el.classList.toggle() method exists for toggling an element's class using pure JS, but I wish to toggle different attributes using pure JS, specifically the checked attribute of some radio buttons, since this (annoyingly) does not change when different options are selected.
Is it possible to toggle the checked attribute on my two radio buttons with pure JS (by toggling I mean remove the attribute from the element altogether if it is present, and add it if it is not)?
radios = document.getElementsByName("Floor");
for (i = 0; i < radios.length; i++) {
radios[i].addEventListener('change', function () {
this.(/*checked attribute*/).toggle()
}, false);
}
<input checked id="Floor" name="Floor" type="radio" value="0">Ground Floor
<input id="Floor" name="Floor" type="radio" value="1">First Floor
Edit: The possible duplicate question mentioned in the comments does not quite solve my problem. I don't need to change which radio button appears checked, I just want to toggle the checked attribute, to make it easier for me to reference the button that is checked later on in the code. Of course, if there is another, easier way of doing this, I'm all ears.

There actually is an Element.toggleAttribute method for boolean attributes. MDN Docs.
However, since it is not supported in IE, you might want to add the MDN Polyfill

there is no toggle method for attribute.
You can use:
elm[elm.hasAttribute('hidden')?'removeAttribute':'setAttribute']('hidden', '')
or
elm.hasAttribute('hidden') ? removeAttribute('hidden') : setAttribute('hidden')
EDIT: there is now toggle method for attribute.
elm.toggleAttribute('hidden')
https://developer.mozilla.org/docs/Web/API/Element/hasAttribute

This will work definitely well
const attrToggle = (el, attr) => el.getAttribute(attr) == 'false' ? el.setAttribute(attr, "true") : el.setAttribute(
attr, "false")
It's similar to native toggleAttribute.

I didn't test this, but this should do the trick.
radios = document.getElementsByName("Floor");
for (i = 0; i < radios.length; i++) {
radios[i].addEventListener('change', function () {
if ( this.checked ) {
this.setAttribute("checked", "false");
} else {
this.setAttribute("checked", "true");
}
}, false);
}

Element.toggleAttribute(name) used to toggle boolean attribute https://developer.mozilla.org/en-US/docs/Web/API/Element/toggleAttribute
this.toggleAttribute("checked");

To anyone stumbling on this question, no one in comments or answers since 2017 seems to have pick up on the OP's incorrect assumptions on the true nature of the checked element attribute they are trying to 'toggle'. As this post has so far been viewed 19k times, here is the information you might actually be looking for:
<input type="radio" checked>
In this context the element's checked attribute is a flag developers can use to tell the browser to render a "checked" state on a radio or checkbox input on page load. After page load, the browser does not update or toggle this attribute when a user later selects or un-selects the input.
From MDN:
Checked: A Boolean attribute which, if present, indicates that this radio button is the default selected one in the group.
Therefore the approach of using Element.toggleAttribute('checked') suggested by some here, won't work as expected as the .toggleAttribute() method adds or removes the pre-render flag from the input, but doesn't update the element's 'checked' state as the OP is trying to do. Applying a boolean value to the attribute also has no effect on the state of the element: (this wont work) checked="false"
In JavaScript you can access the current state of an input through HTMLInputElement's IDL boolean property .checked, not to be confused with the Element attribute by the same name referenced by the OP. Here HTMLInputElement.checked is both a getter and setter, meaning you can access (and toggle the value of) .checked as follows:
<input type="radio" id="spam-machine" class="blackhat" name="spam-me" value="sure!">
<script>
const spamMe = document.querySelector('#spam-machine');
spamMe.checked = !spamMe.checked;
</script>
You can additionally selectively style checked inputs using the :checked CSS pseudo class:
input[type="radio"].blackhat:checked { visibility: hidden; }
Now go forth into the world .... rendering to no one evil for evil.

Related

How to check if element is not visible due to parent is hidden thanks its class

I have an array of checkboxes and want to switch them (check/uncheck) as a group, but only these which are really visible.
<style id=dynamicStyle>DIV.filterLevel3{display:none;}</style>
<div class="filterLevel3">
<input type=checkbox id=cbx_123456 name=cbx_123456 class=cbxForSwitch>
... more elements belonging to the checkbox,
... always hidden on shown together
</div>
The dynamicStyle.innerHTML may be changed by another javascript. Changing the visibility works fine, but I need to select all checkboxes of class "cbxForSwitch" that are currently visible.
I have seen many examples using jQuery, but all of them were inspecting css attributes of said element or his style etc. I need to get actual visibility after the explorer have implemented all rules of style including inheritance.
Using jQuery you can get the parent element's css attributes by using the parent() function. If the parent's 'display' css property is set to none, you can then check the box by using the jquery function prop().
$('input[type=checkbox]').each(function() {
if ($(this).parent().css('display') !== 'none') {
$(this).prop('checked', true);
}
});
Here is a JSFiddle

Primefaces p:inplace component: how to read state in JavaScript?

How to access the state of PrimeFaces p:inplace component in Javascript?
I need to check if the component is in state inline or not, in order to call toggle()function when needed... AFAIK toggle() can only change the state and not set the state to desired value?
Suppose you got something like thisL
<p:inplace id="basic" widgetVar="myWidget">
<p:inputText value="Edit Me" />
</p:inplace>
You can check if the inplace was opened with the help of the widgetVar and jQuery , like this
jQuery(myWidget.content).is(":visible")
Or you can check it with the :visible selector and the id of the inplace :
append _display to your inplace element id to check if the editor wasn't open yet
append _content to your inplace element id to check if the editor was already open
jQuery("#basic_display").is(":visible")
jQuery("#basic_content").is(":visible")
you can check it in browser console in the showcase Primefaces Inplace
I have achieved it with checking the CSS display value of ui-inplace-display and ui-inplace-content elements:
$('.ui-inplace-display').filter(function(){
return $(this).css('display') == 'inline';
}).toggle();
$('.ui-inplace-content').filter(function(){
return $(this).css('display') == 'none';
}).toggle();
However, for me it's more a hack that a solution, so I'd expect something more elegant, such as a state in dedicated attribute of JavaScript object, or at least dedicated CSS class for that.

How to use string argument of a function in a jQuery expression

I have some set of links and select boxes. My html code is below:
<div>
<div>
<a href='#' onclick='set_checked(false,"checkbox1")'>clear</a>
<a href='#' onclick='set_checked(true,"checkbox1")'>select</a>
</div>
<div>
<input type='checkbox' name='checkbox1'/>
</div>
</div>
<div>
<div>
<a href='#' onclick='set_checked(false,"checkbox2")'>clear</a>
<a href='#' onclick='set_checked(true,"checkbox2")'>select</a>
</div>
<div>
<input type='checkbox' name='checkbox2'/>
</div>
</div>
Now my requirement is when I click on select link I have to check the checkbox based on it's arguments, and reversal for clear. Here I'm passing two parameters. One is to pass Boolean value (i.e. if true check else uncheck) and another one is to pass name argument of a checkbox field. And I'm using the following function to check or uncheck a checkbox:
function set_checked(checked,inputFeildName){
$('input[name=inputFeildName]').attr('checked',checked);
}
but the above code is not working. And this is my fiddle http://jsfiddle.net/vu6fs/5/.
I have one more requirement, before selecting any checkbox all clear links have to be disabled, after selection of checkbox respective clear link have to be enable. I'm applying opacity and also 'disabled' property in JavaScript but it's not working,can anyone suggest me where my fault is.. Can anyone please help me?
jQuery 1.6+
function set_checked(checked,inputFeildName){
$('input[name="'+ inputFeildName +'"]').prop('checked',true);
}
jQuery 1.5 and below
function set_checked(checked,inputFeildName){
$('input[name="'+ inputFeildName +'"]').attr('checked','checked');
}
Here is an example for your extension of question (more you want, About disable/enable a tag on checkbox change)
CSS
.disButton {
background: transparent;
border: none;
}
.disButton a {
text-decoration: none;
color: #ddd;
}
jQuery
$('input:checkbox').on('change', function() {
enable_clear(this, this.checked);
}).change();
function enable_clear(el, checked) {
var target = $(el).parent('div').prev('div').find('a:contains(clear)');
if (checked) {
target.unwrap();
} else {
target.wrap($('<button/>', {
disabled: true,
'class': 'disButton',
width: target.width() + 'px'
}));
}
}
$('a').on('click', function(e) {
e.preventDefault();
var target = $(this).parent().next('div').find('input:checkbox');
if (!target.is(':checked') && $(this).text() == 'select') target.click();
if ($(this).text() == 'clear') target.click();
});
DEMO
I think this is what you are trying to do... btw you have misspelt field so be careful when using the variable/attr again.
function set_checked(checked,inputFeildName){
$('input[name="'+inputFeildName+'"]').attr('checked',checked);
}
you forget to append string that i did as below , this will resolve your issue
function set_checked(checked,inputFeildName)
{
$('input[name="'+ inputFeildName+'"]').attr('checked',checked);
}
There are some errors in your fiddle:
Your function set_checked is declared in the onLoad-Handler (as selected), and is only available in that locally and not in the global scope. Remove the wrapping function by selecting "no wrap (head)" or assign your function to window.set_checked.
Please note that the checked attribute only represents the default value of the checkbox, to change the actual state you need to use the checked property (with jQuery, you can use val()).
If you wanted to change the default value, you can't do it by setting the attribute to (the string) false. The attribute represents a checked checbox through its existence, you would need to use removeAttribute() for disabling. It's easier to use the defaultChecked property with a boolean value.
last but not least there's the obvious error detected by all others: To use a variable, you will need to use it instead of putting its name into a string (like in PHP).
You also might be more happy with ids than name attributes. I've updated your fiddle with a proper solution: http://jsfiddle.net/vu6fs/7/
To disable the clear/select link when it's not appropriate:
you can't disable a link (anchor) as you can a form element (see Disable link using javascript, jQuery disable a link, Disable link using css). OK, we don't really need to disable its functionality (nothing changes), so so I guess you only think of graying it out. This can be done with CSS, and you'll need to trigger the update both on user-change events and the setting through set_checked. Example code at http://jsfiddle.net/vu6fs/9/
It might be easier to use just one link that toggles the checked state. Its lettering may change between "clear" and "select", depending on the current state.
I now have written a plugin (i.e. a jQuery prototype function) to add those links dynamically to any checkbox elements. That means it also can use (scoped) click handlers instead of a global-scope-polluting set_checked function.
The function has a little error:
function set_checked(checked,inputFeildName){
$(**'input[name='+inputFeildName+']'**).attr('checked',checked);
}

Adapt my js code to an input

I have this javascript code that creates a slider:
http://jsfiddle.net/samccone/ZMkkd/
Now, i want to use this code on a checkbox input. the problem is that the code creates a child element that slides in it's parent using a css position, and an input cannot have a child.
My idea was to use background-position and just slide the background of the input from left to right using css instead of using real positioning.
How can I adapt this script? It is quite easy I think but after a couple of tries I just gave up, i'm not good enough :).
Thanks for your help,
Christopher
Believe it or not, for checkboxes a switch effect is possible to create without JavaScript.
If you follow your checkbox with a label:
<input type="checkbox" id="jim" />
<label for="jim"></label>
You will find that you can select the label with the next sibling selector:
input + label { /* some CSS */ }
Why is that useful? Because using the pseudo selector :checked you can now style the label based on the state of the checkbox:
input + label { background-position: 0 0; }
input:checked + label { background-position: 100% 0; }
Clearly, due to the for="jim" attribute, clicking on the label will change the state of the checkbox. So if you hide the checkbox, you end up with a styled, clickable label.
input { display: none; }
Of course, labels can have children so you can be as fancy as you want with your recreation of a switch. And you should be careful to include :focus styles as well, for people who tab to your checkbox rather than click on it.
For browsers that do not support the :checked pseudo class (IE8 and below), it's pretty easy to emulate with a global handler and a 'checked' class. Something like:
jQuery(document).bind('change', function(e){
var elem = jQuery(e.target);
// If this is not a checkox, do nothing.
if (elem.attr('type') !== 'checkbox') { return; }
// Add or remove checked class based on current state.
if (elem.attr('checked')) { elem.removeClass('checked'); }
else { elem.addClass('checked'); }
});
...should do it.
You might need to store some data in object properties (or the .data() api), but your background position idea should work just fine. Just replace your calls to .offset().left with .css('background-position') (you'll have to split and parseInt the string it returns tho) and keep plugin' away at it.

Reference HTML Elements by name (with square brackets in them) via javascript

Hey everyone, I am trying to hide/show different html elements (div, etc...) based on whether a checkbox is checked or if a specific value is chosen from a dropdown box. I was wondering if someone can help me out. The html element is defined along the lines of this (below), and i'm not sure how to reference it by name with brackets in it. The page i'm using has jquery enabled, and i'd like to use it if possible. Thanks!
<input type="checkbox" name="addons[2]" />
Also - I cannot modify the checkbox's code.
jQuery to check if element is checked:
$("input[name='addons[2]']").attr("checked")
jQuery to loop over such elements that are checked:
$("input[name^='addons']:checked").each(function() {
// ...
});
Thanks for the help, here is the final code I used
$("input[name='customfield[4]']").click(
function()
{
if ($("input[name='customfield[4]']").is(":checked"))
{
$("#addons").hide();
}
else
{
$("#addons").show();
}
}
);
Here is an inline non-jQuery solution that bypasses the need to reference the square brackets entirely by using the javascript this keyword. Assuming you want to show/hide a <div> with id="mydiv":
<input type="checkbox" name="addons[2]" onclick="document.getElementById('mydiv').style.display = (this.checked ? 'block' : 'none');" />
avoid using [] in naming html elements

Categories

Resources