Numerous perspectives within an angular.js application

Issue

I'm currently working on creating a product list with the following initial features:

  • Server-side pagination
  • Server-side filtering

I am facing several challenges with my current setup, but the main issue is that I can't figure out how to separate the views effectively. Currently, whenever the page is changed, the category list gets updated (and any checked items get unchecked).

Is there a way for me to load the category list only when the page initially loads?

Thank you

Code

index.html:

<div ng-app="relv">
    <div ng-view></div>
</div>

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<script src="//cdn.jsdelivr.net/angularjs/1.0.2/angular-resource.min.js"></script>
<script src="/angular/app.js"></script>
<script src="/angular/services.js"></script>
<script src="/angular/controllers.js"></script>
<script src="/angular/filters.js"></script>
<script src="/angular/directives.js"></script>

app.js:

'use strict';
angular.module('relv', ['relv.filters', 'relv.services', 'relv.directives']).
  config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/products', {templateUrl: '/angular/partials/product_list.html', controller: ProductListCtrl});
    $routeProvider.when('/products/:page', {templateUrl: '/angular/partials/product_list.html', controller: ProductListCtrl});
    $routeProvider.otherwise({redirectTo: '/products'});
  }]);

product_list.html:

<div id="category_list">
    <label ng-repeat="category in categories">
        <input type="checkbox" name="category" ng-model="filterCategories[category.id]"> {{ category.name }}
    </label>
</div>
{{ filterCategories }}

Product list, page {{ page }}.
<br><br>
<ul>
    <li ng-repeat="product in products">
        <a href="#/product/{{ product.id }}">{{ product.name }}</a><br>
        <span ng-repeat="category in product.categories">{{ category.name }}</span>
    </li>
</ul>

<a href="#/products/{{ page-1 }}">Previous page</a>
<a href="#/products/{{ page+1 }}">Next page</a>

controllers.js:

'use strict';

function ProductListCtrl($routeParams, $scope, ProductList, CategoryList) {
    $scope.page = $routeParams.page ? parseInt($routeParams.page) : 1;
    $scope.products = ProductList.query({'page': $scope.page});
    $scope.categories = CategoryList.query();
    $scope.filterCategories = {};
}
ProductListCtrl.$inject = ['$routeParams', '$scope', 'ProductList', 'CategoryList'];

services:js:

'use strict';

angular.module('relv.services', ['ngResource']).
    factory('Product', function($resource){
        return $resource('http://endpoint/api_dev.php/products/:productId.json', {}, {
            query: {method:'GET', params:{lang:'en'}, isArray:false}
        });
    }).
    factory('ProductList', function($resource){
        return $resource('http://endpoint/api_dev.php/products.json', {}, {
            query: {method:'GET', params:{lang:'en', page: ':page'}, isArray:true}
        });
    }).
    factory('CategoryList', function($resource){
        return $resource('http://endpoint/api_dev.php/categories.json', {}, {
            query: {method:'GET', params:{lang:'en'}, isArray:true}
        });
    })
;

Answer №1

If you want the category list to always be visible, insert this code into your index.html file, above <ng-view>:

<div id="category_list">
    <label ng-repeat="category in categories">
        <input type="checkbox" name="category" ng-model="filterCategories[category.id]"> {{ category.name }}
    </label>
</div>
{{ filterCategories }}

In this way, the category list will remain static even when navigating between routes within the application.

Update: Place the code responsible for loading the categories inside a new controller:

function CategoryCtrl($scope, CategoryList) {
    $scope.categories = CategoryList.query();
    $scope.filterCategories = {};
}

index.html:

<div ng-controller="CategoryCtrl">
  <div id="category_list">
     <label ng-repeat="category in categories">
        <input type="checkbox" name="category" ng-model="filterCategories[category.id]"> {{ category.name }}
     </label>
  </div>
{{ filterCategories }}
</div>

<div ng-app="relv">
    <div ng-view></div>
</div>

Answer №2

Whenever you switch between views, the entire page's HTML is swapped out, including the checkboxes.

Split the HTML code into two separate views: master and detail (a minor adjustment).

The Master view should contain the checkboxes and pager, while the Detail view should display the product list.

By doing this, AngularJS will only swap out the HTML related to the products, leaving the categories untouched.

This specific issue has been discussed in Google forums.

Updated: Example of moving categories outside of the detail view

<div id="category_list">
    <label ng-repeat="category in categories">
        <input type="checkbox" name="category" ng-model="filterCategories[category.id]"> {{ category.name }}
    </label>
</div>
{{ filterCategories }}

<div ng-app="relv">
    <div ng-view></div>
</div>


<a href="#/products/{{ page-1 }}">Previous page</a>
<a href="#/products/{{ page+1 }}">Next page</a>


<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
...

Alternatively

In this scenario, forego using views altogether. Instead, organize your products into groups and update the data using a repeater (similar to paging, refer to another example in my response here).

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 Saving process.argv in a .js File for Future Reference

