Angular: Selecting all checkboxes outside of an ng-repeat loop

Project Overview

In my project, there is a system for managing small product orders. Users have the ability to add order lines and attach one or more products to each order line. While it may be uncommon to have multiple products on the same order line, this functionality is supported in the system.

The selection of products for each line is structured based on a hierarchy. As an example:

Sample Product Hierarchy

T-Shirts
   V-neck
   Round-neck
   String vest

Data Structure (JSON)

$scope.products = [
{ 
  id: 1, 
  name: 'T Shirts', 
  children: [
    { id: 4, name: 'Round-neck', children: [] },
    { id: 5, name: 'V-neck', children: [] },
    { id: 6, name: 'String vest (exclude)', children: [] }
  ] 
},
{ 
  id: 2, 
  name: 'Jackets', 
  children: [
    { id: 7, name: 'Denim jacket', children: [] },
    { id: 8, name: 'Glitter jacket', children: [] }
  ] 
},
{ 
  id: 3, 
  name: 'Shoes', 
  children: [
    { id: 9, name: 'Oxfords', children: [] },
    { id: 10, name: 'Brogues', children: [] },
    { id: 11, name: 'Trainers (exclude)', children: []}
  ] 
}

];

While T-Shirts are not directly selectable, their child products can be added to the order line.

Objective

The primary goal is to implement a 'select all' button that automatically populates the order line with all three child products when clicked.

Additionally, the 'select all' functionality should exclude specific products based on their IDs as defined in the exclusion array.

A working demonstration of the shopping cart setup and desired behavior can be viewed on Plunker.

Current Functionality:

  • Add or remove order lines
  • Add or remove products
  • Select all products within a section while excluding those listed in the exclusions array

Issue Faced

An existing problem revolves around checkbox input elements not triggering the expected ng-change action when checked via the 'select all' feature:

<table class="striped table">
...

JavaScript Enhancements

Efforts were made to ensure smoother integration by refactoring the code to avoid excessive DOM manipulation. The revised approach involved introducing a 'checked' property within the product data structure to accurately reflect selections and update the view accordingly.

This new method, though effective, poses potential challenges related to increased data payload due to storing information about all products for every order line, regardless of selection status.

Noteworthy was the learning point regarding object/array references in JavaScript versus creating new copies.

Solution Implementation

Javascript snippet outline:

 var myApp = angular.module('myApp', []);
...

Explore the updated Plunker for a detailed solution overview.

Answer №1

You're making things more complicated by not utilizing objects and arrays in your controller functions, and relying too much on the DOM instead of data models to update states.

Here's a simpler approach that adds a checked property to each product using ng-model:

<!-- checkboxes -->
<li ng-repeat="child in product.children">
       <input ng-model="child.checked"  >
</li>

If adding properties to the items themselves isn't feasible, you can create another array for the checked properties that correspond with the child arrays. Utilize $index in ng-repeat for this purpose.

Also, consider passing entire objects into selectAll():

<a ng-click="selectAll(product,line)">

This allows you to handle it in your controller like so:

$scope.selectAll = function(product, line){      
  angular.forEach(product.children, function(item){
       item.checked=true;
  });
  line.products=product.children;      
}

Remember, when working with Angular, prioritize manipulating your data models and let Angular manage the DOM.

I recommend checking out: "Thinking in AngularJS" if I have a jQuery background?

DEMO

Answer №2

Why does ng-change fail to trigger when the checkbox is programmatically checked?

This issue occurs because

  if($scope.excluded.indexOf(parseInt(category)) == -1)
  {
    checkboxes[i].checked = true;
    // TODO: Check the checkbox, and set its boolean parameter to TRUE     
  }

Only impacts the view (DOM). The ng-change directive functions in conjunction with ngModel, which may not detect visual changes made to the checkbox.

I recommend looking into the solution outlined at How can I get angular.js checkboxes with select/unselect all functionality and indeterminate values?, as it accommodates any model structure you are working with (some may refer to this as the Angular way).

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

Tips for assisting flow with managing the initialization of react component state

