Display multiple blocks, radio is checked - javascript

I need some help in editing my current script.
I use 1 radio button, that should hide/display multiple divs when 1 of the radio buttons is selected.
It works fine for just 1 div, but I can not make it work with multiple divs.
My current HTML:
<div class="col-md-12">
<div class="form-group form-group-xl">
<label for="Particulier"><input type="radio" id="Particulier"checked="checked" name="checkzakelijk" onclick="ShowHideDiv()" />Particulier</label>
<label for="Zakelijk"><input type="radio" id="Zakelijk" name="checkzakelijk" onclick="ShowHideDiv()" />Bedrijf</label>
</div>
</div>
<div class="col-sm-6" id="checkzakelijk1" style="display:none;">
<div class="form-group">
<label class="control-label" for="customfield{$customfield.id}">{$customfield.name}</label>
<div class="control">
{$customfield.input} {$customfield.description}
</div>
</div>
</div>
<div class="col-sm-6" id="checkzakelijk2" style="display:none;">
<div class="form-group">
<label class="control-label" for="customfield{$customfield.id}">{$customfield.name}</label>
<div class="control">
{$customfield.input} {$customfield.description}
</div>
</div>
</div>
Current script:
<script type="text/javascript">
function ShowHideDiv() {
var chkYes = document.getElementById("Zakelijk");
var dvPassport = document.getElementById("checkzakelijk");
var dvPassport = document.getElementById("checkzakelijk1");
var dvPassport = document.getElementById("checkzakelijk2");
dvPassport.style.display = chkYes.checked ? "block" : "none";
}
</script>

You are overwriting dvPassport variable, so only the last element will be have its effect.
Change it to
function ShowHideDiv() {
var chkYes = document.getElementById("Zakelijk");
var dvPassport1 = document.getElementById("checkzakelijk");
var dvPassport2 = document.getElementById("checkzakelijk1");
var dvPassport3 = document.getElementById("checkzakelijk2");
var display = chkYes.checked ? "block" : "none";
dvPassport1.style.display = display;
dvPassport2.style.display = display;
dvPassport3.style.display = display;
}

Have a closer look at this bit:
var dvPassport = document.getElementById("checkzakelijk");
var dvPassport = document.getElementById("checkzakelijk1");
var dvPassport = document.getElementById("checkzakelijk2");
What you are doing here is declaring a new variable with the same name multiple times, which doesn't make much sense.
I would suggest jQuery class selector, i.e.
$(".col-sm-6").hide();
Also, in cases where you want to apply something to multiple elements, it's worth giving them the same class, rather than listing the ids. It's simpler and makes the code much more readable.

Related

javascript how to set double appendChlid function

