How would one set the initial value of an editable div? - javascript

So, I've got a notepad extension for Google Chrome that syncs and displays stored notes from a user. Currently my problem is as follows.
When the extension is run for the first time after download, the word 'undefined' is displayed in the editable div (id = edit_notepad). I want it to just be blank instead of displaying anything. Obviously, I know its undefined because the user hasn't been able to add any text yet.
Picture of what's displayed on initial run:
From my content script, here are my chrome.storage get and set functions (which do work):
document.body.onload = function() {
chrome.storage.sync.get("edit_notepad", function(items) {
if (!chrome.runtime.error) {
console.log(items);
document.getElementById("edit_notepad").innerHTML = items.edit_notepad;
}
});
}
document.getElementById("edit_notepad").onkeyup = function() {
var d = document.getElementById("edit_notepad").innerHTML;
chrome.storage.sync.set({ "edit_notepad" : d }, function() {
if (chrome.runtime.error) {
console.log("Runtime error.");
}
});
}
I presume I'm going to need some sort of if statement, but after hours of playing around, I'm lost as to what exactly it'd contain. The issue I've kept running into is that whatever I set the initial value of edit_notepad to, it always reverts back to "undefined" even when a user has written some notes! e.g. "This is a notes test" would revert back to "undefined" when the notepad is closed and reopened.

