3

Hello I currently have a script where I append some data into a table then I type into a input and press the add button and that saves all the cells in that table as whatever you typed into the taskName input.

It gets set as localstorage and pops up in two selects one on another html page and one on the html page that it was made in.

the script works well and Im able to call the cells depending on which one I select. The only problem is that I cant delete the task. I want to be able to select the task in the html select and then have it append all the cells into the html page where I can delete all the cells and after I do It removes the task from the localStorage or other words just deletes it completely here is my html code:

<div id="taskContainer">
    <table id="items-table">
    <!--<caption>Task</caption>-->
        <tr>
            <th>Item</th>
            <th>Size</th>
            <th colspan="3">Options</th>
    </table>
</div>
<label for="loadTask">Load Task:</label>
<label for="taskName">Task Name:</label>
<select id="loadTask">
    <option></option>
</select>
<input type="text" id="taskName"></input>
<button type="submit" id="addTask">Add</button>

and here is my JS:

$(function() {

    loadAllTasks();

    $("#addTask").click(function() {
        let cells = Array.prototype.map.call(document.getElementById("items-table").rows, row => {
            return Array.prototype.map.call(row.cells, cell => cell.innerHTML);
        });
        // create task object from cells
        var task = { cells: cells };

        // set name property of the task
        task.Name = $("#taskName").val();

        // call save method using the new task object
        saveTaskInStorage(task);
    });
});

function saveTaskInStorage(task) {
    // Get stored object from localStorage
    var savedTasks = JSON.parse(localStorage.getItem('tasks'));

    // To be sure that object exists on localStorage
    if (!savedTasks || typeof (savedTasks) !== "object")
    savedTasks = {};

    // Set the new or exists task by the task name on savedTasks object
    savedTasks[task.Name] = task;

    // Stringify the savedTasks and store in localStorage
    localStorage.setItem('tasks', JSON.stringify(savedTasks));

    alert("Task has been Added");
}

function loadAllTasks() {

    // Get all saved tasks from storage and parse json string to javascript object
    var savedTasks = JSON.parse(localStorage.getItem('tasks'));

    // To be sure that object exists on localStorage
    if (!savedTasks || typeof (savedTasks) !== "object")
        return;

    // Get all property name of savedTasks object (here it means task names)
    for (var taskName in savedTasks){
        $("#loadTask").append('<option>' + taskName + '</option>')
    }
}

function loadTaskFromStorage1(taskName) {
    var savedTasks = JSON.parse(localStorage.getItem('tasks'));

    // Return the task by its name (property name on savedTasks object)
    return savedTasks[taskName];
}

var tasky = loadTaskFromStorage1($("#loadTask").val());
$("#items-table").append(tasky.cells);

if ((tasky.cells) = "") {
    delete savedTask[taskName]
} 

as you can see at the very bottom I have tried to do what I wanted but it didn't work. I changed up to task(y) and loadTaskFromStorage(1) because I already have these functions called in the other html page as (task =) and (loadTaskFromStorage) and they work perfectly fine.

When I try and run the very bottom script it does not recognize the task and says that it is undefined. Am I not able to call localStorage in the same file as I set it? or is there something else I am missing.

I have html code and JS that I missed out its just the inputs and when I press the button it ads there val(); into the table

I want to be able to make tasks and delete them easily.

update:

I added the loadTasksFrom Storage function outside of the function where the task is created then I made a test button the see if that would work:

$(function() {
    $("#test-add").click(function() {
        var task = loadTaskFromStorage1($("#loadTask").val());
        $("#items-table").append(task.cells);

    })
})

when I ran this I got this error: html.replace is not a function that pointed to this line: $("#items-table").append(task.cells); but when I changed this line to: alert(task.cells); I got it to actually alert the cells in the task Which has never happend before so that is huge progress!

the only thing I need to solve now is:

  1. How to get it to append into the table

  2. Be able to add the task into the table just by changing the select (not by clicking button)

  3. be able to delete the task completely from all the selects when I delete it with the small delete buttons that each task gets added with.

another update:

I am able to append task.cells[1][0] with stuff like that but I cant just do task.cells I also dont want to append the so.. How would I append row by row with each X button that is added into each table row something like