I try to lern and to transform an HTML CODE(normal code) to javascript unter using the appendChild function atm and i dont understand how it works if i want to create appended parts for an div DOM which is in an div DOM included, because i want to write functions for many many papers ^_^ which i dont want to set it by hand. the problem is, if i try to use the same code under for the other images doesnt take the CSS formats that the images doesnt change it from img1 to img2 to img3 if i klick the right parts. The normal HTML format works fine. any ideas would be cool. thx
What i did: Will see it in the code under //(A). If i try to use it together it doesnt work, and also if i try (A) alone
//--Thats the (normal code) which i want to transform to javascript
<div class="container">
<input type="radio" name="images" id="i1" checked>
<input type="radio" name="images" id="i2" >
<input type="radio" name="images" id="i3" >
<div class="slide_img" id="one">
<img class="img" src="bilder/UE_1_2018.PNG">
<label for="i3" class="pre"></label>
<label for="i2" class="nxt"></label>
</div>
<div class="slide_img" id="two">
<img class="img" src="bilder/UE_2_2018.PNG">
<label for="i1" class="pre"></label>
<label for="i3" class="nxt"></label>
</div>
<div class="slide_img" id="three">
<img class="img" src="bilder/UE_3_2018.PNG">
<label for="i2" class="pre"></label>
<label for="i1" class="nxt"></label>
</div>
</div>
//DIV where the javascript code would be included
<div class="container">
<div id="y2018"></div>
</div>
//Thats my first try to transform it before i write the for functions
<script>
function inputradios(year, divName) {
//---MAIN-ELEMENT---
var element1 = document.getElementById(divName);
//---INPUT---
var para1 = document.createElement("input");
para1.type = "radio";
para1.name = 'images';
para1.setAttribute('checked','checked');
para1.setAttribute("id", "i1");
element1.appendChild(para1);
//---DIV---
var para1_1 = document.createElement("div");
para1_1.setAttribute('class','slide_img');
para1_1.setAttribute("id", "one");
element1.appendChild(para1_1);
//---IMG---
var element2 = document.getElementById(para1_1);
var para1_1_1 = document.createElement("img");
para1_1_1.setAttribute('class','img');
para1_1_1.setAttribute('src','bilder/UE_1' + '_' + year + '.PNG');
element1.appendChild(para1_1_1);
//(A) element2.appendChild(para1_1_1);
//---lABEL 1---
var para1_1_2 = document.createElement("label");
para1_1_2.setAttribute('class','pre');
para1_1_2.setAttribute('for', 'i1' );
element1.appendChild(para1_1_2);
//(A) element2.appendChild(para1_1_2);
//---lABEL 2---
var para1_1_3 = document.createElement("label");
para1_1_3.setAttribute('class','nxt');
para1_1_3.setAttribute('for', 'i1' );
element1.appendChild(para1_1_3);
//(A) element2.appendChild(para1_1_3);
//SAME CODE WITH SOME DIFFERENT CHANGES TO IMPLEMENT IMAGE2,3,...
}
//inputradios(year, NrOfPages, divName);
inputradios(2018, 'y2018');
</script>
I modified your code a bit to make it more clear and consolidated.
If you're working with DOM functions, keep with using setAttribute rather than doing element.id='whatever';, it'll save you frustration later on.
In this example I use loops to create brevity instead of creating basically the same thing over and over.
In the second loop you'll see some nonsense with ? : like (i===0) ? 'one' : (i===1) ? 'two' : 'three'. If you are unfamiliar these are ternary operators which can be used to shortcut if/else blocks.
function inputradios(year, id) {
// I changed divName to id, for clarification an id is not a name
const parentDiv = document.getElementById(id);
// Create INPUTS
// <input type="radio" name="images" id="i1" checked>
// <input type="radio" name="images" id="i2" >
// <input type="radio" name="images" id="i3" >
for (var i=0;i<3;i++) {
const input = document.createElement('input');
input.setAttribute('type', 'radio');
input.setAttribute('name', 'images');
input.setAttribute('id', 'i'+ (i+1));
if (i===0) {
input.setAttribute('checked','checked');
}
parentDiv.appendChild(input);
}
// Create the DIVs
// <div class="slide_img" id="one">
// <img class="img" src="bilder/UE_1_2018.PNG">
// <label for="i3" class="pre"></label>
// <label for="i2" class="nxt"></label>
// </div>
// <div class="slide_img" id="two">
// <img class="img" src="bilder/UE_2_2018.PNG">
// <label for="i1" class="pre"></label>
// <label for="i3" class="nxt"></label>
// </div>
// <div class="slide_img" id="three">
// <img class="img" src="bilder/UE_3_2018.PNG">
// <label for="i2" class="pre"></label>
// <label for="i1" class="nxt"></label>
// </div>
for (var i=0;i<3;i++) {
const div = document.createElement('div');
div.setAttribute('id', (i===0) ? 'one' : (i===1) ? 'two' : 'three');
div.setAttribute('class', 'slide_img');
const img = document.createElement('img');
img.setAttribute('class', 'img');
img.setAttribute('src', 'bilder/UE_'+ (i+1) +'_2018.PNG');
const labelPre = document.createElement('label');
labelPre.setAttribute('for', 'i'+ ((i==0) ? 3 : (i-1)));
labelPre.setAttribute('class', 'pre');
const labelNxt = document.createElement('lable');
labelNxt.setAttribute('for', 'i'+ ((i===2) ? 1 : (i+1)));
labelNxt.setAttribute('class', 'nxt');
div.appendChild(img);
div.appendChild(labelPre);
div.appendChild(labelNxt);
parentDiv.appendChild(div);
}
}
//---IMG---
var element2 = document.getElementById('one');
element1.appendChild(para1_1_1);
//(A)
element2.appendChild(para1_1_1);
Works like a charm :) many thx

Is there a way to edit a javascript function to live update in a html form output?

