Organizing AngularJS ng-repeat into sets of n items

I am facing a challenge with a data set structured like this:

$scope.items = [
    { model:"A", price: 100, quantity: 30}, 
    { model:"B", price: 90, quantity: 20 },
    { model:"C", price: 80, quantity: 200 }, 
    { model:"D", price: 70, quantity: 20 },
    { model:"E", price: 60, quantity: 100 }, 
    { model:"F", price: 50, quantity: 70 },
    { model:"G", price: 40, quantity: 230 }, 
    { model:"H", price: 30, quantity: 50 }
];

My goal is to utilize ng-repeat while grouping the items in sets of 4, resulting in an output similar to this:

<ul>
    <li> model:"A", price: 100, quantity: 30</li>
    <li> model:"B", price: 90, quantity: 20</li>
    <li> model:"C", price: 80, quantity: 200</li>
    <li> model:"D", price: 70, quantity: 20</li>
</ul>
<ul>
    <li> model:"E", price: 60, quantity: 100</li>
    <li> model:"F", price: 50, quantity: 70</li>
    <li> model:"G", price: 40, quantity: 230</li>
    <li> model:"H", price: 30, quantity: 50</li>
</ul>

Furthermore, I aim to implement sorting by both price and quantity. While I attempted to achieve this using the ng-repeat directive within a limited slice range, it only allowed me to sort within each group. Additionally, I am seeking a solution that can adapt to any number of elements dynamically. The suggested approach mentioned in this Stack Overflow post relies on knowing the exact number of items beforehand.

Note: I prefer to avoid utilizing the pagination directive due to conflicts with other scripts.

Thank you for your assistance!

Answer №1

Utilized lodash's _.sortBy and _.chunk functions to create a working example:

Link to the example

If you want to shorten the code, replace:

$scope.itemssorted = _.sortBy($scope.items, 'price');

with:

$scope.itemschunk = _.chunk(_.sortBy($scope.items, 'price'), 4);

New jsfiddle link: New Example Link

Example with sort buttons on jsfiddle: Sort Buttons Example

Documentation:

._sortBy() -> _.sortBy Documentation ._chunk() -> _.chunk Documentation

jsfiddle code:

Script:

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

app.controller('theController', ['$scope',function($scope){
    $scope.test = 'sample test text';

  $scope.items = [
    { model:"A", price: 100, quantity: 30}, 
    { model:"B", price: 90, quantity: 20 },
    { model:"C", price: 80, quantity: 200 }, 
    { model:"D", price: 70, quantity: 20 },
    { model:"E", price: 60, quantity: 100 }, 
    { model:"F", price: 50, quantity: 70 },
    { model:"G", price: 40, quantity: 230 }, 
    { model:"H", price: 30, quantity: 50 }
    ];

  //$scope.itemssorted = _.sortBy($scope.items, 'price');
  //example: reverse array
  //$scope.itemssorted = _.sortBy($scope.items, 'price').reverse();

  $scope.itemschunk = _.chunk(_.sortBy($scope.items, 'price'), 4);


  console.log("items: ", $scope.items);
  console.log("items chunked: ", $scope.itemschunk);
  //console.log("items sorted: ", $scope.itemssorted);

}]);

HTML:

<div ng-app="anExample" ng-controller="theController">

    Hello, {{test}}!
    <ul ng-repeat="group in itemschunk">
      <li ng-repeat="items in group"> Model: {{items.model}}, price: {{items.price}}, quantity: {{items.quantity}}</li>
    </ul>

</div>

Result:

Hello, this is a test!

Model: H, price: 30, quantity: 50
Model: G, price: 40, quantity: 230
Model: F, price: 50, quantity: 70
Model: E, price: 60, quantity: 100

Model: D, price: 70, quantity: 20
Model: C, price: 80, quantity: 200
Model: B, price: 90, quantity: 20
Model: A, price: 100, quantity: 30

Answer №2

To start, organize your data within the controller. After that, utilize nested ng-repeat in the view and implement the orderBy condition.

Controller

$scope.items = [
  { model:"A", price: 100, quantity: 30}, 
  { model:"B", price: 90, quantity: 20 },
  { model:"C", price: 80, quantity: 200 }, 
  { model:"D", price: 70, quantity: 20 },
  { model:"E", price: 60, quantity: 100 }, 
  { model:"F", price: 50, quantity: 70 },
  { model:"G", price: 40, quantity: 230 }, 
  { model:"H", price: 30, quantity: 50 }
];

$scope.groupedItems = _groupItems($scope.items, 4, 'price');

function _groupItems (items, size, sort) {
  var grouped = [],
      index = 0;

  if (angular.isDefined(sort)) {
    $filter('orderBy')(items, sort);
  }

  for (var i = 0; i < items.length; i++) {
    if (angular.isUndefined(grouped[index])) {
      grouped[index] = [];
    }

    grouped[index].push(items[i]);

    if ((i+1) % size === 0) {
      index++;
    }
  }

  return grouped;
}

View

<ul ng-repeat="group in groupedItems">
  <li ng-repeat="item in group | orderBy:'price'">
    model:"{{item.model}}", price:{{item.price}}, quantity: {{item.quantity}}
  </li>
</ul>

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

