npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ng-paginable

v1.52.3

Published

Paginated table/list

Downloads

795

Readme

Paginable

This is an Angular module that provides a table component with sorting and filtering capabilities. Out-of-the-box integration with Laravel responses and other frameworks and Boostrap layout.

Versions

| Angular | ng-pagination | |------------------|:---------:| | >=14.0.0 <18.0.0 | v1.x |


Table of contents

Features

  • [x] Customizable pagination object
  • [x] server or local pagination option
  • [x] Filtering and sorting
  • [x] Customization of headers, cells, filters, error message and no items message through templates
  • [x] Columns with action buttons
  • [x] Individual and multiple row selection
  • [x] Integration of selection with reactive forms
  • [x] Batch action buttons and dropdowns
  • [x] Column resizing
  • [x] Global and column-specific search engine
  • [x] Adapted to Bootstrap 5,
  • [x] Responsive table
  • [x] Pagination customization options
  • [x] Accessibility
  • [x] Expandable columns

Getting started

Installation

To install this component, run the following command in your project directory:

npm install ng-paginable --save 

Usage

To use this component, import it into your module:

import { NgPaginableModule } from 'ng-paginable';  
@NgModule({   
	imports: [NgPaginableModule.forRoot()] 
}) 
export class AppModule {}      
código del componente
<paginable-table [headers]="headers" [pagination]="pagination">
</paginable-table>

Table Options

The paginated table component accepts a PaginableTableOptions object to customize styling and behavior via the @Input() options binding.

The available options are:

  • serverSidePagination - Enable server-side pagination. Default is false.

  • cursor - Cursor style when hovering rows. 'pointer' or 'default'.

  • hoverableRows - Enable highlight row on hover. Default false.

  • striped - Stripe table 'rows' or 'columns'.

  • variant - Color variant for styled tables. Accepts any string value.

For example:

@Component({

  // ...

})
export class TableComponent {

  options: PaginableTableOptions = {
    serverSidePagination: true,
    cursor: 'pointer',
    hoverableRows: true,  
    striped: 'columns',
    variant: 'dark'
  };

}

This enables server-side pagination, row hovering, column stripes, custom cursor, and a dark theme variant.

The variant property allows applying custom color theming to the table by passing any string value. Some common options are 'primary', 'secondary', 'success', 'danger' etc.

This provides flexibility to customize the table styling based on your design system or theme requirements.

Generating Headers

The headers for the paginated table are configured by passing an array of PaginableTableHeader objects.

Each header can have the following properties:

  • title - The text to display in the header cell.

  • property - The key mapping to the property in the row data.

  • icon - An optional icon to display next to the title text.

  • align - Alignment of the text, either 'start', 'center', or 'end'. Default is 'start'.

  • sortable - Whether the column can be sorted. Default is false.

  • wrapping - Whether text in the column can wrap. Either 'wrap' or 'nowrap'. Default is 'nowrap'.

  • sticky - Stick the header to the 'start' or 'end' of the table when scrolling.

  • buttons - An array of buttons or dropdowns to display in the header.

  • filter - Add filtering for the column. Can be either an InputFilter or DropdownFilter.

  • onlyButtons - Hide the title and only show configured buttons.

Filtering

The filter property on a header can be used to enable filtering for a column. There are two types of filters:

Input Filter

An input filter displays a text input in the header:

filter: {
  type: 'text',
  key: 'name',
  placeholder: 'Filter names...' 
}

The type can be 'text', 'number', 'date', etc.

Dropdown Filter

A dropdown filter shows a select dropdown in the header:

filter: {
  type: 'dropdown',
  key: 'category',
  options: [
    { label: 'Electronics', value: 'electronics' },
    { label: 'Furniture', value: 'furniture' }
  ]
}

The options can be an array, promise, or observable that provides the options for the select.

This allows adding rich filtering options for the paginated table headers.

Filter modes

The mode controls where the filter UI is displayed - either inline in the header cell or in a menu that toggles:

Inline Mode

Setting mode: 'row' will display the filter inline, embedded directly in the header cell:

filter: {
  mode: 'row',
  type: 'text',
  key: 'name'
}

This displays the filter UI directly in the header cell for that column.

Menu Mode

Setting mode: 'menu' will hide the filter UI behind a menu toggle:

filter: {
  mode: 'menu',  
  type: 'text',
  key: 'name'
}

This adds a menu toggle button to the header. When clicked, it opens a panel that displays the filter UI.

