Save change in custom list display using local storage - javascript

I am trying to create a customizable list with links that can be hidden using a class if you click in a button. Also the list have a sortable option that you can move the links on the list, which saves to localstorage.
The problem is that I don't know how to save the class change with the list order in the localstorage if you click the "add/remove" button on each li.
Also, if anyone can help me improve the code I will be grateful, I am a newbie with localstorage and only managed this with a lot of reading in tutorials and documentation.
Here's a working example:
http://codepen.io/RogerHN/pen/EgbOzB
var list = document.getElementById('linklist');
var items = list.children;
var itemsArr = [];
for (var i in items) {
itemsArr.push(items[i]);
}
// localStorage
var ls = JSON.parse(localStorage.getItem('userlist') || '[]');
for (var j = 0; j < ls.length; j++) {
for (i = 0; i < itemsArr.length; ++i) {
if(itemsArr[i].dataset !== undefined){
if (ls[j] === itemsArr[i].dataset.id) {
list.appendChild(itemsArr[i]);
}
}
}
}
$('.list-block.sortable').on('sort', function () {
var newIdsOrder = [];
$(this).find('li').each(function(){
newIdsOrder.push($(this).attr('data-id'));
});
// store in localStorage
localStorage.setItem('userlist', JSON.stringify(newIdsOrder));
});

You want something like this:
var myApp = new Framework7({
swipePanel: 'left'
});
// Export selectors engine
var $$ = Dom7;
var mainView = myApp.addView('.view-main');
var list = document.getElementById('linklist');
var items = list.children;
var itemsArr = [];
for (var i in items) {
itemsArr.push(items[i]);
}
// localStorage
var ls = JSON.parse(localStorage.getItem('userlist') || '[]');
var classes = JSON.parse(localStorage.getItem('classes') || '["","","","","","","","","",""]');
for (var j = 0; j < ls.length; j++) {
for (i = 0; i < itemsArr.length; ++i) {
if(itemsArr[i].dataset !== undefined){
if (ls[j] === itemsArr[i].dataset.id) {
itemsArr[i].className = classes[i];
list.appendChild(itemsArr[i]);
// handle [add/remove] thing
if (classes[i] != "") {
$(itemsArr[i]).find(".checky").removeClass("selected");
}
}
}
}
}
$('.list-block.sortable').on('sort', saveInfo);
$(".restore").click(function(e) {
$(".confirm").show();
$(".shadow").show();
});
$(".no,.shadow").click(function(e) {
$(".confirm").hide();
$(".shadow").hide();
});
$(".yes").click(function(e) {
$(".confirm").hide();
});
$(".lbl").click(function(e) {
$(".toggle-text").toggleClass("blue");
$(".restore").toggle();
$(".checky").toggle();
$("li.hidden").toggleClass("visible");
});
$('.checky').click(function() {
if (!$(this).hasClass("selected")) {
$(this).parent().removeClass("hidden").addClass("visible");
}
else {
$(this).parent().addClass("hidden visible");
}
$(this).toggleClass("selected");
saveInfo();
});
function saveInfo() {
var newUserList = [];
var newClassList = [];
$("#linklist").find('li').each(
function() {
newUserList.push($(this).attr('data-id'));
if ($(this).hasClass("hidden")) {
newClassList.push("hidden");
}
else {
newClassList.push("");
}
});
// store in localStorage
localStorage.setItem('userlist', JSON.stringify(newUserList));
localStorage.setItem('classes', JSON.stringify(newClassList));
console.log("saved.");
}
function reset() {
console.log("Removing data from local storage.");
localStorage.setItem('userlist', '["1","2","3","4","5","6","7","8","9","10"]');
localStorage.setItem('classes', '["","","","","","","","","",""]');
window.location.reload(true);
};
Codepen
Technically, I should've added explanation...

Related

pdfjs: Fill out a form and get the fieldValues

