Why reset my value after create new textarea? - javascript

I have following problem, with this code i can create a room with a textarea, after i fill this with values and create a new room and fill again will resets all first textarea's only the last have values...
var rooms = {};
function addRoom(name, data) {
rooms[name] = data;
}
function updateRoom(name, key, value) {
rooms[name][key] = value;
}
var Room = function() {
this.description = 0;
};
function createroom() {
var roomname = document.getElementById('innerhtml').value;
var coldiv = document.createElement('div');
coldiv.className = "col-md-6 mb-3";
coldiv.setAttribute("id", `room_col_${roomname}`);
var room = document.createElement('div');
room.className = "text-center roombox";
room.innerHTML = roomname;
room.setAttribute("id", `room_count_${roomname}`);
room.setAttribute("data-toggle", `modal`);
room.setAttribute("data-target", `#room${roomname}`);
var roomnamehidden = document.createElement('input');
roomnamehidden.setAttribute("name", "roomname");
roomnamehidden.setAttribute("type", "hidden");
roomnamehidden.setAttribute("value", `${roomname}`);
document.getElementById("rooms").appendChild(coldiv).appendChild(room);
document.getElementById("rooms").appendChild(roomnamehidden);
document.getElementById("rooms").innerHTML += '<div class="modal fade" id="' + `room${document.getElementById('innerhtml').value}` + '" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true" xmlns="http://www.w3.org/1999/html"><div class="modal-dialog modal-lg" role="document"><div class="modal-content"><div class="modal-header"><h5 class="modal-title" id="exampleModalLabel">Inventar für <b>' + `${document.getElementById('innerhtml').value}` + '</b> hinzufügen</h5><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button></div><div class="modal-body"><textarea name="description" class="form-control" rows="5" placeholder="description here..." id="' + `${document.getElementById('innerhtml').value}_description` + '"></textarea></div><div class="modal-footer"><button data-dismiss="modal" aria-label="Close" class="btn btn-primary" onclick="updateRoomItems(\'' + `${document.getElementById('innerhtml').value}` + '\')" id="' + `saveall${document.getElementById('innerhtml').value}` + '">Gegenstände Speichern</button></div></div></div></div>';
document.getElementById('innerhtml').value = '';
}
function numKeys(obj) {
var count = 0;
for (var prop in obj) {
count++;
}
return count;
}
function updateRoomItems(a) {
var roomname = a;
if (rooms[`${roomname}`] === undefined) {
var roomData = new Room();
roomData.description = document.getElementById(`${roomname}_description`).value;
addRoom(`${roomname}`, roomData);
console.log(rooms);
} else {
updateRoom(`${roomname}`, "description", document.getElementById(`${roomname}_description`).value);
}
how i say i got every time only the last value of the textarea, I need all values, why reset the other values? What have i wrong?

This statement is causing the problem:
document.getElementById("rooms").innerHTML += '<div ... // etc
The innerHTML property of the rooms element is read, concatenated with the right hand side of += and written back. When read, it returns the tags of textarea elements already in the rooms element, but not their content. So every time you add a new room it recreates existing textareas with nothing in them.
The Element​.insert​Adjacent​HTML() method was introduced to solve this exact issue. Stylistically I would not recommend the use of "innerhtml" as an element id.

Related

Button generated inside javascript code to onclick insert value in input type text in form

I have a very nice SEO-keyword suggestion tool working with CKeditor, it displays the most used word in the text while writing. The problem is that I want to make these generated keywords clickable one by one. So when you click on a keyword, it auto-fills an input-type text.
Here is the HTML code:
<!-- Textarea -->
<div class="form-group">
<label class="col-md-2 control-label" for="editor1">Insert your text here </label>
<div class="col-md-10">
<textarea class="form-control" id="editor1" name="editor1"><p>text example with ahöäåra</p></textarea>
</div>
</div>
<!-- KW density result -->
<div class="form-group">
<label class="col-md-2 control-label" for="editor1">Suggested SEO keywords</label>
<div class="col-md-10">
<div id="KWdensity" ></div>
</div>
</div>
Here is the javascript code:
<script type="text/javascript">
$(document).ready(function() {
CKEDITOR.replace('editor1');
$(initKW);
CKEDITOR.instances.editor1.on('contentDom', function() {
CKEDITOR.instances.editor1.document.on('keyup', function(event) {
$(initKW);
});
});
function KeyDensityShow(srctext, MaxKeyOut, keylenMin) {
var Output;
var words = srctext.toLowerCase().split(/[^\p{L}\p{M}\p{N}]+/u)
var positions = new Array()
var word_counts = new Array()
try {
for (var i = 0; i < words.length; i++) {
var word = words[i]
if (!word || word.length < keylenMin) {
continue
}
if (!positions.hasOwnProperty(word)) {
positions[word] = word_counts.length;
word_counts.push([word, 1]);
} else {
word_counts[positions[word]][1]++;
}}
word_counts.sort(function(a, b) {
return b[1] - a[1]
})
return word_counts.slice(0, MaxKeyOut)
} catch (err) {
return "";
}}
function removeStopWords(input) {
var stopwords = ['test', ];
var filtered = input.split(/\b/).filter(function(v) {
return stopwords.indexOf(v) == -1;
});
stopwords.forEach(function(item) {
var reg = new RegExp('\\W' + item + '\\W', 'gmi');
input = input.replace(reg, " ");
});
return input.toString();
}
function initKW() {
$('#KWdensity').html('');
var TextGrab = CKEDITOR.instances['editor1'].getData();
TextGrab = $(TextGrab).text();
TextGrab = removeStopWords(TextGrab);
TextGrab = TextGrab.replace(/\r?\n|\r/gm, " ").trim();
TextGrab = TextGrab.replace(/\s\s+/g, " ").trim();
if (TextGrab != "") {
var keyCSV = KeyDensityShow(TextGrab, 11, 3);
var KeysArr = keyCSV.toString().split(',');
var item, items = '';
for (var i = 0; i < KeysArr.length; i++) {
item = '';
item = item + '<b>' + KeysArr[i] + "</b></button> ";
i++;
item = '<button class="btn btn-default btn-xs" type="button" onclick="document.getElementById(thebox).value="head of gwyneth paltrow";"><span class="badge">' + KeysArr[i] + "</span> " + item;
items = items + item;
}
$('#KWdensity').html(items);
}}});
</script>
And here is some extra HTML for the input that needs to be auto-filled.
The keywords box:
<input type="text" id="thebox" value="" style="width:80%;height:30px;background:#000;color:#fff;"/>
<br><input type="button" value="this one is working" onclick="document.getElementById('thebox').value='test button is working';">
So if you write something, it will generate keywords buttons. When you click on one of these buttons, the keyword must be entered in the input text like this
keyword,
Here is a Fiddle DEMO.
Any idea how to fix that? I added a document.getElementById('thebox'). but it does not return anything
Your code in
item = '<button class="btn btn-default btn-xs" type="button" onclick="document.getElementById(thebox).value="head of gwyneth paltrow";"><span class="badge">' + KeysArr[i] + "</span> " + item;
Will add to the DOM (in other words, to the HTML of the page), the following bit:
<button
class="btn btn-default btn-xs"
type="button"
onclick="document.getElementById(thebox).value="head of gwyneth paltrow";"
>
Now, the resulting onclick above has some problems. First, notice that the quotes it uses in the string after .value= are actually closing the onclick declaration because they are not escaped. I mean, instead of
onclick="document.getElementById(thebox).value="head of gwyneth paltrow";"
^--- problem here ^--- and here
It should've been
onclick="document.getElementById(thebox).value=\"head of gwyneth paltrow\";"
^--- fixed here ^--- and here
Secondly, the argument to .getElementById(thebox) is thebox. Notice here that the way it is now, thebox is actually a variable, not a string. So instead of the above, what you want is:
onclick="document.getElementById(\"thebox\").value=\"head of gwyneth paltrow\";"
^--- ^--- fixed here
These fixes should be enough to make the clicks on the words set the "head of gwyneth paltrow" value in the textbox.
I believe, though, you want to actually set the key when the button is clicked. To do that, instead of having "head of gwyneth paltrow" after the .value, you should have the text of the key. All in all, here's how that line could be:
item = '<button class="btn btn-default btn-xs" type="button" onclick="document.getElementById(\'thebox\').value=\'' + key + '\';"><span class="badge">' + KeysArr[i] + "</span> " + item;
^-- ^-- ^^^^^^^^^^^^^^--- changed here (notice in the demo below I declare the key variable before using it here)
Updated fiddle here. Running demo below as well.
$(document).ready(function() {
CKEDITOR.replace('editor1');
$(initKW);
CKEDITOR.instances.editor1.on('contentDom', function() {
CKEDITOR.instances.editor1.document.on('keyup', function(event) {
$(initKW);
});
});
function KeyDensityShow(srctext, MaxKeyOut, keylenMin) {
var Output;
var words = srctext.toLowerCase().split(/[^\p{L}\p{M}\p{N}]+/u)
var positions = new Array()
var word_counts = new Array()
try {
for (var i = 0; i < words.length; i++) {
var word = words[i]
if (!word || word.length < keylenMin) {
continue
}
if (!positions.hasOwnProperty(word)) {
positions[word] = word_counts.length;
word_counts.push([word, 1]);
} else {
word_counts[positions[word]][1]++;
}
}
word_counts.sort(function(a, b) {
return b[1] - a[1]
})
return word_counts.slice(0, MaxKeyOut)
} catch (err) {
return "";
}
}
function removeStopWords(input) {
var stopwords = ['test', ];
var filtered = input.split(/\b/).filter(function(v) {
return stopwords.indexOf(v) == -1;
});
stopwords.forEach(function(item) {
var reg = new RegExp('\\W' + item + '\\W', 'gmi');
input = input.replace(reg, " ");
});
return input.toString();
}
function initKW() {
$('#KWdensity').html('');
var TextGrab = CKEDITOR.instances['editor1'].getData();
TextGrab = $(TextGrab).text();
TextGrab = removeStopWords(TextGrab);
TextGrab = TextGrab.replace(/\r?\n|\r/gm, " ").trim();
TextGrab = TextGrab.replace(/\s\s+/g, " ").trim();
if (TextGrab != "") {
var keyCSV = KeyDensityShow(TextGrab, 11, 3);
var KeysArr = keyCSV.toString().split(',');
var item, items = '';
var previousKeys = [];
for (var i = 0; i < KeysArr.length; i++) {
item = '';
var key = KeysArr[i];
previousKeys.push(key);
item = item + '<b>' + key + "</b></button> ";
i++;
item = '<button class="btn btn-default btn-xs" type="button" onclick="document.getElementById(\'thebox\').value=\'' + previousKeys.join(', ') + '\';"><span class="badge">' + KeysArr[i] + "</span> " + item;
items = items + item;
}
$('#KWdensity').html(items);
}
}
});
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script type="text/javascript" src="//cdn.ckeditor.com/4.6.1/standard/ckeditor.js"></script>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!-- Textarea -->
<div class="form-group">
<label class="col-md-2 control-label" for="editor1">Insert your text here </label>
<div class="col-md-10">
<textarea class="form-control" id="editor1" name="editor1"><p>text example with ahöäåra</p></textarea>
</div>
</div>
<!-- KW density result -->
<div class="form-group">
<label class="col-md-2 control-label" for="editor1">Suggested SEO keywords</label>
<div class="col-md-10">
<div id="KWdensity" ></div>
</div>
</div>
The keywords box: <input type="text" id="thebox" value="" style="width:80%;height:30px;background:#000;color:#fff;"/>
<br><input type="button" value="this one is working" onclick="document.getElementById('thebox').value='test button is working';">

How can I make this click counter work properly?

I'm making a Marvel API project. I added a Like button so it could count the likes, but everytime I click any like button the only counter adding numbers is the first one. Can anyone tell me how I do this properly?
The problem is because the ID is being made by a for, so how could I solve this?
This is my JS code (on the js file of my project) :
success: function(data)
{
footer.innerHTML = data.attributionHTML;
var string = "";
string += "<div class='row'>";
for (var i = 0; i < data.data.results.length; i++)
{
var element = data.data.results[i];
string += '<div class="col-md-3" align="center">';
string += "<img src='" + element.thumbnail.path + "/portrait_fantastic." + element.thumbnail.extension + "'/>";
string += '<button class="btn btn-success" onClick="testo()"><i class="fas fa-thumbs-up"></i> | <a id="likes">0</a></button>';
string += "<h3>" + element.title + "</h3>";
string += "</div>";
if ((i + 1) % 4 == 0)
{
string += "</div>";
string += "<div class='row'>";
}
}
marvelContainer.innerHTML = string;
}
And this is my onclick function (It is on my html file because it wont work on my js file)
<script>
var likes=0;
function testo()
{
likes += 1;
document.getElementById("likes").innerHTML = likes;
}
</script>
That is because all your buttons are being generated with the same id="likes" and then you are changing the HTML with document.getElementById("likes").innerHTML = likes;
for your code to work properly you will need to use a different approach, maybe adding a data-* attribute to your buttons and then change the likes by the data-* atribute using .getAttribute('data-id-something').innerHTML instead of document.getElementById("likes").innerHTML.
Or even better in this case you can give the buttons a class name and handle it with: document.getElementsByClassName("like-btn")
You can check the last option in this example:
var init = function(data){
var string ="";
string += "<div class='row'>";
for(var i = 0; i<4; i++)
{
// var element = data.data.results[i];
string += '<div class="col-md-3" align="center">';
string += "<img src='/portrait_fantastic.jgeg'/>";
string += '<button class="btn btn-success" onClick="testo('+i+')"><i class="fas fa-thumbs-up"></i> | <span class="like-btn">0</span></button>';
string += "<h3>Element title</h3>";
string += "</div>";
if((i+1) % 4 ==0)
{
string += "</div>";
string += "<div class='row'>";
}
}
document.getElementById("marvelContainer").innerHTML = string;
}
init();
<script>
var likes=0;
function testo(id) {
var btn = document.getElementsByClassName("like-btn");
likes = parseFloat(btn[id].innerHTML);
likes += 1;
btn[id].innerHTML = likes;
}
</script>
<div id="marvelContainer"></div>
I hope it will help you...
Gave the buttons a class, as that is what is going to be clicked.
Changed the link element to a span. Having a link in a button doesn't make much sense, as you can't "not" click the button and click the link.
Removed the inline onclick for the link and added an event listener logically on all the buttons.
The click logic finds the nested span in the button
It takes the data attribute on the span, turns it into an integer, and increments it
It then updates the data attribute value for the next click
And finally it updates the visible text that the user can see
EDIT
Changed it to bind the click event listener on the span as well and stop propagation on the click event. Actually clicking the span was causing the click event to register for the span, and not the button.
// fake out some data for the element generation
var data = { data: {
results: [
{ thumbnail: { path: '/path1', extension: 'jpg', title: 'Element1' } }
,{ thumbnail: { path: '/path2', extension: 'png', title: 'Element2' } }
,{ thumbnail: { path: '/path3', extension: 'gif', title: 'Element3' } }
]
} };
// fake out the container the elements are built to
var marvelContainer = document.querySelector('#container');
var string = "<div class='row'>";
for (var i = 0; i < data.data.results.length; i++) {
var element = data.data.results[i];
string += '<div class="col-md-3" align="center">';
string += "<img src='" + element.thumbnail.path + "/portrait_fantastic." + element.thumbnail.extension + "'/>";
// put a class on the button
// also removed the id and inline onclick
// change the id on the link to a class
// also initialized the data-likes on the link to zero
string += '<button class="btn btn-success likes-button"><i class="fas fa-thumbs-up"></i> | <span class="likes" data-likes="0">0</span></button>';
string += "<h3>" + element.title + "</h3>";
string += "</div>";
if ((i + 1) % 4 == 0) {
string += "</div>";
string += "<div class='row'>";
}
}
marvelContainer.innerHTML = string;
document.querySelectorAll('.likes-button, .likes').forEach(function(likeButton){
likeButton.addEventListener('click', incrementLikes);
});
function incrementLikes (e) {
e.stopPropagation();
// find the inner likes element of the button
var likes = e.target.querySelector('.likes') || e.target;
// increment the likes
var incrementedLikes = parseInt(likes.dataset.likes) + 1;
// update the data attribute for next click, and update the text
likes.dataset.likes = incrementedLikes.toString();
likes.innerText = incrementedLikes;
}
<div id="container">
</div>

Change DIV content based on Toggle button clicked

If user click "Twin Bed" or "King Bed", Content inside "demand-message" have to change either "high demand" or "Only ??? rooms left".
ID will be same for button because of existing logic. Now my message to display on "demand-message" is not changing if i click "King Bed". It displays correctly for "Twin Bed".
Is it possible to change message by getting ID with data-bed-type attribute to match and change the message (either high demand or No. of rooms left)?
HTML:
<div class="col-lg-4 col-md-12 col-sm-12 col-12 left-container">
<div class="demand-message--wrapper">
<div class="demand-message"></div>
</div>
<div class="left-column">
<div class="btn-group">
<button type="button" data-bed-container-id="deluxe-balcony-room" data-bed-max="190" data-bed-type="twin">Twin Bed</button>
<button type="button" data-bed-container-id="deluxe-balcony-room" data-bed-max="90" data-bed-type="king">King Bed</button>
</div>
</div>
JS:
function onToggleBed(e) {
var thisButton = $(e.currentTarget);
var bedTypeSelected = thisButton.data('bed-type');
var bedValueSelected = thisButton.data('bed-value');
var roomContianerId = thisButton.data('bed-container-id');
var buttonMaxRoom = thisButton.data('bed-max');
var message = '';
if (buttonMaxRoom < 100) {
message = 'Only ' + buttonMaxRoom + ' rooms left';
} else if (buttonMaxRoom > 100) {
message = 'In high demand';
}
if (message == '') {
$('#' + roomContianerId + ' .demand-message').hide();
} else {
$('#' + roomContianerId + ' .demand-message').show();
$('#' + roomContianerId + ' .demand-message').html(message);
}
}
As I mentioned in my comment, hypens will removed and turned into camelCase.
In this case use:
var bedTypeSelected = thisButton.data('bedType');
Let's console.log(thisButton.data()); to see your data items.

How to display charts in different modal windows after multiple ajax calls?

I do multiple ajax calls and I want to show a chart inside the modal window after clicking on symbol name. Right now I can see the chart only for the last symbol. For the first symbol the modal window is empty. I understand that with each ajax call the new chart function overrides the previous result and display new chart in last modal window. But how can I still show all previous charts and display new one in the lsat window?
var stocks = [];
window.onload = function() {
var symbols = ['AAPL', 'MSFT', 'FB'];
symbols.forEach( symbol => makeAjaxCall(symbol));
}
function makeAjaxCall(param){
$.ajax({
type: "GET",
url: "https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=" + param + "&interval=1min&apikey=T6UEJETEQRVGDJS9",
success: function(result){
stocks = result;
getPrices();
}
});
}
function getPrices() {
var metaData = stocks["Meta Data"],
timeSeries = stocks["Time Series (1min)"],
sym = metaData["2. Symbol"];
var mdl1 = '<div id="chartModal" class="modal fade" role="dialog">' +
'<div class="modal-dialog modal-lg" role="content">' +
'<div class="modal-content">' +
'<div class="modal-header">' +
'<h4>',
mdl2 = '</h4>' +
'<button type="button1" class="close" data-dismiss="modal">×</button>' +
'</div>' +
'<div class="modal-body" id="modalBody">' +
'<div class = "container-canvas">' +
'<canvas class = "line-chart" width = "400" height = "250"></canvas>' +
'</div>' +
'</div>' +
'</div>' +
'</div>' +
'</div>',
mdl3 = mdl1 + sym + mdl2;
document.getElementById("loadedStocks").innerHTML += '<div class="eachStock"><span><a onclick="showChart()">' + sym + '</a></span></div><div></div>' + mdl3;
var datasetsValues = Object.values(timeSeries),
datasetsValuesReverse = datasetsValues.reverse();
highPrice = Object.values(datasetsValuesReverse).map(o => o["4. close"]),
dateKeys = Object.keys(timeSeries),
datesReverse = dateKeys.reverse();
var ctx = document.getElementById('loadedStocks').querySelectorAll('.line-chart');
var last = ctx[ctx.length - 1];
new Chart(last, {
type: 'line',
data: {
labels: datesReverse,
datasets: [{
data: highPrice,
borderColor: "#FF4500",
label: "Close",
fillset: "#FFDAB9"
}],
pointStyle: "cross",
},
options: {
title: {
display: true,
text: "Stock's close price changes"
}
}
});
}
function showChart() {
$('#chartModal').modal();
}
My html:
<div id='loadedStocks'></div>
Thanks!
The main issue is that you gave the same ID to all your modals.
Below is a revision.
// better to use document.ready() than window.load()
// good idea to wrap jQuery-related code within document.ready()
$(function() {
// good idea to cache elements that you will re-use
var loadedStocks = $("#loadedStocks");
var API = 'https://www.alphavantage.co/query';
function makeAjaxCall(param) {
// simplified
$.getJSON(API, {
'function': 'TIME_SERIES_INTRADAY',
'symbol': param,
'interval': '1min',
'apikey': 'T6UEJETEQRVGDJS9',
}, getPrices);
}
function getPrices(stocks) {
var metaData = stocks["Meta Data"],
timeSeries = stocks["Time Series (1min)"],
symbol = metaData["2. Symbol"];
// give a unique id to each modal e.g. chartModal-AAPL
// in rare cases, use inline style to hide your HTML
var modal =
'<div id="chartModal-' + symbol + '" class="modal fade" role="dialog" style="display:none">' +
'<div class="modal-dialog modal-lg" role="content">' +
'<div class="modal-content">' +
'<div class="modal-header">' +
'<h4>' + symbol + '</h4>' +
'<button type="button1" class="close" data-dismiss="modal">×</button>' +
'</div>' +
'<div class="modal-body" id="modalBody">' +
'<div class="container-canvas">' +
'<canvas class="line-chart" width="400" height="250"></canvas>' +
'</div>' +
'</div>' +
'</div>' +
'</div>' +
'</div>';
// use HTML5-data attribute to store the stock value (*)
loadedStocks.append('<div class="eachStock">' + symbol + '</div>' + modal);
var datasetsValues = Object.values(timeSeries),
datasetsValuesReverse = datasetsValues.reverse(),
highPrice = Object.values(datasetsValuesReverse).map(o => o["4. close"]),
dateKeys = Object.keys(timeSeries),
datesReverse = dateKeys.reverse();
var last = loadedStocks.find('.line-chart').last()[0]; // simplified
new Chart(last, {
type: 'line',
data: {
labels: datesReverse,
datasets: [{
data: highPrice,
borderColor: "#FF4500",
label: "Close",
fillset: "#FFDAB9"
}],
pointStyle: "cross",
},
options: {
title: {
display: true,
text: "Stock's close price changes"
}
}
});
}
// attach a click handler on the dynamically-created link
$(document).on('click', '.eachStock a[data-stock]', function showChart(e) {
e.preventDefault();
// find modal based on this link's stock value (*)
$('#chartModal-' + this.dataset.stock).modal('show');
});
// start!
['AAPL', 'MSFT', 'FB'].forEach(symbol => makeAjaxCall(symbol));
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.bundle.min.js"></script>
<div id="loadedStocks"></div>
(Give the demo a few seconds to load everything. You should probably change your API key afterwards.)
window.onload vs document.ready
jQuery shorthand methods
Event propogation
Data attributes

How to add a class to an element based on something saved in Local Storage with JQuery?

Basically, I'm making a TODO list, the functions are save and delete records, which are already implemented and mark as important and mark as done, which are the functions that I'm having trouble with.
This is the method that I use to retrieve the items saved in Local Storage as an array.
function get_todos() {
var todos = new Array;
var todos_str = localStorage.getItem('todo');
if (todos_str !== null) {
todos = JSON.parse(todos_str);
}
return todos;
}
This is the method that I use to save records in Local Storage
function add() {
var task = "00"+document.getElementById('task').value;
var todos = get_todos();
todos.push(task);
localStorage.setItem('todo', JSON.stringify(todos));
show();
return false;
}
As you can see, I add the records with two 00 at the beginning, the first number is 0 when that item of the TODO list is "undone", and 1 when it is marked as done, the second number is 0 when that item if the TODO list is "not important", and 1 when it is marked as important, for changing those numbers on the local storage, I do this:-
//if the second digit is 0 then the task is not important
function markAsImportant(){
var id = parseInt(this.getAttribute('id'));
var todos = get_todos();
var task = todos[id].replaceAt(1, "1");
console.log(task);
todos.splice(id, 0, task);
todos.splice(id+1, 1);
localStorage.setItem('todo', JSON.stringify(todos));
show();
return false;
}
That method is already well implemented and working as it should.
Now, knowing what item of the TODO is important and which one is not, I simply want to add a class to the items which second character is a one, and that is what I try to do here:-
function show() {
var todos = get_todos();
var html = '<div class="list">';
for(var i=0; i<todos.length; i++) {
//HERE HERE HERE HERE HERE
if (todos[i].charAt(1) == '1') {
console.log("important");
$('.item').addClass('important');
}
else{
console.log("not important");
}
html += '<div class="item"> <input type="checkbox" class="check" id="' + i + '"> ' +' <div class="title">' + todos[i].substring(2) + '</div> <div class="tools"> <span class="tag" id="' + i + '"> <img class="important-img" src="resources/important.png"> </span> <span class="delete remove " id="' + i + '"> <img src="resources/thrash.png"> </span> </div></div>';
};
html += '</div>';
document.getElementById('todos').innerHTML = html;
var deleteButtons = document.getElementsByClassName('remove');
for (var i=0; i < deleteButtons.length; i++) {
deleteButtons[i].addEventListener('click', remove);
};
var doneButtons = document.getElementsByClassName('check');
for (var i=0; i < doneButtons.length; i++) {
doneButtons[i].addEventListener('click', markAsDone);
};
var importantButtons = document.getElementsByClassName('tag');
for (var i=0; i < importantButtons.length; i++) {
importantButtons[i].addEventListener('click', markAsImportant);
};
var listItems = document.getElementsByClassName('item');
for (var i=0; i < listItems.length; i++) {
console.log(listItems[i]);
$(listItems[i]).attr('id', i);
};
}
But it simply won't add anything at all to the .item tags, how can I make it actually add the class important to the items that I want ?
You are not adding the html to DOM so $(".item") won't work. This should work:
for (var i = 0; i < todos.length; i++) {
html += '<div class="item';
if (todos[i].charAt(1) == '1') {
console.log("important");
html += ' important'; // The space must be there, so change just the "important" bit, but don't remove the space
} else {
console.log("not important");
}
html += '"><input type="checkbox" class="check" id="' + i + '"> ' + ' <div class="title">' + todos[i].substring(2) + '</div> <div class="tools"> <span class="tag" id="' + i + '"> <img class="important-img" src="resources/important.png"> </span> <span class="delete remove " id="' + i + '"> <img src="resources/thrash.png"> </span> </div></div>';
}
Paste this instead your for loop and post the result in comments under this answer.

Categories