Last active
April 9, 2024 20:09
-
-
Save bng44270/65922f5f8c21defb4acb89c0fe260034 to your computer and use it in GitHub Desktop.
Create a local-storage browser-based notepad
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
WebNotepad - create a local-storage browser-based notepad app | |
Usage: | |
1) Include webnotepad.js | |
2) Create DIV element | |
<div id="webnote"></div> | |
3) Instantiate the WebNotepad using the DOM ID of the DIV | |
var editor = new WebNotepad('webnote'); | |
OR | |
Custom configuration values can be supplied for HTML elements | |
var editor = new WebNotepad('webnote',{ | |
selectorId : 'selectNoteHere', | |
editorId : 'editNoteHere' | |
}); | |
*/ | |
class WebNotepad { | |
constructor(id,customConfig) { | |
if (!localStorage.webnotepad_content) { | |
localStorage.webnotepad_content = '[]'; | |
} | |
this.config = { | |
//Element containing application | |
parentId : id, | |
//Element containing note selector | |
selectorId : 'selector', | |
//Element containing note editor | |
editorId : 'editor', | |
//Create note button | |
createNoteId : 'createnote', | |
//Label for new note field | |
newNoteDisplayId : 'newnotedisplay', | |
//New note input box | |
newNoteNameId : 'newnotename', | |
//Download all notes button | |
downloadAllId : 'downloadall', | |
//Select box for existing notes | |
noteListId : 'notelist', | |
//Increase font size button | |
fontBigId : 'fontbig', | |
//Decrease font size button | |
fontSmallId : 'fontsmall', | |
//Save note button | |
saveNoteId : 'savenote', | |
//Download note button | |
downloadNoteId : 'dlnote', | |
//Close note button | |
closeNoteId : 'closenote', | |
//Delete note button | |
deleteNoteId : 'deletenote', | |
//Note name field | |
noteNameId : 'notename', | |
//Note content text area | |
noteTextBoxId : 'notepadcontent', | |
//Note status bar | |
notepadStatusId : 'notepadstatusbar', | |
//Function runs when application loads | |
onload : function(notepad) { }, | |
//Function runs when a note is saved | |
onsave : function(notepad) { }, | |
notes : JSON.parse(localStorage.webnotepad_content), | |
noteExists : false, | |
activeNote : null | |
}; | |
if (customConfig) { | |
Object.keys(customConfig).forEach(cfg => { | |
this.config[cfg] = customConfig[cfg]; | |
}); | |
} | |
this.interfaceInit(); | |
this.populateNoteList(); | |
} | |
interfaceInit() { | |
var htmlContent = '<div id="' + this.config.selectorId + '" style="display:block;">'; | |
htmlContent += '<select id="' + this.config.noteListId + '"></select><br/>'; | |
htmlContent += '<span id="' + this.config.newNoteDisplayId + '" style="display:none">Note Name:<input type="text" id="' + this.config.newNoteNameId + '" /><input type="button" value="Create" id="' + this.config.createNoteId + '" /></span><br/>'; | |
htmlContent += '<input type="button" value="Download All" id="' + this.config.downloadAllId + '" />' | |
htmlContent += '</div>'; | |
htmlContent += '<div id="' + this.config.editorId + '" style="display:none;">'; | |
htmlContent += '<span style="font-weight:bold;" id="' + this.config.noteNameId + '"></span> '; | |
htmlContent += 'Font size: <input type="button" value="+" id="' + this.config.fontBigId + '" /><input type="button" value="-" id="' + this.config.fontSmallId + '" /> '; | |
htmlContent += '<input type="button" value="Save" id="' + this.config.saveNoteId + '" /> '; | |
htmlContent += '<input type="button" value="Download" id="' + this.config.downloadNoteId + '" /> '; | |
htmlContent += '<input type="button" value="Close" id="' + this.config.closeNoteId + '" /> '; | |
htmlContent += '<input type="button" value="Delete" style="color:#ffffff;background-color:#ff0000;" id="' + this.config.deleteNoteId + '" /><br/>'; | |
htmlContent += '<textarea style="width: 100%; height: 90%; box-sizing: border-box; font-family:courier;" id="' + this.config.noteTextBoxId + '"></textarea><br/>'; | |
htmlContent += '</div>'; | |
htmlContent += '<span id="' + this.config.notepadStatusId + '" style="color:#ff0000;"></span>'; | |
document.getElementById(this.config.parentId).innerHTML = htmlContent; | |
document.getElementById(this.config.noteListId).addEventListener('change',this.changeNoteOption.bind(this),false); | |
document.getElementById(this.config.newNoteNameId).addEventListener('keyup',this.checkName.bind(this),false); | |
document.getElementById(this.config.createNoteId).addEventListener('click',this.createNote.bind(this),false); | |
document.getElementById(this.config.downloadAllId).addEventListener('click',this.downloadAll.bind(this),false); | |
document.getElementById(this.config.fontBigId).addEventListener('click',this.fontBigger.bind(this),false); | |
document.getElementById(this.config.fontSmallId).addEventListener('click',this.fontSmaller.bind(this),false); | |
document.getElementById(this.config.saveNoteId).addEventListener('click',this.saveNote.bind(this),false); | |
document.getElementById(this.config.downloadNoteId).addEventListener('click',this.downloadNote.bind(this),false); | |
document.getElementById(this.config.closeNoteId).addEventListener('click',this.closeNote.bind(this),false); | |
document.getElementById(this.config.deleteNoteId).addEventListener('click',this.deleteNote.bind(this),false); | |
document.getElementById(this.config.noteTextBoxId).addEventListener('keyup',this.markAsEdited.bind(this),false); | |
this.config.onload(this); | |
} | |
changeNoteOption() { | |
var noteSelection = document.getElementById(this.config.noteListId).options[document.getElementById(this.config.noteListId).selectedIndex].value; | |
if (noteSelection != 'NONE') { | |
if (noteSelection == 'CREATENEW') { | |
document.getElementById(this.config.newNoteDisplayId).style.display = 'block'; | |
} | |
else { | |
document.getElementById(this.config.newNoteDisplayId).style.display = 'none'; | |
this.openNote(); | |
} | |
} | |
else { | |
document.getElementById(this.config.newNoteDisplayId).style.display = 'none'; | |
} | |
} | |
populateNoteList() { | |
document.getElementById(this.config.noteListId).innerHTML = '<option value="NONE">--Select Note--</option><option value="CREATENEW">--Create New Note--</option>'; | |
this.config.notes.forEach(n => { | |
var o = document.createElement('option'); | |
o.value = n.shortName; | |
o.innerHTML = n.name; | |
document.getElementById(this.config.noteListId).appendChild(o); | |
}); | |
} | |
checkName() { | |
var noteName = document.getElementById(this.config.newNoteNameId).value; | |
var noteShortName = noteName.replace(/[ \t]+/g,'_').toLowerCase(); | |
var noteExists = (this.config.notes.filter(n => n.shortName == noteShortName).length > 0) ? true : false; | |
if (noteExists) { | |
this.setStatusUI('Note already exists'); | |
this.config.noteExists = true; | |
} | |
else { | |
this.setStatusUI(''); | |
this.config.noteExists = false; | |
} | |
} | |
createNote() { | |
if (!this.config.noteExists) { | |
var noteName = document.getElementById(this.config.newNoteNameId).value; | |
document.getElementById(this.config.newNoteNameId).value = ''; | |
var noteShortName = noteName.replace(/[ \t]+/g,'_').toLowerCase(); | |
this.config.notes.push({ | |
name : noteName, | |
shortName : noteShortName, | |
note : '', | |
fontSize : '12pt' | |
}); | |
localStorage.webnotepad_content = JSON.stringify(this.config.notes); | |
document.getElementById(this.config.newNoteDisplayId).style.display = 'none'; | |
this.populateNoteList(); | |
this.openNote(noteShortName); | |
} | |
} | |
openNote(notename) { | |
document.getElementById(this.config.selectorId).style.display = 'none'; | |
document.getElementById(this.config.editorId).style.display = 'block'; | |
var noteShortName = ''; | |
if (notename) { | |
noteShortName = notename; | |
} | |
else { | |
var selectBox = document.getElementById(this.config.noteListId).options[document.getElementById(this.config.noteListId).selectedIndex].value; | |
noteShortName = selectBox.replace(/[ \t]+/g,'_').toLowerCase(); | |
document.getElementById(this.config.noteListId).value = 'NONE'; | |
} | |
this.config.activeNote = this.config.notes.filter(n => n.shortName == noteShortName)[0]; | |
this.config.activeNote.saved = true; | |
this.setNoteTextUI(this.config.activeNote.note); | |
this.setFontSizeUI(this.config.activeNote.fontSize); | |
this.setNoteNameUI(this.config.activeNote.name); | |
} | |
setNoteNameUI(name) { | |
document.getElementById(this.config.noteNameId).innerHTML = name; | |
} | |
setNoteTextUI(text) { | |
document.getElementById(this.config.noteTextBoxId).value = text; | |
} | |
setStatusUI(text) { | |
document.getElementById(this.config.notepadStatusId).innerHTML = text; | |
} | |
setFontSizeUI(size) { | |
document.getElementById(this.config.noteTextBoxId).style.fontSize = size; | |
} | |
fontBigger() { | |
var newFont = (parseInt(this.config.activeNote.fontSize.replace(/pt$/,'')) + 1).toString() + 'pt'; | |
this.config.activeNote.fontSize = newFont; | |
document.getElementById(this.config.noteTextBoxId).style.fontSize = newFont; | |
this.markAsEdited(); | |
} | |
fontSmaller() { | |
var newFont = (parseInt(this.config.activeNote.fontSize.replace(/pt$/,'')) - 1).toString() + 'pt'; | |
this.config.activeNote.fontSize = newFont; | |
document.getElementById(this.config.noteTextBoxId).style.fontSize = newFont; | |
this.markAsEdited(); | |
} | |
saveNote() { | |
this.config.notes = this.config.notes.filter(n => n.shortName != this.config.activeNote.shortName); | |
var noteText = document.getElementById(this.config.noteTextBoxId).value; | |
this.config.notes.push({ | |
name : this.config.activeNote.name, | |
shortName : this.config.activeNote.shortName, | |
note : noteText, | |
fontSize : this.config.activeNote.fontSize | |
}); | |
this.setStatusUI(''); | |
this.config.activeNote.saved = true; | |
localStorage.webnotepad_content = JSON.stringify(this.config.notes); | |
this.config.onsave(this); | |
} | |
closeNote() { | |
var doClose = true; | |
if (!this.config.activeNote.saved) { | |
doClose = confirm('Note ' + this.config.activeNote.shortName + ' is not saved. Continue\?'); | |
} | |
if (doClose) { | |
document.getElementById(this.config.selectorId).style.display = 'block'; | |
document.getElementById(this.config.editorId).style.display = 'none'; | |
this.setStatusUI(''); | |
this.config.activeNote = null; | |
} | |
} | |
deleteNote() { | |
var doDelete = confirm('Note ' + this.config.activeNote.shortName + ' is about to be deleted. Continue\?'); | |
if (doDelete) { | |
this.config.notes = this.config.notes.filter(n => n.shortName != this.config.activeNote.shortName); | |
localStorage.webnotepad_content = JSON.stringify(this.config.notes); | |
this.populateNoteList(); | |
document.getElementById(this.config.selectorId).style.display = 'block'; | |
document.getElementById(this.config.editorId).style.display = 'none'; | |
this.setStatusUI(''); | |
this.config.activeNote = null; | |
} | |
} | |
markAsEdited() { | |
if (document.getElementById(this.config.notepadStatusId).innerHTML.length == 0) { | |
document.getElementById(this.config.notepadStatusId).innerHTML = 'Modified'; | |
this.config.activeNote.saved = false; | |
} | |
} | |
downloadAll() { | |
var textToWrite = JSON.stringify(this.config.notes); | |
var textFileAsBlob = new Blob([textToWrite], { type: 'application/json' }); | |
var fileNameToSaveAs = 'all_notes-' + new Date().toISOString().replace(/:/g,".") + ".json"; | |
var downloadLink = document.createElement("a"); | |
downloadLink.download = fileNameToSaveAs; | |
downloadLink.innerHTML = "My Hidden Link"; | |
window.URL = window.URL || window.webkitURL; | |
downloadLink.href = window.URL.createObjectURL(textFileAsBlob); | |
downloadLink.onclick = function(e) { | |
document.body.removeChild(e.target); | |
}; | |
downloadLink.style.display = "none"; | |
document.body.appendChild(downloadLink); | |
downloadLink.click(); | |
} | |
downloadNote() { | |
var doDownload = true; | |
if (!this.config.activeNote.saved) { | |
doDownload = confirm('Note ' + this.config.activeNote.shortName + ' is not saved. Download saved version\?'); | |
} | |
if (doDownload) { | |
var textToWrite = this.config.activeNote.note; | |
var textFileAsBlob = new Blob([textToWrite], { type: 'text/plain' }); | |
var fileNameToSaveAs = this.config.activeNote.shortName + '-' + new Date().toISOString().replace(/:/g,".") + ".txt"; | |
var downloadLink = document.createElement("a"); | |
downloadLink.download = fileNameToSaveAs; | |
downloadLink.innerHTML = "My Hidden Link"; | |
window.URL = window.URL || window.webkitURL; | |
downloadLink.href = window.URL.createObjectURL(textFileAsBlob); | |
downloadLink.onclick = function(e) { | |
document.body.removeChild(e.target); | |
}; | |
downloadLink.style.display = "none"; | |
document.body.appendChild(downloadLink); | |
downloadLink.click(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment