Javascript & HTML unit converter - how to use one input field as constant - javascript

I am trying to convert a Python script into an HTML/Javascript web based converter. The script is very simple and I followed the steps at https://www.w3schools.com/howto/howto_js_length_converter.asp, which work great, if all fields are dynamic. In my case, I need one variable to not change. On an example: user provides the "AssayWeight" value and one of the following: PPM or Grav. After that, scripts calculates the other value from PPM/Grav that the user didn't provide. Here's the code I have so far:
<script>
function ppmtoGravConverter(source,valNum) {
valNum = parseFloat(valNum);
var inputPPMtoGrav = document.getElementById("inputPPMtoGrav");
var inputAssayWeight = document.getElementById("inputAssayWeight");
var inputGravtoPPM = document.getElementById("inputGravtoPPM");
if (source=="inputPPMtoGrav") {
inputGravtoPPM.value=(valNum*inputAssayWeight/1000).toFixed(4);
}
if (source=="inputGravtoPPM") {
inputPPMtoGrav.value=(valNum*1000/inputAssayWeight).toFixed(4);
}
}
</script>
and html from w3schools:
<label>Assay Weight</label>
<input id="inputAssayWeight" type="number" placeholder="Assay Weight" oninput="ppmtoGravConverter(this.id,this.value)" onchange="ppmtoGravConverter(this.id,this.value)">
<br><br>
<label>PPM</label>
<input id="inputPPMtoGrav" type="number" placeholder="PPM" oninput="ppmtoGravConverter(this.id,this.value)" onchange="ppmtoGravConverter(this.id,this.value)">
<label>Grav (mg)</label>
<input id="inputGravtoPPM" type="number" placeholder="Grav (mg)" oninput="ppmtoGravConverter(this.id,this.value)" onchange="ppmtoGravConverter(this.id,this.value)">
Please let me know what am I missing. This is my 2nd day looking at Javascript. Thanks!

The issue is that in your formula, you are using inputAssayWeight instead of actually taking its value and using it. Replace those two if conditions with
if (source=="inputPPMtoGrav") {
inputGravtoPPM.value=(valNum*parseFloat(inputAssayWeight.value)/1000).toFixed(4);
}
if (source=="inputGravtoPPM") {
inputPPMtoGrav.value=(valNum*1000/parseFloat(inputAssayWeight.value)).toFixed(4);
}
That should fix your issue.

