Find nearest div with class disableDiv and disable all of its contents - javascript

In this code I am checking the chekbox with class disableDivCheckbox and the code is disabling all of the div content with class disableDiv. But if I apply this combination to another checkbox and another div, this is not working properly. So I want to find closest div with class disableDiv and disable only that div. I am using disabale * because I want to disbale div and its contents.
$(".disableDivCheckbox").click(function () {
if ($(this).is(":checked")) {
$('.disableDiv *').removeAttr("disabled");
}
else {
$('.disableDiv *').val('').prop('checked', false).attr("disabled", "disabled");
}
});
fiddle : https://jsfiddle.net/8c0x1pho/

You can try this approach:
Get checked state and save it in a variable
Navigate to all necessary elements using this. It will make your code more modular.
Try not to use * selector. Use more specific selectors as this will specify element types you are manipulating and make your code more reusable.
Instead of attr and removeAttr, you can just set value of disabled as true or false . You can just use !$(..).is(":checked")
Sample:
// Only call functions. DON'T declare any functions in ready.
$(document).ready(function() {
// Have a common function.
// If size grows, this can be exported to its own file
registerEvents();
// Initialise on load states.
updateUIStates("#addBusinessObjectivesCheckbox")
});
function registerEvents() {
$(".disableDivCheckbox").click(function() {
updateUIStates(this)
})
}
function updateUIStates(el) {
var isNotChecked = !$(el).is(":checked");
var inputs = $(el)
.parents(".checkbox")
.siblings(".disableDiv")
.find('input');
inputs.attr("disabled", isNotChecked)
isNotChecked && inputs.val('').prop('checked', false)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<fieldset id="AddBusinessObjectivesFieldset" class="">
<legend>
Add business objectives
</legend>
<div class="checkbox">
<label>
<input type="checkbox" value="addBusinessObjectivesCheckbox" name="addBusinessObjectivesCheckbox" class="disableDivCheckbox" id="addBusinessObjectivesCheckbox"> Add business objectives
</label>
</div>
<div style="border: 2px solid;margin-bottom: 5px;border-color: gray;padding: 0px 0px 0px 5px;margin-top: 5px;margin-right: 10px;" class="disableDiv">
<div class="form-inline" style="margin-top:5px;margin-bottom:5px;">
<table>
<tr>
<td>
<div class="radio">
<label>
<input type="radio" name="AddBusinessObjectives" id="" value="0" class=""> Fixed N
</label>
</div>
</td>
<td>
<div class="radio">
<label>
<input type="radio" name="AddBusinessObjectives" id="" value="1" class=""> Random upto N
</label>
<input type="text" placeholder="Enter N" id="indexTextboxAddBusinessObjectives" name="indexTextboxAddBusinessObjectives" style="width:70px" class="" />
</div>
</td>
</tr>
</table>
</div>
</div>
</fieldset>
Pointers
$(document).ready() is more like init function. Try to call functions instead of defining in it. This will make easier to understand as it will depict a flow.
Use pure functions and call then. Like onChange, you can call few functions: updateUIStates(), postDataToServer(), processResponse(), otherTodos(). This may look like overkill but in long run this will help.
Create a tree structure in your markup.
<div class="container">
<div class="checkbox-container">...</div>
<div class="input-containers">...</div>
</div>
This will ease navigation part. No matter what structure you use, keep it standardised. This will keep your JS clean.

Try this,
$(".disableDivCheckbox").click(function () {
if ($(this).is(":checked")) {
$(this).closest('.disableDiv *').removeAttr("disabled");
} else {
$(this).closest('.disableDiv *').val('').prop('checked', false).attr("disabled", "disabled");
}
});
This means that, you will disable all content of only that disableDiv class to which disableDivCheckbox belongs.
Give it a try, this will work.

Related

Changing table style when changing radiobutton

Javascript:
function changeStylePruefung(radiobutton) {
if (radiobutton.value === "stoerungsbehebung") {
document.getElementById("table-stoerung").style.display = "block";
document.getElementById("table-haupt").style.display = "none";
} else {
document.getElementById("table-stoerung").style.display = "none";
document.getElementById("table-haupt").style.display = "block";
}
}
HTML:
<fieldset id="uberpruefung">
<legend style="font-weight: bold">Prüfung im Rahmen einer</legend>
<div>
<label for="stoerungbeh">Störungsbehebung</label>
<input type="radio" id="stoerungbeh" name="pruefung" value="stoerungsbehebung" onchange="changeStylePruefung(this)"
checked><br>
</div>
<div>
<label for="hauptpruefung">Hauptprüfung</label>
<input type="radio" id="hauptpruefung" name="pruefung" value="hauptpruefung" onchange="changeStylePruefung(this)">
</div>
</fieldset>
<br><br>
<fieldset>
<legend style="font-weight: bold">In Ordnung</legend>
<div class='table-haupt' style="display: none">
<table class='rg-table' summary='Hed'>
.....
</table>
</div>
<div class='table-stoerung' style="display: block">
<table class='rg-table-stoerung' summary='Hed'>
.....
</table>
</div>
</fieldset>
I would like to change the style of a table if the radiobutton changes. But with that code it just do nothing.I looked up on several websites and tryed their way but it also didn't worked. Any ideas why?
You have defined the class of the Tables in the HTML file and you're searching for the ID of the Tables in the JavaScript code, that isn't available. So you should create the ID of the tables, with the same value Of The Table's class. You have used Class instead of ID, just this is the problem, replace class with id. This Will 100% Help You.
If i was approaching this my first point of call would be to look to see where and what is calling this function, firstly this is the deceleration of a function, not the invocation of a function. So where are you calling this function - is it in a html page or js file in your app?
I would step through the expectations of where it is called, console.log radiobutton in the first line of your function, then radiobutton.value, then document, then document.getElementById("table-stoerung") and keep going until you understand the scope of your function.
You need to step through incrementally and just debug - there is nothing wrong with this code, it may be that document does not have elements with these ids or one of these props is missing. That said having an else condition to get an element id is not recommended.

Different way to generate divs via checkbox

Currently I am using the below method using JS to generate a block of text in a right column when a check box is clicked ticked in a left column.
This has been working fine, however each time I need to add a check box, I need to add a new class and new formContainer element. With the original 3 I had, wasn't a big deal. But now that I'm up to 10 and growing, getting a bit cumbersome.
What better possibilities exist to generate a div/block of text on a different part of the page as a result of a ticked check box?
Check Box
<input id="chk" data-detail="<br>Right 1" class="chkbox" type="checkbox" value="results" />1
Creating individual class
<div class="formContainer"></div>
Script
<script>
$('.chkbox').on('click',function(){
if($(this).is(':checked'))
{
$('.formContainer').html('<div class="new">'+$(this).data('detail')+'</div>');
}
else
{
$('.formContainer').html('');
}
});
</script>
If you are wanting them in columns you can generate them using bootstrap gridsystem.
<div class="formContainer>
<div class="container">
<div class="row">
<div class="col-m-4"></div>
<div class="col-m-4"></div>
<div class="col-m-4"></div>
</div>
<div class="row">
...
</div>
</div>
</div>
If you are wanting to keep them in the same column you could just use .append()
$('.formContainer').append('<div class="new">'+$(this).data('detail')+'</div>');
These can be used together to generate a fluid system or just the append can be used to keep adding divs to your formContainer
I would suggest appending a form after your checkbox using the Jquery function .after(newElement);
Play with it on codepen
Html:
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
<style>
.formContainer{
height: 50px;
width: 100%;
background-color: gray;
}
</style>
<label class="checkboxLabel">
<input class="checkboxesThatAppends" type="checkbox" value="results" />
Show me a form
</label>
<label class="checkboxLabel">
<input class="checkboxesThatAppends" type="checkbox" value="results" />
Show me a form
</label>
<label class="checkboxLabel">
<input class="checkboxesThatAppends" type="checkbox" value="results" />
Show me a form
</label>
<label class="checkboxLabel">
<input class="checkboxesThatAppends" type="checkbox" value="results" />
Show me a form
</label>
JQuery:
$(document).ready(function(){
$('.checkboxesThatAppends').click(function(){
var associatedFormId = $(this).attr('data-associated-form-id');
if(associatedFormId){
//if there is a form container associated with this checkbox already
//then let's remove that form.
//and remove the association from the checkbox
$('#'+associatedFormId).remove();
$(this).attr('data-associated-form-id', '');
}else{
//generate an Id for the new form to attach.
var newId = new Date().getTime();
$(this).attr('data-associated-form-id', newId);
$(this).parent().after('<div id="'+newId+'" class="formContainer"></div> ');
}
});
});
You can just use jQuery's append() and remove() methods in combination with wrapping HTML elements to achieve this effect.
JSFiddle: https://jsfiddle.net/xuc4tze0/1/
HTML
<div class="row">
<div class="left">
<input id="chk" data-detail="Right 1" class="chkbox" type="checkbox" value="results" />1
</div>
</div>
<div class="row">
<div class="left">
<input id="chk" data-detail="Right 2" class="chkbox" type="checkbox" value="results" />2
</div>
</div>
<div class="row">
<div class="left">
<input id="chk" data-detail="Right 3" class="chkbox" type="checkbox" value="results" />3
</div>
</div>
CSS
.row {
display: flex;
width: 400px;
}
.left, .right {
flex: 0 0 50%;
}
Javascript / jQuery
$('.chkbox').on('click', function() {
if ($(this).is(':checked'))
// Find the row and add the 'right' column
$(this).closest('.row').append('<div class="right">' + $(this).data('detail') + '</div>');
} else {
// Find the 'right' column and remove it
$(this).closest('.row').find('.right').remove();
}
});
Depending on your need and the content of the divs I got a couple of suggestions :
Modal popups. If you these divs are just notifications then a popup would do (but doubt this is what you need).
List group, use bootstrap's neat class list group to show the needed info in an <ul> element, the JS that comes with these can be neat as well with special animations.
Use tooltips on each checkbox instead of getting a whole div appearing.
Last suggestion which I like least is putting all of your div's in a single container div on the right. Fix its width and height and set overflow attribute so you can scroll up and down the shown divs