I'm using pdfjs to display a PDF form (acroforms example). If I fill in some fields, how do I get those annotations.
I've tried:
pdfPage.getAnnotations().then(function(a) {
for(var i = 0;i < a.length; i++) {
console.log(a[i].id + ' - ' + a[i].fieldValue);
}
});
But all I get are empty fieldValues. I guess I'm getting them from the original PDF. How do I access the live document which includes the new annotations?
async getAnnotations() {
var result = {};
var pages = PDFViewerApplication.pdfDocument.numPages;
for (var i = 1; i <= pages; i++) {
var page = await PDFViewerApplication.pdfDocument.getPage(i);
var annotations = await page.getAnnotations();
for (var j = 0; j < annotations.length; j++) {
var element = annotations[j];
// Field Name
if (result[element.fieldName] == null) {
result[element.fieldName] = null;
}
var val = PDFViewerApplication.pdfDocument.annotationStorage.getOrCreateValue(element.id);
if (element.radioButton) {
if (val.value) {
result[element.fieldName] = element.buttonValue;
}
} else if (element.checkBox) {
result[element.fieldName] = val.value ? "On" : "Off";
} else {
result[element.fieldName] = val.value;
}
}
};
return result;
}
You should save values written by user in a local variable
Then you should create a xfdf file ( xml file by Adobe ) , look for Example nere : https://developer.salesforce.com/page/Adobe_XFDF . The xfdf should then be merged with original pdf to produce a new compiled pdf

Javascript Works on Desktop but only Partially Works on Mobile

