winjs/javascript: input number validation? - javascript

I have textbox with id number. I have 454 html files and I displayed these files by the respective input number. if users gives 3 and it will displays /def/f3.html and 4 means it will displays /def/f4.html and likewise it will all 454 files.
If users gives other than these number, an alert box alerts user. Still now, there is no problem.
What i am asking is, if users gives 003 and it will try to display /def/f003.html. Since, i don't have files with that name. it shows error.
Any help regarding this issue, will be seriously much appreciated. JavaScript Code:
function buttonClick()
{
var getFile = document.getElementById("number").value;
if (getFile < 455 && getFile > 0) {
var output = new WinJS.UI.HtmlControl(document.getElementById("def-content"), { uri: '/def/f' + getFile + '.html' });
} else {
var popup = Windows.UI.Popups.MessageDialog("Expected Value Range: 1 to 454.");
popup.showAsync();
}
}

use var getFile = parseInt(document.getElementById("number").value) and you also have to make sure than no file name number starts with zero except for f0.html.

Related

How to write (SetValues) to a Google Sheet using a filtered forEach loop?

I've been trying for hours to make the following Google Apps Script work. What it needs to do, is send emails (from an html-template) to anyone that:
has a complete Event Schedule (which is completed if they have been
assigned to at least 4 events, which is counted in column Q);
has NOT been sent an email earlier (which is kept track of in column
R);
The script keeps track of errors in column S, i.e. if there's no email address provided.
It appears it only works:
if I comment out
data = data.filter(function(r){ return r[17] == true & r[16] > 3});
or if I comment out
ws.getRange("S3:S" + ws.getLastRow()).setValues(errors);
ws.getRange("R3:R" + ws.getLastRow()).setValues(mailSucces);
How can I get this script to work properly?
A copy of the Google Sheet I'm referring to is this one:
https://docs.google.com/spreadsheets/d/1sbOlvLVVfiQMWxNZmtCLuizci2cQB9Kfd8tYz64gjP0/edit?usp=sharing
This is my code so far:
function SendEmail(){
var voornaam = 3;
var achternaam = 4;
var email = 5;
var event1 = 9;
var event2 = 10;
var event3 = 11;
var event4 = 12;
var event5 = 13;
var event6 = 14;
var event7 = 15;
var emailTemp = HtmlService.createTemplateFromFile("email");
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Events Day 1");
var datum = ws.getRange(1,3).getValue();
var spreker = ws.getRange(1,6).getValue();
var data = ws.getRange("A3:R" + ws.getLastRow()).getValues();
data = data.filter(function(r){ return r[17] == false && r[16] > 3}); //Either this needs to be commented out...
let errors = [];
let mailSucces = [];
data.forEach(function(row){
try{
emailTemp.voornaam = row[voornaam];
emailTemp.email = row[email];
emailTemp.datum = datum;
emailTemp.spreker = spreker;
emailTemp.event1 = row[event1];
emailTemp.event2 = row[event2];
emailTemp.event3 = row[event3];
emailTemp.event4 = row[event4];
emailTemp.event5 = row[event5];
emailTemp.event6 = row[event6];
emailTemp.event7 = row[event7];
var htmlMessage = emailTemp.evaluate().getContent();
GmailApp.sendEmail(
row[email],
"Here you go! Your personal schedule for the event of " + datum,
"Your emailprogramm doesn't support html.",
{
name: "Event Organisation Team", htmlBody: htmlMessage, replyTo: "info#fakeemail.com"
});
errors.push([""]);
mailSucces.push(["TRUE"]);
}
catch(err){
errors.push(["Error: no message sent."]);
mailSucces.push(["False"]);
}
}); //close forEach
ws.getRange("S3:S" + ws.getLastRow()).setValues(errors); //or this and the next line need to be commented out.
ws.getRange("R3:R" + ws.getLastRow()).setValues(mailSucces);
}
Edit I have been trying and thinking en trying... but still haven't found out how to make it work. But I also got understanding of why it's not working; I just don't know how to get it fixed.
Let me elaborate on the problem a bit more:
The problem is, that within the forEach loop the range is a filtered variant of the data, pulled from the spreadsheet with getValues. Therefore, writing data back with ws.getRange("R3:R" + ws.getLastRow()).setValues(mailSucces); results in mismatched checkmarks in te spreadsheet.
So, somehow I need to put the range of the previous used filter data = data.filter(function(r){ return r[17] == false & r[16] > 3}); in a variable...? I guess?
Furthermore, I don't think it's wise to use setValue within the loop, because (from what I understand from my searching on the topic) this results in a slow script, because every loop the script makes an API call to write in the spreadsheet. Hence the errors.push and mailSucces.push, and my attempt to do a setValue at the end, after the loop is finished.
Can someone help me to finish this problem?
The problem is different size of the range you write to and data you are writing in.
Try replacing:
ws.getRange("S3:S" + ws.getLastRow()).setValues(errors);
ws.getRange("R3:R" + ws.getLastRow()).setValues(mailSucces);
With:
ws.getRange(3, 19, errors.length, 1).setValues(errors);
ws.getRange(3, 18, mailSucces.length, 1).setValues(mailSucces);
You should use this variation of getRange
https://developers.google.com/apps-script/reference/spreadsheet/sheet#getrangerow,-column,-numrows,-numcolumns
Your data has non-fixed number of rows and fixed number of columns (1). In general case your data will be matrix of X rows and Y columns. For that purpose you can make it completely dynamic:
sheet.getRange(startRow, startColumn, data.length, data[0].length)
Just make sure data.length is > 0 before you do this, otherwise data[0].length will break.
Edit:
I started writing a comment but it got too long. There are couple of things that may go wrong with sending emails. First thing I noticed is that you use & in filter, but in AppsScript/JavaScript/C-like-languages, you should use && for logical AND. Now the email: you only detect the code break with the catch block. At this point you don't know why the code breaks it could be anything. With GmailApp I recommend you to use createDraft while developing, then when all ok replace it with sendEmail for the final version, both functions have the exact same parameters, thank you Google devs ;-).
To find out the exact problem you should get the error message on break and display it. err.stack should tell you pretty much everything:
catch(err){
Logger.log(err.stack); // Added
errors.push(["Error: no message sent."]);
mailSucces.push(["False"]);
}
Run the sendEmail function from the code editor and you should see the Log for each catch(err) pass.