Javascript check bootstrap checkbox by id

I have the following form :
<form class="form-inline" role="form">
<div class="col-xs-3">
<div class="pic-container">
<div class="checkbox">
<label>
<input type="checkbox" name="discounting" onchange='handleChange(this);' id='check11' > Show only price-discounted products
</label>
</div>
</div>
</div>
<div class="col-xs-3">
<div class="pic-container">
<div class="checkbox" id='check21'>
<label>
<input type="checkbox" name="discounting" onchange='' id='check21'> Show only price-discounted products
</label>
</div>
</div>
</div>
</form>
I'd like to be able to check the second checkbox automatically with JavaScript once I check the first one. I tried using the following script :
<script>
function handleChange(cb) {
if(cb.checked == true) {
alert('Message 1');
document.getElementById("check21").checked = true;
} else {
alert('Message 2');
var x = document.getElementById("check21").disabled= false;
}
}
</script>
But it doesn't work since I think with bootstrap is a question of classes.
The problem as Didier pointed out is that you have two elements with the same ID:
<div class="checkbox" id='check21'>
and
<input type="checkbox" name="discounting" onchange='' id='check21'>
The call to document.getElementById('check21') will probably (because the behavior is undefined) return the first one, which in this case is the <div> element, not the checkbox.
You must not use the same ID on two HTML elements, so you need to change the ID on one or the other of them.
http://jsfiddle.net/uywaxds5/2/
I included boostrap as an external reference.
<div class="checkbox" id='check22'>
<label>
<input type="checkbox" name="discounting" onchange='' id='check21'> Show only price-discounted products
</label>
</div>
Fixing the duplicate id seems to work.
If it does not works, the issue might be in another part of your code.
Use a different name for the second radio button
<input type="checkbox" name="discounting21">
There can only be one selected radio button belonging to the same group(ie. name).