The menu mode is useful for hiding filters behind a toggle and keeping the header more compact.

So in summary:

  • mode: 'row' displays the filter inline in the header cell.
  • mode: 'menu' hides the filter UI behind a menu toggle.

The mode option gives flexibility in how the filter UI is presented in the headers.

Batch Actions

The batchActions input allows defining action buttons and dropdowns that apply to the currently selected rows.

It takes an array of PaginableTableDropdown objects, each configuring a dropdown with action buttons:

@Component({

  // ...

})
export class TableComponent {

  batchActions: PaginableTableDropdown[] = [

    // Dropdown with action buttons
    {
      buttons: [
        {
          icon: 'fa fa-pencil', 
          title: 'Edit',
          handler: () => {
            // edit selected rows  
          }
        },
        {
          icon: 'fa fa-trash',
          title: 'Delete',
          color: 'danger', 
          handler: () => {
            // delete selected rows
          }
        }
      ]
    },

    // Single action button
    {
      icon: 'fa fa-file-export',
      title: 'Export',
      handler: () => {
        // export selected rows
      }
    }

  ];

}
<paginable-table
	[headers]="headers"
	[rows]="items"
	[batchActions]="batchActions"
	[(ngModel)]="selected"
>
</paginable-table>

Each button accepts properties for icon, title, color and handler.

The handler method will receive the array of selected rows as an argument.

This allows performing bulk actions on the currently selected rows in the table.

Inputs

| Name | Type | Default | Required | Description | |:----------|:----------|:----------|:----------|:----------| | options | PaginableTableOptions | - | false | Allows customizing the table's style, behavior, and pagination strategy through a flexible set of properties. | | headers | PaginableTableHeader | - | true | A boolean value that determines whether or not the table will display column headers. | | pagination | PaginableTablePagination | Observable<PaginableTablePagination> | - | true | A boolean value that determines whether or not the table will display pagination control. | | ordination | PaginableTableOrdination | - | false | A object representing the initial ordination. | | rows | Array<any> | null | true | An array of objects, each object representing a row in the table. En este caso la paginación se generará automáticamente | | batchActions | Array<PaginableTableDropdown | PaginableTableButton> | [] | false | An array of objects, each object representing a batch action that can be applied to multiple rows at once. | | perPageOptions | Array<number>| [10, 20, 50, 100] | false | An array of numbers, each number representing an option for how many rows should be displayed per page. | | responsive | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | null | false | A boolean value that determines whether or not the table will be responsive to different screen sizes. | | id | string | null | false | A string value that is used as an identifier for the table component instance. | | showSearchInput | boolean | true | false | A boolean value that determines whether or not a search input will be displayed at the top of the table. | | selectable | boolean | false | false | Determines whether or not rows can be selected by clicking on them. | | multiple | boolean | false | false | Determines whether or not multiple rows can be selected at once by clicking on them. | | selectableProperty | string | null | false | The name of a property on each row object which indicates whether or not it is selectable. | | paginationPosition | 'bottom' | 'top' | 'both' | 'bottom' | false | The position where pagination controls should be displayed (e.g., "top" or "bottom"). | | paginationInfo | boolean | true | false | Determines whether or not pagination information is displayed. | | searchKeys | Array | [] | false | Determines in which properties the search has to be performed when the pagination is performed by the component itself. They can be properties not included in the headers. |

Outputs

| Output | Type | Description | | ------------- | ------------- | ------------- | | (onPageClick) | number | Fired on select blur | | (onSelected) | T | Array | Triggered when a row or multiples rows are selected or unselected | | (onParamsChange) | PaginationParamsChangeEvent | Triggered when ordination or page change | | (filterChange) | FilterChangeEvent | Triggered when filters change |

Methods

Name | Description | | ------------- | ------------- | | open | Opens the select dropdown panel | | close | Closes the select dropdown panel | | focus | Focuses the select element | | blur | Blurs the select element |

Templates

Each of the following templates can be used for different purposes:

No data message

The no data message template can be used to display a custom message when no results are found.

<paginable-table [rows]="[]" [headers]="headers">
	<ng-template paginableTableNotFound>
		<div class="d-flex flex-column p-4 text-center">
			<img src="https://media.giphy.com/media/3ohA2ZD9EkeK2AyfdK/giphy.gif" alt="Sorry!" class="m-auto"
				style="width: 256px;">
			<div>
				<i class="fa fa-info-circle" aria-hidden="true"></i> Nothing has been found...
			</div>
		</div>
	</ng-template>