Why method setValue doesn't output same as Browser.msgBox?

Since I could not make .toFixed(2) to work I designed my own piece of code to add desired decimal digits after the "." by simple joining two strings with + sign.
While Browser.msgBox outputs the 2 strings joined correctly as "1.00",
it seems like getRange.setValue outputs only the first of the 2 strings as "1" :(
function myFunction() {
var ss_calc = SpreadsheetApp.openById("1cFt0DbnpWGHquKk4ijxdKhwkaF8GhumWDWjTpHuSXbQ");
var sheet_calc = ss_calc.getSheetByName("Calcs");
var ss_source = SpreadsheetApp.openById("1gXeXmiw9EnzQXaiE7H8_zrilE2zyotlSuuIS8X9IxfQ");
var sheet_source = ss_source.getSheetByName("Farmah");
var decDig = ""; var strDec = ""; var impVal = "";
impVal = sheet_source.getRange(12,7).getValue().toString();
if (JSON.stringify(impVal).indexOf(".")>-1)
{ if (JSON.stringify(impVal).split(".")[1].length < 2 )
{
if (JSON.stringify(impVal).split(".")[1].length < 1)
{
decDig = "00";
}
else
{
decDig = "0";
}
}
}
else
{
decDig = ".00";
}
var strDec = impVal.toString() + decDig.toString();
Browser.msgBox(JSON.stringify(impVal).indexOf(".")+ "\\n" +
impVal.toString()+ "\\n" +
decDig+ "\\n" +
strDec);
sheet_calc.getRange(1,1).setValue(strDec);
}
From sheet_calc.getRange(1,1).setValue(strDec); I am expecting to get output "1.00" but I get only "1" :(
What am I missing?
Here are the links to google spreadsheets ( anyone with the link can edit :)
(above code has to be triggered manually by script editor in the first spreadsheet here under):
https://docs.google.com/spreadsheets/d/1cFt0DbnpWGHquKk4ijxdKhwkaF8GhumWDWjTpHuSXbQ/edit?usp=sharing
https://docs.google.com/spreadsheets/d/1gXeXmiw9EnzQXaiE7H8_zrilE2zyotlSuuIS8X9IxfQ/edit?usp=sharing
You want to put the value of 1.00 to a cell "A1".
If my understanding is correct, how about this modification? I think that the reason of your issue is that the value by putting by setValue() is converted to the number. By this, 1 is shown. In order to put the value as 1.00, I think that there are 3 patterns. Please select one of them for your situation.
Pattern 1:
In this pattern, from your question, the value is put as a string using setNumberFormat("#").
From:
sheet_calc.getRange(1,1).setValue(strDec);
To:
sheet_calc.getRange(1,1).setNumberFormat("#").setValue(strDec);
Pattern 2:
In this pattern, from your question, the format of cell is set using setNumberFormat("0.00").
From:
sheet_calc.getRange(1,1).setValue(strDec);
To:
sheet_calc.getRange(1,1).setNumberFormat("0.00").setValue(strDec);
Pattern 3:
In this pattern, from the script of your shared Spreadsheet, When decDig is ".00", the format is set.
From:
sheet_calc.getRange(x+6,c).setValue(strDec);
To:
var range = sheet_calc.getRange(x+6,c);
if (decDig) {
range.setNumberFormat("0.00").setValue(strDec); // or setNumberFormat("#")
} else {
range.setValue(strDec);
}
Reference:
setNumberFormat(numberFormat)
If I misunderstood your question and this was not the result you want, I apologize.
From sheet_calc.getRange(1,1).setValue(strDec); I am expecting to get output "1.00" but I get only "1" :(
Google Sheets, as well as other spreadsheet apps, have an automatic data type assignation, so things that look as numbers are converted to Google Sheets number data type, etc.
You could prepend an ' to force that a value be treated as text or you could set the number format in such way that numbers are displayed with two decimals. The cell formatting could be applied in advance, i.e., by using the Google Sheets UI commands or you could use Apps Script to set the format for you.

Javascript Math.log() help wanted

World!
I'm trying to create a program in Javascript that takes the log of a number typed into an HTML input. Unfortunately i've encountered a problem where it wont accept the string with the .replace().
Its Function:
I.E: When log(10) is calculated, the function should first remove the first 4 char's "log(" next remove the last parenthesis ")" and then take the log of the no. between.
HTML includes style elements, button and input form and an output < DIV >.
//Function
function calculate()
{
var inputString = document.getElementById("inpstr");
var output = document.getElementById("output");
//TESTING CODE
/*
if (inputString.value.startsWith("log(").endsWith(")"))
{
console.log(output.innerHTML = inputString.value.substring(4, 20).replace(")", ""));
}
else
{
output.innerHTML = "false";
}
*/
//Math.log() calc *****DOESNT WORK*****
if (inputString.value.startsWith("log(").endsWith(")"))
{
output.innerHTML = Math.log(inputString.value.replace(")", "").substring(4, 20));
}
else
{
output.innerHTML = inputString.value;
}
event.preventDefault();
}
If someone can give me an effective solution that would be much appreciated.
Thanks,
Syntax
Since Math.log() accepts only number values and you're trying to pass a string to it, you should first parse this value into a float number and then pass it to the log function:
let val = parseFloat(inputString.value.replace(")", "").substring(4, 20));
output.innerHTML = Math.log(val);
I'm guessing I got downvoted for being lazy, so here is the quick info. Gonras got it right relating to what you want to extract, but he forgot to check that what's being input is actually a log.
That's where the regex below comes in handy! I'm matching the field to:
^ start of word, since we want to match the entire field.
log(
([-.\d])) any consecutive sequence () of numbers (\d), -, and '.', represented by the []. The \(...\) makes sure to save this inner part for later.
$ is end of word, see 1.
res will be null if there is no match. Otherwise, res[0] is the entire match (so the entire input field) and res[1] is the first 'capture group', at point 3 - which is presumably the number.
This of course fails for multiple "-" inside, or "." etc... so think it over.
//Function
function calculate()
{
var inputString = document.getElementById("inpstr");
var output = document.getElementById("output");
var res = /^log\(([-.\d]*)\)$/.exec(inputString.value);
if (res)
output.innerHTML = Math.log(res[1]);
else
output.innerHTML = res;
}
document.getElementById("output").innerHTML='start';
calculate()
<div id='output'></div>
<input id='inpstr' value='log(2.71828)'></input>
If I wanted to fix your if to supplement Gonras's solution:
if (inputString.value.startsWith("log(") && inputString.value.endsWith(")"))
Yours fails since startsWith() returns a boolean, which obviously doesn't have a endsWith function.

jquery hide/show or condiiton failing

Is there anything wrong with the jQuery/JS below? I have an input field aAmt which on change calls below. ${dAmt} = "10000" from DB. It basically converts the number to $ format(eg.. 23 to $23.00) and focuses the value to the input field. Issue is the if loop (if(aAmt >= a_amount)...) fails.
Even if the condition fails it goes to if loops and shows the div which should not happen. I don't see any error in developers console.
$('#aAmt').change(function() {
var aAmt = $("#aAmt").val();
var a_amount = "${dAmt}";
curFormat(aAmt);
if(aAmt >= a_amount)
{
$("#dsDiv").show();
}else{
$("#dsDiv").hide();
}
});
function curFormat(aAmt)
{
var nAmt = Number(aAmt.replace(/[^0-9\.]+/g,""));
var fAmt = '$' + nAmt.toFixed(2).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
document.getElementById("aAmt").value = fAmt;
}
Have you tried to convert a_amount to an int, to be sure to compare two integers together:
var a_amount = parseInt("${dAmt}");

Replace Picture Source (Error Handling)

Hi I have a script wich changes the source of an image ie webpics/1.jpg to webpics/2.jpg on click of an image. One problem i am having though is that the script will still work for one more image after there is images, so if i have 11 images i can press next 11 times and will get an empty image, what i would like is for the script to run a error check and stay on the current image if the next on doesn't exist. Here is the script:
$("#prev, #next").click(function() {
var currentNumber = parseInt($("#image1").attr("src").split('gallery/')[1]); // get the
number
var newNumber = ($(this).attr("id")=="next")?currentNumber+1:currentNumber-1;
var testImage = new Image();
testImage.onload=function() {
var img = $("#image1");
img.attr("src",this.src);
img.css("visibility","visible");
}
testImage.onerror=function() {
$("#image1").css("visibility","hidden");
}
testImage.src="http://www.yogahealth.net.au/gallery/"+newNumber+".jpg";
return false;
});
Do you know how many images exist? If so, just test if the new number would exceed the total count (if newNumber ...) and do nothing (i.e. skip the part where you change the testImage.src.
For example, you need to have the total count in the variable totalImages, then you could do:
$("#prev, #next").click(function() {
var currentNumber = parseInt($("#image1").attr("src").split('gallery/')[1]); // get the number
var newNumber = ($(this).attr("id")=="next")?currentNumber+1:currentNumber-1;
var totalImages = // get the number of total images here
if ((newNumber > totalImages) || (newNumber <= 0)) {
return false; // just do nothing
}
// here comes the rest of your code
});
Note that I also added the possibility that your number becomes less than 0 or 0, depending on whether you have an image named 0. If yes, you can change the <= to <, otherwise it won't show the 0 image.
In order to get this number into your Javascript code, you could either render the code using PHP and insert it into your script with <?php echo $total; ?> or you extract it from another element from the HTML page, as you did with the currentNumber.

Categories