I'm trying to retrieve values set in chrome storage. The original value was stored using a different script in the same extension.
The value stored was stored using:
chrome.storage.sync.set({
logoStore: logolink})
Then I am using below to retrieve the storage value and replace the image url. No doubt the entirely incorrect method, syntax and all. :(
chrome.storage.local.get('logoStore', function (result) {
alert(logoStore.result);
});
var logourl = logoStore.result;
// ======= SWAP IMAGES ==========
var images = document.getElementsByTagName ("img");
var x=0;
while(x<images.length)
{
if(images[x].src == "https://www.this-url.com/images/new-brand-2016/common/logo-2016-246x48-v1.gif")
{
images[x].src = 'logourl';
}
x=x+1;
}
I'm very new to js, and have searched extensively on SO and elsewhere for the correct method to use the stored values. Sorry for such a noob question.
On an upnote - I did manage to resolve my last question with help and some further efforts myself :) Thanks.
========= UPDATE =========
I got this part working thanks to your input :)
Working code for this is...
chrome.storage.sync.get(['logoStore'], function(result) {
console.log('Value currently is ' + result.key);
var logourl = result.logoStore;
// ======= SWAP IMAGES ==========
var images = document.getElementsByTagName ("img");
var x=0;
while(x<images.length)
{
if(images[x].src == "https://www.url.com/images/new/common/logo-246x48-v1.gif")
{
images[x].src = logourl;
}
x=x+1;
}
});
Next Step...
Now I have to get two more values from storage and insert them into existing HTML.
I can successfully get the first value to load, but it is breaking my inline style, and the second value is not loading.
Code below.
// ========== ADD HEADER TEXT ==============
chrome.storage.sync.get(['companyStore', 'dataStore'], function(result) {
console.log('Value currently is ' + result.key);
var company = result.companyStore;
var data = result.dataStore;
var el = document.querySelector('table.delivery-address');
// get element content as string
console.log(el.innerHTML)
// prepend to the element's content
el.innerHTML = '</table><div style="margin-right:0px;float:right;text-align:right;margin-top:20px;"><h2 style="font-size: 28px;">Info</h2><br/><p style="font-size:18px;line-height:1.4em;"><b>' + company; + '</b><br/>' + data; + '<b></p></div><br/><br/><table class="delivery-address">' + el.innerHTML;
});
Related
Hi I just wondering if i can get some pointers with my code, I am trying to capture and save the input value of a textarea. I am fairly new to JavaScript and I have been wrecking my brain trying to figure it out. My issue is regarding the saveEntry() function, which isn't complete I have only posted how my code is right now, and isn't causing errors/unwanted effects. Any tips or hints would be fantastic, as I keep getting errors
function addTextEntry(key, text, isNewEntry) {
// Create a textarea element to edit the entry
var textareaElement = document.createElement("textarea");
textareaElement.rows = 5;
textareaElement.placeholder = "(new entry)";
// Set the textarea's value to the given text (if any)
textareaElement.value = text;
// Add a section to the page containing the textarea
addSection(key, textareaElement);
// If this is a new entry (added by the user clicking a button)
// move the focus to the textarea to encourage typing
if (isNewEntry) {
textareaElement.focus();
}
// Create an event listener to save the entry when it changes
// (i.e. when the user types into the textarea)
function saveEntry() {
// Save the text entry:
// ...get the textarea element's current value
var currentValue = document.getElementById('textarea').value;
// ...make a text item using the value
// ...store the item in local storage using the given key
localstroage.setItem(key, item);
}
// Connect the saveEntry event listener to the textarea element 'change' event
textareaElement.addEventListener("change", saveEntry());
}
function addImageEntry(key, url) {
// Create a image element
var imgElement = new Image();
imgElement.alt = "Photo entry";
// Load the image
imgElement.src = url;
// Add a section to the page containing the image
addSection(key, imgElement);
}
/**
* Function to handle Add text button 'click' event
*/
function addEntryClick() {
// Add an empty text entry, using the current timestamp to make a key
var key = "diary" + Date.now();
var text = "";
var isNewEntry = true;
addTextEntry(key, text, isNewEntry);
I was told to utilise something similar to this code below, but not exactly the same as I need to capture the data value of the user input text, not pre-created data.
function createDemoItems() {
console.log("Adding demonstration items to local storage");
var item, data, key;
// Make a demo text item
data =
"Friday: We arrived to this wonderful guesthouse after a pleasant journey " +
"and were made most welcome by the proprietor, Mike. Looking forward to " +
"exploring the area tomorrow.";
item = makeItem("text", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000001";
// Store the item in local storage
localStorage.setItem(key, item);
// Make a demo text item
data =
"Saturday: After a super breakfast, we took advantage of one of the many " +
"signed walks nearby. For some of the journey this followed the path of a " +
"stream to a charming village.";
item = makeItem("text", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000002";
// Store the item in local storage
localStorage.setItem(key, item);
// Make a demo image item
data = window.DUMMY_DATA_URL;
item = makeItem("image", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000003";
// Store the item in local storage
localStorage.setItem(key, item);
// Make a demo text item
data =
"Sunday: Following a tip from Mike we drove to a gastropub at the head of " +
"the valley - a great meal and fabulous views all round.";
item = makeItem("text", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000004";
// Store the item in local storage
localStorage.setItem(key, item);
}
You are very close, you just have to make some adjustments here and there!
Just as a disclaimer, I had to re-create your addSection() function, in order to have it properly working. If you already had one, you could discard mine
When we create a new entry, in order to make it distinguishable, I have assigned it the id of the key. Before, you were trying to call getElemenyById("textarea"), but no element had id textarea, which is in fact the tag name of the textarea element that you created. Read more about getElementByTagName if you want.
I have changed the way the event listener is set to:
textareaElement.addEventListener(
'input',
function () { saveEntry(); },
false
);
The difference between change and input are that change will fire only when you are done with the changes and click outside of the textarea, whilst input will fire everytime that you input something. Now you know, so of course, feel free to change it to what you would like it to behave.
Lastly, I have made the just-created item to be retrieved immediately and logged to console. This will be useful just for testing, you can comment out those lines when you are happy.
Beware that the snippet below is playable, but it won't actually save data to LocalStorage because of SO limitations, so you won't be able to fully test it on this page.
function addSection(key, element) {
element.id = key;
var test = document.querySelector("#test");
test.appendChild(element);
}
function addTextEntry(key, text, isNewEntry) {
// Create an event listener to save the entry when it changes
// (i.e. when the user types into the textarea)
function saveEntry() {
// Save the text entry:
// ...get the textarea element's current value
var currentValue = document.getElementById(key).value;
// ...store the item in local storage using the given key
localStorage.setItem(key, currentValue);
//Testing if we can retrieve the item, comment out when you're happy
var item = localStorage.getItem(key);
console.log(item);
}
// Create a textarea element to edit the entry
var textareaElement = document.createElement("textarea");
textareaElement.rows = 5;
textareaElement.placeholder = "(new entry)";
// Set the textarea's value to the given text (if any)
textareaElement.value = text;
// Add a section to the page containing the textarea
addSection(key, textareaElement);
// If this is a new entry (added by the user clicking a button)
// move the focus to the textarea to encourage typing
if (isNewEntry) {
textareaElement.focus();
}
textareaElement.addEventListener(
'input',
function () { saveEntry(); },
false
);
// Connect the saveEntry event listener to the textarea element 'change' event
//textareaElement.addEventListener("change", saveEntry());
}
function addImageEntry(key, url) {
// Create a image element
var imgElement = new Image();
imgElement.alt = "Photo entry";
// Load the image
imgElement.src = url;
// Add a section to the page containing the image
addSection(key, imgElement);
}
/**
* Function to handle Add text button 'click' event
*/
function addEntryClick() {
// Add an empty text entry, using the current timestamp to make a key
var key = "diary" + Date.now();
var text = "";
var isNewEntry = true;
addTextEntry(key, text, isNewEntry);
}
window.onload = () => addEntryClick();
<html>
<head>
</head>
<body>
<div id="test"></div>
</body>
</html>
There are a number of things wrong with the way you're doing things, but you know that: that's why you're here!
You have a typo: localstroage should be localStorage
You create a text area but don't give it an ID. In your saveData function you attempt to find it, but you're searching for it by tag name. There's no need to search: your event handler will already have this set to the element.
In your event handler you refer to your function as saveData(). This will invoke the function immediately and assign its return value as an event handler. Just pass the function name.
Here's a demonstration of concept for you:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Explore local storage</title>
</head>
<body>
<textarea id="txt" placeholder="Enter text and press TAB"></textarea>
<script>
"use strict";
let txtKey = "someKey"
// Save the data. No need to search for the text area:
// the special value 'this' is already set to it.
function saveEntry() {
localStorage.setItem(txtKey, this.value);
}
// Look fr the previous text and if it exists, put it in the textarea
let storedText = localStorage.getItem(txtKey);
if (storedText) {
document.getElementById('txt').value = storedText;
}
// Now add the event listener.
tArea.addEventListener('change', saveEntry); // Pass just the function name
</script>
</body>
</html>
This code uses a hard-coded value for txtKey. Your code might need to generate and track some value for the key, otherwise you risk overwriting earlier data with later data.
So I'm doing a freeCodeCamp project that shows information regarding specific streamers. I have bumped into multiple problems, regarding if statements inside a for loop (I think).
First, the Status is always "Offline" for every streamer, second, the borders around the logos don't change except for the first one. If it worked, I'm still not sure whether the border colors would be correct though (red for offline streams, green for online).
If you watch closely, what I did was I provided a specific id for each iteration of streamer info, 1 for the corresponding image, and 1 for status, so I can target them with the i variable inside an if statement.
Here is the JS code, it is better visible via Codepen using the link I provided, mainly because you see the whole work and I don't know how to format code properly so that you don't have to use horizontal scrollbar to see long lines. :/
Thanks in advance!
$(document).ready(function() {
var channels = ["freecodecamp", "wudijo", "ThijsHS", "HSdogdog", "Sjow"];
for (var i = 0; i < channels.length; i++) {
var channelURL = "https://wind-bow.gomix.me/twitch-api/channels/"+ channels[i] +"?callback=?";
var streamURL = "https://wind-bow.gomix.me/twitch-api/streams/"+ channels[i] +"?callback=?";
$.getJSON(channelURL, function(data1) {
var logo = data1.logo;
var name = data1.display_name;
var twitchLink = data1.url;
var status;
$.getJSON(streamURL, function(data2) {
if (data2.stream === null) {
status = "Offline";
}
else {
status = data2.stream.channel.status;
}
$("#followerInfo").append("<div class = 'row'><div class = 'col-md-4'><a href = '"+ twitchLink +"' target = 'blank'><img id = 'img"+ i +"' src = '"+ logo +"'></a></div><div class = 'col-md-4'><p>" + name + "</p></div><div class = 'col-md-4'><p id = 'status"+ i +"'>" + status + "</p></div></div>");
if (data2.stream === null) {
$("#img"+ i +"").addClass('img-offline');
}
else {
$("#img"+ i +"").addClass('img-online');
}
});
});
}
});
If you console.log(channelURL) you can see that only "Sjow" his data is being called. This happens because your loop finishes before any requests are made, therefore only the last value in the array (Sjow) is used.
You can fix this by following this answer.
I have a page which has 3 sections. On the left a static menu
e.g.
<li>New File</li>
This can start new actions e.g.
$('.actionLink').click(function() {
var folderID; // trying set ID here
var fileName = $(this).attr('id');
$("#myAction").load('/ajax/actions/' + fileName + '.php?folder_id=' + folderID);
})
So, this loads /ajax/actions/newFile.php
In the middle is a page loaded using jquery .load(). Within the page in the middle is a series of folders which have an ID. On click, these folders display their contents are shown on the right of the page.
e.g.
<span id="12" class="folder active99">Music</span>
$('.folder').click(function() {
var folderID = $(this).attr('id');
$("#myAction").load('/ajax/actions/links.php?folder_id=' + folderID);
})
When clicked shows contents on the right. Note variable folderID. This all works ok.
What I would like to happen is when a folder is selected in the middle, it changes the folderID variable on the left hand menu so when a new action is chosen it corresponds to the folder its supposed to.
I've tried setting the variable everywhere i.e. in all sections var folderID; but whatever I try doesn't carry the variable around.
Is this possible or is there a better way to do this? Am I going about it wrongly?
To summarize: When I click a folder in the middle I need it to add the variable to the left menu.
UPDATE
This is code I currently use:
$(document).ready(function(){
var folderID = '';
$('.actionLink').click(function() {
var fileName = $(this).attr('id');
$("#myAction").load('/ajax/actions/' + fileName + '.php?folder_id=' + folderID);
});
$('.folder').click(function() {
$('.folder').removeClass('active99'); // remove from all other <SPAN>s
$(this).addClass('active99'); // add onto current
var folderID = $(this).attr('id');
$("#myAction").load('/ajax/actions/links.php?folder_id=' + folderID);
});
});
I've now changed things slightly so middle section is actually included as opposed to using .load() but still not working
You're dealing with a variable scope issue, you must declare the folderID variable outside (at a greater scope) so it's available for both actions:
$(document).ready(function(){
var folderID = '';
$('.actionLink').click(function() {
var fileName = $(this).attr('id');
$("#myAction").load('/ajax/actions/' + fileName + '.php?folder_id=' + folderID);
});
$('.folder').click(function() {
folderID = $(this).attr('id');
$("#myAction").load('/ajax/actions/links.php?folder_id=' + folderID);
});
});
i'm trying to make a live search for my mobile website, I don't want to query the database every time a user type a letter so I created a ordered list with all the names that can be searched for and i'm looping through it with jquery, problem is that I have 3300 names and it's freezing the browser when it searches through them, can anyone give me a tip about better ways to do it? here is my code:
$(document).ready(function(){
$("input#search").keyup(function(){
var filter = $(this).val(), count = 0;
var html = "";
$("ol.pacientes li").each(function(){
var nome_paciente = $(this).text();
if(nome_paciente.indexOf(filter.toUpperCase()) != -1){
html = html + " " + nome_paciente;
}
$('#pacientes_hint').html(html);
});
Use the jQuery autocomplete version. You can load an array with all your names and pass it in to autocomplete, which will work on the fly.
http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/
You could change your each to:
var text = $("ol.pacientes li:contains(\""+filter.toUpperCase()+"\")").map(function() {
return $(this).text();
}).join(' ');
$('#pacientes_hint').text(text);
Besides being shorter, the only improvement will be setting the contents of $('#pacientes_hint') only at the end, which could help.
Let me know if you need a more creative solution.
First of all, you could move #pacientes_hint outside the each function.
$(document).ready(function(){
$("input#search").keyup(function(){
var filter = $(this).val(), count = 0;
var html = "";
$("ol.pacientes li").each(function(){
var nome_paciente = $(this).text();
if(nome_paciente.indexOf(filter.toUpperCase()) != -1){
html = html + " " + nome_paciente;
} // end if
}); // end each
$('#pacientes_hint').html(html);
Then, you can define ol.pacientes as a variable before the keyup handler, so it doesn't look for it everytime and in the each function, search inside the variable:
$(document).ready(function(){
var pacientes_list = $("ol.pacientes");
var pacientes_hint = $("#pacientes_hint");
$("input#search").keyup(function(){
...
$("li", $(pacientes_list)).each(function(){ // search in the container
...
}); // end each
$(pacientes_hint).html(html);
Using a sidebar, I get user input and save it as a script property. Next time the sidebar is loaded, I'd like to check if the saved property exists. If so, display it instead of the text entry box.
I know to use:
google.script.run.withSuccessHandler().myFunction()
Honestly, I have tried so many different things at this point. Any help would be greatly appreciated.
This is what I have tried, I want to load values in the sidebar if they exist. If they do not I want it load a text entry box, that is what it does by default.
Edit - Adding Code
function loadSidebarValues() {
if (dateText != 'ErrorStuff') {
var div = document.getElementById('dateValue');
div.innerHTML = dateText;
var errorDiv = document.getElementById('error');
errorDiv.innerHTML = "";
$('#dateText').val(
PropertiesService.getScriptProperties().getProperty('dateColumn')
);
} else {
var div = document.getElementById('sidebarValues');
div.innerHTML = "";
var errorDiv = document.getElementById('error');
errorDiv.innerHTML = 'There was an error.';
}
var scriptProperties = PropertiesService.getScriptProperties();
scriptProperties.setProperties({
'dateColumn': 'dateText',
});
Logger.log("date: " + userProperties.getProperty('dateColumn'));
}
function onLoad(){
if (PropertiesService.getScriptProperties().getProperty('dateColumn') != null) {
loadSidebarValues();
};
}
You can write server code to retrieve UserProperties value, then run the HTML script to get that value as instructed in File-open dialogs
section in this guide
What they do:
getOAuthToken in Code.gs
Call that function in Picker.html by this code:
function getOAuthToken() {
google.script.run.withSuccessHandler(createPicker)
.withFailureHandler(showError).getOAuthToken();
}
createPicker method from withSuccessHandler take token value from getOAuthToken in first step.
You can use the same pattern for your own case.