function find() with variable as a parameter returns empty object

I'm refactoring a code on a generated web page and there is a div (tab) which can occur multiple times. There is a small section with check-boxes on each and every such div, which lets you choose other divs that will be shown.
Since there is a chance for other divs to be added to the page I wanted to make the code modular. Meaning that every checkbox id is identical to the class of the div, which it should toggle, with added "Div" at the end. So I use checked id, concat it with "." and "Div" and try to find it in closest fieldset.
Here is the almost working fiddle: http://jsfiddle.net/ebwokLpf/5/ (I can't find the way to make the onchange work)
Here is the code:
$(document).ready(function(){
$(".inChecks").each(function(){
changeDivState($(this));
});
});
function changeDivState(element){
var divClassSel = "." + element.attr("id") + "Div";
var cloField = element.closest("fieldset");
if(element.prop("checked")){
cloField.find(divClassSel).toggle(true);
} else {
cloField.find(divClassSel).toggle(false);
}
}
Aside for that not-working onchange, this functionality does what it's intended to do. However only on the jsfiddle. The same code does not work on my page.
When I used log on variables from the code, the result was as this
console.log(divClassSel) => inRedDiv
console.log($(divClassSel)) => Object[div.etc.]
console.log(cloField) => Object[fieldset.etc.]
//but
console.log(cloField.find(divClassSel)) => Object[]
According to firebug the version of the jQuery is 1.7.1
Since I can't find any solution to this is there any other way how to make it in modular manner? Or is there some mistake I'm not aware of? I'm trying to avoid writing a function with x checks for element id, or unique functions for every check-box (the way it was done before).
Remove the inline onchange and also you don't need to iterate on the elements.
Just write one event on class "inCheckes" and pass the current element reference to your function:
HTML:
<fieldset id="field1">
<legend>Fieldset 1</legend>
<table class="gridtable">
<tr>
<td>
<input id="inRed" class="inChecks" type="checkbox" checked="checked" />
</td>
<td>Red</td>
</tr>
<tr>
<td>
<input id="inBlue" class="inChecks" type="checkbox" />
</td>
<td>Blue</td>
</tr>
</table>
<div class="inDivs">
<div class="inRedDiv redDiv"></div>
<div class="inBlueDiv blueDiv" /></div>
</fieldset>
<fieldset id="field2">
<legend>Fieldset 2</legend>
<table class="gridtable">
<tr>
<td>
<input id="inRed" class="inChecks" type="checkbox" />
</td>
<td>Red</td>
</tr>
<tr>
<td>
<input id="inBlue" class="inChecks" type="checkbox" checked="checked" />
</td>
<td>Blue</td>
</tr>
</table>
<div class="inDivs">
<div class="inRedDiv redDiv"></div>
<div class="inBlueDiv blueDiv" /></div>
</fieldset>
JQUERY:
$(document).ready(function () {
$(".inChecks").change(function () {
changeDivState($(this));
})
});
FIDDLE:
http://jsfiddle.net/ebwokLpf/4/
As gillesc said in the comments changing the javascript code to something like this made it work.
$(document).ready(function(){
$(".inChecks").each(function(){
changeDivState($(this));
});
$(".inChecks").on("change", function() {
changeDivState($(this));
});
});
function changeDivState(element){
var divClassSel = "." + element.attr("id") + "Div";
var cloField = element.closest("fieldset");
if(element.prop("checked")){
cloField.find(divClassSel).toggle(true);
} else {
cloField.find(divClassSel).toggle(false);
}
}
You asked for an other way how to make it in modular manner:
You can create a jQuery plugin which handles the logic for one fieldset including changing the color when clicking different checkboxes.
This way all logic is bundled in one place (in the plugin) and you can refine it later on.
For example you can decide later on that the plugin should create the whole html structure of the fieldset (like jQuery UI slider plugin creates the whole structure for the slider element) and therefore change the plugin.
The code for the (first version) of your jQuery plugin could look something like this:
$.fn.colorField = function() {
var $colorDiv = this.find('.colorDiv'),
$inputs = this.find('input'),
$checked = $inputs.filter(':checked');
if($checked.length) {
// set initial color
$colorDiv.css('background', $checked.attr('data-color'));
}
$inputs.change(function() {
var $this = $(this),
background = '#999'; // the default color
if($this.prop('checked')) {
// uncheck the other checkboxes
$inputs.not(this).prop('checked', false);
// read the color for this checkbox
background = $(this).attr('data-color');
}
// change the color of the colorDiv container
$colorDiv.css('background', background);
});
};
The plugin uses the data-color-attributes of the checkboxes to change the color of the colorDiv container. So every checkbox needs an data-color attribute, but multiple divs for different colors are not necessary anymore.
The HTML code (for one fieldset):
<fieldset id="field1">
<legend>Fieldset 1</legend>
<table class="gridtable">
<tr><td><input id="inRed" class="inChecks" type="checkbox" checked="checked" data-color='#ff1005' /></td><td>Red</td></tr>
<tr><td><input id="inBlue" class="inChecks" type="checkbox" data-color='#00adff' /></td><td>Blue</td></tr>
</table>
<div class="colorDiv"></div>
</fieldset>
Now you can create instances with your colorField-plugin like this:
$(document).ready(function(){
$('#field1').colorField();
$('#field2').colorField();
});
Here is a working jsFiddle-demo