</paginable-table>

Header

The header cell template can be used to customize each individual cell within the header.

<paginable-table [headers]="headers" [rows]="items">
	<ng-template paginableTableHeader header="name" let-header="header">
		<div class="animate-character">Name</div>
	</ng-template>
</paginable-table>

Row

The row template can be used to customize the entire content of a row.

<paginable-table [headers]="headers" [rows]="items">
	<ng-template paginableTableRow let-item>
		<tr>
			<td>
				<img [src]="'assets/avatars/64_' + (item.id % 16 + 1) + '.png'" [alt]="item.name">
			</td>
			<td>{{ item.name }}</td>
			<td>{{ item.email }}</td>
			<td>
				<a class="btn btn-link" (click)="item.unfold  = !item.unfold">
					<i class="fa" [ngClass]="{'fa-chevron-down': !item.unfold, 'fa-chevron-up': item.unfold}"></i>
				</a>
			</td>
		</tr>
		<ng-container *ngIf="item.unfold">
			<tr>
				<td colspan="4">
					Columna personalizada
				</td>
			</tr>
			<tr>
				<td>
					Columna personalizada 1
				</td>
				<td>
					Columna personalizada 2
				</td>
				<td>
					Columna personalizada 3
				</td>
				<td>
				</td>
			</tr>
		</ng-container>
	</ng-template>
</paginable-table>

Cell

The cell template can be used to customize each individual cell within a row.

<paginable-table [headers]="headers" [rows]="items">
	<ng-template paginableTableCell header="avatar" let-item="item">
		<img
			[src]="'assets/avatars/64_' + ((item.id % 16) + 1) + '.png'"
			[alt]="item.name"
		/>
	</ng-template>
	<ng-template paginableTableCell header="name" let-property="property">
		<span class="badge badge-pill badge-info"> customized column </span>
		{{ property }}
	</ng-template>
	<ng-template paginableTableCell header="email" let-item="item">
		{{ item.email }}
		<span class="badge badge-pill badge-warning"> also customized </span>
	</ng-template>
</paginable-table>

Loading

The loading template can be used to display a loading animation while results are being fetched.

<paginable-table [headers]="headers" [pagination]="pagination">
	<ng-template paginableTableLoading>
		<div class="text-center">
			<img src="../images/loading.svg">
		</div>
	</ng-template>
</paginable-table>

Error message

The error message template can be used to display a custom error message if there is an issue fetching results.

<paginable-table [headers]="headers" [pagination]="pagination">
	<ng-template paginableTableError>
		<div class="text-center">
			<img src="../images/error.svg">
		</div>
	</ng-template>
</paginable-table>

Expandable row

The expandable row template can be used to define the content that appears when a row is expanded.

<paginable-table [headers]="headers" [rows]="items">
	<ng-template paginableTableExpandingRow let-item="item">
		<tr class="bg-warning">
			<td [attr.colspan]="headers.length + 1">
				<div class="d-flex">
					<div class="align-self-center pr-4">
						<img [src]="'assets/avatars/64_' + (item.id % 16 + 1) + '.png'" [alt]="item.name">
					</div>
					<div class="flex-grow">
						<h3>{{ item.email }}</h3>
						<h4>{{ item.name }}</h4>
					</div>
				</div>
			</td>
		</tr>
	</ng-template>
	<ng-template paginableTableExpandingRow let-item="item">
		<tr class="bg-warning">
			<td [attr.colspan]="headers.length + 1" class="bg-success">
				<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla commodo leo eget elementum
					condimentum.
				</p>
			</td>
		</tr>
	</ng-template>
</paginable-table>

Filters

The filters template can be used to customize the appearance and behavior of filters for each column.

<paginable-table
	(filterChange)="onFilterChange($event)"
	(onParamsChange)="fetch($event)"
	[selectable]="true"
	[headers]="headers"
	[pagination]="pagination"
>
	<ng-template
		paginableTableFilter
		header="email"
		let-header="header"
		let-formControl="formControl"
	>
		...
		<div
			class="form-check"
			*ngFor="let option of header.filter.options | async"
		>
			<input
				class="form-check-input"
				type="checkbox"
				[value]="option.value"
				[formControl]="formControl"
			/>
			<label class="form-check-label">
				{{ option.text }}
			</label>
		</div>
	</ng-template>
	...
</paginable-table>

Other

Here is the documentation for ng-paginable-list in English:

ng-paginable-list

