Tips for assigning a unique button and checkbox to each item in an ng-repeat list

I am currently working on a ToDo-List exercise in JavaScript and have chosen to utilize AngularJS in order to enhance my skills.

Check out the Github repository here

In my initial attempt, I have set up two unordered lists - one for active items and another for completed items. Each item should feature its own delete button and checkbox to indicate whether it is active or complete.

While the delete button functions correctly, I encountered an issue when implementing the checkboxes. Whenever I mark an item as complete, it ends up deleting the description from the following item and renders the delete buttons inactive.

Since I am still learning Angular, I would greatly appreciate any advice on what I might be doing wrong.

  <body ng-controller="ToDoListController as ctrl">
    <h1>To Do List</h1>
    <div>

      <form class="form-horizontal">
        <input ng-model="newItem" id="newItem" type="text" placeholder="What needs doing?">
        <button ng-click="ctrl.addItem(newItem); newItem=''" class="btn" id="addNewItem">Add</button>
      </form>

      <ul class="list-group" ng-repeat="activeItem in ctrl.listActive track by $index">
        <li>
        <input type="checkbox" ng-click="ctrl.toggle(activeItem)" ng-model="checkBoxModel.completed">
          {{activeItem}}
        <button ng-click="ctrl.deleteItem(activeItem)" class="btn" id="deleteItem">Delete</button>
        </li>
      </ul>

      <ul class="list-group" ng-repeat="completedItem in ctrl.listCompleted track by $index">
        <li>
        <input type="checkbox" ng-click="ctrl.toggle(completedItem)" ng-model="checkBoxModel.completed">
          {{completedItem}}
        <button ng-click="ctrl.deleteItem(completedItem)" class="btn" id="deleteItem">Delete</button>
        </li>
      </ul>

    </div>
  </body>

My JS controller:

toDoList.controller('ToDoListController', [function(){
  this.listActive = [];
  this.listCompleted = [];

  var self = this;

  self.addItem = function(item){
    self.listActive.push(item);
  };

  self.isItemActive = function(item){
    return self.listActive.indexOf(item) >= 0;
  };

  self.deleteItem = function(item){

    if (self.isItemActive(item)) {
      self.listActive.splice(item, 1);
    } else {
      self.listCompleted.splice(item, 1);
    }
  };

  self.toggle = function(item){

    if (self.isItemActive(item)) {
      self.listCompleted.push(item);
      self.listActive.splice(item, 1);
    } else {
      self.listActive.push(item);
      self.listCompleted.splice(item, 1);
    }
  };

  self.editItem = function(item, newItem){

    // code for editing an item

  };

  self.totalTaskCount = function(){
    return self.listActive.length + self.listCompleted.length;
  };

  self.activeTaskCount = function(){
    return self.listActive.length;
  };

  self.completedTaskCount = function(){
    return self.listCompleted.length;
  };

  self.clearCompleted = function(){
    self.listCompleted = [];
  };
}]);

Answer №1

To enhance efficiency, I recommend utilizing a single array of tasks. By iterating through this array using two ng-repeat blocks, you can exhibit completed items in one list and pending items in the other:

<body ng-app="bowling" ng-controller="ToDoListController as ctrl">
  <h3>ToDo:</h3>
  <ul ng-repeat="task in ctrl.taskList">
    <li ng-if="!task.done" ng-class="{classdone: task.done}">
      {{task.text}}
      <input type="checkbox" ng-model="task.done" ng-click="ctrl.toggleDone(task)"></input>
    </li>
  </ul>

  <h3>Done:</h3>
  <ul ng-repeat="task in ctrl.taskList">
    <li ng-if="task.done" ng-class="{classdone: task.done}">  {{task.text}} 
      <input type="checkbox" ng-model="task.done" ng-click="ctrl.toggleDone(task)"></input>
    </li>
  </ul>

  <form>
    <input ng-model="taskText" type="text"></input>
    <button ng-click="ctrl.newTask(taskText)">Add Task</button>
  </form>
</body>

In your stylesheet, define the class .classdone which will be applied when task.done is true.

Within your Controller:

toDoList.controller('ToDoListController', function(){

  this.taskList = [];
  self = this;

  this.newTask = function(taskText){
    var newTask = {done: false, text: ""};
    newTask.text = taskText;
    self.taskList.push(newTask)
  };

  this.toggleDone = function(task){
    if(task.done == true){
      task.done = false
    }else{
      task.done = true
    }
  };
});

The key Angular components in this challenge: - automatic updates for both lists in the view - ng-if removing a task from the DOM based on the expression (task.done or !task.done) evaluation.

Please feel free to reach out if any part of this code requires further clarification.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to connect and interact with a different ng-controller's ng-model within a separate ng-controller?

Is it possible to access the ng-model from another ng-controller and if so, how can it be done? In this scenario, I am using two controllers. The first controller has a model called mddl1, while the second controller does not have any other model. However, ...

Add a unique CSS style to both text and image using anchor tags

Why isn't the hover effect of color transition and underline being applied to the image? It seems to only work for text. While I understand that the color transition may require a change in image color, shouldn't the underline still occur? This ...

Tips for adjusting the order in which styles load in NuxtJS

I need to adjust the loading order of styles in my current project. In my custom stylesheet style.css, I've made some overrides, body { font-family: "Lato", sans-serif; font-size: 14px; font-weight: 400; font-style: normal; ...

My div is currently being concealed by a jQuery script that is hiding all of its

Below is the current code snippet: jQuery(document).ready(function($) { $("ul.accordion-section-content li[id*='layers-builder'] button.add-new-widget").click(function() { $("#available-widgets-list div:not([id*='layers-widget']) ...

Dealing with 404 page not found error without replacing the default in Next.js 13

I followed the Next.js 13 documentation's suggestion to create a file called not-found.jsx in my app directory to handle 404 errors. But, despite placing it inside the app directory and intended for layout and loading purposes, it is not overriding th ...

Sharing information between controllers in OnsenUI using AngularJS and PhoneGap

I've encountered similar questions to mine that have been addressed, but I believe my scenario is unique. I began with the sample code available on this page for a basic app featuring a sliding menu integrated with Google Maps. My current project inv ...

Ways to emphasize search outcomes in Flask/HTML?

I am currently working on creating a search box using HTML and the Flask framework in Python. Below is the layout I am working with: Layout My goal is to input text into the search box and have it highlighted within the text area on the same HTML page. F ...

The Material UI read-only rating component fails to update even after the data has been successfully loaded

I have a rating component in my child component, and I am passing data from the parent component through props. However, there seems to be an issue with the MUI rating value not updating when the data is ready for viewing. https://i.sstatic.net/bqSfh.jpg ...

What is the method for rotating a map using JavaScript?

My map built with Leaflet displays a route and a moving car marker. Now, I am looking to implement a feature where the map rotates based on the direction of the car. I have access to both the current coordinates of the car and the target coordinates. ...

How to efficiently import Xlsx and csv files using AngularJS

I am looking for a way to extract data in json format from each line of xlsx and csv files using AngularJS. Currently, I am utilizing the angular-file-upload library to access the file as shown below: $scope.LatLongUploader = new FileUploader({ //url ...

Wiki experiencing issues with NodeJS HttpGet functionality

Goal Retrieve the HTML content of a Wiki Page. Introduction In an attempt to fetch the HTML of a Wiki page () for data parsing purposes, I am utilizing NodeJS and its HTTP Request methods. Code Snippet Below is the simple code snippet that accesses th ...

Angular2 - Error: The view has been destroyed and cannot be updated: detectChanges

My application keeps encountering this persistent error: extensions::uncaught_exception_handler:8 Error in event handler for runtime.onMessage: Attempt to use a destroyed view: detectChanges at ViewDestroyedException.BaseException [as constructor] (chrome ...

Display a hoverable button for a singular element within an array during the process of mapping through the array

const ChatWidget = () => { const bodyRef = useRef(null) const [{messages,roomMessages,roomID,socket,user}, dispatch] = useStateValue() const [dropdown, setDropdown] = useState(false) useEffect(()=>{ const setScreen = () =>{ bodyRef.cur ...

The appearance of a Phonegap-built application may vary when compared to running it on the Phonegap Developer app

Hey there! I've been experiencing some issues with my phonegap app. Everything runs smoothly when I use the app on my phone, but once I build the app, it appears completely different. The CSS is not being applied and everything looks much smaller than ...

The random quote generator or current tweet quote feature is malfunctioning

I am having trouble with a jQuery on click function that is not working to tweet the current quote. I am working on building a random quote machine and tweeting the current quote is essential. Despite successfully implementing the JSON API, I cannot seem t ...

Ways to prevent recurring variables in Twitter bootstrap dialogues

I need assistance with deleting multiple links using ajax: <a id="id-1">link1</a> <a id="id-2">link2</a> <a id="id-3">link2</a> <a id="id-4">link2</a> ... This is the simplified version of my code: $(docum ...

In a Vue.js application, parameter passing does not function as intended

As someone who is new to JavaScript, I have a question regarding Vuex and creating a simple Todo Manager. I am facing an issue with deleting todos from my list and not getting the desired parameter (the id of the todo) in my actions. Here is the code snip ...

I am facing difficulties in adding dynamic content to my JSON file

I've encountered a challenge in appending new dynamic data to a JSON file. In my project, I receive the projectName from an input form on the /new page. My API utilizes node.js's fs module to generate a new JSON file, where I can subsequently add ...

How can I transfer form data to a PHP variable using an AJAX request?

Encountering some difficulties, any insights? I have included only the necessary parts of the code. Essentially, I have an HTML form where I aim to extract the value from a field before submission, trigger an ajax call, and fill in another field. It seems ...

The 'else' statement does not seem to function properly with the 'src' attribute

I have been attempting to include alt text in a web page using jQuery with the code below. However, I am only able to get the correct value for the first image. The else if and else conditions do not seem to be working properly as I am unable to add alt ...