The following is the full JavaScript code for a quiz. It works perfectly on desktop browsers. However, when I went to test it on my phone, it doesn't work.
Mobile loads the JSON quiz, but after all the answers are selected, it does not freeze all the selected answers and display the results. Instead, nothing happens, no result is shown/calculated, and the user can continue to select answers.
I'm not experienced with JavaScript on Mobile and don't know what is causing the problem.
I've deleted a few parts of the code that simply appended html in order to cut down on size.
You can view it here: plnkr.co/edit/tkCQVxoIq9oOiApeUY66?p=preview
// Adds the functionality to check if an element has a class
HTMLElement.prototype.hasClass = function (className) {
"use strict";
if (this.classList) {
return this.classList.contains(className);
}
return (-1 < this.className.indexOf(className));
};
// Adds the ability to remove classes from elements
HTMLElement.prototype.removeClass = function (className) {
"use strict";
if (this.classList) {
this.classList.remove(className);
}
return this;
};
var BF_QUIZ = {};
BF_QUIZ.quiz = function () {
"use strict";
// Sets variables
var highest_score, quiz_div, quiz_title, quiz_image, questions = [],
results = [], inputs = [], answers = [], userAnswers = [],
// Gets the Quiz "canvas"
getQuizCanvas = function getQuizCanvas() {
quiz_div = document.getElementById("bf-quiz");
},
// Parses the JSON data passed from the Loader
getJSONData = function getJSONData(json_data) {
//Main Quiz Title
quiz_title = json_data[0].quiz_title;
//Main Quiz Image
quiz_image = json_data[0].quiz_image;
//Populates questions arrary with questions from JSON file
for (var i = 0; i < json_data[0].quiz_questions.length; i++) {
questions.push(json_data[0].quiz_questions[i]);
}
//Populates results array with results from JSON file
for (var j = 0; j < json_data[0].quiz_results.length; j++) {
results.push(json_data[0].quiz_results[j]);
}
},
// Writes the Quiz into the document
writeQuiz = function writeQuiz() {
var newQuizWrapper, newTitle, newQuestionTextWrapper, newQuestionText,
newAnswerForm, newAnswer, newAnswerImage, newAnswerTextWrapper, newAnswerInput,
newAnswerText, newQuestion;
newQuizWrapper = document.createElement("div");
newQuizWrapper.className = "quiz-wrapper";
newTitle = document.createElement("h1");
newTitle.innerHTML = quiz_title;
newQuizWrapper.appendChild(newTitle);
for (var i = 0; i < questions.length; i++) {
newQuestionTextWrapper = document.createElement("div");
newQuestionTextWrapper.className = "quiz-question-text-wrapper";
newQuestionText = document.createElement("h2");
newQuestionText.innerHTML = questions[i].question.text;
newQuestionTextWrapper.appendChild(newQuestionText);
newAnswerForm = document.createElement("form");
for (var j = 0; j < questions[i].question.question_answers.length; j++) {
newAnswer = document.createElement("div");
newAnswer.className = "quiz-answer";
newAnswer.setAttribute("data-quizValue",
questions[i].question.question_answers[j].answer.value);
if (questions[i].question.question_answers[j].answer.image) {
newAnswerImage = document.createElement("img");
newAnswerImage.src = questions[i].question.question_answers[j].answer.image;
newAnswer.appendChild(newAnswerImage);
}
else{
//no image
}
newAnswerTextWrapper = document.createElement("div");
newAnswerTextWrapper.className = "quiz-answer-text-wrapper";
newAnswerTextWrapper.id = "quiz-answer-text-wrapper";
newAnswerInput = document.createElement("input");
newAnswerInput.type = "radio";
newAnswerInput.name = "answer";
inputs.push(newAnswerInput);
newAnswerText = document.createElement("label");
newAnswerText.htmlFor = "quizzer";
newAnswerText.innerHTML = questions[i].question.question_answers[j].answer.text;
newAnswerTextWrapper.appendChild(newAnswerInput);
newAnswerTextWrapper.appendChild(newAnswerText);
newAnswer.appendChild(newAnswerTextWrapper);
answers.push(newAnswer);
newAnswerForm.appendChild(newAnswer);
}
newQuestion = document.createElement("div");
newQuestion.className = "quiz-question";
newQuestion.appendChild(newQuestionTextWrapper);
newQuestion.appendChild(newAnswerForm);
newQuizWrapper.appendChild(newQuestion);
}
quiz_div.appendChild(newQuizWrapper);
},
//Checks all of the inputs to see if the
checkInputs = function checkInputs() {
var c = 0;
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].checked) {
userAnswers.push(inputs[i].parentNode.parentNode.dataset.quizvalue);
c++;
}
}
if (c==questions.length) {
calcResult();
}
},
calcResult = function calcResult() {
var highest = 0;
for (var i = 0; i < results.length; i++) {
results[i].countof = 0;
for (var j = 0; j < userAnswers.length; j++) {
if (userAnswers[j] == results[i].result.id) {
results[i].countof++;
}
}
if (results[i].countof > highest) {
highest = results[i].countof;
highest_score = results[i];
}
}
//disable the inputs after the quiz is finished
writeResult();
disableAnswers();
},
writeResult = function writeResult() {
newResult = document.createElement("div");
//append html to render (quiz result)
...;
quiz_div.appendChild(newResult);
},
updateSelectedAnswer = function updateSelectedAnswer(element) {
element.children.namedItem("quiz-answer-text-wrapper").firstChild.checked = true;
for (var i = 0; i < element.parentNode.children.length; i++) {
if (element.parentNode.children.item(i).hasClass("selected")) {
element.parentNode.children.item(i).removeClass("selected");
}
}
element.className = element.className + " selected";
},
addClickEvents = function addClickEvents() {
var onAnswerClick = function onAnswerClick() {
if (!this.hasAttribute("disabled")) {
updateSelectedAnswer(this);
checkInputs();
}
};
for (var i = 0; i < answers.length; i++) {
answers[i].addEventListener("click", onAnswerClick);
}
},
disableAnswers = function disableAnswers() {
for (var q = 0; q < answers.length; q++) {
answers[q].disabled = true;
answers[q].setAttribute("disabled", true);
answers[q].className = answers[q].className + " disabled";
}
};
return {
init: function (json_data) {
getQuizCanvas();
getJSONData(json_data);
writeQuiz();
addClickEvents();
}
};
}();
BF_QUIZ.quizLoader = function () {
"use strict";
var json_data, request,
loadQuizJSON = function loadQuizJSON(json_url) {
request = new XMLHttpRequest();
request.open("GET", json_url, false);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success!
json_data = JSON.parse(request.responseText);
} else {
// We reached our target server, but it returned an error
}
};
request.onerror = function() {
// There was a connection error of some sort
};
request.send();
};
return {
init: function(json_url) {
loadQuizJSON(json_url);
BF_QUIZ.quiz.init(json_data);
}
};
}();
If you ever try to see console log on a mobile device, you might notice that there is a JavaScript error because iOS Safari is less forgiving than whatever desktop browser you use. Particularly it is illegal to set style property of HTMLElement as string in strict mode. You may see examples of the ways to set it properly at https://developer.mozilla.org/en/docs/Web/API/HTMLElement/style If you fix this issue, code seems to be working on Mobile Safari as well.
P.S. note that the offending code is missing in your question and is only visible in the full code of writeResult on plunker. This is why it is so important to provide a Minimal, Complete, and Verifiable example
From your plunker, if you update your code on line 152 from newResultTitle.style = "color:rgba(238,62,52,.99);"; to newResultTitle.style.color = "rgba(238,62,52,.99)"; this would make it work on mobile browsers.
HTMLElement.style reruns a read only property, desktop browser ignoring it when you are trying to assign a value to it, and mobile browser throwing an error.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style
Working plunker http://plnkr.co/edit/aVxTP5YCbL94v2GI0IKh?p=preview

Determine if a string is in an array using Jquery

