JS for each replacement of manual copy function - javascript

I am looking for way to automate this selection.
For example, I will have 10 double inputs (20 inputs total) and I don't want to write JS script for each inputs, but simply use each() function (I am open to different ways) and declare only selectors.
JsFiddle: http://jsfiddle.net/vs7fa/
Idea:
var SELECTORS_H = array();
$.each(SELECTORS_H){
$('SELECTOR_H').keyup(function () {
// do magic
$('SELECTOR_V').val(num);
});
$('SELECTOR_V').keyup(function () {
// do magic
$('SELECTOR_H').val(num);
});
}
HTML:
<label for="h_one">H_ONE:</label>
<input type="text" name="h_one">
<label for="v_one">V_ONE:</label>
<input type="text" name="v_one">
There will be more of inputs. Pattern is:
h_one, v_one
h_two, v_two
h_something, v_something
...
JS:
$(function() {
$('input[name="h_one"]').keyup(function() {
var one = $(this).val();
if (one > 0) {
var num = Math.abs(one) * -1;
}
else {
var num = Math.abs(one) * 1;
}
$('input[name="v_one"]').val(num);
});
$('input[name="v_one"]').keyup(function() {
var two = $(this).val();
if (two > 0) {
var num = Math.abs(two) * -1;
}
else {
var num = Math.abs(two) * 1;
}
$('input[name="h_one"]').val(num);
});
});

You can handle this using a selector with a common class for all your element and data-attributes to know the element and the linked elements.
HTML:
<label>H_ONE:</label>
<input type="text" class="handler" data-id="h1" data-link="v1" />
<br>
<label>V_ONE:</label>
<input type="text" class="handler" data-id="v1" data-link="h1" />
Code:
$(function () {
$('.handler').keyup(function () {
var one = $(this).val();
if (one > 0) {
var num = Math.abs(one) * -1;
} else {
var num = Math.abs(one) * 1;
}
$('input[data-id=' + $(this).attr("data-link")+']').val(num);
});
});
Demo: http://jsfiddle.net/8KgTk/

may be this...
Jsfiddle: http://jsfiddle.net/vs7fa/3/
$('input[name="h_one"]').keyup(function () {
var num = DoMagic($(this));
$('input[name="v_one"]').val(num);
});
$('input[name="v_one"]').keyup(function () {
var num = DoMagic($(this));
$('input[name="h_one"]').val(num);
});
function DoMagic(element) {
var one = $(element).val();
if (one > 0) {
var num = Math.abs(one) * -1;
} else {
var num = Math.abs(one) * 1;
}
return num;
}

