How to increase numbers line by line - javascript

Plunker.
I have Implemented the above plunker, In that plunker the rowId is increasing with Alphabets.Like the below
There will be + and ++ and - buttons in that component.
If I press + then The Rowid will start from Starting Alphabet(A).
If I press ++ Then The parent rowid + starting with Starting Alphabet means(AA).
And Again if I press ++ then parent rowId + starting with Starting Alphabet means(AAA). Like this it will increase.
Please access the Plunker here.
But I want to achieve that functionality with Numbers means
For single plus it should show 1, For ++ it should show 111 like this I need to achieve.
Can you please help me to do this functionality.
var newRow = {
"rowId": "A"
}
$scope.componentList = [];
$scope.componentList.push(angular.copy(newRow));
$scope.addParentRow = function(rowId) {
var newGridRow = angular.copy(newRow);
var lastChar = getListOfSameLevel(rowId, true); //isParentRow
var parentId = rowId.length > 1 ? rowId.slice(0, rowId.length - 1) : "";
newGridRow.rowId = parentId + getNextChar(lastChar);
$scope.componentList.push(newGridRow);
}
$scope.addChildRow = function(rowId) {
var newGridRow = angular.copy(newRow);
var lastChar = getListOfSameLevel(rowId, false);
if (rowId.length === lastChar.length) {
newGridRow.rowId = rowId + "A";
} else {
var parentId = lastChar.length > 1 ? lastChar.slice(0, lastChar.length - 1) : "";
newGridRow.rowId = parentId + getNextChar(getLastChar(lastChar));
}
$scope.componentList.push(newGridRow);
};
var getNextChar = function(inputChar) {
return String.fromCharCode(inputChar.charCodeAt(0) + 1);
};
var getLastChar = function(fullStr) {
return fullStr.slice(-1);
};

You need to change the initial value of newRow.rowId from A to 1 and to change the initiation of the next digits from A to 1 in the addChildRow function like this :
if (rowId.length === lastChar.length) {
newGridRow.rowId = rowId + "1";
}
Here is your plunker with numbers

Related

Javascript to calculate and display odds as their simplest fraction