Show Field if Radio Button is Selected

I'm attempting to get the Website URL field on this page to display only when the previous question has the radio button "Yes" selected. I've searched and tried a few code examples, but they aren't working. Does anyone have any suggestions for me?
Thanks in advance!
<div class="editfield">
<div class="radio">
<span class="label">Do you have your own website? (required)</span>
<div id="field_8"><label><input type="radio" name="field_8" id="option_9" value="Yes"> Yes</label><label><input type="radio" name="field_8" id="option_10" value="No"> No</label></div>
</div>
</div>
<div class="editfield">
<label for="field_19">Website URL </label>
<input type="text" name="field_19" id="field_19" value="" />
</div>
I noticed that you initally put the javascript I gave you at the top of the page. If you are going to do this then you need to encapsulate the code in a jquery $(document).ready(function(){ });. You only need to use a document ready when your html follows after the javascript.
$(function() {
// place code here
});
However, in this scenario I have created another alternative that will be better, but do not forget that you have to initially set the web url div as hidden. Also, I highly recommend that you set better control ids; it will make your javascript easier to understand.
$('input[name=field_8]').on("click", function(){
var $div_WebUrl = $('#field_19').closest('.editfield');
if($('input[name=field_8]').index(this) == 0)
$div_WebUrl.show();
else
$div_WebUrl.hide();
});​
Live DEMO
I have created a little example:
<div class="editfield">
<div class="radio">
<span class="label">Do you have your own website? (required)</span>
<div id="field_8"><label><input type="radio" name="field_8" id="option_9" value="Yes" onclick="document.getElementById('divUrl').style.display='block'"> Yes</label><label><input type="radio" name="field_8" id="option_10" value="No" onclick="document.getElementById('divUrl').style.display='none'"> No</label></div>
</div>
</div>
<div class="editfield" id="divUrl" style="display:none">
<label for="field_19">Website URL </label>
<input type="text" name="field_19" id="field_19" value="" />
</div>​
jsFiddle: http://jsfiddle.net/EQkzE/
Note: I have updated the div to include a style, cause I do not know what your css class looks like. Good luck.
Here's a pure JS Solution:
document.getElementById("field_19").parentNode.style.display = "none";
document.getElementById("option_9").onclick = toggleURLInput;
document.getElementById("option_10").onclick = toggleURLInput;
function toggleURLInput(){
document.getElementById("field_19").parentNode.style.display = (document.getElementById("option_9").checked)? "block" : "none";
}
Not a very dynamic solution, but it works.
Something like this will bind the click event to a simple function to look at the radio button and show the other div.
$('#option_9').on('click', function() {
if ($('#option_9').is(':checked')) {
$('#field_19').closest('.editfield').show();
} else {
$('#field_19').closest('.editfield').hide();
}
});
Run sample code

Categories