I have the following code:
function checkIfUnitCostItemsAreZero(finaliseIDList)
{
var selectedItems = finaliseIDList;
selectedItems = $.makeArray(selectedItems); //array is ["-2,-3"]
var getItem = $("#builderItemsList .listItem");
for (i = 0; i < getItem.length; i++)
{
var currentItem = ($(getItem[i]).attr("key"));
if (currentItem.indexOf(selectedItems) > -1)
{//currentItem = "-2" then "-3"
var unitCost = $(getItem[i]).attr("unitcost");
console.log(unitCost);
unitCost = parseFloat(unitCost);
if(unitCost==0.00)
{
return true;
break;
}
}
}
return false;
}
selected item currently equates to the following:
selectedItems = ["-2,-3"]
And further down, currentItem is evaluated at:
"-2", and the next loop "-3".
In both instances, neither go into the if statement. Any ideas why?
Courtesy of Hossein and Aer0, Fixed using the following:
String being passed in as a single value. Use split to seperate it for array.
Modify the if clause.
function checkIfUnitCostItemsAreZero(finaliseIDList)
{
var selectedItems = $.makeArray(finaliseIDList.split(','));
var getItem = $("#builderItemsList .listItem");
for (i = 0; i < getItem.length; i++) {
var currentItem = ($(getItem[i]).attr("key"));
if (selectedItems.indexOf(currentItem) > -1)
{
var unitCost = $(getItem[i]).attr("unitcost");
unitCost = parseFloat(unitCost);
if(unitCost==0.00)
{
return true;
break;
}
}
}
return false;
}

JavaScript Json row undefined for TreeView

I have a question. When querying my Json object, although i have my Field as same name and all Json rows available give me an error that is undefined.
//e.g: row.DepParentId
Bellow is my code. Am I missing some tag?
function convert(rows) {
debugger;
function exists(rows, parent) {
for (var i = 0; i < rows.length; i++) {
if (rows[i].DepId === parent) return true;
}
return false;
}
var nodes = [];
// get the top level nodes
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
if (!exists(rows, row.DepParentId)) {
nodes.push({
id: row.DepId,
name: row.Title
});
}
}
var toDo = [];
for (var i = 0; i < nodes.length; i++) {
toDo.push(nodes[i]);
}
while (toDo.length) {
var node = toDo.shift();
// the parent node
// get the children nodes
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
if (row.DepParentId == node.Id) {
var child = {
Id: row.DepId,
Name: row.Title
};
if (node.options) {
node.options.push(child);
} else {
node.options = [child];
}
toDo.push(child);
}
}
}
return nodes;
}
My Json example for one row picked from Firefox
"{"DepId":7,"DepParentId":3,"Title":"OTT"}"
Thanks for helping
Joao
thanks all for helping, it's working now, the problem was the JSON.stringify() was returning only an [Object] so when you use JSON.parse() generates a sintax error.
function onLoaded() {
var itemsCount = items.get_count();
for (var i = 0; i < itemsCount; i++) {
var item = items.itemAt(i);
var dep = JSON.stringify(item.get_fieldValues());
deps.push(dep);
}
So, i had to change the format to be valid to parse like this
var dt = "[" + deps + "]";
var ret = JSON.parse(dt);
Thanks
Joao

Populate form from JSON.parse

I am trying to re-populate a form from some values in localStorage. I can't quite manage the last part to get the loop to populate my name and values.
function loadFromLocalStorage() {
PROCESS_SAVE = true;
var store = localStorage.getItem(STORE_KEY);
var jsn = JSON.parse(store);
console.log(jsn);
if(store.length === 0) {
return false;
}
var s = jsn.length-1;
console.log(s);
for (var i = 0; i < s.length; i++) {
var formInput = s[i];
console.log(s[i]);
$("form input[name='" + formInput.name +"']").val(formInput.value);
}
}
Could I get some pointers please.
Your issue is in this section of code.
var s = jsn.length-1;
console.log(s);
for (var i = 0; i < s.length; i++) {
You are setting s to the length of the jsn array minus 1, then using it as if it were jsn. I think you intended something like this.
function loadFromLocalStorage() {
PROCESS_SAVE = true;
var store = localStorage.getItem(STORE_KEY);
var jsn = JSON.parse(store);
console.log(jsn);
if(store.length === 0) {
return false;
}
for (var i = 0; i < jsn.length; i++) {
var formInput = jsn[i];
console.log(jsn[i]);
$("form input[name='" + formInput.name +"']").val(formInput.value);
}
}

Categories

Resources