The ng-paginable-list component allows rendering data in a nested, hierarchical list.

Basic Usage

To use it, simply pass the data structure to the tree input:

<hub-ui-paginable-list [tree]="data"></hub-ui-paginable-list>
data = [
  {
    label: 'Item 1', 
    children: [
      {label: 'Subitem 1'},
      {label: 'Subitem 2'},
    ]
  },
  {
   label: 'Item 2'
  }
];

This will generate a list with the items and subitems.

Options

The available options are:

  • bindLabel - Property of the item object to use as label
  • bindValue - Property for the unique value of each item
  • bindChildren - Property with child items
  • selectable - Enables single or multiple selection. Values: 'single' | 'multiple'

Customization

You can use a template to customize the markup for each item. The listItemTpt template now receives the next parameters:

<ng-template listItemTpt let-data="data" let-depth="depth" let-index="index" let-collapsed="collapsed" let-selected="selected">

</ng-template>  

Where:

  • data - Item
  • depth - Item depth
  • index - Item index
  • collapsed - Whether it is collapsed
  • selected - Whether it is selected
<hub-ui-paginable-list
  [items]="data"
  bindValue="id"
  bindChildren="subItems"
  selectable="multiple" 
  (clickFn)="onClick($event)">

  <ng-template
    listItemTpt
    let-data="data"
    let-depth="depth"
    let-selected="selected">
    
    <div>
     {{ data.name }} (depth: {{depth}}, selected: {{selected}})
    </div>
  
  </ng-template>

</hub-ui-paginable-list>

This allows fully customizing the rendered item.

Integration with Forms

The component implements ControlValueAccessor to integrate with reactive forms.

The selected value will be available in the formControl.

Accessibility

The component properly manages focus and keyboard navigation for good accessibility.

Translating Labels

ng-paginable includes predefined labels in English and Spanish that are used in the component's UI.

These labels can easily be replaced to support other languages or custom translations.

Default Translations

By default, ng-paginable uses the browser's language to select between English and Spanish. This displays the default labels without needing additional configuration.

Customizing Translations

You can provide custom translations to the PaginableTranslationService:

@Component({
  // ..
})
export class AppComponent {

  constructor(private translationService: PaginableTranslationService) {

    this.translationService.setTranslation({
      first: 'First',
      prev: 'Previous', 
      next: 'Next',
      last: 'Last'
      // ...
    });

  }

}

This overrides the default labels.

Integration with Translation Libraries

To integrate ng-paginable with translation libraries like ngx-translate, you can subscribe to language changes:

@Component({
  // ...  
})
export class AppComponent {

  constructor(
    private translate: TranslateService,
    private translationService: PaginableTranslationService
  ) {

    this.translate.onLangChange.subscribe((event) => {

      this.translate.get('PAGINATION').subscribe((translations) => {
        this.translationService.setTranslation(translations);
      })

    });

  }

}

This way, when the language changes in the app, the pagination labels are updated.

This allows for complete, integrated translation across the UI.

Translation API

The PaginableTranslationService exposes the following methods:

setTranslation(translations: PaginableTranslations) // sets translations
getTranslation(key: string) // gets a specific label

This provides full control over the labels and language used by the component.

With this flexible API it's straightforward to integrate ng-paginable with any translation strategy.

Configuration (Optional)

You can also set global configuration and localization messages by passing a config to forRoot method of NgPaginableModule, typically in your root component, and customize the values of its properties in order to provide default values.

  @NgModule({
	declarations: [UserListComponent],
	imports: [
		CommonModule,
		NgPaginableModule.forRoot({
			mapping: {
				currentPage: 'page',
				data: 'content',
				lastPage: 'last',
				total: 'total'
			}
		})
	],
	exports: [UserListComponent],
	providers: []
})
export class UserListModule {}

Change Detection

Ng-paginable component implements OnPush change detection which means the dirty checking checks for immutable data types. That means if you do object mutations like:

this.rows.push({id: 1, name: 'New item'})

Component will not detect a change. Instead you need to do:

this.rows = [...this.rows, {id: 1, name: 'New item'}];

Inspiring

This component was created to make it easier for developers to display data from Laravel paginated objects in an Angular table without having to write custom code. Over time, options for configuration were added to make it easier to use with any framework or with custom pagination structures.s

Support

If you find this library helpful and want to support its development, consider buying me a coffee. Thank you for your support!

About the author

Carlos Morcillo is a web developer and open source contributor. You can find more of his work on this website.