Filter ng-repeat according to the user's choice

Currently, I am developing a music catalog and working on implementing a feature that allows users to filter the catalog based on a list of artists and genres

The list:

    <ul class="artists">
        <li class="title">
            <h5>Artists</h5>
            <ul class="sub-menu">
                <li ng-repeat="artist in music | orderBy:'-views'">
                    <p ng-click="select(artist.artist)">{{artist.artist}}</p>
                </li>
            </ul>
        </li>
    </ul>

I attempted to create a custom filter but found it challenging to grasp the concept. All I managed to do was extract the value from the selected option.

    // value from ng-click
    $scope.select = function(value){
        filterBy = value;
    }

I understand I can use the filter in ng-repeat by adding

ng-repeat="artist in music | filter: {artist:'artistName' | orderBy:'-views'}"

However, how do I change the artist: 'value' based on what the user selects from the list?

This is the main area where I am focusing on filtering:

    <div class="item" ng-repeat="artist in music | orderBy:'-views'"> 
        <div class="img">
            <img ng-src="{{artist.image}}"/>
        </div>
        <div class="info">
            <h6>{{artist.artist}}</h6>
            <p>{{artist.songName}}</p>
        </div>
    </div>

Initially, all items should be displayed when the view loads, and then the user can select an artist or genre from the list to filter the results. My thought was to include the custom filter function inside the click function so that the value from the click function could be passed into the custom filter and update the filter with the correct value. However, I struggled to implement this.

Being new to angular.js, if my explanation isn't clear enough, here is a JSfiddle replicating my project.

http://jsfiddle.net/0n2qptg6/5/

Thank you in advance for any assistance, suggestions, or feedback.

Answer №1

Check out the live demonstration here

To make the filter work for your music album list, you must assign it to the $scope:

$scope.selectArtist = function(value){
    // Value passed from ng-click
    $scope.filterByArtist = value;
    alert(filterBy);
}

$scope.selectGenre = function(value){
    // Value passed from ng-click
    $scope.filterByGenre = value;
    alert(filterBy);
}

Afterwards, apply the filter to your music album list like this:

<div class="item" ng-repeat="artist in music | 
   filter:{ artist: filterByArtist, genre: filterByGenre } |
   orderBy:'-views'">

Answer №2

To enhance user experience, consider implementing a filter object that dynamically updates when users interact with different elements. Utilize this filter within the ng-repeat tag for efficient filtering.

<div class="item" ng-repeat="artist in music | filter:filteredBy | orderBy:'-views'">

Revise the methods as follows:

$scope.selectArtist = function(value){
   //triggered by ng-click
    $scope.filteredBy.artist = value;
}

$scope.selectGenre = function(value){
    //triggered by ng-click
    $scope.filteredBy.genre = value;
}

Refer to the updated fiddle for a practical demonstration:

http://jsfiddle.net/0n2qptg6/6/

Feel free to optimize the implementation further if needed, but the provided solution should suffice.

Answer №3

First off, the filter parameters are bindable, allowing you to implement something like this:

ng-repeat="artist in music | filter: {artist: path.to.artistSearchTerm | orderBy:'-views'"}
.

Here's an example that includes a text input and a select list as filters. This concept can be expanded to include checkbox lists and select dropdowns.

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

app.filter('unique', function() {

  return function (arr, field) {
    var o = {}, i, l = arr.length, r = [];
    for(i=0; i<l;i+=1) {
      o[arr[i][field]] = arr[i];
    }
    for(i in o) {
      r.push(o[i]);
    }
    return r;
  };

});