Wrap everything in a <form> tag and give it an #id.
<form id='main'><!-- EVERYTHING --></form>
Bind "input" event to the <form> and call an event handler (i.e. a function to handle a triggered event). Refer to: JavaScript Event Handling
document.forms.main.oninput = inputHandler;
Define function inputHandler() -- remember to pass the Event Object
function inputHandler(event) {...
Define all variables -- refer to: Obtaining References to Forms and Form Elements in JavaScript
// Collect all form controls into a NodeList
const field = this.elements;
// Find the element user interacted with
const input = event.target;
// Reference any form control by #id or [name] attribute by prefixing it with `field`
const aW = field.assayWeight;
// Assign a variable to form control values and convert them into a real Number
let AWT = parseFloat(aW.value);
Delegate "input" event by using if/else flow control statements. By explicitly allowing specific elements to react to an event and implicitly preventing other elements by simple omission is an important part of a programming paradigm called Event Delegation.
if (input.matches('#assayWeight')) {...
The HTML/CSS layout and styling features a toggling system in which it allows the user to enter "assay weight" and either "PPM" or "Grav". Hover over the titles and then click one and then the other to see the toggling. Refer to: Exposing Form Fields Via Checked Radio Buttons
[name=conv],
.mask {
display: none
}
[name=conv]:checked + fieldset .mask {
display: inline-block;
}
Demo
document.forms.convPpmG.oninput = convert;
function convert(event) {
const field = this.elements;
const input = event.target;
const awt = field.aWt;
const ppm = field.pPM;
const grv = field.grv;
const gtp = field.gToP;
const ptg = field.pToG;
let AWT = parseFloat(awt.value);
let PPMin = parseFloat(ppm.value);
let GRVin = parseFloat(grv.value);
if (input.matches('#aWt')) {
// log(AWT, "Assay Weight");
}
if (input.matches('#pPM')) {
// log(PPMin, "PPM Input");
let GRVout = PPMin * AWT / 1000;
// log(GRVout, "Grav Output");
ptg.value = GRVout.toFixed(4);
}
if (input.matches('#grv')) {
// log(GRVin, "Grav Input");
let PPMout = GRVin * 1000 / AWT;
// log(PPMout, "PPM Output");
gtp.value = PPMout.toFixed(4);
}
}
// A utility logger - not required
const log = (data, key = 'Field') => console.log(JSON.stringify(key + ': ' + data));
root,
body {
font: 400 3vw/1.5 Consolas, monospace;
}
fieldset fieldset {
min-height: 20vh;
}
input,
output {
width: 10ch;
margin-right: 5px;
margin-bottom: 8px;
font: inherit;
text-align: right;
}
#aWt {
display: inline-block;
}
[type=reset] {
text-align: center;
}
.switch {
padding: 3px 5px;
}
[type=reset]:hover,
.switch:hover {
color: tomato;
background: rgba(56, 87, 199, 0.4);
cursor: pointer;
}
[name=conv],
.mask {
display: none
}
[name=conv]:checked+fieldset .mask {
display: inline-block;
}
<form id='convPpmG'>
<fieldset>
<legend>PPM / Grav Convertor</legend>
<label>Assay Weight</label>
<input id="aWt" type="number" min='0' value="0">
<input type='reset'>
<br>
<input id='ppmToGrav' name='conv' type='radio'>
<fieldset>
<legend>
<label for='ppmToGrav' class='switch'>PPM to Grav</label>
</legend>
<label class='mask'>
PPM: <input id="pPM" type="number" min='0' value="0">
to Grav: <output id='pToG'>0</output> mg
</label>
</fieldset>
<hr>
<input id='gravToPPM' name='conv' type='radio'>
<fieldset>
<legend>
<label for='gravToPPM' class='switch'>Grav to PPM</label>
</legend>
<label class='mask'>
Grav: <input id="grv" type="number" min='0' value="0">
mg to PPM: <output id='gToP'>0</output>
</label>
</fieldset>
</fieldset>
</form>

Related

How can I get my validation fields to go red and green?

I literally started coding two days ago. I'm working on a project for a job application in which I have to create a form that goes green and red depending on success/error, and I used a YouTube tutorial to guide me through. Everything was going fine until I tried to code the error and success classes (i.e. the fields turning red or green) for the inputs, and after clicking submit nothing happens!
Here is the code I have written so far. Where have I gone wrong?
HTML:
<div class="container">
<form class="form" id="form"; action="mailto:changed#email.com"
method="POST"
enctype="text/plain:
name="EmailForm>
<div class="form-control">
<label>Name</label>
<input type="text" name="Name" placeholder="Enter Your Name" id="name">
</div>
<div class="form-control">
<label>Email</label>
<input type="email" name="Email" placeholder="Enter Your Email" id="email">
</div>
<div class="form-control">
<label>Card</label>
<input type="tel" inputmode="numeric" pattern="[0-9\s]{13,19}"
autocomplete="cc-number" maxlength="19"
placeholder="Enter A Proxy Credit Card Number" id="ccn">
</div>
<button type="submit"; style="background-color:#e70064;
border-color:#3c3c3b; color:#3c3c3b">Submit</button>
</form>
</div>
CSS:
* {
box-sizing: border-box;
}
body {
background-color:fff;
display:flex;
align-items: center;
justify-content: center;
min-height: 100vh;
margin: 0;
}
.container {
background-color:#89c82e;
border: 5px solid #3c3c3b;
border-radius:20px;
margin-top:15px;
margin-bottom:15px;
width:300px;
max-width:100%;
}
.form{
padding: 30px 40px;
font-family:"calibri"
}
.form-control.success input {
border-color: #2ecc71;
}
.form-control.error input {
border-color:#e74c3c
}
JS:
const form = document.getElementById('form');
const name = document.getElementById('name');
const email = document.getElementById('email');
const ccn = document.getElementById('ccn');
form.addEventListener('submit', (e) => {
e.preventDefault();
checkInputs();
});
function checkInputs() {
// get the values from the inputs
const nameValue = name.value.trim();
const emailValue = email.value.trim();
const ccnValue = ccn.value.trim();
if(nameValue === "") {
// show error
// add error class
setErrorFor(name)
} else {
// add success class
setSuccessFor(name)
}
}
function setErrorFor(input) {
const formControl = input.parentElement; // .form-control
// add error class
formControl.classname = 'form-control error'
}
thanks so much!
By doing
.form-control.error input {
border-color:#e74c3c
}
You are setting any divs with a class name of form-control error that has an input inside to have a border color of red. But by default divs don't have a visible border. If you want the input field to turn red or green based on success/failure, set the inputs to have a border-color. You have the inputs already at the top of the js file, you can use those.
Also, in the setErrorFor function, it is .className, not .classname.

How to get score from correct answer through form input

I'm creating a quiz that contains 10 questions: 5 multiple choice through radio input and 5 written answers through text input. See code for both inputs below. But I would also like to add a score system to these questions. I found a nice script here on stack overflow that can keep the score while user enters form input. I will add it below.
The script I use to check answers from radio input:
$(document).ready(function(){
$('input[name=radio1]').change(function(){
$('.alert').remove();
if($('input[name=radio1]:checked').val() === "1") {
$(this).parent().append('<span class="correct">✓ Correct!</span>');
} else {
$(this).parent().append('<span class="incorrect">✗ Correct answer = B</span>');
}
});
});
The correct anser given is based on value="1". The other answers have value="0".
The script I use to check answers from text input:
$('submit').on('click', function() {
markAnswers(1)
});
var answers = {
q1: ["Auto's"]
};
function markAnswers(id) {
$(`#q${id}`).each(function () {
let userAnswer = this.value.replace(/[^\w\'\,\-\?\!\"\:\—\;]/g,'');
if ($.inArray(userAnswer, answers[this.id]) === -1) {
$(this).parent().append(`<br><span class='incorrect'>✗ Correct answer = ${answers[this.id]}</span>`);
} else {
$(this).parent().append("<br><span class='correct'>✓ Correct!</span>");
}
});
}
The correct value from text input is determined by this script above.
Now, the script I found that keeps the score, collects score through data-score=. But I was thinking to just use value instead. See original script below:
$('.track').change(function(e) {
update_progress();
});
// supports any number of inputs and calculates done as %
function update_progress() {
var score = 0
$('input.track').each(function(){
var _score = $(this).data("score")
if ($(this).val().length > 0) {
score += _score
}
})
$('#score').text(score)
var count = $('.track').length;
var length = $('.track').filter(function() {
return this.value;
}).length;
var done = Math.floor(length * (100 / count));
$('.perc').text(done);
$('.meter').width(done + "%");
}
The script can be found here: https://stackoverflow.com/a/58297288/4546157
It is really nice. It keeps the score but it also shows you if you have completed the form or not.
I would like each correct answer to have a value of 1 so at the end of the quiz the user can have a maximum score of 10/10. But, a big but, I don't know how to implement it. Hoping to see suggestions or solutions from you guys. Thank you!
You would do it something like this. Though it's bad practice to use globally available variables, but for the sake of simplicity i put them there. Better to wrap everything in a div and store score/progress as data attributes.
Pen: https://codepen.io/lenadax/pen/QWQqMxP?editors=1111
// global vars, put them somewhere else
var progress = 0;
var score = 0;
$('form.question').each(function(i, el) {
// I'm lazy so form id is the same as input name for each question
let inputs = $(`input[name=${$(this).attr('id')}]`);
inputs.on('change', function() {
// increase progress by 1 if button has been selected.
progress++;
if ($(this).val() === "1") {
// increase score if correct choice selected
score++;
$('<span class="result correct">').text('✓ Correct!').appendTo(el);
} else {
$('<span class="result incorrect">').text('X Incorrect!').appendTo(el);
}
// get number of questions
let question_count = $('form.question').length;
// disable after choosing for less hassle
inputs.prop('disabled', true);
// calculate the progress in percent
let progress_num = progress / question_count * 100;
$('.perc').text(progress_num);
$('#score').text(`${score} / ${question_count}`);
});
})
input {
display: inline-block;
}
label {
display: inline-block;
}
button {
display: block;
}
form {
width: 200px;
border: 1px solid gray;
margin: 10px;
padding:10px 5px;
}
.result {
display: block;
}
.result.incorrect {
color: red;
}
.result.correct {
color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<form class="question" id="question1">
<span>Question 1</span>
</p>
<input name="question1" id="answer1" type="radio" value="0"/>
<label for="answer1">Wrong answer</label>
</p>
<input name="question1" id="answer2" type="radio" value="1"/>
<label for="answer2">Right answer</label>
</form>
<form class="question" id="question2">
<span>Question 2</span>
</p>
<input name="question2" id="answer1" type="radio" value="0"/>
<label for="answer1">Wrong answer</label>
</p>
<input name="question2" id="answer2" type="radio" value="0"/>
<label for="answer2">Wrong answer</label>
</p>
<input name="question2" id="answer3" type="radio" value="1"/>
<label for="answer3">Right answer</label>
</form>
<h5>Done <span class='perc'>0</span>%</h5>
<h5>Score <span id="score">0</span></h5>
</body>
</html>

How to get counter when inputs, select etc. change in form?

var inpts = $('.map-form .val-input');
var radio = $('.map-form .radio-input');
var counter = $('.filtr-map-count');
$('.detect-change').change(function() {
countInputs();
});
function countInputs() {
var click = 0;
$(inpts).each(function(){
if($(this).val() != ""){
click++;
}
counter.text(click);
});
$(radio).each(function() {
if($(this).val() != ""){
click++;
}
counter.text(click);
});
};
$(window).on('load', function() {
countInputs();
});
.filtr-map {
background-color: red;
width: 100px;
height: 40px;
color: #fff;
z-index: 99;
font-weight: bolder;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
margin-top: 50px;
}
.filtr-map-count {
font-size: 10px;
position: relative;
top: -5px;
left: 5px;
background-color: #000;
border-radius: 50%;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class='map-form'>
<div>
<h2>Search</h2>
<fieldset>
<label>Price</label>
<span>min</span>
<input type="text" class='val-input detect-change ' value="" />
<span>max</span>
<input type="text" class='val-input detect-change ' value="" />
</fieldset>
<fieldset>
<label>Category</label>
<div class="styled_select">
<select class='val-input detect-change '>
<option value="">Default</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
</div>
</fieldset>
<fieldset>
<div class="styled_radio"><input class='radio-input detect-change' checked="checked" type="radio" id="Radio1" name="Radio" /><label
class="input" for="Radio1"><span class="circle"><span></span></span><span>Test One Test</span></label></div>
<div class="styled_radio"><input class='detect-change' type="radio" id="Radio2" name="Radio" /><label class="input"
for="Radio2"><span class="circle"><span></span></span><span>Test test</span></label></div>
</fieldset>
<input type="submit" value='Send'>
</div>
</form>
<div class="filtr-map">
Filter<span class='filtr-map-count'>0</span>
</div>
Hey, How to get counter when inputs, select etc. change in form? How to make a counter. If input/select/radio change in fieldset counter should increase, if back to default value decrease. The counter number should also works after page reload. I added a js code with im working on but something goes wrong.
---UPDATE---
I added working jquery code for this example, maybe will be helpful for someone else. Also I added classes that help with select the changed elements.
Ok so this becomes a little more complicated if you're considering all input types.
I have written the code below as a starting point. Yes, it does do what you need it to. BUT it hasn't been fully tested and it can be improved.
See a working example here: https://jsfiddle.net/hber3q0z/
The jQuery that's doing the heavy lifting...
var $form = $('.map-form');
var $counter = $('.filtr-map-count');
var changed = {};
// Listen for an `update` event on counter element
$counter.on('update', function() {
// Update the text value
$(this).text(function() {
var count = 0;
// Loop through the `changed` object and count if value has changed
$.each(changed, function(key, hasChanged) {
if (hasChanged) {
count++;
}
});
// Return count
return count;
});
});
// Find all form inputs
$form.find(':input').each(function(key) {
var $this = $(this);
// Get the input name, else create a temporary name
var name = $this.attr('name') || new Date().getTime().toString() + key;
// Store the original value
var original = $this.val();
// If the input is a checkbox
if ($this.is(':checkbox')) {
// Create a function to get checkbox group values
var checkboxValue = function() {
var values = [];
// Find all `checked` inputs with the same type and name
$form.find('[type="' + $this.attr('type') + '"][name="' + $this.attr('name') + '"]:checked').each(function() {
// Push values to array
values.push($(this).val());
});
// Join them for easier comparisom
return values.join(',');
};
// Store original group value
original = checkboxValue();
// Listen to checkbox events
$this.on('change keyup keydown mouseup', function() {
// Perform value changed check
changed[name] = checkboxValue() !== original;
// Tell the counter element to update contents
$counter.trigger('update');
});
}
// If the input is a radio
else if ($this.is(':radio')) {
// Create a function to get radio group value
var radioValue = function() {
// Find the first `checked` input with the same type and name
return $form.find('[type="' + $this.attr('type') + '"][name="' + $this.attr('name') + '"]:checked').val();
};
// Store original group value
original = radioValue();
// Listen to radio input events
$this.on('change keyup keydown mouseup', function() {
// Perform value changed check
changed[name] = radioValue() !== original;
// Tell the counter element to update contents
$counter.trigger('update');
});
}
// Catch-all other input types
else {
// Listen to input events
$this.on('change keyup keydown cut paste', function() {
// Perform value changed check
changed[name] = $this.val() !== original;
// Tell the counter element to update contents
$counter.trigger('update');
});
}
});
The code is checking all inputs in the form for an actual changed value, not just a change event. I have also included support for checkbox and radio groups.

Javascript form validation for phone numbers

Trying to create a form with pretty simple validation and I'm curious as to two things.
One; how do I check if a form is empty?
Two; on the phone number field how would I only accept numbers in this format:
xxx-xxxx (where X is a number)
Here is what I have done so far:
HTML:
<form onsubmit="return false" method="post" name="myForm">
<div class="form-block">
<label>Name: </label>
<input type="text" name="name" id="name" />
<span id="name-error" class="error"></span>
</div>
<div class="form-block">
<label>Phone Number: </label>
<input type="text" name="phone" id="phone" />
<span id="phone-error" class="error"></span>
</div>
<input type="submit" id="mysubmit" name="submit" onclick="validate()" />
</form>
CSS:
a, p, h1, h2, h3, h4, h5, h6, li, label, span {
font-family: sans-serif;
}
#mysubmit {
display: block;
margin-top: 10px;
}
span.error {
color: red;
font-weight: bold;
}
.form-block {
display: block;
width: 100%;
margin: 10px 0;
}
label {
display: inline-block;
width: 150px;
text-align: right;
}
JS:
validate = function() {
var name = document.getElementById("name").value;
var phone = document.getElementById("phone").value;
if(/^[a-zA-Z]*$/.test(name)) {
document.getElementById("name-error").innerHTML = "Good.";
} else {
document.getElementById("name-error").innerHTML = "Invalid. Only letters.";
}
if(isNaN(phone)) {
document.getElementById("phone-error").innerHTML = "Can only contain numbers";
} else {
document.getElementById("phone-error").innerHTML = "Good.";
}
};
You can test if the value of a form element is empty by simply checking for an empty string.
I've already posted something that will help you access and iterate through form fields.
// ES5: a very crude validation check
// your form field elements should share a class in order to collect them all
var formElements = document.querySelectorAll('.your-form-field-class');
// set a flag to keep track of whether you have an empty field
var containsEmptyField = false
i,
l = formElements.length;
for (; i < l; i++) {
if (formElements[i].value === '') {
containsEmptyField = true;
// do something in response to an empty field
// the break is to stop looping since you've found
// a match
break;
}
}
// ES6: a very crude validation check
const formElements = document.querySelector('#some-form').elements;
let containsEmptyField = false;
for (let element of formElements) {
if (element.value === '') {
containsEmptyField = true;
break;
}
}
I haven't tested it properly, but the regex for the phone number, might look something like this:
(/^(\d){3,3}\-(\d){4,4}$/).test(someNumber)
// returns true if value matches or false if it doesn't

Using Checkboxes to contol an Input.value (With an annoying twist.)

I've been researching for a few days methods of controlling UI with checkboxes and with the help of some members on Stack' I've come really quite far. But my balding doesn't quite stop yet. I've been trying to further tweak my code snippet, by including a numeric value alongside my UI controller. (This value will be of use later inside the web-java applet.)
For example, when a checkbox is checked var total is ammended from 0 to 30. If a Checkbox is unchecked the value returns to '0'.
(Main Build JS Fiddle),
(Checkbox Example).
The second fiddle allows the use of data attributes, however these will need to be injected into the HTML via, JS. As like before I have 'NO' access to the CSS or HTML source files.
(Original Post)
- This post is a follow on from another question asked here on stack, due to the nature of the question changing, and the comments getting fairly confusing I was asked to open a new thread.
Below I'll post two snippets, one is of the original build, built with the aid of user #acontell. The other is an example of the type of result I am after, built with the aid of, user #Rajesh. Link to (Example Source).
The Base Build
// Control UI...
(function(domElements, cbState) {
// Number increment
var total = 0 + ' mm';
document.getElementById('adjvar').value = total;
function clickCallback() {
toggleElements(this.className);
}
function toggleElements(className, initialShow) {
var checkNumber = ((/ editoropt(\d*) /).exec(className))[1],
checkBox = document.getElementById('checkboxopt' + checkNumber),
division = document.querySelectorAll('.editoraccvar' + checkNumber)[0],
isShown = initialShow === undefined ? window.getComputedStyle(division).display === 'none' : initialShow;
division.style.display = isShown ? 'block' : 'none';
checkBox.checked = isShown;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// increment count...
var val = 30;
total += (+val * (checkBox.checked ? 1 : -1));
document.getElementById('adjvar').value = total + ' mm';
document.getElementsByClassName('adjvar').value = checkBox.checked ? val : 0 + ' mm';
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
}
domElements
.filter(function(el) {
return el.className.indexOf('editoropt') !== -1;
})
.forEach(function(el, index) {
el.addEventListener('click', clickCallback, false);
toggleElements(el.className, cbState[index]);
});
})([].slice.call(document.querySelectorAll('.seq-box-form-field')), [false, false]);
// Default Checked...
if (document.getElementById('checkboxopt').checked) {
// do nothing
} else {
document.getElementById('checkboxopt').click();
}
// inject style
function ctSe() {
var css = "input[type='checkbox'] { float:left; margin-right: 1em !important;}",
head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
style.type = 'text/css';
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
head.appendChild(style);
console.log(head)
console.log(style)
console.log(css)
};
ctSe();
.editoraccvar {
width: 300px;
background: #f0f;
padding: .5em;
}
.editoropt {
width: 300px;
background: #0f0;
padding: .5em;
}
.editoraccvar1 {
width: 300px;
background: #0ff;
padding: .5em;
}
.editoropt1 {
width: 300px;
background: #ff0;
padding: .5em;
}
textarea {
display: block;
width: 95%;
resize: none;
padding: .5em;
}
<!-- I'm trying to hide & show this entire division... -->
<div class="seq-box-form-field field-summernote editoraccvar ">
<label for="accvar1">Ground Floor Info</label>
<div class="clearfix"></div>
<textarea id="richaccvar1" name="richaccvar1" class="summernote"></textarea>
<input type="hidden" name="accvar1" id="accvar1" value="" />
</div>
<!-- Using only what the system has supplied. -->
<div class="seq-box-form-field editoropt ">
<label for="opt1"><span style="padding-right: 10px; vertical-align: 1px;">Ground Floor </span>
<input type="checkbox" name="checkboxopt" id="checkboxopt" value="true" checked="true" />
<input type="hidden" name="opt1" id="opt1" value="true" />
</label>
</div>
<!-- Secondary Division -->
<div class="seq-box-form-field field-summernote editoraccvar1 ">
<label for="accvar1">First Floor</label>
<div class="clearfix"></div>
<textarea id="richaccvar1" name="richaccvar1" class="summernote"></textarea>
<input type="hidden" name="accvar1" id="accvar1" value="" />
</div>
<!-- Secondary Checkbox -->
<div class="seq-box-form-field editoropt1 ">
<label for="opt1"><span style="padding-right: 10px; vertical-align: 1px;">First Floor </span>
<input type="checkbox" name="checkboxopt1" id="checkboxopt1" value="true" checked="true" />
<input type="hidden" name="opt1" id="opt1" value="true" />
</label>
</div>
<input name="adjvar" id="adjvar" readonly>
The Example
(function() {
var total = 0;
function calculate(index) {
var el = document.getElementsByClassName('checkbox-input')[index];
var val = el.getAttribute("data-value");
total += (+val * (el.checked ? 1 : -1));
document.getElementById('pnvar').value = total;
document.getElementsByClassName('pnvar')[index].value = el.checked ? val : 0;
}
function registerEvents() {
var cbs = document.querySelectorAll('[type="checkbox"]');
[].forEach.call(cbs, function(cb, i) {
cb.addEventListener("click", function() {
calculate(i);
});
});
document.getElementById('pnvar').addEventListener('keydown', function(event) {
if (event.keyCode == 13) {
event.preventDefault();
return false;
}
})
}
window.addEventListener('load', function() {
registerEvents();
calculate(0)
})
})()
.editoropt {
font-family: Calibri, sans-serif;
width: 160px;
background: #f8f8ff;
padding: .5em;
border: solid 1px #ddd;
}
#checkboxopt {
float: left;
margin-right: 1em;
margin-top: 4px;
}
#checkboxopt1 {
float: left;
margin-right: 1em;
margin-top: 4px;
}
.pnvar {
width: 95%;
}
input:-moz-read-only {
/* For Firefox */
background-color: transparent;
border: none;
border-width: 0px;
}
input:read-only {
background-color: transparent;
border: none;
border-width: 0px;
}
<div class="seq-box-form-field editoropt ">
<label for="opt1">
<span style="padding-right: 10px; vertical-align: 1px;">Default 80mm </span>
<input type="checkbox" class="checkbox-input" data-value="80" name="checkboxopt" id="checkboxopt" value="true" checked />
<input type="hidden" name="opt1" id="opt1" value="true" />
</label>
</div>
<div class="seq-box-form-field editoropt ">
<label for="opt1">
<span style="padding-right: 10px; vertical-align: 1px;">Add 30mm </span>
<input type="checkbox" class="checkbox-input" name="checkboxopt1" data-value="30" id="checkboxopt1" value="true" />
<input type="hidden" name="opt2" id="opt2" value="true" />
</label>
</div>
<div class="editoropt">
<input id="pnvar" name="pnvar" placeholder="Null" onkeydown="" value="" class="required" type="text">
<input name="adjvar" class="pnvar" id="adjvar" readonly value="0">
<input name="adjvar" class="pnvar" id="adjvar2" readonly value="0">
</div>
As I mentioned in my previous post, I'm not a JS Whizz and I'm just finding my feet, however I am abitious to learn and further my knowledge. Any assistance would be greatly appreciated.
Note : All tags, classes and names, must remain the same for consistancy with another application.
I might be mistaken but I think that this two lines of code:
// Default Checked...
if (document.getElementById('checkboxopt').checked) {
// do nothing
} else {
document.getElementById('checkboxopt').click();
}
Could be avoided if you passed [true, false] as the initial states of the checkboxes:
([].slice.call(document.querySelectorAll('.seq-box-form-field')), [true, false]);
I might be wrong, you might be doing something else or the state of the page could require that click, I don't know.
Going back to the issue, if you want to increase/decrease by 30 when the checkbox is checked/unchecked, you could do as follows:
Create a function that retrieves the value of the input an updates it with a quantity added to it. The value of the input is a string of the form 'x mm' so a bit of tinkering is necessary to get the integer part of the value.
function updateInputValue(n) {
var actual = +document.getElementById('adjvar').value.split(' mm')[0] || 0;
document.getElementById('adjvar').value = (actual + n) + ' mm';
}
Inside toggleElement call this function in order to update the input value.
var increment = isShown ? 30 : -30;
updateInputValue(initialShow === undefined ? increment : +initialShow * 30);
It gets a bit complicated because you have to control the initial state of the inputs, but it's not that hard: if it's the initial state, initialShow is different from undefined so we transform the value (it's a boolean) into a number a multiply it by 30 (when it's checked, it'd be 1 * 30, when it's unchecked it'd be 0 * 30). When it's not the initial state, we increment/decrement depending on whether it's checked or not.
And here's the fiddle (I also commented out the part that clicked the checkbox). Hope it helps.

Categories

Resources