I am struggling with passing process.argv value to a config file for later use. I am trying to call it from npm scripts. I have the following config file: module.exports = { foo: proccess.argv[2] } So far, I have tried calling it via node config.js &apo ...

Tips for concurrently and asynchronously executing multiple AJAX requests

I am working with a javascript object named Agendamento which includes the following key parts: const Agendamento = { // ... storeResultados: async function (consulta) { //... $.ajax({ type: 'POST', ...

grab the content from a text editor and insert it into a div element

Currently, I am trying to extract text from my content editable div and place it in another div (similar to the one seen on stack overflow). However, I am encountering a frustrating issue. 1. My content div seems to be lagging behind. When I type in my ed ...

Updating a table dynamically after a form submission using jQuery, Ajax, and PHP without needing to refresh the page

My current setup involves an ajax form along with a table. Here is the ajax code I am using: $(function () { $(".submitann").click(function () { var title = $("#title").val(); var announcement = $("#announcement").val(); var d ...

The functionality of the Eslint object-property-newline feature is not functioning as expected

Within my configuration file .eslintrc, I have set "object-property-newline": ["error", { "allowAllPropertiesOnSameLine": true }], and "max-len": "off". However, objects like const something = {a: 5, ffsdfasdasdsddddd: 'asdasdasdddddddddddssssssddddd ...

The specified container does not exist in the DOM: MERN

I am currently working on a project where I aim to develop a Web Application featuring a stock dashboard. During my coding process, I encountered a minor issue that can be seen in this image. My goal is to have a login form displayed on the browser using ...

Convert text into a clickable link

Creating a form with numerous text fields, some of which require numerical input. The main goal is to have users enter a tracking number, order number, or any other type of number that, when submitted, will open a new URL in a separate window with the spec ...

How can I customize button colors in react-bootstrap components?

Changing colors in react-bootstrap may be a challenge, but I'm looking to customize the color of my button beyond the primary options. Any suggestions on how I can achieve this using JS and SCSS? ...

Highlight and trim lengthy text using React

Imagine I have a lengthy text: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo con ...

Issue with AngularJS templates failing to hide a div while navigating between routes

My user registration process consists of two pages; the second page may vary depending on the role, but the first page remains constant. I want users to be able to navigate forward and backward on both screens with persistent data. I am attempting to use a ...

Unable to transfer Vue.js components in and out of the project

I have a directory structured like this. VueTree components Classic.vue Modern.vue index.js The Classic and Modern components consist of a template, export default {}, and a style. I am importing both of them in index.js as: import Classic ...

Utilizing jQuery for interacting with iframes

My script functions perfectly on the page, but when I embed it using an iframe, the jQuery features stop working even though the script is written as usual. Even using $.noConflict(); does not resolve the issue. ...

Exploring Protractor functionality by testing ui-bootstrap-alert with the dismiss-on-timeout attribute

When running my protractor test, I encountered an issue where an alert is displayed when an error occurs in the app. Here is a snippet of the relevant HTML: <uib-alert type="danger" dismiss-on-timeout="5000" close="closeAlert()"> <span>Err ...

Guide to activating the 'Next' button on WP Forms using JavaScript code when certain conditions are fulfilled

Is there a way to adjust the JavaScript code provided so that the visibility of the "Next" button is dependent on whether at least one item in the 'wpforms-icon-choices-item' class has the '.wpform-selected' class on the current page or ...

Are NPM and Eslint supposed to be this confusing, or am I missing something?

Recently, I've started delving into the world of JS and have been eager to learn more about linting. Following a tutorial, we set up the lint stage in our package.json file. The configuration looks like this: "lint": "./node_modules/.bin/eslint ." U ...

Steps for transferring an `<li>` element from one `<ul>` to another

<ul id="List"> <li class="li">1</li> <li class="li">2</li> </ul> <ul id="List2"></ul> const items = document.querySelectorAll(".li"); for(var i = 0; i < ...

Issues with AngularJS Directives not functioning properly when elements are added dynamically through an AJAX request

I am facing a scenario where I have a page featuring a modal window that is created using the AngularUI Bootstrap modal directive. The DOM structure for this modal is being dynamically loaded from the server, and it is triggered to open when a specific but ...

Can I programmatically retrieve a comprehensive list of all global HTML attributes available?

Exploring the extensive list of global HTML attributes can be overwhelming, especially when considering how it continues to evolve with browser updates. Can JavaScript be leveraged to dynamically generate a complete list of these attributes without the ne ...

Unable to POST data from Angular.js to Express.js

I'm facing issues with the communication between my Angular.js application and my Express.js REST API. I am using Yeoman 1.0 along with generator-angular 0.7.1. I attempted to use a middleware configuration for my grunt serve, but I could not get it ...

When working with JavaScript and Node.js, it is not possible to access an object's index that is

Utilizing babyparse (PapaParse) in nodejs to convert CSV to JavaScript objects has been quite challenging for me. After processing, the output of one object looks like this: { 'ProductName': 'Nike t-shirt', ProductPrice: '14.9 ...