I've written a working absence calculator using a HTML form and a javascript function. Unfortunately I need this to update to the output in real time and I cannot figure out how to do it without firing the function multiple times.
HTML
<form id="absence-form">
<div class="input">
<div id="title">Absence Calculator</div>
<div id="firstCell">
<div id="instruct">
Enter number of employees:
</div>
<input id="employees" type="text" name="employees">
<div id="secondCell">
<div id="instruct">
Enter average salary:
</div>
</div>
<input id="salary" type="text" name="salary">
<div id="thirdCell">
<div id="instruct">
Enter absence %:
</div>
</div>
<input id="absence" type="text" name="absence">
</div>
<div id="instruct">
<div id="output">Total salary (£):
<div id="totalSalary">
</div></div>
<div id="output">Monthly absence cost (£):
<span id="monthlyAbsence">
</span></div>
<div id="output">Annual absence cost (£):
<span id="absenceCost">
</span></div>
</div>
</div>
</form>
Javascript Function
function multiply() {
var employees = document.getElementById('employees').value;
var salary = document.getElementById('salary').value;
var totalSalary = parseInt(employees) * parseInt(salary);
var result1 = document.getElementById('totalSalary');
result1.innerHTML += totalSalary;
var absence = document.getElementById('absence').value;
var absenceCost = parseInt(totalSalary) / 100 * parseInt(absence);
var result2 = document.getElementById('absenceCost');
result2.innerHTML += absenceCost;
var monthlyAbsence = parseInt(absenceCost) / 12;
var result3 = document.getElementById('monthlyAbsence');
result3.innerHTML += monthlyAbsence;
}
});
Any pointers would be greatly appreciated.
You'll need to bind your function to the change event for the input elements.
This can be done a couple of ways:
Obtrusively (not recommended) with the element's onChange attribute (JSFiddle)
Non-obtrusively (preferred) with .on('change', function() {} }) (JSFiddle)
I'm assuming from the tag that you're using jQuery but you can achieve the same thing with vanilla JS using .addEventListener('change', callback, false) (JSFiddle)

Modify input names in childnodes with JavaScript

I need help extending this JavaScript (borrowed from https://www.quirksmode.org/dom/domform.html):
var appCounter = 0;
function anotherApp() {
appCounter = appCounter + 1;
var newAppField = document.getElementById("keyApp").cloneNode(true);
newAppField.id = '';
newAppField.style.display = 'block';
var newApp = newAppField.childNodes;
for (var i = 0; i < newApp.length; i++) {
var theName = newApp[i].name
if (theName) {
newApp[i].name = theName + appCounter;
}
}
var insertApp = document.getElementById('keyApp');
insertApp.parentNode.insertBefore(newAppField, insertApp);
document.getElementById('appCount').value = appCounter
}
This works fine when element in my form is:
<div id="keyApp" style="display:none">
<input type="text" name="application" id="application">
<input type="text" name="usage" id="usage">
<\div>
But when I add div's around the inputs (bootstrap styling reasons) I loose the ability to update the input names:
<div id="keyApp" style="display:none">
<div class="col-md-2">
<input type="text" name="application" id="application">
</div>
<div class="col-md-2">
<input type="text" name="usage" id="usage">
</div>
<\div>
How do I extend the script to modify the input names in these new div's?
Since there is now another layer, you need to get newApp[i].childNodes[0] now in order to get the actual input elements.
newApp now holds a list of the div elements with col-md-2 styling, and you need to get the children inside of these div elements.

Collect form values to make literal array for loop to display values using getElementById() and the innerHTML property?

I am totally new to javascript and trying to understand how to collect multiple values from a form to collect to make an array, which then will have another function to loop through a for loop array to display in an unordered list by innerHTML-ing the element into the dom. However, it's saying that ul.appendChild is not a function? I'm not do not know what means and have searched. Here is my code to give you a better idea. I don't want just the answer, if someone could point out what's possibly wrong and steer me the right direction? Thanks!
https://jsfiddle.net/rtomino/eu10htcm/2/
<form name="contact" id="contactForm" action="#">
<div class="six columns">
<label for="firstName" class="req">First Name:</label>
<input class="u-full-width" type="text" name="userInput[]" required>
</div>
<div class="six columns">
<label for="lastName" class="req">Last Name:</label>
<input class="u-full-width" type="text" name="userInput[]" required>
</div>
</div>
<div class="row">
<div class="six columns">
<label for="email" class="req">Email:</label>
<input class="u-full-width" type="email" placeholder="test#test.com" name="userInput[]" pattern="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?" required>
</div>
<div class="six columns">
<label for="tel">Phone:</label>
<input class="u-full-width" type="tel" placeholder="(000)-000-0000" name="userInput[]">
</div>
</div>
<div class="row">
<div class="six columns">
<div class="required"><em>* Required</em></div>
</div>
<div class="six columns">
<input type="button" id="submit" value="Submit">
<p class="clear">Clear fields</p>
</div>
</div>
</form>
window.onload = init;
function init() {
var button = document.getElementById("submit");
button.onclick = handleButtonClick;
}
function handleButtonClick(e) {
var collectInput = document.getElementsByName("userInput[]");
if (collectInput == "") {
alert("Please fill the form");
} else {
for (var i = 0; i < collectInput.length; i++) {
var myArray = collectInput[i].value;
var li = document.createElement("li");
li.innerHTML = myArray;
var ul = document.getElementById("userInformation").innerHTML += myArray;
ul.appendChild(li);
}
}
}
Hi and welcome to JavaScript ;)
Well lets take a look on your javascript code
var myArray = collectInput[i].value;
var li = document.createElement("li");
li.innerHTML = myArray;
var ul = document.getElementById("userInformation").innerHTML += myArray;
ul.appendChild(li);
So first you take collectInput[i] and save it to myArray variable.
var myArray = collectInput[i].value;
Then you create li element and sets myArray as its innerHtml
var li = document.createElement("li");
li.innerHTML = myArray;
And that is perfectly fine. But then you do this
var ul = document.getElementById("userInformation").innerHTML += myArray;
You want to find "userInformation" element and save it to local ul variable but instead you take its innerHTML and adds myArray to it. So instead of storing "userInformation" DOM element in your ul variable you store .innerHTML + myArray string there.
So to make it work change this line to
var ul = document.getElementById("userInformation")
And then it should work just fine.
Good luck with Javascript ;)

