Guys help me with this code. The idea is to save new inputs in a string and display them using HTML. Every time I add a new one the HTML displays it, if I reload the page the items are still displayed and the first getItem method and if I reload again is still working but here is the problem. After I reload the page and I insert a new element in string then it will display the just the lates inputs and will delete the ones from other sessions.
If I insert now :"one","two","three" it I will display "one,two,three" if I reload it will still display " one,two,three" which is good, but after the reload if I insert "four" it will display only "four" and I want to be displayed "one,two,three,four".
How can I make this happen?
<!DOCTYPE html>
<html>
<body>
<div id="result"></div>
<button onclick="reloadd()">Reload</button>
<button onclick="clearF()">Clear</button>
<input id="valoare">
<button id="adauga" onclick="adauga()">+</button>
<button onclick="nrElemente()">ElemNr?</button>
<script>
var cars = [];
var two = "kes";
document.getElementById("result").innerHTML = localStorage.getItem("array1");
function clearF() {
window.localStorage.clear();
location.reload();
}
function adauga() {
var x = document.getElementById('valoare').value;
cars.push(x);
localStorage.setItem("array1", cars);
document.getElementById("result").innerHTML = localStorage.getItem("array1");
}
function reloadd() {
location.reload();
}
function nrElemente() {
alert(localStorage.length);
}
</script>
</body>
</html>
Your code is not working because you are not storing your array anywhere.
To save your array into localStorage you would use:
localStorage.setItem("cars", JSON.stringify(cars));
Then instead of doing this:
var cars = [];
You would load your cars array like this:
var cars = localStorage.getItem("cars");
cars = (cars) ? JSON.parse(cars) : [];
What this is doing is, it is checking if the localStorage object contains an array called cars. Now if it does it will parse that string and return the stored cars array, if it does not it will set the cars array to a new empty array.
Here, I have fixed and tidied your code:
<!DOCTYPE html>
<html>
<body>
<div id="result"></div>
<button onclick="reloadd()">Reload</button>
<button onclick="clearF()">Clear</button>
<input id="valoare" />
<button id="adauga" onclick="adauga()">+</button>
<button onclick="nrElemente()">ElemNr?</button>
<script type="text/javascript">
var array1 = localStorage.getItem("array1");
array1 = (array1) ? JSON.parse(array1) : [];
var two = "kes";
document.getElementById("result").innerHTML = localStorage.getItem("array1");
function clearF() {
window.localStorage.clear();
location.reload();
}
function adauga() {
var x = document.getElementById("valoare").value;
array1.push(x);
localStorage.setItem("array1", JSON.stringify(array1));
document.getElementById("result").innerHTML = localStorage.getItem("array1");
}
function reloadd() {
location.reload();
}
function nrElemente() {
alert(localStorage.length);
}
</script>
</body>
</html>
Also, it's considered bad practice to place your JavaScript events & functions in HTML attributes. Try to separate HTML, CSS & JS as much as possible by placing all (or at-least most) of your JS in your script element / JS file.
Good luck and all the best.
You are creating an empty array every page load and when you add to array you store that but never connect cars array to the data that is already stored
Try changing
var cars =[];
To
var localData = localStorage.getItem("array1");
// if localData not undefined then parse that as cars array, otherwise is empty array
var cars = localData ? JSON.parse(localData) : [];
When you go to store the cars array change to:
localStorage.setItem("array1",JSON.stringify(cars));
There were some major issues with your code, this is a fixed version:
<script type="text/javascript">
var cars = [];
try {
cars = JSON.parse(localStorage.getItem("array1"));
} catch (err) {}
var two = "kes";
document.getElementById("result").innerHTML = cars;
function clearF() {
window.localStorage.clear();
location.reload();
}
function adauga() {
var x = document.getElementById('valoare').value;
cars.push(x);
localStorage.setItem("array1", JSON.stringify(cars));
document.getElementById("result").innerHTML = localStorage.getItem("array1");
}
function reloadd() {
location.reload();
}
function nrElemente() {
alert(localStorage.length);
}
</script>
Related
i need a help to register only unique values inside the google spreadsheet behind the web script app
currently to save I use this script, practical find a way to block the launch if you already have values the same values in the spreadsheet.
basically there are two fields "cod" and "val"
if "cod" and "val" have already been registered before, it would need to show a message that these data are repeated.
I tried to do a check, but you can only do it in one "cod" field,
I would like to do it in both "cod" and "val" fields
https://docs.google.com/spreadsheets/d/1ZfIqw6_pkt1AdWsayyk1LdW_I6lU2yjsY1VfxfJneCA/edit#gid=0
function save_on_sheet(Data){
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1ZfIqw6_pkt1AdWsayyk1LdW_I6lU2yjsY1VfxfJneCA/edit#gid=0");
var ws = ss.getSheetByName("page");
const cod = ws.getRange(2, 1, ws.getLastRow()-1, 1).getValues().map(r => r[0].toString().toLowerCase());
const posicaoIndex = cod.indexOf(Data.cod.toString().toLowerCase());
if (posicaoIndex === -1) {
ws.appendRow([
Data.cod,
Data.val
])
return 'NEW';
} else {
return 'DUPLICATE';
}
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<label for="cod">COD:</label>
<input type="text" id="cod"><br><br>
<label for="val">VALUE:</label>
<input type="text" id="val"><br><br>
<input type="submit" value="SAVE UNIQUE SHEET" onclick="save()">
</body>
<script>
function save(){
Data = {}
Data.cod = document.getElementById("cod").value;
Data.val = document.getElementById("val").value;
google.script.run.withSuccessHandler(retorno).save_on_sheet(Data);
}
function retorno(mensagem_retorno){
alert(mensagem_retorno);
}
</script>
</html>
You can refer to this sample code:
function save_on_sheet(Data){
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1ZfIqw6_pkt1AdWsayyk1LdW_I6lU2yjsY1VfxfJneCA/edit#gid=0");
var ws = ss.getSheetByName("page");
const dataVal = ws.getRange(2,1,ws.getLastRow()-1, 2).getDisplayValues();
Logger.log(dataVal);
for(var i=0; i<dataVal.length;i++){
var rowData = dataVal[i];
if(rowData[0]==Data.cod.toString().toLowerCase() && rowData[1]==Data.val.toString().toLowerCase()){
//Exit function, duplicate found
return 'DUPLICATE';
}
}
//No duplicate found. Append new data
ws.appendRow([
Data.cod,
Data.val
]);
return 'NEW';
}
What it does?
Get cod and values data in the spreadsheet using Range.getDisplayValues() which will return a 2-d array of string values.
Loop each row value and compare cod and values to Data.cod and Data.values. If match found, return "DUPLICATE", if no match found, append the Data and return "NEW"
I have a simple text input where users type anything and after sumbitting text appear on a page and stays there, which I done with localStorage, but after refreshing the page only last typed input is showing, Ill post my code to be more specific:
HTML:
<body>
<input id="NewPostField" type="text" value="">
<button onclick="myFunction()">Post</button>
<div id="Posts"></div>
</body>
JavaScript:
function myFunction() {
var NewPostField =
document.getElementById("NewPostField");
var newPost = document.createElement("p");
localStorage.setItem('text',
NewPostField.value);
newPost.innerHTML = NewPostField.value;
var Posts = document.getElementById("Posts");
Posts.appendChild(newPost);
}
(function() {
const previousText = localStorage.getItem('text');
if (previousText) {
var NewPostField = document.getElementById("NewPostField");
NewPostField.value = previousText;
myFunction();
}
})();
Any help will be great!
It seems that your code is only storing the last value posted.
To store more than one post, one idea is to stringify an array of values to store in localStorage.
Then, parse that stringified value back into an array as needed.
Here's an example:
function getExistingPosts() {
// fetch existing data from localStorage
var existingPosts = localStorage.getItem('text');
try {
// try to parse it
existingPosts = JSON.parse(existingPosts);
} catch (e) {}
// return parsed data or an empty array
return existingPosts || [];
}
function displayPost(post) {
// display a post
var new_post = document.createElement("p");
new_post.innerHTML = post;
posts.appendChild(new_post);
}
function displayExistingPosts() {
// display all existing posts
var existingPosts = getExistingPosts();
posts.innerHTML = '';
inputPost.value = '';
if (existingPosts.length > 0) {
existingPosts.forEach(function(v) {
displayPost(v);
});
inputPost.value = existingPosts.slice(-1)[0];
}
}
function addPost(post) {
// add a post
var existing = getExistingPosts();
existing.push(post);
localStorage.setItem('text', JSON.stringify(existing));
displayPost(post);
}
function clearPosts() {
// clear all posts
localStorage.removeItem('text');
displayExistingPosts();
}
var posts = document.getElementById("posts");
var inputPost = document.getElementById("input_post");
var btnPost = document.getElementById('btn_post');
var btnClear = document.getElementById('btn_clear');
btnPost.addEventListener('click', function() {
addPost(inputPost.value)
});
btnClear.addEventListener('click', clearPosts);
displayExistingPosts();
<input id="input_post" type="text" value="">
<button type="button" id="btn_post">Post</button>
<button type="button" id="btn_clear">Clear</button>
<div id="posts"></div>
Since localStorage isn't supported in StackSnippets, here's a JSFiddle to help demonstrate.
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 != "";
});
}
<input type="hidden" id="amenities" value="#Model.Amenities" />
<script type="text/javascript">
$(function () {
arr = new Array();
var str = document.getElementById("amenities").value;
arr = str.split(",");
for(count =0;count<arr.length;count++)
{
$("input[type=checkbox][value=arr[count]]").prop("checked",true);
}
</script>
In the model there is an attribute called "Amenities" of type string. It stores all the amenities like wifi, pool , park etc with delimiter (,). When I go to the edit page I want all those amenities to be checked which were earlier stored for that particular property.
I suggest to do it on the server when you generate the view. All you need is:
public class MyModel
{
...
public string[] Amenities { get; set; }
...
}
Then in the view:
#Html.Checkbox("WiFi", #Model.Amenities.Contains("WiFi"))
#Html.Checkbox("Pool", #Model.Amenities.Contains("Pool"))
Of course it's just an example and in real life you'll probably have a list of possible Amenities and you iterate through to render checkboxes for each of them. Also instead of strings as values I would recommend and enum.
This works:
<script type="text/javascript">
$(document).ready(function(){
var arr = $("#amenities").val().split(",");
$('input[type=checkbox]').each(function(){
if($.inArray($(this).val(), arr) >= 0){
$(this).attr("checked",true);
}
});
});
</script>
<script type="text/javascript">
$(function () {
var arr = new Array();
var str = $("#amenities").val();
arr = str.split(",");
$('input[type=checkbox]').each(function(key,val){
if(jQuery.inArray( $(this).val(), arr){
$(this).prop("checked",true);
}
})
});
</script>
Check the above code.!!
One recommendation, Since you are using jQuery, GO with jQuery syntax.
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>