.append(task.cells[1][0], task.cells[1][1], task.cells[1][2] etc...

this code above just adds in each cell eight beside each other it doesnt add in the cell under its specific table header. How would I do that.

I appreciate anyone taking the time out of there day to help me out.

  • Welcome to Stack Overflow. First, I would consider the overall logic of your code. If you consider your LocalStorage as your data table, adding, remove and sorting is all done there and when changes are made, you simply redraw the HTML Table to match. A more complete example may be needed, such as some sample data or a working example. Also, why did you tag jquery-ui? – Twisty Aug 21 '18 at 18:02
  • Also you have an IF statement syntax error: `if ((tasky.cells) = "")` is not correct. You would want to use a logical comparrison: `if ((tasky.cells) == "")` – Twisty Aug 21 '18 at 18:06
  • And, if `tasky.cells` is an array, you will never be able to compare an array to a string value. The Array would either be empty, `tasky.cells.length == 0`, or the value of each array element could be an empty string. To test for this, you'd need to iterate each array element and perform a comparison. – Twisty Aug 21 '18 at 18:09

1 Answers1

0

With a few code corrections, the code is running without error, yet I am unsure if it is working as intended.

Example: https://jsfiddle.net/Twisty/h901jryt/

JavaScript

$(function() {

  loadAllTasks();

  $("#addTask").click(function() {
    let cells = Array.prototype.map.call($("#items-table")[0].rows, row => {
      return Array.prototype.map.call(row.cells, cell => cell.innerHTML);
    });
    // create task object from cells
    var task = {
      cells: cells
    };

    // set name property of the task
    task.Name = $("#taskName").val();

    // call save method using the new task object
    saveTaskInStorage(task);
  });

  function saveTaskInStorage(task) {
    // Get stored object from localStorage
    var savedTasks = JSON.parse(localStorage.getItem('tasks'));

    // To be sure that object exists on localStorage
    if (!savedTasks || typeof(savedTasks) !== "object")
      savedTasks = {};

    // Set the new or exists task by the task name on savedTasks object
    savedTasks[task.Name] = task;

    // Stringify the savedTasks and store in localStorage
    localStorage.setItem('tasks', JSON.stringify(savedTasks));

    alert("Task has been Added");
  }

  function loadAllTasks() {

    // Get all saved tasks from storage and parse json string to javascript object
    var savedTasks = JSON.parse(localStorage.getItem('tasks'));

    // To be sure that object exists on localStorage
    if (!savedTasks || typeof(savedTasks) !== "object")
      return;

    // Get all property name of savedTasks object (here it means task names)
    for (var taskName in savedTasks) {
      $("#loadTask").append('<option>' + taskName + '</option>')
    }
  }

  function loadTaskFromStorage1(taskName) {
    var savedTasks = JSON.parse(localStorage.getItem('tasks'));

    // Return the task by its name (property name on savedTasks object)
    return savedTasks[taskName];
  }

  var tasky = loadTaskFromStorage1($("#loadTask").val());
  $("#items-table").append(tasky.cells);

  $.each(tasky.cells, function(k, v) {
    if (v == "") {
      delete tasky.cells[k];
    }
  });
});

In your click function, I update some of the JavaScript code to jQuery. Simply for consistency.

In regards to the code you attempted, I used this as a replacement:

var tasky = loadTaskFromStorage1($("#loadTask").val());
$("#items-table").append(tasky.cells);

$.each(tasky.cells, function(k, v) {
  if (v == "") {
    delete tasky.cells[k];
  }
});

The object tasky is populated with elements, one being cells that is an array of Strings. I assumed you were looking for empty cells. the $.each() is a good way to iterate these. See More: http://api.jquery.com/jquery.each/

The function will run and receive k as the Key and v as the Value from each array element. So for example, if tasky.cells was assigned the following Array:

var tasks = [
  "Wake Up",
  "Eat Breakfast",
  "Help Mom",
  "Drive to Work"
  "",
  "Go to Bed"
];

You would have an array called tasks with 6 keys: 0,1,2,3,4,5; and 6 elements. Using something like:

$.each(tasks, function(k, v){
  $("#results").append(k + ": " + v + "<br />");
});

We would see resulting HTML like:

0: Wake Up<br />
1: Eat Breakfast<br />
2: Help Mom<br />
3: Drive to Work<br />
4: <br />
5: Go to Bed

We can use this key value to manipulate the array. To fully remove the element, you might want to consider .splice() versus delete.

$.each(tasks, function(k, v) {
  if (v == "") {
    tasky.cells.splice(k, 1);
  }
});

If we have the above data and perform this operation, the resulting array wil lbe:

[
  "Wake Up",
  "Eat Breakfast",
  "Help Mom",
  "Drive to Work"
  "Go to Bed"
];

This will also have a re-indexed set of keys. See more: Deleting array elements in JavaScript - delete vs splice

Hope that helps.

Twisty
  • 30,304
  • 2
  • 26
  • 45
  • I am still getting this error Cannot read property 'cells' of undefined and it points to this line $("#items-table").append(tasky.cells); –  Aug 21 '18 at 23:08
  • This was the same problem I was getting with my old code. –  Aug 21 '18 at 23:09
  • its wierd becuase I added the loadAllTasks and LoadTaskFromStorage functions into another js file to add the same tasks to another html select and then I was able to call alert(task.cells); and It would actually work and alert me all the cells in each task I selected when I pressed a button –  Aug 21 '18 at 23:12
  • You jsfiddle doesn't not append the cells back into the table when selected. That is the main thing I want to accomplish so I could then be able to delete the task from storage –  Aug 21 '18 at 23:15