Adding event on ng-repeat element

I am very new to angular :). I would like to add a simple event one form element with a particular value, built by ng-repeat. This is how the HTML looks:
<div class="labels">
<div class="checkbox-element" ng-repeat="suggestName in $ctrl.suggests" ng-click="$ctrl.toggleSelection(suggestName, 'suggestsSelection', this)">
<label>
<input type="checkbox" name="suggestsSelection[]"
class="hidden"
value="{{suggestName}}"
><span></span>{{suggestName}}
</label>
</div>
<div class="optionary hidden">
<br>
<div class="question__text">Any other?</div>
<label><input type="text"
ng-model="$ctrl.survey.suggest_other"
name="suggests_other1"></label><br>
</div>
</div>
And the controller code:
vm.survey = {};
vm.suggests = ['quality', 'price', 'habbit', 'other'];
// selected
vm.survey.suggestsSelection = [];
// toggle selection for a given names
vm.toggleSelection = function toggleSelection(value, array, scope) {
var idx = vm.survey[array].indexOf(value);
// is currently selected
if (idx > -1) {
vm.survey[array].splice(idx, 1);
}
// is newly selected
else {
vm.survey[array].push(value);
}
};
What I need is to create an event that would toggle the class "hidden" from the div with class "optionary" after clicking on the last created checkbox ("other" in this case). Clicking on other checkboxes shouldn't affect the "optionary" div.
I tried with some configurations like:
if(scope.$last){
$(scope).closest('.optionary').toggleClass('hidden');
}
or similar. I don;t know what should be the way to approach the topic.
You need to use ng-show and a control variable. Take a look.
jsFiddle here: https://jsfiddle.net/U3pVM/24834/
<div ng-app class="labels" ng-controller="MyCtrl">
<div class="checkbox-element" ng-repeat="suggestName in suggests" ng-click="toggleSelection(suggestName, suggestsSelection, this)">
<label>
<input type="checkbox" ng-model="cbSuggest[$index]" name="suggestsSelection[]" class="hidden" value="{{suggestName}}">
<span>{{suggestName}}</span>
</label>
</div>
<div class="optionary hidden" ng-show="showOther">
<br>
<div class="question__text">Any other?</div>
<label><input type="text" ng-model="survey.suggest_other" name="suggests_other1"></label><br>
</div>
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.survey = {};
$scope.suggests = ['quality', 'price', 'habbit', 'other'];
$scope.cbSuggest = [];
$scope.showOther = true;
// selected
$scope.survey.suggestsSelection = [];
// toggle selection for a given names
$scope.toggleSelection = function(value, array, scope) {
var showOther = true;
angular.forEach($scope.cbSuggest, function(k,v){
if(k) {
showOther = false;
}
});
$scope.showOther = showOther;
};
}
As you can see ng-repeat has special properties: https://docs.angularjs.org/api/ng/directive/ngRepeat
The one you're interested in is $last. You could add ng-change to your checkboxes, call a function with the paramter $last, and that function would set a scope variable. The hidden class could rely on that.
Something like this:
<input type="checkbox" name="suggestsSelection[]"
class="hidden"
ng-change="showHidden($last)"
value="{{suggestName}}">
And in your controller:
$scope.hidden = true;
$scope.showHidden = function(isLast) {
if (isLast) $scope.hidden = false;
else $scope.hidden = true;
}
And then you add ng-class to your div:
<div class="optionary" ng-class="{'hidden': hidden}">...</div>

Categories