You should be able to perform the .each function by using jQuery and making the items the same class.
such as:
<label class="forElement" for="h_one">H_ONE:</label>
<input class="inputElement" type="text" name="h_one">
<label class="forElement"for="v_one">V_ONE:</label>
<input class="inputElement" type="text" name="v_one">
$('.forElement').each( function() {
//some code
}

You can do this without adding extra attributes if you want.
$(function () {
$('input[name^="h_"], input[name^="v_"]').keyup(function () {
var one = $(this).val();
var num = - one;
var inputType = $(this).attr("name").substr(0,1);
var inputNumber = $(this).attr("name").substr(2);
$('input[name="'+(inputType == 'v' ? 'h' : 'v')+'_' + inputNumber + '"]').val(num);
});
});
However Irvin Dominin aka Edward's solution is quite good.

Here's a sollution that doesn't require extra markup, and doesn't use string concatenation for logic. It uses $.proxy() to get correct scoping.
Fiddle

Related

Adding the result of separate results

Thanks in advance for any replies. I am new to JavaScript and have got this far in calculating 2 results that I require. My question is how do I add both results together?
Please see first result below:
$(document).ready(function() {
function checkSum(e) {
var result = 0;
$(".checksum").each(function() {
var i = 0;
if ($(this).val() != "") {
i = parseFloat($(this).val());
}
result = result + i;
});
$("#resultsum").html(result * 60.60);
}
checkSum();
$(".checksum").bind("keyup", checkSum);
});
and this is the second:
$(document).ready(function() {
function checkSum2(e) {
var result2 = 0;
$(".checksum2").each(function() {
var j = 0;
if ($(this).val() != "") {
j = parseFloat($(this).val());
}
result2 = result2 + j;
});
$("#resultsum2").html(result2 * 14.88);
}
checkSum2();
$(".checksum2").bind("keyup", checkSum2);
});
Just add one line in the end of functions:
$("#resultsum3").html($("#resultsum").text() + $("#resultsum2").text());
$(document).ready(function() {
function checkSum(e) {
var result = 0;
$(".checksum").each(function() {
var i = 0;
if ($(this).val() != "") {
i = parseFloat($(this).val());
}
result = result + i;
});
$("#resultsum").html(result * 60.60);
$("#resultsum3").html($("#resultsum").text() + $("#resultsum2").text());
}
checkSum();
$(".checksum").bind("keyup", checkSum);
function checkSum2(e) {
var result2 = 0;
$(".checksum2").each(function() {
var j = 0;
if ($(this).val() != "") {
j = parseFloat($(this).val());
}
result2 = result2 + j;
});
$("#resultsum2").html(result2 * 14.88);
$("#resultsum3").html($("#resultsum").text() + $("#resultsum2").text());
}
checkSum2();
$(".checksum2").bind("keyup", checkSum2);
});
I've combined your snippets in to one to remove the redundant code you have. This approach will allow you to add more checksums in future (.checksum3?) and also makes sure your calculation logic is same for all.
The result is calculated in to new element whenever any of the checksums change. Try the snippet below:
// function to calculate checksum
// used for both individual results as well as for total
function calcChecksum(elements) {
let result = 0;
elements.each( function(index, ele) {
result = result + (parseFloat($(ele).val()) || 0)
});
return result;
}
// update total result
function updateTotal() {
let total = calcChecksum($('.result'));
$('#resultsum_total').val(total);
}
$(document).ready(function() {
// generate function for each set of checksum inputs
function genCheckSumFn(inputSel, outputSel, multiplier) {
return () => {
const result = calcChecksum($(inputSel));
$(outputSel).val(result * multiplier);
updateTotal();
}
}
//checkSum bindings
$(".checksum").bind("keyup",
genCheckSumFn('.checksum','#resultsum',60.60)
);
$(".checksum2").bind("keyup",
genCheckSumFn('.checksum2','#resultsum2',14.88)
);
// trigger initial calculation
$(".checksum").trigger('keyup');
$(".checksum2").trigger('keyup');
});
.checksum,
.checksum2{
display: block;
}
.box {
padding:10px 0px;
}
.box div {
margin-top:5px;
}
.box.results input {
color: #FFA500;
border:0px;
font-size: 14px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box">
Checksum
<input class="checksum" value="10">
<input class="checksum" value="5">
Checksum(2)
<input class="checksum2" value="20">
<input class="checksum2" value="15">
<div>
<div class="box results">
<div> Resultsum:
<input id="resultsum" class="result" readonly> </div>
<div> Resultsum(2):
<input id="resultsum2" class="result" readonly> </div>
<div> Resultsum(Total): <input id="resultsum_total" readonly> </div>
</div>

Add space after dot

Good day. I've got some problem.
I've got input where I wrote some information.
Example:
<div class="wizard wizardstep1" ng-controller='someCtrl'>
<p class="wizardtitle">Put you Theme</p>
<input id="taskTheme" required type="text" placeholder="Put you Theme" ng-model="taskThemeWizardInputValue" ng-change="checkThemeWizardInputValue()">
</div>
And I've got my controller.
Example:
$scope.checkThemeWizardInputValue = function () {
if ($scope.taskThemeWizardInputValue === undefined) {
$scope.taskThemeWizardInputValue = "";
console.log($scope.taskThemeWizardInputValue);
console.log($scope.taskThemeWizardInputValue.length);
} else {
var strt = $scope.taskThemeWizardInputValue.split('.');
for (var i = 0 ; i < strt.length; i++) {
strt[i] = strt[i].charAt(0).toUpperCase() + strt[i].substr(1);
}
$scope.taskThemeWizardInputValue = strt.join('.');
console.log($scope.taskThemeWizardInputValue);
console.log(strt);
}
}
How I can add space after dot? Who knows?
Here is link to jsfiddle with my example.
We achieve it by adding space to each splitted string other than first one and an empty string
function someCtrl($scope) {
$scope.checkThemeWizardInputValue = function () {
if ($scope.taskThemeWizardInputValue === undefined) {
$scope.taskThemeWizardInputValue = "";
console.log($scope.taskThemeWizardInputValue);
console.log($scope.taskThemeWizardInputValue.length);
} else {
var strt = $scope.taskThemeWizardInputValue.split('.');
for (var i = 0 ; i < strt.length; i++) {
var addSpace='';
if(i>0 && strt[i].trim().length>0){
addSpace=' ';
}
strt[i] = addSpace+strt[i].trim().charAt(0).toUpperCase() + strt[i].trim().substr(1);
}
$scope.taskThemeWizardInputValue = strt.join('.');
console.log($scope.taskThemeWizardInputValue);
console.log(strt);
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<div class="wizard wizardstep1" ng-controller='someCtrl'>
<p class="wizardtitle">Put you Theme</p>
<input id="taskTheme" required type="text" placeholder="Put you Theme" ng-model="taskThemeWizardInputValue" ng-change="checkThemeWizardInputValue()">
</div>
</div>
You can do this simply by changing strt.join('.') to strt.join('. ').
$scope.checkThemeWizardInputValue = function () {
if ($scope.taskThemeWizardInputValue === undefined) {
$scope.taskThemeWizardInputValue = "";
console.log($scope.taskThemeWizardInputValue);
console.log($scope.taskThemeWizardInputValue.length);
} else {
var strt = $scope.taskThemeWizardInputValue.split('.');
for (var i = 0 ; i < strt.length; i++) {
strt[i] = strt[i].trim();
if(strt[i].length > 0) {
strt[i] = ' '+strt[i].charAt(0).toUpperCase() + strt[i].substr(1);
}
}
$scope.taskThemeWizardInputValue = strt.join('.');
console.log($scope.taskThemeWizardInputValue);
console.log(strt);
}
}
This is working fiddle
I suggest creating a directive so that you can plugin this behaviour whenever required., rather than writing your ng-change in every controller.
In directive simple line element.val(event.target.value.split(".").join(". ")); will work for you., with help of directive controller parameter.
See example fiddle

Targeting two separate elements with JavaScript

I have an spinner element made from two spans for + and - and an text input element in the middle that shows the quantity selected from the increase and decrease:
<div class="quantity-spinner">
<span class="input-number-decrement">–</span><input class="input-number" type="text" value="1" min="0" max="10"><span class="input-number-increment">+</
</div>
I have two instances of this element, but currently when increasing the quantity for one of the elements it also controls the other one.
My question is, how can I separate the two elements, so that they are controller independently.
Here is my JavaScript:
(function() {
window.inputNumber = function(el) {
var min = el.attr('min') || false;
var max = el.attr('max') || false;
var els = {};
els.dec = el.prev();
els.inc = el.next();
el.each(function() {
init($(this));
});
function init(el) {
els.dec.on('click', decrement);
els.inc.on('click', increment);
function decrement() {
var value = el[0].value;
value--;
if(!min || value >= min) {
el[0].value = value;
}
}
function increment() {
var value = el[0].value;
value++;
if(!max || value <= max) {
el[0].value = value++;
}
}
}
};
})();
inputNumber($('.input-number'));
Thank you in advance!
try replacing
els.dec.on('click', decrement);
els.inc.on('click', increment);
by
el.prev().on('click', decrement);
el.next().on('click', increment);
you bug comes from the fact that els.dec and els.inc contain
predecessors and successors for both counters

Unable to call function within jQuery

I am trying to call a function in this javascript code. My code needs to check for whether the user selects var num, var letters and var symbols to be true or false. In the code, I preset the values but I still search the object choices for the variables that are true and push it into the array choices_made. However, since I need to randomly choose the order in which the num, letters and symbols appear, I randomly choose the class based on the Math.random(). However, it doesn't show me the alert(jumbled_result) afterwards.
http://jsfiddle.net/bdaxtv2g/1/
HTML
<input id="num" type="text" placeholder="Enter desired length">
<br/><br/>
<input id="press" type="button" value="jumble it up">
JS
$(document).ready(function(){
var fns={};
$('#press').click(function(){
var length = parseInt($('#num').val());
var num = true;
var letters = true;
var symbols = false;
gen(length, num, letters, symbols);
});
function gen(len, num, letters, sym){
var choices = {
1:num,
2:letters,
3:sym
};
var choice_made = ['0'];
var choice = 0;
var jumbled_result = '';
for(x in choices){
if(choices[x]==true){
choice_made.push(x);
}
}
for(i=0;i<len;i++){
var funName = 'choice';
choice = Math.round(Math.random() * (choice_made.length-1));
funName += choice_made[choice];
jumbled_result = fns[funName](jumbled_result);
}
alert(jumbled_result);
}
fns.choice0 = function choice0(jumbled_result){
var numbers = '0123456789';
return jumbled_result += numbers.charAt(Math.round(Math.random() * numbers.length));
}
fns.choice1 = function choice1(jumbled_result) {
var alpha = 'abcdefghijklmnopqrstuvwxyz';
return jumbled_result += alpha.charAt(Math.round(Math.random() * alpha.length));
}
});
You never declare functions within document.ready of jQuery. The functions should be declared during the first run(unless in special cases).
Here is a working code made out of your code. What I have done is just removed your functions out of document.ready event.
$(document).ready(function() {
$('#press').click(function() {
var length = parseInt($('#num').val());
var num = true;
var letters = true;
var symbols = false;
gen(length, num, letters, symbols);
});
});
var fns = {};
function gen(len, num, letters, sym) {
var choices = {
1: num,
2: letters,
3: sym
};
var choice_made = ['0'];
var choice = 0;
var jumbled_result = '';
for (x in choices) {
if (choices[x] == true) {
choice_made.push(x);
}
}
for (i = 0; i < len; i++) {
var funName = 'choice';
choice = Math.round(Math.random() * (choice_made.length - 1));
funName += choice_made[choice];
jumbled_result = fns[funName](jumbled_result);
}
alert(jumbled_result);
}
fns.choice0 = function choice0(jumbled_result) {
var numbers = '0123456789';
return jumbled_result += numbers.charAt(Math.round(Math.random() * numbers.length));
}
fns.choice1 = function choice1(jumbled_result) {
var alpha = 'abcdefghijklmnopqrstuvwxyz';
return jumbled_result += alpha.charAt(Math.round(Math.random() * alpha.length));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="num" type="text" placeholder="Enter desired length">
<br/>
<br/>
<input id="press" type="button" value="jumble it up">
Its because of the way the object choices have been intitialized.. Try this..
var choices = {
0:num,
1:letters,
2:sym
};
And also
var choice_made = [];
JS fiddle link : http://jsfiddle.net/8dw7nvr7/2/

Why cant i enter decimal values in input in the following case

Before anything you need to see the effect:
jsFiddle
As you can see it is a calculator where you can put a value anywhere and covert it to other values, but the problem is that i cant enter decimal int values like 0.3 or 0.999. What is the cause of this?
var id = {
mm: 1,
cm: 10,
m: 1000,
km: 1000000
};
$('input.bx').on('keyup', function() {
var t = $(this).val();
var i = id[$(this).attr("id")];
var v = parseInt(t, 10);
for (pp in id) {
if (t !== '') {
$("#" + pp).val(v / id[pp] * i);
} else {
$(".bx").val('');
}
}
});
<input type='text' class='bx' id='mm'> Milimeter<br>
<input type='text' class='bx' id='cm'> Centimeter<br>
<input type='text' class='bx' id='m'> Meter<br>
<input type='text' class='bx' id='km'> Kilometer<br>
parseInt is the "problem" since it returns integer - decimal values are not integer but floats. If you want that you must replace it with parseFloat.
1.First you need to use parseFloat because int cant have decimals.
2.Second i would use onChange.
http://jsfiddle.net/Kfkjy/10/
a working fiddle here
you have to use parseFloat and dont try to set the current focused element value cause you are over riding it while typing.
this example is working fine
http://jsfiddle.net/Mohamed_aboelenen/D6T7j/1/
$('input.bx').on('keyup', function() {
var t = $(this).val();
var i = id[$(this).attr("id")];
var v = parseFloat(t, 10);
var a = $(this).attr("id"); // the textbox you write in
for (pp in id) {
if (t !== '' ) {
if(a != pp){ // make changes to any textbox except the one you write in
$("#" + pp).val(v / id[pp] * i);
}
} else {
$(".bx").val('');
}
}
});
$('input.bx').on('blur', function() {
var t = $(this).val();
var i = id[$(this).attr("id")];
var v = Number(t, 10);
for (pp in id) {
if (t !== '') {
$("#" + pp).val(parseFloat(v / id[pp] * i));
} else {
$(".bx").val('');
}
}
});

Categories

Resources