app.controller('MainCtrl', function($scope, $http, $filter) {

    $scope.music = [ { "artist": "noisia", "songName": "machine gun", "genre": "Drum and Bass", "views": "19" }, { "artist": "etnik", "songName": "n7", "genre": "Techno", "views": "30" }, { "artist": "Jack U", "songName": "To U", "genre": "RnB", "image": "images/cover_3.jpg", "views": "32" }, { "artist": "Makonnen", "songName": "Tuesday", "genre": "Electronic", "image": "images/cover_4.jpg", "views": "72" }, { "artist": "Dillon Francis", "songName": "When We Were Young", "image": "images/cover_5.jpg", "views": "54" }, { "artist": "Justice", "songName": "Stress", "image": "images/cover_6.jpg", ...
    
    $scope.filteredBy = {
        artist: '',
        genre: ''
    };

    $scope.clear = function() {
        $scope.filteredBy.artist = '';
        $scope.filteredBy.genre = '';
    }
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js"></script>
<div  ng-app="main"  ng-controller="MainCtrl">
    <div class="nav">
        <p> 
            <label for="byArtistInput">Choose Artist:</label>
            <input id="byArtistInput" type="text" ng-model="filteredBy.artist" />
          
            <label for="byGenreInput">Choose genre:</label>
            <select id="byGenreInput" 
                    ng-model="filteredBy.genre" 
                    ng-options="song.genre as song.genre for song in music | unique: 'genre'"></select>
            <button type="button" ng-click="clear()">clear</button>
        </p>
    </div>

    <div class="clear"></div>

    <div class="content">
        <div class="item" ng-repeat="artist in music | filter:filteredBy | orderBy:'-views'">
            <div class="border">
                <!--   | filter: {artist:'etnik'}   -->
                <div class="img"></div>
                <div class="sub-info">
                   <h4>{{artist.artist}}</h4>   
                   <p>{{artist.songName}}</p>  
                </div>
            </div>
        </div>
    </div>
</div>

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

Integrating VueJS seamlessly with your current Angular project

I am currently working on an angular application and I am interested in transitioning parts of it to a vueJS application. During development, all scripts are loaded in the main html file (in production mode they are bundled into app.js, but I would like t ...

Utilizing Selenium to locate an element by its class name and then deleting it from the document object model through

I have found a code that worked really well for me. It involves getting the quantity of messages first and then removing them from the DOM. public static void RemoveMessages() { // Removing messages from the DOM using JavaScript ...

Using AngularJS date picker to set value in Spring model setter

When using AngularJS with Spring, I noticed a discrepancy in the date values between my view file and the POJO User object. In my view file, I have used an input type date to bind the "user.dateOfBirth" attribute. When I select a date, it is displayed cor ...

Is it possible to integrate HTML pages as sections within an HTML file using AngularJS?

There are three individuals each working on separate sections of a webpage. One is focusing on moving images, another is devoted to the tab section. This begs the question: 1) Is it feasible to embed all these HTML sections into a single HTML page and dis ...

Tips for utilizing callback function in Angular 4

I previously used the Google API to obtain a current address and now I want to incorporate a callback function in this process using Angular 4. How can I go about implementing it? let geocoder = new google.maps.Geocoder(); geocoder.geocode({ &ap ...

Ensure accurate detection of invalid values for SVG Elements in React using jest testing framework

When testing my react app, I am attempting to capture any errors that are thrown or logged to the console. If a regular HTML element such as <p> contains invalid attributes like <p color={false}></p>, react will display an error via cons ...

Struggling to incorporate pagination with axios in my code

As a newcomer to the world of REACT, I am currently delving into the realm of implementing pagination in my React project using axios. The API that I am utilizing (swapi.dev) boasts a total of 87 characters. Upon submitting a GET request with , only 10 cha ...

The React/Redux application is experiencing difficulties with API calls, as they are returning empty responses and the actions are not being triggered

Hey there, I'm currently working on a React Native app and running into some issues with making API get requests. It seems like the response is throwing an error and the action isn't executing properly. I'll share my code below, so if anyone ...

Get the XML element containing the desired value in the downloadURL

Seeking assistance from experienced individuals regarding XML usage. Admitting to my lack of knowledge in this area, I am a beginner and seeking patience. I have successfully implemented code that loads marker data from a MySQL database and displays it on ...

Checking CORS permissions with a pre-flight OPTIONS request

During development, I implement a middleware called cors using the following syntax: app.use(cors({origin: 'http://localhost:8100'})); However, I have noticed that for every route request, two requests are being made as shown in the image below ...

Unleashing the power of scroll-based dynamic pagination in ReactJS

I have 33 entries in a json format. I've implemented a code that tracks the scroll on my page and loads new 10 entries at a time. Everything works smoothly when the scroll value is set to equal or less than zero. When the scroll reaches the bottom of ...

When pasting Arabic text into an input box, the words in HTML appear to be jumbled and shuffled around

When I replicate this text يف عام and input it into a box, the output is shown as follows عام يف ...

Error encountered: jQuery AJAX JSON request failed to be caught

While my WordPress AJAX process is successful, a peculiar error keeps popping up in Chrome Devtools: Uncaught TypeError: Cannot read property 'vehicle' of undefined. It's puzzling, as the parsed JSON data seems to be in the correct object fo ...

The ExpressJS app generator seems to be struggling to identify and interpret the flags

I seem to be having trouble running the express app generator with flags. For example, when I run express --version, it interprets the --version part as a target directory and creates the app there. This is happening on Windows XP SP3. Could I be doi ...

Attempting to transmit a dynamic array of promises from Angular to an Express server

Currently, I am attempting to send an array of promises to an express app in order to retrieve data from a mongo database. The behavior seems to be working fine on the front end. In this scenario, both objects are sent to the server and resolved using $q ...

Issue with custom fonts not showing in PDFs when using Puppeteer, even though they are displayed in screenshots

I've been working on dynamically creating PDF files using the puppeteer library, but I'm facing an issue where the generated PDF doesn't display the custom fonts (.woff) that I have specified. Instead, it defaults to using the system font, T ...

Attempting to insert items into a storage array and subsequently outputting them using a loop

I am attempting to add "contacts" to local storage, and every time I add a new contact I want to refresh it in a jQuery list. I have successfully achieved this without using local storage. However, now I am facing a problem that I can't seem to solve. ...

Unusual issue encountered in next.js production: ENOENT error - File or directory not found (image cache)

Encountering an issue with my AWS EC2 deployment of next.js. After running npm run build followed by npm run start, everything appears to be functioning correctly. Initially, there are no webp images in the cache as expected. However, I have noticed that t ...

Display a div in JQuery along with all of its associated label elements

Here is my HTML code: <div id="summarySpan" style="padding-left: 20px" hidden> <label id="currentStatusSummary" style="padding-left: 20px" /> <br /> <label id="currentMonitoringSummary" style="padding-left: 20px" /> < ...

A comprehensive guide on displaying data in Angular using an API

I have encountered an issue while trying to display data from an API in the 'home.component.html'. Although my 'home.component.ts' successfully fetches the data from the service, I'm facing difficulty rendering it in 'home.com ...