In my React components, I am initializing state like this: export default class LoginForm extends Component { state = { // (*) flash: { message: null, style: null } // initialiser for flash message: show no ...

Show only the items in bootstrap-vue b-table when a filter is actively applied

How can I set my bootstrap-vue b-table to only show items when a filter is applied by the user (i.e., entered a value into the input)? For example, if "filteredItems" doesn't exist, then display nothing? This is primarily to prevent rendering all rows ...

What is the best way to start and display an animation for a div element?

Hey all! I'm trying to create a menu div layer that opens when a button is clicked and closes on mouseover using Angular. I want the div to start partially closed and then fully open on click, but my code isn't working as expected. Here's wh ...

Issue: EACCES error encountered while attempting to execute bower install operation

After running bower install css-circle-menu, I encountered the following error: /usr/local/lib/node_modules/bower/lib/node_modules/configstore/index.js:54 throw err; ^ Error: EACCES: permission denied, open '/Users/ja ...

JQuery Ajax request functioning smoothly while native JavaScript falls short

I am currently troubleshooting two AJAX calls. One is written in native JavaScript while the other utilizes JQuery to call a PHP script. The jQuery AJAX call seems to be functioning properly, but I am encountering issues with the JavaScript version. Here i ...

Highcharts failing to connect the dots with lines between data points

UPDATE: After some investigation, it turns out that the issue stemmed from inconsistent intervals. By following the solution outlined in this post, the problem was easily resolved. I have implemented highcharts to create a chart, where the initial data po ...

I am experiencing challenges with utilizing the fetch() function and am unable to retrieve the data

I'm currently struggling with integrating Google's reCaptchaV3 into my website, particularly when using the fetch() function. Here is the code snippet I have developed so far: function sendData(name, email, captcha) { const info = JSON.stri ...

Can you explain the distinction between a synchronous and asynchronous request in terms of their async parameter values (true/false)?

Can you explain the difference between setting async=false and async=true when utilizing the open method of the XMLHttpRequest? function GetXML() { if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp = new X ...

What is the best way to ensure that each link displays unique text in a separate div when clicked on?

<aside class="side_article_content"><p id="defaultText">Chakras are explained here.</p> <p id="baseChakraInfo" style="display:none;">Base Chakra details here.</p> <p id="sacralChakraInfo" style="display:none;">Sa ...

Can media queries styles be applied to a window of random size using JavaScript?

Can JavaScript be used to apply media queries style based on random window sizes? I have 5 buttons that I want to switch styles for using JavaScript according to the media queries defined in my CSS stylesheet. Is there a method to achieve this? ...

Disabling the current date on date pickers in material ui: A step-by-step guide

In my current React project, I am utilizing material-ui-date-pickers and need to prevent users from selecting today's date. This is important in the context of manufacturing products, managing expiration dates, and handling billing processes. Since a ...

Updating the parent's reference from a child component in Vue 3

In one of my child components, I have a component named Navbar that includes an option for logging out. <a @click="(event) => {event.preventDefault();}"> Logout </a> This Navbar component has been imported into my parent compon ...

Struggling to understand why I'm having trouble connecting my AJAX handler within WordPress

Following the instructions here as a guide seems to be leading me astray. After submitting the form below, a POST request to http://thesite/wp-admin/member-update results in a 404 error. I believed that this request should trigger my function member_update ...

What do you do when schema.parseAsync cannot be found?

Currently facing an issue with zod validation in my Node.js environment, specifically encountering the error: TypeError: schema.parseAsync is not a function Despite attempting various solutions like re-importing and troubleshooting, I am unable to resol ...

jQuery on-click event malfunctioning as expected

I'm currently developing a project that utilizes the GIPHY API to retrieve GIFs. Each time a search is performed, I am storing the search history as individual buttons which users can click on to view the results without needing to re-enter the search ...

ActivatedRoute not receiving the parameter value

Having trouble retrieving the parameter from the route and passing it to a function within the component which then communicates with the service. Initially tried placing the parameter retrieval in the NgInit but moved it to the constructor, still no succ ...

Submitting forms with Ajax in IE(8)

Sample Google form Related spreadsheet I modified the original code to create two custom forms: First created form Second created form Both forms are functional on most browsers except for IE(8). Any idea why? First form: <!DOCTYPE html> <h ...

Each Vue instance on the page has its own isolated Vuex store

I have a situation where I am creating multiple Vue apps on the same page: import Vue from "vue"; import App from "./App.vue"; import useStore from "./store"; const arr = [1, 2]; for (const index of arr) { const store = use ...

Looking to show the contents of a Rails AJAX JSON response in your application? Having trouble with Javascript displaying [object HTMLDocument] instead? Let

I have been working on a Rails application where I implemented an AJAX / JSON controller to facilitate dynamic HTML updates within the view. For guidance, I referred to this helpful resource: When making a call like this: ../related.json?vendor_id=1&b ...

Upload an array of choices to the server by utilizing ng-model

I have almost resolved my issue, but now I need help with sending the data to the server. In my current situation, there is a form that includes employee details and projects for that employee (which can be multiple). When the user wants to add projects, ...