I'm writing a bit of script for the WooCommerce product page that takes the quantity entered in the qty input field and displays some text based on that qty:
function reduce(numerator,denominator){
var gcd = function gcd(a,b){
return b ? gcd(b, a%b) : a;
};
gcd = gcd(numerator,denominator);
return [numerator/gcd,denominator/gcd];
}
jQuery('.qty').on('change', function() {
showOdds();
});
function showOdds() {
var qty = 1; // hard coded for testing
var min = 200; // hard coded for testing
var sofar = 40; // hard coded for testing
var plural = '';
var total = 0;
var odds = '';
if (qty > 1){
plural = 'tickets';
}
else{
plural = 'ticket';
}
if (qty > 0){
if ((qty + sofar) > min){
total = qty + sofar;
odds = reduce(qty, total);
}
else {
odds = reduce(qty, min);
}
var text = document.createElement('p');
text.className = 'product-odds';
text.innerHTML = 'Max odds of ' + qty + ' ' + plural + ' winning is ' + odds + '.';
var theDiv = document.getElementById('odds');
theDiv.appendChild(text);
}
}
jQuery(document).ready(function loadPage() {
showOdds();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='odds'></div>
The current output:
Max odds of 1 ticket winning is 1,200
How can I make the odds display in their simplest fraction form? For example if there are 200 tickets available and '1' is entered, it should show '1/200' but if someone enters '20' it should show '1/10'. The 'total' figure will eventually be picked up from the page rather than a fixed value too.
I can use the gcd as posted here but how can I get the two numbers from the array and display them as a fraction (with the /) in the required div?
You can return the desired string instead of array. Check the snippet below.
I've changed return [numerator/gcd,denominator/gcd]; to return numerator/gcd+'/'+denominator/gcd;
function reduce(numerator,denominator){
var gcd = function gcd(a,b){
return b ? gcd(b, a%b) : a;
};
gcd = gcd(numerator,denominator);
return numerator/gcd+'/'+denominator/gcd;
}
jQuery('.qty').on('change', function() {
showOdds();
});
function showOdds() {
var qty = 1; // hard coded for testing
var min = 200; // hard coded for testing
var sofar = 40; // hard coded for testing
var plural = '';
var total = 0;
var odds = '';
if (qty > 1){
plural = 'tickets';
}
else{
plural = 'ticket';
}
if (qty > 0){
if ((qty + sofar) > min){
total = qty + sofar;
odds = reduce(qty, total);
}
else {
odds = reduce(qty, min);
}
var text = document.createElement('p');
text.className = 'product-odds';
text.innerHTML = 'Max odds of ' + qty + ' ' + plural + ' winning is ' + odds + '.';
var theDiv = document.getElementById('odds');
theDiv.appendChild(text);
}
}
jQuery(document).ready(function loadPage() {
showOdds();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='odds'></div>

How can I optimize the below code with less number of line?

I have coded the below piece of code which handle the number bigger than 999 and add a comma to it. For example 1,000 and 1,000,000. Wheare as once the number increase the comma will be placed in the correct position. I used DRY principle and I feel still there is another easy way to handle it.
Now, I want to know if there is much better way than that I did.
Waiting for your opinion.
Thanks.
function seperate_num_by_comma() {
var num = '199228754645.25',
withOutComma = num.split('.'),
addNewCommaAfter = 3,
x = withOutComma[0].length % addNewCommaAfter,
lenOfWithOutComma_0 = withOutComma[0].length,
length_1 = withOutComma[0].length - x,
starter = 0,
wholeNumber = ' ';
for (var i = 0; i < lenOfWithOutComma_0; i++) {
function run_first_func() {
wholeNumber += withOutComma[0].substr(starter, addNewCommaAfter);
};
function run_second_fun() {
wholeNumber += withOutComma[0].substr(starter, addNewCommaAfter) + ",";
starter += addNewCommaAfter;
length_1 -= addNewCommaAfter;
};
if (x > 0) {
if (length_1 == 0) {
run_first_func();
break;
} else if (wholeNumber == ' ') {
wholeNumber += withOutComma[0].substr(starter, x) + ",";
length_1 -= addNewCommaAfter;
starter = x;
} else {
run_second_fun();
}
} else if (x == 0) {
if (length_1 == 3) {
run_first_func();
break;
}
run_second_fun();
}
}
console.log(wholeNumber + '.' + withOutComma[1]);
}
seperate_num_by_comma();
One Line:
165B minified version (no IE): seperate_by_comma=t=>(x=(""+t).split("."),z=x[0].replace(/((\d{3})*?)(\.|$)/,"|$1").split("|"),x[0]=z[0]+z[1].replace(/(.{3})/g,",$1").slice(!z[0].length),x.join("."))
OR 180B, IE-friendly: seperate_by_comma=function(t){x=(""+t).split(".");z=x[0].replace(/((\d{3})*?)(\.|$)/,"|$1").split("|");x[0]=z[0]+z[1].replace(/(.{3})/g,",$1").slice(!z[0].length);return x.join(".")}
Explanation:
seperate_num_by_comma = function(number){//12345678.9
var str = String(t);
var withoutDot = str.split("."); //["12345678", "9"]
var chunksOfThree = withoutDot[0].replace(/((\d{3})*?)(\.|$)/,"|$1");//"12|345678"
chunksOfThree = chunksOfThree.split("|");//["12", "345678"]
chunksOfThree[1] = chunksOfThree[1].replace(/(.{3})/g,",$1") //",345,678"
if(chunksOfThree[0].length==0){
chunksOfThree[1] = chunksOfThree[1].slice(1); //Fix for specific cases
}
withoutDot[0] = chunksOfThree[0] /*"12"*/ + chunksOfThree[1] /*",345,678"*/
return withoutDot.join(".") //"12,345,678.9"
}

jQuery price calculator function is not working with tabs

I have been trying to get this working from last couple of days without any success. I have this price calculator function developed by a freelancer who is not reachable from last few weeks.
This function works fine without any JavaScript tabs but not quite right with them. I need to have tabs on page because there are tons of options in this calculator.
This is the jQuery function.
$(document).ready(function() {
// For tabs
var tabContents = $(".tab_content").hide(),
tabs = $("ul.nav-tabs li");
tabs.first().addClass("active").show();
tabContents.first().show();
tabs.click(function() {
var $this = $(this),
activeTab = $this.find('a').attr('href');
if (!$this.hasClass('active')) {
$this.addClass('active').siblings().removeClass('active');
tabContents.hide().filter(activeTab).fadeIn();
}
return false;
});
// For Calculator
function Cost_Calculator() {
var Currency = '$';
var messageHTML = 'Please contact us for a price.';
function CostFilter(e) {
return e;
}
//Calculate function
function calculate() {
//Blank!
var CalSaveInfo = [];
$('#cost_calc_custom-data, #cost_calc_breakdown').html('');
//Calculate total
var calCost = 0;
var calculate_class = '.cost_calc_calculate';
$('.cost_calc_active').each(function() {
//Calculation
calCost = calCost + parseFloat($(this).data('value'));
//Add to list
var optionName = $(this).attr('value');
var appendName = '<span class="cost_calc_breakdown_item">' + optionName + '</span>';
var optionCost = $(this).attr('data-value');
var appendCost = '<span class="cost_calc_breakdown_price">' + Currency + optionCost + '</span>';
if (optionCost != "0") {
var appendItem = '<li>' + appendName + appendCost + '</li>';
}
//hidden data
var appendPush = ' d1 ' + optionName + ' d2 d3 ' + optionCost + ' d4 ';
$('#cost_calc_breakdown').append(appendItem);
CalSaveInfo.push(appendPush);
});
//Limit to 2 decimal places
calCost = calCost.toFixed(2);
//Hook on the cost
calCost = CostFilter(calCost);
var CustomData = '#cost_calc_custom-data';
$.each(CalSaveInfo, function(i, v) {
$(CustomData).append(v);
});
//Update price
if (isNaN(calCost)) {
$('#cost_calc_total_cost').html(messageHTML);
$('.addons-box').hide();
} else {
$('#cost_calc_total_cost').html(Currency + calCost);
$('.addons-box').show();
}
}
//Calculate on click
$('.cost_calc_calculate').click(function() {
if ($(this).hasClass('single')) {
//Add cost_calc_active class
var row = $(this).data('row');
//Add class to this only
$('.cost_calc_calculate').filter(function() {
return $(this).data('row') == row;
}).removeClass('cost_calc_active');
$(this).addClass('cost_calc_active');
} else {
// Remove class if clicked
if ($(this).hasClass('cost_calc_active')) {
$(this).removeClass('cost_calc_active');
} else {
$(this).addClass('cost_calc_active');
}
}
//Select item
var selectItem = $(this).data('select');
var currentItem = $('.cost_calc_calculate[data-id="' + selectItem + '"]');
var currentRow = currentItem.data('row');
if (selectItem !== undefined) {
if (!$('.cost_calc_calculate[data-row="' + currentRow + '"]').hasClass('cost_calc_active'))
currentItem.addClass('cost_calc_active');
}
//Bring in totals & information
$('#cost_calc_breakdown_container, #cost_calc_clear_calculation').fadeIn();
$('.cost_calc_hide').hide();
$('.cost_calc_calculate').each(function() {
if ($(this).is(':hidden')) {
$(this).removeClass('cost_calc_active');
}
calculate();
});
return true;
});
$('#cost_calc_clear_calculation').click(function() {
$('.cost_calc_active').removeClass('cost_calc_active');
calculate();
$('#cost_calc_breakdown').html('<p id="empty-breakdown">Nothing selected</p>');
return true;
});
}
//Run cost calculator
Cost_Calculator();
});
You can see this working on jsfiddle without tabs. I can select options from multiple sections and order box will update selected option's price and details dynamically.
But when I add JavaScript tabs, it stop working correctly. See here. Now if I select option from different sections, order box resets previous selection and shows new one only.
I think the problem is with calculator somewhere.
You are removing the active class from hidden elements. This means that when you move to the second tab you disregard what you've done in the first.
line 120 in your fiddle:
if ($(this).is(':hidden')) {
$(this).removeClass('cost_calc_active');
}
I haven't taken the code in depth enough to tell if you can just remove this.

Image slide won't slide

I have programmed an image slider in javascript, and it's "functional," but it doesn't alternate the images except for the very first and last images. For example, if I'm on the first image and press the right button, it won't change to the next image in the array. However, if I were to push the left button, it will change to last image in the array. The same thing will happen for the last image. I don't know how to fix this. Can you help?
I think it might have to do something with the "total" variable, but I'm not sure.
Here's the code...
window.onload = function () {
var nmbr_imgs = 4;
var imgs_holder = ["IMGS/Actinium.png", "IMGS/Aluminum.png", "IMGS/Astatine.png", "IMGS/Barium.png"];
var total = imgs_holder.length;
var left_btn = document.getElementById('left_btn');
var right_btn = document.getElementById('right_btn');
var imgs_display = document.getElementById('imgs_display');
left_btn.addEventListener('click', function() {
var lefting = total - 1;
imgs_display.src = imgs_holder[lefting];
if (lefting < 0) {
imgs_display.src = imgs_holder[(nmbr_imgs - 1)];
}
}, false);
right_btn.addEventListener('click', function() {
var righting = total + 1;
imgs_display.src = imgs_holder[righting];
if (righting > (nmbr_imgs - 1)) {
imgs_display.src = imgs_holder[0];
}
}, false);
}
Your listeners are off a bit ...
total = total - 1;
imgs_display.src = imgs_holder[total];
if(lefting < 0) {
total = nmbr_imgs - 1;
imgs_display = imgs_holder[total]
}
... try incrementing/decrementing total, not lefting/righting which are reset to total +/- 1 each time.

Javascript decrement -- not working in my script

var backgroundImages = new Array(); // create an array holding the links of each image
backgroundImages[0] = "style/images/bg0.png";
backgroundImages[1] = "style/images/bg1.png";
backgroundImages[2] = "style/images/bg2.png";
backgroundImages[3] = "style/images/bg3.png";
backgroundImages[4] = "style/images/bg4.png";
backgroundImages[5] = "style/images/bg5.png";
backgroundImages[6] = "style/images/bg6.png";
var ImageCnt = 0;
function nextImage(direction) // this should take into account the current value (starts at 3) and determines whether a higher or lower value should be returned based on the direction
{
if(direction == "left")
{
ImageCnt-- ;
}
if(direction == "right")
{
ImageCnt++ ;
}
document.getElementById("body-1").style.background = 'url(' + backgroundImages[ImageCnt] + ')'; //put's the new background together for rendering by using the returned value from nextImage()
if(ImageCnt == 6)
{
ImageCnt = -1;
}
}
In this script, ImageCnt ++ is working fine, on the function "nextImage('right')" but on nextImage('left') which triggers ImageCnt-- , the function breaks. What am I doing wrong? (Newbie with js)
Well, your "wrap" code says to make it -1, but what if I then go left? It will try to access -2, which doesn't exist.
Try this instead:
ImageCnt = (ImageCnt + (direction == "left" ? backgroundImages.length-1 : 1)) % backgroundImages.length;
document.getElementById("body-1").style.background = "url('"+backgroundImages[ImageCnt]+"')";
Note also that it is very inefficient to build an array piece by piece like that. Try this:
var backgroundImages = [
"style/images/bg0.png",
"style/images/bg1.png",
"style/images/bg2.png",
"style/images/bg3.png",
"style/images/bg4.png",
"style/images/bg5.png",
"style/images/bg6.png",
];

Categories