Attempting to control an array of objects

In my current records:

The parts with IDs 14.3, 14.2, and 14.1 belong to part ID = 30.

The goal is to achieve the following:

1) By default, the first two IDs will be selected. If a user tries to select ID = 71, which belongs to part 30, they should not be allowed because a higher version of part 30 (ID = 76) is already selected.

2) If a user unchecks ID = 77(33), then they should be allowed to check ID=71 because there are no different parts selected. The user should be allowed to check all parts with ID = 30 but as soon as a different part is selected, the lower part should be unchecked.

Issue with the code:

1) When I uncheck 16.1 and try to check 14.2, I am not allowed to do so even though there are no different parts selected.

2) Both 16.1 and 14.3 are checked by default. Now if I check 15.1 and then check 14.1, it causes 14.3 to get unchecked, which is incorrect as 14.3 is the highest among part ID = 30, so I shouldn't be able to check 14.1.

  
                var app = angular.module('myApp', []);
                app.controller('myCtrl', function ($scope) {
                    $scope.myArray = [
                        {
                            "id": 77,
                            "selected": true,
                            "part": 33,
                            "name": "16.1", 
                         },
                        // Include the rest of the array items here...
                    ];
                    
                    // Function for checking item selection logic
                    $scope.checkItem = function (item) {
                        // Write your logic here
                    };
                });
            

                <!DOCTYPE html>
                <html ng-app="myApp" ng-controller="myCtrl">
                <!-- HTML content removed -->
                </html>
            

Answer №1

My preferred approach involves separating some of the logic into a service to maintain clean code. This strategy makes it easier for me to manage, debug, and test the code effectively. Check out this fiddle

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

 app.controller('myCtrl', function($scope, myCollection) {
   $scope.myArray = myCollection.items;

   // Invoke function whenever an item is checked
   $scope.checkItem = function(item) {

     // Rearrange collection items before and after 
     myCollection.mapCheckedItems();

     // Perform actions based on user interaction only if there are
     // multiple selected parts by definition
     if (item.selected && myCollection.selectedPartsOnly.length > 1) {

       // Iterate through the selected parts
       myCollection.selectedPartsOnly.map(part => {

         // Retrieve the array of items associated with the specific part number
         var map = myCollection.selectedPartsMap[part];

         for (var j = map.length - 1; j > 0; j--) {
           // Deselect all except the highest version by definition.
           // This occurs when different part numbers are selected simultaneously
           map[j].selected = false;
         }
       })

     }

     // Update collection map to synchronize with the
     // items' array
     myCollection.mapCheckedItems();

   };

 });

 app.service('myCollection', function() {
   // Initialize the collection object
   var self = {};

   // Function to calculate and map items' dependencies
   self.mapCheckedItems = mapCheckedItems;

   // Store a list of selected unique part numbers
   // Helps determine necessary actions easily. If only 
   // one part number is selected, iterate through the map
   self.selectedPartsOnly = [];

   // Dictionary mapping part numbers to their child items
   // Enables easy access to items grouped by part number
   self.selectedPartsMap = {};

   // Define the actual array of items
   self.items = [{
     "id": 77,
     "selected": true,
     "part": 33,
     "name": "16.1",
   }, {
    ... (remaining original data omitted for brevity)
   }];

   // Initialize the helpers once at start. Executes just once
   mapCheckedItems();

   // Return the service object for controller access
   return self;

   // Create and update the objects mapping in this function
   function mapCheckedItems() {

     // Reset the helper variables
     self.selectedPartsOnly = [];
     self.selectedPartsMap = {};
     
     // Iterate through the selected items         
     self.items
       .filter(item => item.selected)
       .map(item => {

         // Map each selected item directly to a part number
         mapSelectedParts(item);

         // Identify which part numbers are in use
         mapSelectedPartsOnly(item.part);
       })
   }

   function mapSelectedPartsOnly(part) {
     if (self.selectedPartsOnly.indexOf(part) == -1)
       self.selectedPartsOnly.push(part);
   }

   function mapSelectedParts(item) {
     if (!self.selectedPartsMap[item.part])
       self.selectedPartsMap[item.part] = [];

     self.selectedPartsMap[item.part].push(item);
   }

 })
<!DOCTYPE html>
<html ng-app="myApp" ng-controller="myCtrl">
<head>
    <title></title>
    <meta charset="utf-8" />
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
    <div ng-repeat="item in myArray">
        <input ng-model="item.selected" ng-click="checkItem(item)" type="checkbox" />{{ item.name }}
    </div>
</body>
</html>

Answer №2

I have devised a solution that addresses both points and resolves the issues mentioned above.

To implement this, you just need to update the checkItem function in the controller.

$scope.checkItem = function(item) {
  // Code implementation here
};

You can view a working example on this fiddle.

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

Opposite path matching with Next.js middleware

For my Next.js project, I have implemented a middleware and now I need it to only apply to routes that do not start with /api/. I have checked the documentation but couldn't find a similar example. Is there a way to achieve this without manually excl ...

