How can I copy this function but with preset values? - javascript

Currently when a button is clicked, it subtracts an inputted value. I want to have a preset value subtracted once a preset button is clicked. It would also be perferable that I could reuse a function later on a different button with different values like so:
var preset = function(val1, val2, val3, val4) {
//function to subtract from current values
}
$('presetButton').click(function(){
preset(1,2,3,4)
}
Here is the current function as I have it. The first button function works, but I wanted to copy it into a preset button with preset values. The function would not include $(this) because the button would not be in the same wrapper div and are not siblings.
$(document).ready(function(){
$('button').click(function(){
var $button = $(this);
var subtract = parseInt($button.siblings('input').val(), 10);
var $currentP = $button.siblings('.number').children('p');
var current = parseInt($currentP.text(), 10);
var newVal = current - subtract;
var $history = $button.siblings('.wrap').children('.history');
if (isNaN(subtract)) {
alert("Please enter in a number");
} else {
$currentP.effect('bounce', function() {
$currentP.text(newVal);
$(this).show();
});
$history.append("<p>"+subtract+"</p>");
}
});
$('#presets').click(function(){
//set up the subtracting and current variables
var subCal = 120;
var subPro = 24;
var subCarbs = 3;
var subFat = 1;
//retrieve current number then convert to a number
var toNum = function(id) {
return parseInt($(id + ' .number').children('p').text(), 10);
}
var curCal = toNum('#calories');
var curPro = toNum('#protein');
var curCarbs = toNum('#carbs');
var curFat = toNum('#fats');
//create new values
var newCal = curCal - subCal;
var newPro = curPro - subPro;
var newCarbs = curCarbs - subCarbs;
var newFat = curFat - subFat;
//apply new values
var applyNew = function(id, newVal) {
$(id + ' .number p').text(newVal)
}
applyNew('#calories', newCal);
applyNew('#protein', newPro);
applyNew('#carbs', newCarbs);
applyNew('#fats', newFats);
//Add to presets to history
})
});
The HTML
<h1>Track your Macros</h1>
<div class="wrapper">
<div id="calories">
<div class="number"><p>1945</p></div>
<div class="label"><p>Calories</p></div>
<input type="text"></input>
<button>Subtract</button>
<div class="wrap">
<div class="history"></div>
</div>
</div>
<div id="protein">
<div class="number"><p>200</p></div>
<div class="label"><p>Protein</p></div>
<input type="text"></input>
<button>Subtract</button>
<div class="wrap">
<div class="history"></div>
</div>
</div>
<div id="carbs">
<div class="number"><p>173</p></div>
<div class="label"><p>Carbs</p></div>
<input type="text" class="subtract"></input>
<button>Subtract</button>
<div class="wrap">
<div class="history"></div>
</div>
</div>
<div id="fats">
<div class="number"><p>50</p></div>
<div class="label"><p>Fats</p></div>
<input type="text" class="subtract"></input>
<button>Subtract</button>
<div class="wrap">
<div class="history"></div>
</div>
</div>
</div>
<div id="presets"><img src="on-logo.png"></div>

Try
$(document).ready(function(){
$('button').click(function(){
var $button = $(this);
var subtract = parseInt($button.siblings('input').val(), 10);
var $currentP = $button.siblings('.number').children('p');
var current = parseInt($currentP.text(), 10);
var newVal = current - subtract;
var $history = $button.siblings('.wrap').children('.history');
if (isNaN(subtract)) {
alert("Please enter in a number");
} else {
$currentP.effect('bounce', function() {
$currentP.text(newVal);
$(this).show();
});
$history.append("<p>"+subtract+"</p>");
}
});
var preset = function(val1, val2, val3, val4) {
//set up the subtracting and current variables
var subCal = val1;
var subPro = val2;
var subCarbs = val3;
var subFat = val4;
//retrieve current number then convert to a number
var toNum = function(id) {
return parseInt($(id + ' .number').children('p').text(), 10);
}
var curCal = toNum('#calories');
var curPro = toNum('#protein');
var curCarbs = toNum('#carbs');
var curFat = toNum('#fats');
//create new values
var newCal = curCal - subCal;
var newPro = curPro - subPro;
var newCarbs = curCarbs - subCarbs;
var newFats = curFat - subFat;
//apply new values
var applyNew = function(id, newVal) {
$(id + ' .number p').text(newVal);
}
//apply new values
var applyHistory = function(id, val) {
$(id + ' .history').append("<p>" + val + "</p>");
}
applyNew('#calories', newCal);
applyNew('#protein', newPro);
applyNew('#carbs', newCarbs);
applyNew('#fats', newFats);
applyHistory('#calories', subCal);
applyHistory('#protein', subPro);
applyHistory('#carbs', subCarbs);
applyHistory('#fats', subFat);
}
$('#presets').click(function(){
preset(120,24,3,1);
})
});
Demo: Fiddle

Related

How can I execute a function without an event?

Solved by # epascarello
Have to execute function without event so that discount can be displayed along with prices at the start without clicking or any other event
You can see in below snippet that 1st one is running automatic while 2nd one is running on click . Can it possible to run 2nd one as automatic because it solves my most of issues using this keyword
Let me know if you need clarification . Any suggestion or comments will be helpful.
function discount1() {
var sendTotal = document.getElementsByClassName("TotalPrice1")[0].innerHTML;
var send1 = sendTotal.replace(/₹/gi, "");
var send2 = send1.replace(/,/gi, "");
var send3 = Number(send2)
var send = document.getElementsByClassName("DiscPrice1")[0].innerHTML;
var send4 = send.replace(/₹/gi, "");
var send5 = send4.replace(/,/gi, "");
var send6 = Number(send5)
var rest = ((send3 - send6) / send3) * 100
document.getElementsByClassName("demo1")[0].innerHTML = rest.toFixed(0) + "% off";
}
discount1();
function discount(rest) {
var sendTotal = rest.parentElement.getElementsByClassName("TotalPrice")[0].innerHTML;
var send1 = sendTotal.replace(/₹/gi, "");
var send2 = send1.replace(/,/gi, "");
var send3 = Number(send2)
var send = rest.parentElement.getElementsByClassName("DiscPrice")[0].innerHTML;
var send4 = send.replace(/₹/gi, "");
var send5 = send4.replace(/,/gi, "");
var send6 = Number(send5)
var rent = ((send3 - send6) / send3) * 100
rest.getElementsByClassName("demo")[0].innerHTML = rent.toFixed(0) + "% off";
}
<div>
<div class="seen" onclick="discount1()">
<div class="TotalPrice1">₹9,728</div>
<div class="DiscPrice1">₹5,435</div>
<div class="demo1"></div>
</div>
</div>
<br>
<div>
<div class="seen" onclick="discount(this)">
<div class="TotalPrice">₹15,670</div>
<div class="DiscPrice">₹13,785</div>
<div class="demo"></div>
</div>
</div>
So you need to call your function with the element.
How you get the elements is up to you. querySelectorAll, getElementsByClassName, ids, etc.
function discount () { /*...*/ }
document.querySelectorAll(".daad").forEach(discount);
you can do it inside of the function
function discount () {
document.querySelectorAll(".daad").forEach(function (reed) {
var saadTotal = reed.parentElement.getElementsByClassName("Total")[0].innerHTML;
console.log('saadTotal', saadTotal);
var saadTotal2 = reed.querySelector(".Total").textContent;
console.log('saadTotal2', saadTotal2);
}
}
discount();
This is answer for previous question you can see in question edits
This is what I needed to do show discount percentage without any event (like onclick or onload) . You can see in below snippet .
function discount(rest) {
var sendTotal = rest.parentElement.getElementsByClassName("TotalPrice")[0].innerHTML;
var send1 = sendTotal.replace(/₹/gi, "");
var send2 = send1.replace(/,/gi, "");
var send3 = Number(send2)
var send = rest.parentElement.getElementsByClassName("DiscPrice")[0].innerHTML;
var send4 = send.replace(/₹/gi, "");
var send5 = send4.replace(/,/gi, "");
var send6 = Number(send5)
var rent = ((send3 - send6) / send3) * 100
rest.getElementsByClassName("demo")[0].innerHTML = rent.toFixed(0) + "% off";
}
document.querySelectorAll(".seen").forEach(discount);;
<div>
<div class="seen" onclick="discount(this)">
<div class="TotalPrice">₹9,728</div>
<div class="DiscPrice">₹5,435</div>
<div class="demo"></div>
</div>
</div>
<br>
<div>
<div class="seen" onclick="discount(this)">
<div class="TotalPrice">₹15,670</div>
<div class="DiscPrice">₹13,785</div>
<div class="demo"></div>
</div>
</div>

On mouse hover, display the corresponding sizes of bars, as mentioned in the input field

function draw() {
var nums = document.getElementById("number").value.split(",");
console.log(nums);
var w = 40;
var factor = 20;
var n_max = Math.max.apply(parseInt, nums);
var h_max = factor * n_max;
console.log("h max is " + h_max);
console.log("n max is " + n_max);
//var h_max = Math.max(h);
//var a = parseInt(nums);
//var create = document.getElementById("shape");
for (var i = 0; i <= nums.length; i++) {
//var x = parseInt(nums[i]);
//var final_width = w / x;
var x_cor = (i + 1) * w;
//var y_cor = i * w * 0.5;
var h = factor * nums[i];
console.log(x_cor);
console.log(h);
//console.log(h_max);
var change = document.getElementById("histContainer");
//change.className = 'myClass';
var bar = document.createElement("div");
bar.className = 'myClass';
//var c_change = document.createElement("div2");
//change.appendChild(c_change);
change.appendChild(bar);
console.log(change);
//change.style.x.value = x_cor;
//change.style.y.value = y_cor;
bar.style.position = "absolute";
bar.style.top = (h_max - h) + "px";
//bar.style.transform = "rotate(-1deg)"
bar.style.left = i * w * 1 + "px";
bar.style.backgroundColor = "rgb(1,211,97)";
bar.style.opacity = "0.6";
bar.style.width = w + "px";
bar.style.height = h + "px";
//var color1 = document.getElementById("histContainer");
//var bar_color = document.createElement("div");
//color1.appendChild(change);
//bar.style.color = "rgba(1,211,97,0.6)";
}
}
function color() {
//draw();
var change1 = document.getElementsByClassName('myClass');
for (var i = 0; i < change1.length; i++) {
change1[i].style.backgroundColor = "rgb(255,0,27)";
console.log("Change1 = " + change1[i]);
}
// var bar1 = document.createElement("div2");
// change1.appendChild(bar1);
// console.log(change1);
//change1.style.backgroundColor = "rgb(1,,254,16)";
}
$(document).ready(function() {
$(document).on("mouseover", ".myClass", function() {
//var number = this.nums;
//$(this.nums).text($(this.nums).index());
//$(".myClass").append(nums);
var shade = $(this).css("opacity");
$(this).css("opacity", "1.0");
$(document).on("mouseout", ".myClass", function() {
$(this).css("opacity", shade);
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
Number:<input type="text" id="number" /><br>
<input type="button" id="button1" value="Draw" onClick="draw()" /><br>
<input type="button" id="button2" value="Change Color" onClick="color()" /><br>
<div id="histContainer" style="position: relative;"> </div>
<!-- <label for="mouseover" id="label1">Bar Value</label><br>
<input type="text" name="mouseover" id="text2" value="0"/><br> -->
<!-- <input type="button" id="color_change" style="float: right;" value="Change Color" /> -->
My Question is- I have entered some numbers as Input, and corresponding histogram is made according to the input values. Now, I have created mouseover() on each bar, and WANT to display their proportionate sizes, as given in input.
Can you provide me some help? Only thing which i figured out was- I have to call my draw function in the jQuery mouseover.
REFER TO the draw() and jQuery function(last)
I have figured out the answer. It is required that the nums array has to be re-declared again.
Solution Achieved
$(document).ready(function() {
$(document).on("mouseover",".myClass", function(){
//var numbers = $("#number").serialize();
//var number = this.nums;
var nums = document.getElementById("number").value.split(",");
$(this).text(nums[$(this).index()]);
//$(".myClass").append(nums);
var shade = $(this).css("opacity");
$(this).css("opacity", "1.0");
$(document).on("mouseout",".myClass", function() {
$(this).css("opacity", shade);
});
});
});

short date range for selected date checkbox

We have set of checkbox which is identified as date checkbox. These are known as check-in date. Check-out is 1 greater then check-in date. For example if check-in date is 24/09/2017 then checkout is 25/09/2017.
So We are trying to get short date range if continuous date selected, For example, if we have four date 24/09/2017,25/09/2017,26/09/2017,27/09/2017. If we select 24/09/2017 then check-in date is 24/09/2017 and checkout is 25/09/2017. But if we select 24 and 25,26 then in array we have three values
checkindat:"24/09/2017",checkouts:"25/09/2017"
and
checkindat:"25/09/2017",checkouts:"26/09/2017"
and
checkindat:"26/09/2017",checkouts:"27/09/2017"
so we want if date range in sequence then it would show check-in date as 24/0/2017 and checkout date as 27/09/2017. But if we un-check date then it would work as its working now.
here is some part of my code in this jsfiddle
var alreadycheckin = [];
$("input[class='check htcheck']:checkbox").change(function() {
var roomids = $(this).attr("roomid");
checkindat = $(this).attr("name");
var new_dates = moment(checkindat, "DD.MM.YYYY");
var checkid = new_dates.format('DD-MM-YYYY');
//if ($(this).is(":checked"))
{
var html = '';
arr = [];
var roomcods = $(this).attr("value");
var roomids = $(this).attr("roomid");
checkindat = $(this).attr("name");
var new_dates = moment(checkindat, "DD.MM.YYYY");
var checkid = new_dates.format('DD-MM-YYYY');
//console.log(checkid);
var checkouts = new_dates.add(1, 'days').format('DD/MM/YYYY');
var roomcodes = $(this).attr("value");
var uniq = roomids + '_' + name + '_' + checkindat;
uniq = uniq.split("/").join("").split("_").join("");
var uniqs = '';
//console.log($("#aa"+roomids));
// alreadycheckin.push({ roomids : roomids, checkindat : checkindat, checkouts: checkouts });
var arrElement = {
roomids: roomids,
checkindat: checkindat,
checkouts: checkouts
};
if ($(this).is(":checked")) {
//alreadycheckin[uniq]={ roomids : roomids, checkindat : checkindat, checkouts: checkouts };
alreadycheckin.push(arrElement);
} else {
var index1 = arr.indexOf(arrElement);
alreadycheckin.splice(index1, 1);
}
var tmpAlreadycheckin = [];
// tmpAlreadycheckin=alreadycheckin.slice(0);
for (var i = 0; i < alreadycheckin.length; i++) {
if (i > 0) {
if (typeof alreadycheckin[i - 1] != "undefined" || alreadycheckin[i - 1] != null) {
if (alreadycheckin[i].checkouts == alreadycheckin[i - 1].checkindat) {
console.log("111");
var arrElement1 = {
roomids: roomids,
checkindat: alreadycheckin[i].checkindat,
checkouts: alreadycheckin[i - 1].checkouts
};
tmpAlreadycheckin.push(arrElement1);
//tmpAlreadycheckin[i].checkouts =tmpAlreadycheckin[i+1].checkouts;
//tmpAlreadycheckin.splice(i+1, 1);
} else {
console.log("2222");
var arrElement2 = {
roomids: roomids,
checkindat: alreadycheckin[i].checkindat,
checkouts: alreadycheckin[i].checkouts
};
tmpAlreadycheckin.push(arrElement2);
}
} else {
console.log("3333");
var arrElement2 = {
roomids: roomids,
checkindat: alreadycheckin[i].checkindat,
checkouts: alreadycheckin[i].checkouts
};
tmpAlreadycheckin.push(arrElement2);
}
} else {
console.log("3333");
var arrElement2 = {
roomids: roomids,
checkindat: alreadycheckin[i].checkindat,
checkouts: alreadycheckin[i].checkouts
};
tmpAlreadycheckin.push(arrElement2);
}
}
console.log(tmpAlreadycheckin);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<input roomid="15" id="15_24/09/2017" class="check htcheck" name="24/09/2017" value="1" type="checkbox">24/09/2017 <br/>
<input roomid="15" id="15_25/09/2017" class="check htcheck" name="25/09/2017" value="1" type="checkbox">25/09/2017 <br/>
<input roomid="15" id="15_26/09/2017" class="check htcheck" name="26/09/2017" value="1" type="checkbox">26/09/2017 <br/>
<input roomid="15" id="15_27/09/2017" class="check htcheck" name="27/09/2017" value="1" type="checkbox">27/09/2017 <br/>
If you have an array of objects in this format: [{checkindat:"24/09/2017",checkouts:"25/09/2017"},{checkindat:"25/09/2017",checkouts:"26/09/2017"}] :then you could first sort the array by checkindate, and then iterate over the array backwards. You would start on the last element, look at its checkindat, then compare it to the previous element's checkouts. If they're the same, update the previous elements checkouts to the one ahead of it, and then delete the one ahead of it.

jQuery slider with input value on drag after refresh

I've found this grate slider which is combo of 4 sliders sharing 100% value. Problem is that it doesn't pick value of input, yet it resets to 25% for each slider every time page is refreshed. Can someone help by making slider picking value of inputs before they determine position of slider knob.
HTML
<div align="center" class="title">Statistiche:</div>
<div id="outer_container">
<div id="container">
<span class='multislider'>Hokuto ShinKen (<input type='text' required name='question_3' class='amount' value='5' data-min='0' data-max='100'/>)
<div class='slider tied'>
</div>
Nanto (<input type='text' required name='question_3' class='amount' value='15' data-min='0' data-max='100'/>)
<div class='slider tied'>
</div>
Gento (<input type='text' required name='question_3' class='amount' value='50' data-min='0' data-max='100'/>)
<div class='slider tied'>
</div>
Artiglio del Monte Taishan (<input type='text' required name='question_3' class='amount' value='30' data-min='0' data-max='100'/>)
<div class='slider tied'></div>
</span>
</div>
</div>
jQuery
var init = true;
var elements = $(".multislider").children(".slider.tied").length;
var MAX = 100;
var inpVal = $('.txt_name').val();
var initValue = (inpVal) >> 0;
//var initValue = (MAX / elements) >> 0;
var InitMod = MAX % elements;
$(".slider.tied").each(function() {
var slidersTied = $(".slider.tied");
var context = $(this);
var input = context.prev(".amount");
var val = input.data('answer');
var min = input.data('min');
var max = input.data('max');
var range = 1;
var proceed = false;
$(this).empty().slider({
value: val,
min: min,
max: max,
range: range,
animate: "slow",
create: function(event, ui){
if (InitMod > 0) {
$(this).slider('value', initValue + 1);
$(this).prev('.amount').val(initValue + 1);
InitMod = InitMod - 1;
}
else
{
$(this).slider('value', initValue);
$(this).prev('.amount').val(initValue);
}
},
slide: function(e, ui) {
// Update display to current value
$(this).prev('.amount').val(ui.value);
var current = ($(this).index() / 2) >> 0;
var total = 0;
var counter = 0
slidersTied.not(this).each(function() {
total += $(this).slider("option", "value");
counter += 1;
});
total += ui.value;
if (total != MAX){
proceed = true;
}
var missing = MAX - total;
console.log("missing: " + missing);
counter = 0;
if(proceed) {
//carico vettore elementi
var elements = [];
slidersTied.each(function() {
elements[counter] = $(this);
counter += 1;
});
var endIndex = counter - 1;
counter = endIndex + 1;
while (missing != 0) {
console.log("current counter: " + counter);
do {
if (counter == 0)
{
counter = endIndex;
}
else
{
counter = counter - 1;
}
} while(counter == current)
console.log("elemento attuale: " + counter);
var value = elements[counter].slider("option", "value");
var result = value + missing;
if (result >= 0)
{
elements[counter].slider('value', result);
elements[counter].prev('.amount').val(result);
missing = 0;
}
else
{
missing = result;
elements[counter].slider('value', 0);
elements[counter].prev('.amount').val(0);
}
}
}
}
});
});
Example
http://jsfiddle.net/vuQz5/116/
Thanks
There are two issues, var val = input.data('answer'); is wrong, there is no such data value what you need is to get the input value like this:
var val = input.val();
val = (val) ? val : 0;
and also use that value in create method instead of initValue there is no need for if condition you only need whatever is in the else clause:
$(this).slider('value', val);
$(this).prev('.amount').val(val);
Check this fiddle

Problems With Making Things Dynamic

Everything Works Fine if I create a duplicate Manually, But when I try to duplicate elements using j-query the function doesn't work except on the original created entry.The first input tag has a auto-complete source linked with the class that also only works with the original elements and not with the clones.
<div class="row add">
<form id="form1" action="#">
<input class="col-md-offset-1 col-xs-3 inpro clac" id="inpro1">
<input class="col-xs-1 mrp calc" id="mrp1">
<input class="col-xs-1 qt calc" id="qt1">
<input class="col-xs-1 dis calc" id="dis1">
<div class="col-xs-2 amt calc" id="amt1"></div>
<input type="submit" class="sub" id="sum1">
</form>
</div>
<button class="row col-md-offset-1 col-xs-1 add" id="copy">Add</div>
</div>
<script>
$('.calc').blur(function(e){
var k = this.id.substr(this.id.length-1);
var mrp = parseFloat( $('#mrp'+k).val() );
var qt = parseFloat( $('#qt'+k).val() );
var di = $('#dis'+k).val();
var dis = parseFloat( di );
var disc = di.substr(di.length-1);
var amt = "";
if (mrp>0 && qt>0 && dis>0) {
if (disc === "%") {
amt = mrp*qt - mrp*qt*dis/100;
} else {
amt = mrp*qt - dis;
}
var amount = "Rs."+ " " + Math.round( amt ) + " "+ "/-";
}
$('#amt'+k).html(amount);
e.preventDefault();
});
var scale = $("#copy").click(function() {
var add = $(".add");
var cnt = add.length + 1;
add.eq(0).clone().insertBefore(this)
.find("form").attr("id", "form" + cnt)
.find("input, div").each(function() {
this.id = this.id.replace(/\d+/, cnt);
if ($(this).is('div')) {
$(this).text = $(this).text("");
} else {
this.value = null;
}
});
});
</script>
Here is the fiddle http://jsfiddle.net/UwMML/
I have edited the fiddle,
You have to have the binding function separate, because you will have to use that to bind blur event each time you add a set of input fields. In your code, blur event is bound to .calc only one time.
This part will do the first event binding
$(document).ready(function(){
reBind();
});
For each time you click on Add button, this function will get executed. It will unbind all the prior bindings (to make the DOM overhead minimize) and re-bind blur event to all .calc inputs
function reBind(){
$('.calc').unbind("blur").blur(function(e){
var k = this.id.substr(this.id.length-1);
var mrp = parseFloat( $('#mrp'+k).val() );
var qt = parseFloat( $('#qt'+k).val() );
var di = $('#dis'+k).val();
var dis = parseFloat( di );
var disc = di.substr(di.length-1);
var amt = "";
if (mrp>0 && qt>0 && dis>0) {
if (disc === "%") {
amt = mrp*qt - mrp*qt*dis/100;
} else {
amt = mrp*qt - dis;
}
var amount = "Rs."+ " " + Math.round( amt ) + " "+ "/-";
}
$('#amt'+k).html(amount);
e.preventDefault();
});
}
You need to reinitialize your calc function after the new elements have been added:
function calc() {
$('.calc').blur(function (e) {
var k = this.id.substr(this.id.length - 1);
var mrp = parseFloat($('#mrp' + k).val());
var qt = parseFloat($('#qt' + k).val());
var di = $('#dis' + k).val();
var dis = parseFloat(di);
var disc = di.substr(di.length - 1);
var amt = "";
if (mrp > 0 && qt > 0 && dis > 0) {
if (disc === "%") {
amt = mrp * qt - mrp * qt * dis / 100;
} else {
amt = mrp * qt - dis;
}
var amount = "Rs." + " " + Math.round(amt) + " " + "/-";
}
$('#amt' + k).html(amount);
e.preventDefault();
});
}
calc();
var scale = $("#copy").click(function () {
var add = $(".add");
var cnt = add.length + 1;
add.eq(0).clone().insertBefore(this)
.find("form").attr("id", "form" + cnt)
.find("input, div").each(function () {
this.id = this.id.replace(/\d+/, cnt);
if ($(this).is('div')) {
$(this).text = $(this).text("");
} else {
this.value = null;
}
});
calc();
});
FIDDLE

Categories