The JavaScript library known as Microsoft JScript Angular is not recognized

While integrating Angular into my .Net MVC website, I keep running into a runtime error that reads as follows: 0x800a1391 - Microsoft JScript Runtime Error: 'angular' is undefined. This essentially means that the 'angular' object ...

Having trouble getting the Google motion chart to work with asynchronous JSON requests

I have been using the code below to make a request for a JSON file and then parsing it. google.load('visualization', '1', {packages: ['controls', "motionchart", "table"]}); google.setOnLoadCallback(function(){ createTable($(& ...

I'm experimenting with crafting a new color scheme using MUI, which will dynamically alter the background color of my card based on the API

I am attempting to create a function that will change the colors based on the type of Pokemon. However, I'm not sure how to go about it. Any suggestions or ideas!? Check out where I'm brainstorming this logic [This is where the color palette sh ...

How many characters are in SCEditor? Let's calculate and display the count

Currently, I am utilizing the real simple WYSIWYG editor SCEditor for my website. I am curious about how I can precisely determine the current number of characters in its textarea and display them below it? Although I posted a question on GitHub, it seem ...

What is the best way to add <li> to every element in an array?

I had a tough day today trying to figure out my code. My English isn't the best, so explaining my issue is hard. I decided to illustrate my problem in HTML and specify the kind of styling I need to achieve with JS. I also included an example using the ...

Redux-form fails to retrieve the value of the SelectField

I'm trying to work with a simple form using react and redux-form. My goal is to gather all the field values from my form and send them to my RESTful API using jQuery ajax. Unfortunately, I've run into an issue where redux-form doesn't seem ...

What is the implementation of booleans within the Promise.all() function?

I am looking to implement a functionality like the following: statusReady: boolean = false; jobsReady: boolean = false; ready() { return Promise.all([statusReady, jobsReady]); } ...with the goal of being able to do this later on: this.ready().then(() ...

Capturing screenshots with Selenium in Node.js is proving to be quite sluggish

My current project involves using Selenium with Mocha in Node.js for UI testing on a website. I want to capture screenshots after each test to review and share the results visually. The challenge arises when there are AJAX calls and JavaScript animations ...

I attempted to upload an image using the Google Drive API, but encountered an error in the response

I am attempting to upload an image using the Google Drive API, but I encountered an error in the response message. The error reads as follows: "Failed to load resource: the server responded with a status of 403 ()" ...

Guide to retriecing a state in Next.js 14

Check out my code below: "useState" // firebase.js import firebase from "firebase/app"; import "firebase/auth"; // Import the authentication module export default async function handler(req, res) { if (req.method !== " ...

Exploring the world of routing parameters in Express.js and AngularJS

Struggling to configure routes with parameters in an AngularJS application supported by a node.js server running on express. The setup involves Node routing all unspecified paths to a catch-all function: app.use(express.bodyParser()); app.use(app.router); ...

How can I retrieve and manipulate the text within an option tag of a form using JavaScript?

<select name="products"> <option value=""> - Choose - </option> <option value="01">table</option> <option value="02">chair</option> <option value="03">book</option> <option value= ...

IE encountered an invalid character

While working on a JavaScript function, I encountered an issue with a string variable. Specifically, when running the page in IE with this script, I receive an error message indicating an invalid character at the following line: let displayString = `${s ...

Experimenting with Selenium to automate processes involving dynamic class attributes

My issue involves a Button class = "searchbar__SearchButton-sc-1546roh-3 searchbar__CancelButton-sc-1546roh-4 glEceZ" I am attempting to locate this element in the browser using return browser.element('button[class^="searchbar__CancelButton-"]&ap ...

A guide on extracting the current website URL in a React application

I wanted to find a method to duplicate the text from a URL so that users could easily share the link with others. ...

Reload iframe content using a .php file within a different iframe

I am currently working on a page that consists of 7 different iframes: <iframe id="leftframe" src="structure/leftbar.php"></iframe> <iframe id="headerframe" src="structure/header.php"></iframe> <iframe id="menuframe" src="struct ...

If the browser is Internet Explorer, then load file [A]; otherwise, load file [B]

One of my webpages requires unique content to be loaded for different web browsers. For example: If the browser is Internet Explorer {include file="/content1.tpl"} Else if it's any other browser {include file="/content2.tpl"} {/if} Content1. ...

What steps should I take to address the issue of fixing the classname rather than using the

<div ng-class:"{{myclass}}" role="progressbar" aria-valuenow="{{roundedtotalPerformanceCount}}" aria-valuemin="0" aria-valuemax="100" ng-style="{'width' : ( totalPerformanceCount + '%' ) }"> {{roundedtotalPerformanceCou ...

How to populate a database with Facebook data by utilizing AJAX post and PHP

I've been developing a Facebook Canvas game and had it running smoothly on my localhost along with a local database via phpMyAdmin. However, after moving it online, I've encountered an issue with the database. Previously, the game would grab pla ...

Guide on accessing and displaying data table values in console.log using Vue.js and vuetify

Hello, I am new to Vue.js and I am trying to work with data tables. I have copied some code from the Vuetify website and I am attempting to call the desserts' names from a sample table using console.log. Below is the code snippet: <template> ...