Well, an easy way to do this would be to specify a default value in your chrome.storage.sync.get(). Doing so would apply the default value when the key does not exist in the storage. However, given that you are replacing any contents which might already exist, the better solution would be not to set the contents when you have no value, or an invalid value, stored. The only valid value will be a string. This will prevent you from overwriting any default value supplied by the webpage when you have no value stored. Thus, an if statement something like the following should work (alternately, you could test for !== 'undefined':
document.body.onload = function() {
chrome.storage.sync.get("edit_notepad", function(items) {
if (!chrome.runtime.error) {
console.log(items);
if(typeof items.edit_notepad === 'string') {
document.getElementById("edit_notepad").innerHTML = items.edit_notepad;
}
}
});
}
Note: Storing the contents of the editable <div> on every key will result in many users running into both the MAX_WRITE_OPERATIONS_PER_MINUTE and MAX_WRITE_OPERATIONS_PER_HOUR quotas. You will need to have some other criteria for writing to storage.sync. Perhaps you could temporarily store the value in storage.local and only to storage.sync every couple of minutes.

Related

How to make a Global Variable with User Input?

I am making a program where I have a user input where the user types in their cat's name, and then I want the name to appear in the text throughout the program. Here is my code, it is in Javascript:
var catName = getText("nameInput");
onEvent("startBtn", "click", function(event) {
setScreen("feedingScreen");
setText("feedingText", catName+" is hungry! Give "+catName+" some food!
Click fish to feed.");
});
Whwn I run this program, however, the cat name does not appear in the text. How can I make it where the text does show up?
If the catName variable is going to be used for a long time, I'd consider using localStorage to store it and retrieve it whenever I want (even when the user leaves the page and comes back).
Example :
function setCatName(name) {
window.localStorage.setItem('catName', name);
}
function getCatName() {
return window.localStorage.getItem('catName');
}
If you don't want that though, you could store it in the window object. Take note that it's considered bad practice (but so are global variables in general).
Example :
function setCatName(name) {
window.catName = name;
}
function getCatName() {
return window.catName;
}
UPDATE :
It's funny because the examples on Mozilla's Docs use localStorage to set and retrieve a cat's name too :
localStorage documentation

SessionStorage Navigation

Greets, so I I'm trying to learn jquery/javascript storage and ran into an issue where I am building a navigation that should remember and place you where you last were if you refresh the page (that's why i use sessionStorage rather then localStorage).
But I can't seem to change the sessionStorage variable to the new location, nor figure out a functional way to get the user back on refreshing the page.
This is what I currently have.
$(function() {
sessionStorage.setItem('position', '.first');
var location = sessionStorage.getItem('position');
$('li', this).click(function() {
cls = $(this).text();
if('.' + cls != location) {
$(location).slideToggle(400);
$('.' + cls).delay(400).slideToggle(400);
sessionStorage.setItem('position', '.' + cls)
console.log(location)
};
});
});
https://jsfiddle.net/Unkn0wn96/ndj9sqpe/
The code works in an very odd way, rather then how it's intended, including never changing the value when I console.log(location).
I made some further testing on this and found a 'more' working way in the was that the sessionStorage does change to something, yet it not being usefull.
https://jsfiddle.net/Unkn0wn96/nkbtykkr/
but yet, they elements don't toggle as they should, including that when I console log sessionStorage.position it returns NaN. Also for some odd reason I can't store sessionStorage.position within a variable, it just refuses to change its value. I have no clue why this is happening.
So I was finally able to solve my issue with sessionStorage, since there was not much of help I'd assume the information regarding the case was limited and so wish to share my solution. All thought it does not work fully as intended it does execute it's main function.
$(function() {
$('button').on('click', function() {
var msg = '.'+$(this).text();
localStorage.setItem('color', 'blue') //Default (does not matter since the if statement does not register)
if(msg != '.' + localStorage.color) { // DOES NOT REGISTER
if(localStorage.length > 0) {
localStorage.removeItem('color')
console.log('localStorage.length : ' + localStorage.length)
};
localStorage.setItem('color', msg)
console.log(localStorage.color)
} else {
console.log('cancelled')
}
});
});
https://jsfiddle.net/mdqjoz69/4/
So what I finally was able to achieve was to make a localStorage key change it's value regarding of what button you press.
What I failed to achieve was being able to check the stored data to not execute whenever you store something that have already been stored. There might be a work around for this. But since the code serves its main purpose I'll let it slide.

Can't overwrite object saved with rhaboo in javascript

I'm trying to save an object with rhaboo in javascript. The first time after initialising it is working but when I'm trying to save it again it gives me the
rhaboo.min.js:1 Uncaught TypeError: Cannot read property 'refs' of undefined error. I pinned down the error to the line where I save the keyArray with notes.write('presentationNotes', keyArray);
How I get the error in detail:
I open my webapplication with a clean localStorage (nothing is saved) and rhaboo gets initialised. After that I navigate to a document and open the notes-div with the notes-button. I write something in the notes-area and hit the notes-submit button to save the notes with rhaboo to localStorage. I do the same for a second document. For now everything works. Both notes get saved correctly so that I have an object like this:
keyArray = {activeDoc1: ['note1', 'note2'], activeDoc2: ['note1', 'note2']}
saved in rhaboo in notes.presentationNotes. Then I reload my webapplication and rhaboo is already initialised. I navigate to the documents as before and check if I can load the saved notes. This works as expected but when I try to hit the notes-submit button again it gives me the aforementioned error. What am I doing wrong?
var notes = Rhaboo.persistent('Presentation Notes');
$(document).ready(function(event) {
var keyArray, activeDoc;
if (!notes.initialised) {
notes.write('initialised', true);
notes.write('presentationNotes', {});
console.log('Rhaboo Initialised');
keyArray = {};
} else {
console.log('Rhaboo already initialised');
keyArray = notes.presentationNotes;
console.log('notes.presentationNotes onLoad = ');
console.log(notes.presentationNotes);
}
//Notes open
$(document).on('click', '#notes-button', function() {
$('.notes-div').show();
activeDoc = $('.node.active').attr('id');
if (notes.presentationNotes[activeDoc] != null) {
//Iterate notes
$.each(notes.presentationNotes[activeDoc], function(index, value) {
$('#notes-area').append(value + '\n');
});
}
});
//Notes save
$(document).on('click', '#notes-submit', function() {
$('.notes-div').hide();
var str = $('#notes-area').val();
var array = str.split("\n");
keyArray[activeDoc] = array;
//Save notes
notes.write('presentationNotes', keyArray);
//Clear textarea
$('#notes-area').val('');
});
}
Without the HTML I haven't been able to try this, so I'm just guessing here, but I suspect your problem will go away if you stop using keyArray and activeDoc. The whole point of rhaboo is that it is not a place to store your data. It IS your data.
I see no transient data in your program, i.e., no data which you actively want to delete when the user goes away and comes back. All the data is supposed to be persistent, therefore it should all be under the Rhaboo.persistent.
That's the philosophy, but to be more specific, I think your problem is here:
keyArray[activeDoc] = array;
When I wonder what keyArray is is find:
keyArray = notes.presentationNotes;
so the earlier line actually says:
notes.presentationNotes[activeDoc] = array;
but it says on the tin that that should read:
notes.presentationNotes.write(activeDoc, array);
The upshot is that that the hooks that make rhaboo work have not been inserted into array, as notes.presentationNotes.write would have done.
When you next said:
notes.write('presentationNotes', keyArray);
it meant:
notes.write('presentationNotes', notes.presentationNotes).
which is clearly not what you meant. Rhaboo doesn't suspect that array has no hooks yet because it can see that notes.presentationNotes does have hooks.
I also forget to use write sometimes, and it really bugs me that JS offers no way to hook into the creation of a NEW key within an object X, no matter what you've done to X. Without that limitation, there'd be no need for write and it could be foolproof.

Why does setting variables from page items break my Web worker?

I have a web worker that runs fine, until I try and set one of the parameters I'm passing to it. The code is:
//global variables
var xRange = [-2.5, 1];
function startWorker() {
if(typeof(Worker) !== "undefined") {
if(typeof(w) == "undefined") {
//xRange[0] = document.getElementById("xRange0").value;
//xRange[1] = document.getElementById("xRange1").value;
w = new Worker("myWorker.js");
w.postMessage({ "args": [xRange[0], xRange[1]] });
}
w.onmessage = function(event) {
//Do something.
};
} else {
//no ww support
}
}
If I un-comment the xRange[1] variable, the application runs as expected. However, if I un-comment the xRange[0] variable, the application does not produce expected results.
I checked that the items on the HTML page have the correct ID's.
I used alert(xRange[0]); after setting the array, and it confirmed that the value is whatever is inputted into the HTML page item.
I'm at a complete loss as to why one of these lines works, and the other does not.
Here's a fiddle with my source, so you can verify the item ID's are correct: http://jsfiddle.net/cxhrbf10/
One other thing that I've noticed, is that if I try to set more variables from page items in this location, the generation of the image goes from about 200ms to about 800ms. Just wondering why there was such a big performance hit just for accessing page item values.
Thanks!

Determine if the content in a (dojo) dijit.Editor is different from the initial value

I have a form containing many dijit.form elements and also a dijit.Editor. The form is initially filled with data that I get from the server. The user can change the content and then submit this back to the serer. A classic use case.
When the user submits the form I need to only send the changed data. The problem with the dijit.Editor is that it sometimes changes the initial content even if the user did not make any changes. For example:
The initial content entered in the dijit.editor is this:
"Gesegmenteerde rand, 115 mm~Max 13280 U/min, 80 m/sec</br>~Drooggebruik"
And when retrieving the content like this editorObj.get('value'); it returns this:
"Gesegmenteerde rand, 115 mm~Max 13280 U/min, 80 m/sec<br />~Drooggebruik"
As you can see the </br> is changed to <br />. I know the original value is wrong, but that's because the source sucks and that is out of my control.
So my question is: is there an easy way to check if the content has indeed been changed by the user instead of just by dijit.Editor itself.
Something like this (on the editor markup) works:
onkeypress="MyObject.setDirty(true);"
And just keep track of it on MyObject.isDirty.
This does have the drawback that if the user types into the editor and then modifies everything to be exactly as it was originally, the value will be wrong (ie, true, whereas content is back to original), but it is sufficient for most purposes.
Well if you just want to check IF the user modified something you could try that :
var editorIsDirty = false;
var someConnect = dojo.connect(myEditor, "onChange", this, function(newValue){
if(originalSource != newValue){
editorIsDirty = true;
return;
}
editorIsDirty = false;
});
something like that, you get the idea ;)
What I ended up doing is was adding two extra attributes to the Editor:
dijitObj.set('originalValue', value);
dijitObj.set('value', value);
dijitObj.set('uneditedValue', dijitObj.get('value'));
In the read out of the value of the the editor I use these to determine if something changed at all:
var value = dijitObj.get('value');
if (dijitObj.get('uneditedValue') === value) {
// The value hasn't changed, so we send the original value
value = dijitObj.get('originalValue');
}

Categories