Utilizing jQuery.post to generate a dynamic dropdown menu

I recently designed a dropdown list that functions well on a standalone page. However, I encountered an issue when attempting to display it in a table on another page using jQuery.post(). The contents appear to overflow from the dropdown list. The jQuery ...

Where is the destination of the response in a Client-Side API Call?

I have developed an API that accepts a person's name and provides information about them in return. To simplify the usage of my API for third parties on their websites, I have decided to create a JavaScript widget that can be embedded using a script ...

Concealing a div based on the checkbox's updated selection

Hello, I am currently working on a project that involves using both Angular and jQuery with checkbox controls. In this particular scenario, I have two checkboxes where selecting one checkbox should display its respective div, as each checkbox is associat ...

I require the capability to retrieve JSON data from beyond the confines of the function

After searching, I was unable to locate it. In my possession is a javascript file and a separate file named data.json. data.json { "today": [ { "id": 1, "title": "Note 1", "date": "21.05.2019", "text": "Lorem ipsum dolor sit ...

Extract JSON content from an array's values containing underscores

I am currently working with an array of objects and need to implement a filter on it. The objects in the list contain an owner_id property within the JSON... Currently, I am looping through all the items in the array. However, I want to exclude those wher ...

Modifying the color of specific sections of SVG elements

Interested in utilizing the d3.js timeknots component, a svg visualization that includes line and circle elements. My goal is to implement a stopwatch animation that dynamically changes the color of the svg visualization over time. I am contemplating crea ...

Having trouble with the click button flip function? It seems to be working in one section but not in

Currently, I am facing an issue with a card section that contains two buttons and a description. The first button adds an image which is working perfectly fine, as well as the description section. On the other hand, the second button adds a video and when ...

Having trouble selecting an element by name that contains a specific string followed by [..] using jQuery

I have elements with names like kra[0][category], kra[1][category], and so on. However, I am facing difficulties in selecting these elements by name. Here is my jQuery code: $("[name=kra[0][category]]").prop("disabled", true); ...

Implementing Angular checkbox repetition controlled from an external controller

I'm looking to streamline my controller by setting a variable from outside the controller to populate my checkbox list. Can this be done? Check out my current code snippet here: http://jsfiddle.net/ilmansg/Lx37kr3e/1/ VIEW HTML <div ng-controlle ...

unable to submit form using angular and express

I am encountering an issue with a post request in AngularJS to express. The HTML form on the client side is defined as follows: <div ng-controller="LoginCtrl"> <form ng-submit="login()"> <div> <label>Username</lab ...

The Javascript function fails to trigger during the OnKeyPress and OnKeyDown events

I have encountered an issue while trying to call a function called validateQty on both the onkeypress and onkeydown events of a text input field. When I was passing only one parameter, which is the event itself, everything was working perfectly fine. Howev ...

The Controller's ActionResult methods are not successfully collecting form data sent through an ajax request

I'm facing an issue with my purchase form where the purchase_return object in the controller is not receiving any data. It seems to be getting productId as 0 and productNm as null. Can someone help me figure out what's causing this issue? Here&a ...

What is the best way to correctly render several React components using a single index.js file?

I am facing an issue with rendering two React component classes. One class creates a counter and works fine, while the other class generates a simple string wrapped in HTML tags but does not render. I have tried various tutorials to troubleshoot this probl ...

Automatically update Dropdown options with value and text through an ajax json request

I am working on dynamically populating a dropdown list with text and values fetched using an ajax call to retrieve a JSONObject. While my current code successfully populates the dropdown, I need the value to be different from the text as I intend to store ...

A guide to troubleshooting the "Cannot resolve all parameters error" in Angular

Recently delved into the world of angular 2, and I've come across my first challenge. I'm trying to establish a service for retrieving data from a server but I keep encountering this particular error Error: Can't resolve all parameters fo ...

What is preventing me from loading js and css files on my web pages?

I have developed a web application using SpringMVC with Thymeleaf and I am encountering an issue while trying to load javascript and CSS on my HTML5 pages. Here is a snippet from my login.html: <html xmlns="http://www.w3.org/1999/xhtml"> <head&g ...

What are some ways to get Angular2 up and running in a newly created distribution directory?

Trying to setup my own Angular2+Typescript (+SystemJS+Gulp4) starter project has hit a roadblock for me. I encountered issues when transitioning from compiling TypeScript in the same folder as JavaScript with access to the node_modules folder, to organizin ...

When additional elements follow, the button ceases to function properly in JavaScript

I am working on creating a text-based idle game that involves multiple buttons and text around them. However, I have encountered an issue where the functionality stops working when I try to add text after the "Work" button. The callback function is no lon ...

Simultaneous malfunction of two ajax forms

I have a dilemma with two boxes: one is called "min amount" and the other is called "max amount." Currently, if I input 100 in the max amount box, it will display products that are priced at less than $100. However, when I input an amount like $50 in the m ...