Currently I save data in input type="hidden" and access them from any JS script using getDocumentById("sourceJson"). For example:
<input type="hidden" id="sourceJson" name="sourceJson" >
var val = document.getElementById("sourceJson").value
But it forces me to scatter many hidden inputs in the HTML file. What is good replacement to hold data and have access to it from all scripts? Some kind of global variables that can also be submitted to the server.
If you declare a variable in any normal script it should be available from any other script.
<html><body>
<script>
var varOne = "Hello ..";
</script>
<script>
var varTwo = ".. world";
</script>
<script>
alert(varOne + varTwo);
</script>
</body></html>
Update
To Store array data we can use localStorage.setItem("data", JSON.stringify(data));
const data = localStorage.getItem("data")? JSON.parse(localStorage.getItem("data")):[];
function setData(name, value){
data.push({"name":name, "value":value});
localStorage.setItem("data", JSON.stringify(data));
}
function getData(name){
var ret = undefined;
for(var x = 0; x < data.length; x++){
if(data[x].name == name){
ret = data[x].value;
}
}
return ret;
}
Related
I have this problem here
The problem has been solved, but my question is how can I get the second value from that, or the third one. The sheet will have many tables and at some point I will need a total for each table. Also, is there any solution to automatically find the the array number which contain date row for each table (instead defining this manually). Hope my explanation make sense.
Thank you!
Kind regards,
L.E. Test file
If I understood your question correctly, instead of breaking the loop when a match to "Total" is found do whatever is needed to be done within the loop like so...
var today = toDateFormat(new Date());
var todaysColumn =
values[5].map(toDateFormat).map(Number).indexOf(+today);
var emailDate = Utilities.formatDate(new Date(today),"GMT+1",
"dd/MM/yyyy");
for (var i=0; i<values.length; i++){
if (values[i][0]=='Total'){
nr = i;
Logger.log(nr);
var output = values[nr][todaysColumn];
// Do something with the output here I"m assuming you email it
}
}
The loop will keep going and find every "Total" and do the same thing. This answer assumes that the "Totals" are in the same column. You can get fancier with this if you only want certain tables to send and not others, but this should get you started.
I didn't quite understand the second part of your question...
"Also, is there any solution to automatically find the the array
number which contain date row for each table (instead defining this
manually). Hope my explanation make sense."
I'm guessing you want all the rows that contain "Total" in the specific column. You could instantiate a variable as an empty array like so, var totals = [];. Then instead of sending the email or whatever in the first loop you would push the row values to the array like so, totals.push(nr+1) . //adding 1 gives you the actual row number (rows count from 1 but arrays count from 0). You could then simply loop through the totals array and do whatever you wanted to do. Alternatively you could create an array of all the values instead of row numbers like totals.push(values[nr][todaysColumn]) and loop through that array. Lots of ways to solve this problem!
Ok based on our conversation below I've edited the "test" sheet and updated the code. Below are my edits
All edits have been made in your test sheet and verified working in Logger. Let me know if you have any questions.
Spreadsheet:
Added "Validation" Tab
Edited "Table" tab so the row with "Email Address" in Column A lines up with the desired lookup values (dates or categories)...this was only for the first two tables as all the others already had this criteria.
Code:
Create table/category selector...
In the editor go to File >> New >> HTMLfile
Name the file "inputHTML"
Copy and paste the following code into that file
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form class="notice_form" autocomplete="off" onsubmit="formSubmit(this)" target="hidden_iframe">
<select id="tables" onchange="hideunhideCatagory(this.value)" required></select>
<p></p>
<select id="categories" style="display:none"></select>
<hr/>
<button class="submit" type="submit">Get Total</button>
</form>
<script>
window.addEventListener('load', function() {
console.log('Page is loaded');
});
</script>
<script
src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
// The code in this function runs when the page is loaded.
$(function() {
var tableRunner = google.script.run.withSuccessHandler(buildTableList);
var catagoryRunner = google.script.run.withSuccessHandler(buildCatagoryList);
tableRunner.getTables();
catagoryRunner.getCategories();
});
function buildTableList(tables) {
var list = $('#tables');
list.empty();
list.append('<option></option>');
for (var i = 0; i < tables.length; i++) {
if(tables[i]==''){break;}
list.append('<option>' + tables[i] + '</option>');
}
}
function buildCatagoryList(categories) {
var list = $('#categories');
list.empty();
list.append('<option></option>');
for (var i = 0; i < categories.length; i++) {
if(categories[i]==''){break;}
list.append('<option>' + categories[i] + '</option>');
}
}
function hideunhideCatagory(tableValue){
var catElem = document.getElementById("categories");
if(tableValue == "Total Calls By Date" || tableValue == "Total Appointments by Date"){
catElem.style.display = "none"
document.required = false;
}else{
catElem.style.display = "block"
document.required = true;
}
}
function formSubmit(argTheFormElement) {
var table = $("select[id=tables]").val(),
catagory = $("select[id=categories]").val();
console.log(table)
google.script.run
.withSuccessHandler(google.script.host.close)
.getTotal(table,catagory);
}
</script>
</body>
<div id="hiframe" style="display:block; visibility:hidden; float:right">
<iframe name="hidden_iframe" height="0px" width="0px" ></iframe>
</div>
</html>
Edits to Code.gs file
Replace code in Code.gs with this...
//This is a simple trigger that creates the menu item in your sheet
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Run Scripts Manually')
.addItem('Get Total','fncOpenMyDialog')
.addToUi();
}
//This function launches the dialog and is launched by the menu item
function fncOpenMyDialog() {
//Open a dialog
var htmlDlg = HtmlService.createHtmlOutputFromFile('inputHTML')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(200)
.setHeight(150);
SpreadsheetApp.getUi()
.showModalDialog(htmlDlg, 'Select table to get total for');
};
//main function called by clicking "Get Total" on the dialogue...variables are passed to this function from the formSubmit in the inputHTML javascript
function getTotal(table,catagory) {
function toDateFormat(date) {
try {return date.setHours(0,0,0,0);}
catch(e) {return;}
}
//get all values
var values = SpreadsheetApp
.openById("10pB0jDPG8HYolECQ3eg1lrOFjXQ6JRFwQ-llvdE2yuM")
.getSheetByName("Tables")
.getDataRange()
.getValues();
//declare/instantiate your variables
var tableHeaderRow, totalRow, tableFound = false;
//begin loop through column A in Tables Sheet
for (var i = 0; i<values.length; i++){
//test to see if values have already been found if so break the loop
if(tableFound == true){break;}
//check to see if value matches selected table
if (values[i][0]==table){
//start another loop immediately after the match row
for(var x=i+1; x<values.length; x++){
if(values[x][0] == "Email Address"){ //This header needs to consistantly denote the row that contains the headers
tableHeaderRow = x;
tableFound = true;
}else if(values[x][0] == "Total"){
totalRow = x;
break;
}
}
}
}
Logger.log("Header Row = "+tableHeaderRow)
Logger.log("Total Row = "+ totalRow)
var today = toDateFormat(new Date())
var columnToTotal;
if(catagory==''){
columnToTotal = values[tableHeaderRow].map(toDateFormat).map(Number).indexOf(+today);
}else{
columnToTotal = values[tableHeaderRow].indexOf(catagory);
}
var output = values[totalRow][columnToTotal];
Logger.log(output);
var emailDate = Utilities.formatDate(new Date(today),"GMT+1", "dd/MM/yyyy");
//here is where you would put your code to do something with the output
}
/** The functions below are used by the form to populate the selects **/
function getTables(){
var cFile = SpreadsheetApp.getActive();
var cSheet = cFile.getSheetByName('Validation');
var cSheetHeader = cSheet.getRange(1,1,cSheet.getLastRow(),cSheet.getLastColumn()).getValues().shift();
var tabelCol = (cSheetHeader.indexOf("Tables")+1);
var tables = cSheet.getRange(2,tabelCol,cSheet.getLastRow(),1).getValues();
return tables.filter(function (elem){
return elem != "";
});
}
function getCatagories(){
var cFile = SpreadsheetApp.getActive();
var cSheet = cFile.getSheetByName('Validation');
var cSheetHeader = cSheet.getRange(1,1,cSheet.getLastRow(),cSheet.getLastColumn()).getValues().shift();
var catagoriesCol = (cSheetHeader.indexOf("Catagory")+1);
var catagories = cSheet.getRange(2,catagoriesCol,cSheet.getLastRow(),1).getValues();
return catagories.filter(function (elem){
return elem != "";
});
}
I need to Get data sent from form in popup but the problem that in the form there is many checkboxes with same name like name='list[]' :
JS :
function showPopup(){
var user = document.getElementById("check").value;
var popup = window.open("milestone.php?a="+user,"hhhhhh","width=440,height=300,top=100,left=300,location=1,status=1,scrollbars=1,resizable=1") ;
}
html :
<input type='checkbox' name="approve[]" value="get from Mysql">
<input type='checkbox' name="approve[]" value="get from Mysql">
<input type='checkbox' name="approve[]" value="get from Mysql">
var user = document.getElementById("check").value;
That won't work because:
You need to get multiple values
You need to get the values only of checkboxes that have been checked
You don't have an element with that id (but an id has to be unique anyway)
The fields all have the same name. Use the name.
var inputs = document.getElementsByName("approve[]")
Then you need to generate your form data from it, filtering out the ones which are not checked:
var form_data = [];
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
if (input.checked) {
form_data.push(encodeURIComponent(input.name) + "=" + encodeURIComponent(input.value));
}
}
Then put all the form data together:
var form_data_query_string = form_data.join("&");
Then put it in your URL:
var url = "milestone.php" + "?" + form_data_query_string;
Then open the new window:
var popup = window.open(url,"hhhhhh","width=440,height=300,top=100,left=300,location=1,status=1,scrollbars=1,resizable=1") ;
If you want to pass the array via get you should loop through all the checked checkboxes and store the value of everyone in array then convert them to Json using JSON.stringify so you can passe them in url :
function showPopup(){
var approve_array=[];
var checked_checkboxes = document.querySelectorAll('input[type="checkbox"]:checked');
for(var i=0;i<all_checkboxes.length;i++){
approve_array[i] = checked_checkboxes[i].value;
}
var url = "milestone.php?approve="+JSON.stringify(approve_array);
var popup = window.open(url,"hhhhhh","width=440,height=300,top=100,left=300,location=1,status=1,scrollbars=1,resizable=1") ;
}
In you php page you could get the array passed as Json using json_decode :
$array_of_approves = json_decode($_GET['approve']);
Hope this helps.
You can access the value as:
$approveList= $_POST['approve'];
and can be iterated as
foreach ($approveList as $approve){
echo $approve."<br />";
}
I want to pass an array from one external .js file to another.
Each of these files works fine by themselves, but I am having a problem passing the array from pickClass.js to displayStudent.js, and getting the names and "remaining" value to display in the html file. I know it has something to do with how the arrays are declared, but I can't seem to get it to work properly.
The first file declares the array choice:
(masterStudentList.js):
var class1 = ['Brown, Abe','Drifter, Charlie','Freed, Eve'];
var class2 = ['Vole, Ug','Xylo, William','Zyzzyx, Yakob'];
The second picks which array to use based on the radio buttons (pickClass.js):
var classPicked = array(1);
function randomize(){
return (Math.round(Math.random())-0.5); }
function radioResult(){
var chooseClass = document.getElementsByName("chooseClass");
for (i = 0; i < chooseClass.length; i++){currentButton = chooseClass[i];
if (currentButton.checked){
var selectedButton = currentButton.value;
} // end if
} // end for
var output = document.getElementById("output");
var response = "You chose ";
response += selectedButton + "\n";
output.innerHTML = response;
chosenClass = new Array();
if (selectedButton == "class1")
{chosenClass = class1;}
else
{chosenClass = class2;}
var text = "";
var nametext = "";
var i;
for (i = 0; i < chosenClass.length; i++) {
text += chosenClass[i]+ ' / ';
}
var showText = "";
l = chosenClass.length;
classPicked = Array(l);
for (var i = 0; i < l; ++i) {
classPicked[i] = chosenClass[i].split(', ').reverse().join(' ');
showText += classPicked[i]+ '<br>';
}
//return = classPicked;
document.getElementById("classList").innerHTML = classPicked;
} // end function
This works properly.
I then want to pass "classPicked" to another .js file (displayStudent.js) which will randomize the student list, loop and display the students for a few seconds, and then end with one student name.
basket = classPicked; //This is where the array should be passed
function randOrd(){
return (Math.round(Math.random())-0.5); }
function showBasket(){
mixedBasket = basket.sort( randOrd ); //randomize the array
var i = 0; // the index of the current item to show
document.getElementById("remaining").innerHTML = basket.length;
fruitDisplay = setInterval(function() {
document.getElementById('showStud')
.innerHTML = mixedBasket[i++]; // get the item and increment
if (i == mixedBasket.length) i = 0; // reset to first element if you've reached the end
}, 100); //speed to display items
var endFruitDisplay = setTimeout(function()
{ clearInterval(fruitDisplay);
var index = mixedBasket.indexOf(document.getElementById('showStud').innerHTML);
mixedBasket.splice(index,1);
}, 3500); //stop display after x milliseconds
}
Here is the html (master.html). It's just rough -- I'll be working on the layout later:
<html>
<head>
<script src="masterStudentList.js" type="text/javascript"></script>
<script src="pickClass.js" type="text/javascript"></script>
<script src="displayStudent.js" type="text/javascript"></script>
</head>
<body>
<h2>Choose Class</h2>
<form action = "">
<fieldset>
<input type = "radio"
name = "chooseClass"
id = "radSpoon"
value = "class1"
checked = "checked" />
<label for = "radSpoon">Class 1</label>
<input type = "radio"
name = "chooseClass"
id = "radFlower"
value = "class2" />
<label for = "radFlower">Class 2</label>
<button type = "button"
onclick = "radioResult()"> Choose Class
</button>
<div id = "output">
</fieldset>
</form>
</div>
<center>
<h1> <span id="chooseStud"></span><p></h1>
<script> var fruitSound = new Audio();
fruitSound.src = "boardfill.mp3";
function showFruitwithSound()
{
fruitSound.play(); // Play button sound now
showBasket()
}
</script>
Remaining: <span id = "remaining" ></span>
<p>
<button onclick="showFruitwithSound()">Choose Student</button>
</center>
pickedClassList = <p id = classList> </p>
</body>
</html>
You shouldn't use global variable like this (I encourage you to read more on this theme) and I'm not sure I understand what you're trying to do... but the solution of your issue should be to move the basket = classPicked; line into your showBasket method :
basket = classPicked; //This is where the array should be passed
function randOrd(){
return (Math.round(Math.random())-0.5);
}
function showBasket(){
// whatever
}
should be :
function randOrd(){
return (Math.round(Math.random())-0.5);
}
function showBasket(){
basket = classPicked; //This is where the array should be passed
// whatever
}
This way, each time you call showBasket, this method will use the last value of classPicked.
Otherwise, basket will always keep the reference on the first value of classPicked.
Why ? because each time you assign a new Array to the basket variable (classPicked = Array(l);) instead of changing directly it's content by :
emptying it : while (classPicked.length > 0) { classPicked.pop(); }
and then adding new data : classPicked.concat(chosenClass)
You can't pass things to files; you could call a function defined in displayStudent.js, pass it classPicked, and have it assign it to basket.
I noticed this at the end of your second chunk of code ...
} // end function
This could indicate the classPicked is declared inside a function (I don't see one on the code). Because it is inside function scope, your set of code that is trying to use it cannot.
Push the declaraction of classPicked outside of the function.
var classPicked = Array(1);
function thisusesclasspicked() {
...
Also, please start indenting your code properly, it will become much easier to maintain and read.
UPDATE FROM COMMENTS:
I see the declaration now ...
classPicked = Array(l);
for (var i = 0; i < l; ++i) {
classPicked[i] = chosenClass[i].split(', ').reverse().join(' ');
showText += classPicked[i]+ '<br>';
}
... however, you are re-assigning the array with an element of one just before you attempt to make modifications to it ... You are emptying it there: classPicked = Array(l);
I tried to build an application in which , there is one HTML page from which I get single input entry by using Submit button, and stores in the container(data structure) and dynamically show that list i.e., list of strings, on the same page
means whenever I click submit button, that entry will automatically
append on the existing list on the same page.
But in this task, firstly I try to catch that input in javascript file, and I am failing in the same. Can you tell me for this, which command will I use ?
Till now my work is :-
HTML FILE :-
<html>
<head>
<script type = "text/javascript" src = "operation_q_2.js"></script>
</head>
<body>
Enter String : <input type= "text" name = "name" id = "name_id"/>
<button type="button" onClick = "addString(this.input)">Submit</button>
</body>
</html>
JAVASCRIPT FILE:-
function addString(x) {
var val = x.name.value;
//var s = document.getElementById("name_id").getElementValue;//x.name.value;
alert(val);
}
EDITED
My New JAVASCRIPT FILE IS :-
var input = [];
function addString(x) {
var s = document.getElementById("name_id").value;//x.name.value;
input.push(input);
var size = input.length;
//alert(size);
printArray(size);
}
function printArray(size){
var div = document.createElement('div');
for (var i = 0 ; i < size; ++i) {
div.innerHTML += input[i] + "<br />";
}
document.body.appendChild(div);
//alert(size);
}
Here it stores the strings in the string, but unable to show on the web page.
See this fiddle: http://jsfiddle.net/MjyRt/
Javascript was almost right
function addString(x) {
var s = document.getElementById("name_id").value;//x.name.value;
alert(s);
}
Try to use jQuery (simpler)
function addString() {
var s = $('#name_id').val();//value of input;
$('#list').append(s+"<br/>");//list with entries
}
<div id='list'>
</div>
I am creating a JSON based on a dynamic form values below, when the user submits, i am displaying the json feed in #results
Is it also possible to get all the values in the form when generating the JSON, I want to get the
name, ids,
title information,
input value etc
and then create/display the JSON in the order below?
A working version can viewed here :
http://jsfiddle.net/dev1212/GP2Y6/25/
Currently its not retuning any values and getting some undefined..
the code peice i tried is below
<script>
x = function(selector){
var attrs = [];
$(selector + " input").each(function(){
var attrObject = {};
$(this.attributes).each(function(index, attr){
attrObject[attr.name] = attr.value;
attrObject[attr.va] = attr.value;
//console.log(attrObject)
});
attrs.push(attrObject);
attrObject = {};
});
return attrs;
}
$(document).ready(function(){
alert(JSON.stringify(x("#myform")));
});
</script>
<script type="text/javascript" src="/www/include/js/jquery.min.js"></script>
<script>
x = function(selector){
var attrs = [];
$(selector + " input").each(function(){
var attrObject = {};
$(this.attributes).each(function(index, attr){
attrObject[attr.name] = attr.value;
//console.log(attrObject)
});
attrs.push(attrObject);
attrObject = {};
});
return attrs;
}
$(document).ready(function(){
alert(JSON.stringify(x("#myForm")));
});
</script>
<form id="myform" class="form-wd">
<input class="ui-dform-text" type="text" title="data for network.node1.eth0.ipaddr" name="network.node1.eth0.ipaddr">
</form>