looking for a bit of help with my jQuery, (i know its not the best)
Currently have a form, split into 2 sides,
on the left I have a list of assests on the right is the liabilities
somewhat of a balance sheet for account, see the image below
the jquery in use just now, is a bit of a mess.. (sorry)
this code will calculate the field totals on each keyup request, which seems to work ok,
jQuery('#ass_cash, #ass_liquid, #ass_lifeinsu, #ass_covvalue, #ass_la1, #ass_la2, #ass_la3, #ass_realestate, #ass_auto1total, #ass_auto2total, #lib_mortgage, #lib_bankloan1, #lib_bankloan2, #lib_loansinsucomp, #lib_loanscreditunion, #lib_creditcards, #lib_od1, #lib_od2, #lib_od3, #lib_rent, #lib_mortgagemthpmt, #lib_bankloan1mthpmt, #lib_bankloan2mthpmt, #lib_loansinsucompmthpmt, #lib_loanscreditunionmthpmt, #lib_creditcardsmthpmt, #lib_od1mthpmt, #lib_od2mthpmt, #lib_od3mthpmt, #lib_rentmthpmt').keyup( function(){
// ASSESTS
var ass_cash = jQuery("#ass_cash").val();
var ass_liquid = jQuery("#ass_liquid").val();
var ass_lifeinsu = jQuery("#ass_lifeinsu").val();
var ass_covvalue = jQuery("#ass_covvalue").val();
var ass_la1 = jQuery("#ass_la1").val();
var ass_la2 = jQuery("#ass_la2").val();
var ass_la3 = jQuery("#ass_la3").val();
var ass_realestate = jQuery("#ass_realestate").val();
var ass_auto1total = jQuery("#ass_auto1total").val();
var ass_auto2total = jQuery("#ass_auto2total").val();
var ass_total = jQuery("#ass_total").val();
if(ass_cash==''){ ass_cash = 0; }
if(ass_liquid==''){ ass_liquid = 0; }
if(ass_lifeinsu==''){ ass_lifeinsu = 0; }
if(ass_covvalue==''){ ass_covvalue = 0; }
if(ass_la1==''){ ass_la1 = 0; }
if(ass_la2==''){ ass_la2 = 0; }
if(ass_la3==''){ ass_la3 = 0; }
if(ass_realestate==''){ ass_realestate = 0; }
if(ass_auto1total==''){ ass_auto1total = 0; }
if(ass_auto2total==''){ ass_auto2total = 0; }
var asssubtotal = parseInt(ass_cash) + parseInt(ass_liquid) + parseInt(ass_lifeinsu) + parseInt(ass_covvalue);
asssubtotal = asssubtotal + parseInt(ass_la1) + parseInt(ass_la2) + parseInt(ass_la3) + parseInt(ass_realestate);
asssubtotal = asssubtotal + parseInt(ass_auto1total) + parseInt(ass_auto2total);
var asstotal = jQuery('#ass_total');
asstotal.val(asssubtotal);
// LIABILITIES
var lib_mortgage = jQuery("#lib_mortgage").val();
var lib_bankloan1 = jQuery("#lib_bankloan1").val();
var lib_bankloan2 = jQuery("#lib_bankloan2").val();
var lib_loansinsucomp = jQuery("#lib_loansinsucomp").val();
var lib_loanscreditunion = jQuery("#lib_loanscreditunion").val();
var lib_creditcards = jQuery("#lib_creditcards").val();
var lib_od1 = jQuery("#lib_od1").val();
var lib_od2 = jQuery("#lib_od2").val();
var lib_od3 = jQuery("#lib_od3").val();
var lib_rent = jQuery("#lib_rent").val();
if(lib_mortgage==''){ lib_mortgage = 0; }
if(lib_bankloan1==''){ lib_bankloan1 = 0; }
if(lib_bankloan2==''){ lib_bankloan2 = 0; }
if(lib_loansinsucomp==''){ lib_loansinsucomp = 0; }
if(lib_loanscreditunion==''){ lib_loanscreditunion = 0; }
if(lib_creditcards==''){ lib_creditcards = 0; }
if(lib_od1==''){ lib_od1 = 0; }
if(lib_od2==''){ lib_od2 = 0; }
if(lib_od3==''){ lib_od3 = 0; }
if(lib_rent==''){ lib_rent = 0; }
var libsubtotal = parseInt(lib_mortgage) + parseInt(lib_bankloan1) + parseInt(lib_bankloan2) + parseInt(lib_loansinsucomp);
libsubtotal = libsubtotal + parseInt(lib_loanscreditunion) + parseInt(lib_creditcards) + parseInt(lib_od1) + parseInt(lib_od2);
libsubtotal = libsubtotal + parseInt(lib_od3) + parseInt(lib_rent);
var lib_subtotal = jQuery('#lib_subtotal'); lib_subtotal.val(libsubtotal);
// MONTHLY PAYMENTS
var lib_mortgagemthpmt = jQuery("#lib_mortgagemthpmt").val();
var lib_bankloan1mthpmt = jQuery("#lib_bankloan1mthpmt").val();
var lib_bankloan2mthpmt = jQuery("#lib_bankloan2mthpmt").val();
var lib_loansinsucompmthpmt = jQuery("#lib_loansinsucompmthpmt").val();
var lib_loanscreditunionmthpmt = jQuery("#lib_loanscreditunionmthpmt").val();
var lib_creditcardsmthpmt = jQuery("#lib_creditcardsmthpmt").val();
var lib_od1mthpmt = jQuery("#lib_od1mthpmt").val();
var lib_od2mthpmt = jQuery("#lib_od2mthpmt").val();
var lib_od3mthpmt = jQuery("#lib_od3mthpmt").val();
var lib_rentmthpmt = jQuery("#lib_rentmthpmt").val();
if(lib_mortgagemthpmt==''){ lib_mortgagemthpmt = 0; }
if(lib_bankloan1mthpmt==''){ lib_bankloan1mthpmt = 0; }
if(lib_bankloan2mthpmt==''){ lib_bankloan2mthpmt = 0; }
if(lib_loansinsucompmthpmt==''){ lib_loansinsucompmthpmt = 0; }
if(lib_loanscreditunionmthpmt==''){ lib_loanscreditunionmthpmt = 0; }
if(lib_creditcardsmthpmt==''){ lib_creditcardsmthpmt = 0; }
if(lib_od1mthpmt==''){ lib_od1mthpmt = 0; }
if(lib_od2mthpmt==''){ lib_od2mthpmt = 0; }
if(lib_od3mthpmt==''){ lib_od3mthpmt = 0; }
if(lib_rentmthpmt==''){ lib_rentmthpmt = 0; }
var lib_surplus = jQuery('#lib_surplus');
if(lib_surplus==''){ lib_surplus = 0; }
var subtotal = parseInt(lib_mortgagemthpmt) + parseInt(lib_bankloan1mthpmt) + parseInt(lib_bankloan2mthpmt) + parseInt(lib_loansinsucompmthpmt);
subtotal = subtotal + parseInt(lib_loanscreditunionmthpmt) + parseInt(lib_creditcardsmthpmt) + parseInt(lib_od1mthpmt) + parseInt(lib_od2mthpmt);
subtotal = subtotal + parseInt(lib_od3mthpmt) + parseInt(lib_rentmthpmt);
var totalmthpmt = jQuery('#lib_totalmthpmt');
totalmthpmt.val(subtotal);
var assets_total = jQuery('#ass_total').val();
var lib_subtotal = jQuery('#lib_subtotal').val();
var lib_surplus = jQuery('#lib_surplus');
if(assets_total==''){ assets_total = 0; }
if(lib_subtotal==''){ lib_subtotal = 0; }
if(lib_surplus==''){ lib_surplus = 0; }
var surplus = assets_total - lib_subtotal;
lib_surplus.val(surplus);
// THIS IS THE PART THAT ISNT WORKING
//surplus/deficit
//var lib_total = jQuery('#lib_total').val();
//if(lib_total==''){ lib_total = 0; }
//var lib_totalmthpmt = jQuery('#lib_totalmthpmt').val();
//if(lib_totalmthpmt==''){ lib_totalmthpmt = 0; }
//var surplustotal = lib_total - lib_totalmthpmt;
//jQuery('#mthsurplus').val(surplustotal);
});
you can see the section which is causing issues above, its the calculation between the subtotal (minus) Surplus to generate the total,
each field for asset has a class .asset
each libability has class .liability
each monthly payment field has class .liabilitymth
Ive tried doing the jQuery('.asset').each(function() and trying to generate the total in the asset field, same for the other 2, sections,
the greyed out boxes are "readonly", were the calculations should appear.
ASSETS: The total on the left side of the page will be the total assets.
LIABILITIES: The 'Subtotal' will reflect the sum of the Liability column.
SURPLUS: This will represent the difference (Negative'-' OR Positive'+'), between the Assets & Liabilities-Balance column.
TOTAL(Right Side): This is to create a 'Balance Sheet'effect, so when you look at it, the calculation should reflect the same figure as the 'Total' over on the Asset side (Left side).
MONTHLY-SURPLUS/ DEFICIT: This should reflect the net difference in Total Income Revenue, either negative OR positive (Figure found From the Employment Tab), when compared with the total of the 'Monthly Payment' column.
this is where my jQuery falls flat on its face, there has to be an easier way to calculate the field totals, anyone shed any light on this, or have a much better use of code, rather than wrapping it all under a very large keyup request :)
This can give you the head start:
var totalAss = 0;
jQuery('.asset').each(function(){
var value = parseFloat(this.value);
if (value)
totalAss += value;
});
jQuery('#ass_total').val(totalAss);
There is indeed some easy way. Do things like that
on all classes means .assets , .liability and .liabilitymth do this on document.ready
$(function()
{
$('.assets , .liability ,.liabilitymth').each(function()
{
var value = $(this).val();
if(value == "")
{
$(this).val('000.00');
}
});
});
And now
var total_assets = 0;
$('.assets').keyup(function(){
var number = $(this).val();
total_assets += parseInt(number);
});
After that
$('#total_assets').val(total_assets);
If you do the calculation in the keyup or any other key events, then there will be a problem of keeping track of the old data that was entered. For ex., at an instant you had typed 50 and then you made it to 500 and then you made it to say 30. Then, the keyevent will not be able to figure out the difference between both the old and new data. You will have to write some logic to figure out the old and the new updated data and then depending on that you will have to update the final value. It is better if you can code something like this...
http://jsfiddle.net/AvSEG/
Related
I'm trying to understand how I can remove a decimal. I have tried Math.trunc() but it never seems to remove. Logger.log(esValues.length) prints 500.0, I tried adding var removeDecimal = Math.trunc(esValues.length) then printing removeDecimal but I still get 500.0
var ss = SpreadsheetApp.getActiveSpreadsheet();
var es = ss.getSheetByName("School1");
var ms = ss.getSheetByName("School2");
var hs = ss.getSheetByName("School3");
var esValues = es.getDataRange().getValues();
var counterDell = 0;
var counterHP = 0;
//var esValues = es.getRange('A:C').getValues();
Logger.log(esValues.length); //This prints 500.0, Also tried adding here Logger.log(Math.trunc(esValues.length))
for (var i = 0; i < esValues.length; i++) {
var data = esValues[i];
var first = data[1];
var last = data[0];
var middle = data[2];
var studentid = data[3];
var device = data[4];
if (device.includes("Dell")) {
counterDell++;
} else if (device.includes("HP")) {
counterHP++;
}
}
Logger.log(`Dell count is ${counterDell}`)
Logger.log(`Hp count is ${counterHP}`)
}
Logger.log(esValues.length.split('.')[0])
breaks the decimal into integer and decimal portions, then we discard the decimal portion.
Actually just not using the logger will elimate the .0. For some stupid reason it has always done that.
function lfunko() {
var ss = SpreadsheetApp.getActive();
var es = ss.getSheetByName("School1");
var vs = es.getDataRange().getValues();
var counterDell = 0;
var counterHP =
for (var i = 0; i < vs.length; i++) {
var device = vs[4];
if (device.includes("Dell")) {
counterDell++;
} else if (device.includes("HP")) {
counterHP++;
}
}
const msg = `HP: ${counterHP} DELL: ${counterDell}`
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutput(msg),"Counts");
}
I have the below JavaScript running on one of my forms OnLoad event :-
function calcServicePriceTotal() {
var grid = document.getElementById('ProjectServicesGrid');
var ids = grid.control.get_allRecordIds();
var sum = 0.00;
var cellValue;
for (i = 0; i < ids.length; i++) {
var cellValue = grid.control.getCellValue('iss_salesprice', ids[i]);
var number = Number(cellValue.replace(/[^0-9\.]+/g, ""));
sum = sum + number;
}
Xrm.Page.data.entity.attributes.get("ava_tempgrossvalue").setValue(sum);
}
Unfortunately I get the following error :-
"Error:'subGridOnload' is undefined"
I believe that the script is firing before the object has had the time it needs to load so what can I do to slow down the function? There must be some way to overcome this but I am far from a JavaScript expert so I could use some help.
Thanks in advance
function calcServicePriceTotal() {
if (document.getElementById("Services")) {
var grid = document.getElementById("Services").control;
var ids = grid.get_allRecordIds()
var sum = 0
for (i = 0; i < ids.length; i++) {
var cellValue = grid.getCellValue('iss_salesprice', ids[i]);
var number = Number(cellValue.replace(/\D/g, ''));
number = number/100;
sum = sum + number;
}
Xrm.Page.data.entity.attributes.get("iss_value").setValue(sum);
}
else {
setTimeout("calcServicePriceTotal();", 500);
}
}
I'm getting HTML from a forum url, and parsing the post count of the user from their profile page. I don't know how to write the parsed number into the Google spreadsheet.
It should go account by account in column B till last row and update the column A with count.
The script doesn't give me any errors, but it doesn't set the retrieved value into the spreadsheet.
function msg(message){
Browser.msgBox(message);
}
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu("Update")
.addItem('Update Table', 'updatePosts')
.addToUi();
}
function getPostCount(profileUrl){
var html = UrlFetchApp.fetch(profileUrl).getContentText();
var sliced = html.slice(0,html.search('Posts Per Day'));
sliced = sliced.slice(sliced.search('<dt>Total Posts</dt>'),sliced.length);
postCount = sliced.slice(sliced.search("<dd> ")+"<dd> ".length,sliced.search("</dd>"));
return postCount;
}
function updatePosts(){
if(arguments[0]===false){
showAlert = false;
} else {
showAlert=true;
}
var spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
var accountSheet = spreadSheet.getSheetByName("account-stats");
var statsLastCol = statsSheet.getLastColumn();
var accountCount = accountSheet.getLastRow();
var newValue = 0;
var oldValue = 0;
var totalNewPosts = 0;
for (var i=2; i<=accountCount; i++){
newValue = parseInt(getPostCount(accountSheet.getRange(i, 9).getValue()));
oldValue = parseInt(accountSheet.getRange(i, 7).getValue());
totalNewPosts = totalNewPosts + newValue - oldValue;
accountSheet.getRange(i, 7).setValue(newValue);
statsSheet.getRange(i,statsLastCol).setValue(newValue-todaysValue);
}
if(showAlert==false){
return 0;
}
msg(totalNewPosts+" new post found!");
}
function valinar(needle, haystack){
haystack = haystack[0];
for (var i in haystack){
if(haystack[i]==needle){
return true;
}
}
return false;
}
The is the first time I'm doing something like this and working from an example from other site.
I have one more question. In function getPostCount I send the function profileurl. Where do I declare that ?
Here is how you get the URL out of the spreadsheet:
function getPostCount(profileUrl){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var thisSheet = ss.getSheetByName("List1");
var getNumberOfRows = thisSheet.getLastRow();
var urlProfile = "";
var sliced = "";
var A_Column = "";
var arrayIndex = 0;
var rngA2Bx = thisSheet.getRange(2, 2, getNumberOfRows, 1).getValues();
for (var i = 2; i < getNumberOfRows + 1; i++) { //Start getting urls from row 2
//Logger.log('count i: ' + i);
arrayIndex = i-2;
urlProfile = rngA2Bx[arrayIndex][0];
//Logger.log('urlProfile: ' + urlProfile);
var html = UrlFetchApp.fetch(urlProfile).getContentText();
sliced = html.slice(0,html.search('Posts Per Day'));
var postCount = sliced.slice(sliced.search("<dd> ")+"<dd> ".length,sliced.search("</dd>"));
sliced = sliced.slice(sliced.search('<dt>Total Posts</dt>'),sliced.length);
postCount = sliced.slice(sliced.search("<dd> ")+"<dd> ".length,sliced.search("</dd>"));
Logger.log('postCount: ' + postCount);
A_Column = thisSheet.getRange(i, 1);
A_Column.setValue(postCount);
};
}
You're missing var in front of one of your variables:
postCount = sliced.slice(sliced.search("<dd> ")+"<dd> ".length,sliced.search("</dd>"));
That won't work. Need to put var in front. var postCount = ....
In this function:
function updatePosts(){
if(arguments[0]===false){
showAlert = false;
} else {
showAlert=true;
}
There is no array named arguments anywhere in your code. Where is arguments defined and how is it getting any values put into it?
I need some fresh eyes on what I'm trying to do. I'm working on making our inventory spreadsheet more accurate and email a person when we get low on something. I got most of the code done, there's one part that I'm having issues with and it's where we add a number to certain parts of the spreadsheet. To be more exact, I'm trying to have a menu with multiple text areas for each part, and each text area will relate to the number that we just bought of that part.
My current code for this section has an array that will create and add the textarea to the panel and the part that is labeled in the spreadsheet. A button that will add the text area to the spreadsheet.
My issue that I'm having is correctly setting up the .addCallbackElement() with an array and get whats in the text area to the spreadsheet.
Can anyone see where I am making the mistake, or possible recommendation at something better that I could do?
Thanks for any help that is given
function addBit() {
var ss = SpreadsheetApp.getActive();
var sheet0 = ss.getSheetByName('Inventory');
var lastrow0 = sheet0.getLastRow();
//var ui = SpreadsheetApp.getUi();
//data for each column that we need
var datarange0 = sheet0.getRange('D2:D'+lastrow0);
var datarange1 = sheet0.getRange('E2:E'+lastrow0);
var datarange2 = sheet0.getRange('F2:F'+lastrow0);
var datarange3 = sheet0.getRange('K2:K'+lastrow0);
var datarange4 = sheet0.getRange('I2:I'+lastrow0);
var data0 = datarange0.getValues();// Column D
var data1 = datarange1.getValues();// Column E
var data2 = datarange2.getValues();// Column F
var data3 = datarange3.getValues();// Column K
var data4 = datarange4.getValues();// Column I
var app = UiApp.createApplication();
app.setHeight(500).setWidth(500);
var scroll = app.createScrollPanel().setPixelSize(500,500);
var vpanel0 = app.createVerticalPanel();
var vpanel1 = app.createVerticalPanel();
var hpanel0 = app.createHorizontalPanel();
var apanel = app.createAbsolutePanel();
var text = new Array(lastrow0-1);
//creating labels and text areas for each part for the first column in the menu
for (var i = 0; i <= Math.round((lastrow0 - 2)/2); i++) {
var hpanel = app.createHorizontalPanel();
var label = app.createLabel(data0[i]+ ' ' + data1[i] + 'mm ('+ Math.round(data2[i]) + 'mil)');
text[i] = app.createTextArea().setName('text'+i).setSize(50,20).setValue(0);//.setId('text'+i);
hpanel.add(text[i]);
hpanel.add(label);
vpanel0.add(hpanel);
}
//creating labels and text areas for each part for the second column in the menu
for (var i = Math.round((lastrow0 - 2)/2) + 1; i <= lastrow0 - 2; i++) {
var hpanel = app.createHorizontalPanel();
var label = app.createLabel(data0[i]+ ' ' + data1[i] + 'mm ('+ Math.round(data2[i]) + 'mil)');
text[i] = app.createTextArea().setName('text'+i).setSize(50,20).setValue(0);//.setId('text'+i);
hpanel.add(text[i]);
hpanel.add(label);
vpanel1.add(hpanel);
}
//Creating handlers for the text areas
var thandler = app.createServerHandler('addition');
for (var j = 0; j <= lastrow0 - 2; j++) {
thandler.addCallbackElement(text[j]).setId('text'+i);
}
//when button is hit, the function 'addition' will run
var addButton = app.createButton("Add", thandler);
hpanel0.add(vpanel0);
hpanel0.add(vpanel1);
apanel.add(hpanel0);
apanel.add(addButton);
scroll.add(apanel);
app.add(scroll);
return app;
}
function addition(e){
var app = UiApp.getActiveApplication();
var ss = SpreadsheetApp.getActive();
var sheet0 = ss.getSheetByName('Inventory');
var lastrow0 = sheet0.getLastRow();
//data for each column
var datarange3 = sheet0.getRange('K2:K'+lastrow0);
var datarange4 = sheet0.getRange('I2:I'+lastrow0);
var data3 = datarange3.getValues();// Column K
var data4 = datarange4.getValues();// Column I
var text0 = new Array(lastrow0-1);
//text0[] will have what was in each text area
for (var i = 0; i <= lastrow0 - 2; i++) {
text0[i] = e.parameter.('text' + 1);
}
//for loop will add what was in the text area to columns 'Qty Acq' and 'Current Stock'
for (var j = 0; j <= lastrow0-2; j++) {
var k = j+2;
var v = data3[j] + text0[j];
var x = data4[j] + text0[j]
sheet0.getRange('M' + k).setValue(v);
sheet0.getRange('N' + k).setValue(x);
}
app.close();
}
Use the highest level panel (scrollpanel I guess) as a single callbackElement, it will automatically include all the child widgets.
var select = [];
for (var i = 0; i < nameslots; i += 1) {
select[i] = this.value;
}
This is an extract of my code. I want to generate a list of variables (select1, select2, etc. depending on the length of nameslots in the for.
This doesn't seem to be working. How can I achieve this? If you require the full code I can post it.
EDIT: full code for this specific function.
//name and time slots
function gennametime() {
document.getElementById('slots').innerHTML = '';
var namelist = editnamebox.children, slotnameHtml = '', optionlist;
nameslots = document.getElementById('setpresentslots').value;
for (var f = 0; f < namelist.length; f += 1) {
slotnameHtml += '<option>'
+ namelist[f].children[0].value
+ '</option>';
};
var select = [];
for (var i = 0; i < nameslots; i += 1) {
var slotname = document.createElement('select'),
slottime = document.createElement('select'),
slotlist = document.createElement('li');
slotname.id = 'personname' + i;
slottime.id = 'persontime' + i;
slottime.className = 'persontime';
slotname.innerHTML = slotnameHtml;
slottime.innerHTML = '<optgroup><option value="1">00:01</option><option value="2">00:02</option><option value="3">00:03</option><option value="4">00:04</option><option value="5">00:05</option><option value="6">00:06</option><option value="7">00:07</option><option value="8">00:08</option><option value="9">00:09</option><option value="10">00:10</option><option value="15">00:15</option><option value="20">00:20</option><option value="25">00:25</option><option value="30">00:30</option><option value="35">00:35</option><option value="40">00:40</option><option value="45">00:45</option><option value="50">00:50</option><option value="55">00:55</option><option value="60">1:00</option><option value="75">1:15</option><option value="90">1:30</option><option value="105">1:45</option><option value="120">2:00</option></optgroup>';
slotlist.appendChild(slotname);
slotlist.appendChild(slottime);
document.getElementById('slots').appendChild(slotlist);
(function (slottime) {
slottime.addEventListener("change", function () {
select[i] = this.value;
});
})(slottime);
}
}
You'll have to close in the iterator as well in that IIFE
(function (slottime, j) {
slottime.addEventListener("change", function () {
select[j] = this.value;
});
})(slottime, i);
and it's only updated when the element actually change
The cool thing about JavaScript arrays is that you can add things to them after the fact.
var select = [];
for(var i = 0; i < nameSlots; i++) {
var newValue = this.value;
// Push appends the new value to the end of the array.
select.push(newValue);
}