Never stop learning, approaching the AI
  • 😄About
  • 🅰️AI-Candy on YouTube
    • 🎬YouTube 视频列表
    • 💠AI项目本地部署
      • 1️⃣安装 Pytorch 运行环境
      • 2️⃣在Python虚拟环境下使用 VS Code or PyCharm
        • VS Code Python format
      • 3️⃣Create python virtual environment in Linux
    • 👽AI 入门系列课程
      • 0️向量及向量运算
        • Reshape array code
      • 1️人工智能,机器学习,深度学习 和神经网络的区别
      • 2️卷积神经网络(CNN)
        • 3D CNN sample code
      • 3️Transformer 原理
      • 4️前馈神经网络 (FNN)
  • 🎭Artificial intelligence
    • 1️⃣Deep learning / machine learning
      • 👉Deep Learning Resources
      • 👉Deep learning notes
    • 2️⃣Python
      • Youtube音乐下载
      • Pytorch 安装环境配置 (old)
        • TorchEEG
      • Anaconda3 Python path
      • Data
      • IEEE-754 Floating Point Converter
        • ieee 754 conversion function
      • 文件读写
      • 文本清理
      • Python 下载在线视频
      • 修改Jupyter Notebook 默认工作目录
    • 3️⃣AI Websites
  • 🪤Programming
    • SQL
      • Delete data and reset auto-increment ID
    • Angular
      • DataTable column re-order
      • Angular-datatables, dd/MM/yyyy, sorting (no paged list)
      • Datatables save state using localStorage
      • Variable storage method
      • Colour picker
      • Error fix for click columns on Datatable
      • Auto address use Google place
      • Auto address use Azure Maps
      • Upload file to Server
      • Validators.required OnChange input
      • Date, Time field
      • VS Code: Auto add missing imports when save
      • Datatable setting
      • Date time format
      • sticky <th> and <td> content
      • Filter booked time
      • Dropdown time selection with interval
      • Angular date online test
      • Updating data without refreshing the page
      • Object array sort and sum
      • Multi-type of columns use in one column
      • Select button for datatables
      • Switch button and event
      • Delete column from Array
      • Three-layer structure
      • Remove shadow when print mat-dialog content
      • JSON Parse && Object Array
      • Detect unused import in Typescript
      • Change location using radio button
      • Toastr - display multiline and position
      • Custom LOCALE_ID
      • Batch add data from csv to API server
        • Angular read csv and upload to Server
      • USB Port reader Web solution
      • Debug Angular app using JavaScript Debugger in VS Code
      • Skills
        • FormData & FormGroup to JSON
        • Dropdown list (customer)
        • Get current datetime
        • Get first day of year, month, and date
        • Call a function in a forEach loop
        • disable and readonly
        • Form element value
        • HTML input type
        • Input pattern (validation)
      • Display pipe (UI format)
        • Input upper case and button checked
        • Icons (Bootstrap and CoreUI)
        • Page Refresh
        • Selection list (two ways)
        • onChange Selection event
        • Random Password and Toggle
        • Password match
        • Select checkbox disable
      • Print and save to PDF
      • Import JS into Angular
      • LocalStorage
      • Angular DataTable
        • Data sort
        • A sample usage
        • Angular DataTable server side big data query
      • Change chart.js chart type
      • Angular UI - .NET API - .NET Auth
      • Angular - .NET API
      • *ngIf else && change to @if
      • Angular add reCAPTCHA v3 (Google)
      • Angular update
        • Update from v13 to v15
        • Update from v15 to v18
      • Angular application version central
      • Face detection
        • Face-api.js
      • Angular, Node version compatibility matrix
      • Clear cache
      • Angular oauth2 OIDC
      • Angular add header
    • .NET Skills
      • Add ID manually
      • Auto Mapping
        • Ignore Nesting
        • Startup setting
        • Datetime processing in AutoMapping
        • AutoMapper example
      • Validation filter
      • BaseController
      • Group by many
      • Database first, scaffold to class
      • Log setting and exception handler
      • Update appsetting.json value
      • Azure service bus message (queue)
      • Read appsetting.json value
      • Auth get user info by email
      • Azure Time zone
      • .NET API Add Service
      • Object comparison
      • Coravel Schedule
        • Read appsettings.json
      • .Net Core RDLC Report, Coravel and Email
      • Check Network and SQL server connections.
      • Datatime custom format
      • Many to Many EF
        • Many to Many CheckBox
      • PDFpig: Send Email with PDF attachment
      • .NET Core Middleware order
      • .NET API add Worker Service
      • .NET Router
      • Partial columns update
      • Add and Delete
      • 图片自适应宽度
      • ASP.NET Identity
      • Upload file to Azure
        • Upload file to Blob
      • Developer Guide
      • Code first one-many
      • ASP.NET MVC 5 Custom Error Page
      • VS can't debug
      • 通过邮编查 NSW COVID-19 感染人数
      • Jquery File Upload
      • Jquery Datepicker
      • ajax delete file from server
      • Autofac in MVC
      • Autofac in .NET Core
      • .NET Core
      • HTTP Return code
      • IdentityServer4
    • Power BI
      • Add parameter to PowerBI report
      • Convert UTC to Local time
      • Python in PowerBI
        • IEEE-754 conversion
      • PowerBI embed app - Server
      • PowerBI embed app - Client
        • Setting on portal
    • Azure service
      • Key Vault
      • Service bus - queue
      • Power Automate
      • Kusto Query Language
      • Azure Data Explorer
      • Reserved keyword on Azure Error
      • SQL Azure time convert
    • Azure blob
      • Azure blob setting
      • Display image from Blob
      • Upload image to Blob through .NET API
    • Html Bootstrap Icon, colour, size
      • Html spacing
      • Html text alignment
    • Video stream - JsMpeg
      • SSL - generate key
      • Client (SSL)
      • Websocket-Server (SSL)
      • Play RTSP video stream
    • ⏰Time Zone
      • datetime-local set date range
      • 🕐Get data by local time (UI, API)
      • 🕑Add offset hours for local UI and report
      • 🕒UTC time and Datetime convert
      • 🕓Angular - Timezone selection
      • 🕔Angular - Convert UTC to local time
      • 🕕C# Time Zone
  • >>>>>>>>>>>>>>>>>>>>>>>>>>>>
  • 🪜Apps and Skills
    • 1️Windows system app skills
      • Brother HL-2130 打印机 Toner 报警
      • VS Code 快捷键
      • Check SHA256 on windows
      • blob 视频下载
      • Photoshop 制作证件照片
      • 获取 Windows Key
      • 10进制36进制互转
      • Error when publish to Azure
      • Disable windows automatic update
      • Outlook setup for Yahoo Email
      • IIS setting
      • Windows 8/10, IIS Service
      • 安装程序出错 2052,2053 报警
      • 6 Yao Chinese UI
    • 2️Linux command
    • 3️Git command
    • 4️Bitbucket
    • 5️Gitbook Skills
    • 6️GitHub Desktop
    • 7️⃣EndNote
      • EndNote V21
      • Endnote使用技巧
      • 批量删除/修改Endnote 中 notes 栏内容
  • Android mobile connect PC
  • 💎USEFUL LINKS
    • 1️Coding websites
      • Website links
    • 2️Windows 平台工具,网站
    • 3️PotPlayer 设置
  • >>>>>>>>>>>>>>>>>>>>>>>>>>>>
  • 🚩Research >>EEG
    • 1️EEG基本知识的理论介绍
      • EEG 简介
      • EEG 的节律信号
      • EEG电极帽
      • EEG 伪迹
      • ERP 介绍
      • ERP 成分
      • EEG 数据分析软件
    • 2️LSL 应用
    • 3️EEG公开数据集汇总整理
    • 4️REDCap
      • Migration (Export & Import)
    • 5️⃣ScaneR
  • ☕Buy me a coffee
Powered by GitBook
On this page

Was this helpful?

  1. Programming
  2. Angular

DataTable column re-order

// install colreorder

  datatables.net-colreorder (v.2.1.0)
 
		
├── datatables.net-colreorder-dt@2.1.0
├── datatables.net-colreorder@2.1.0
├── datatables.net-dt@2.3.1
├── datatables.net-staterestore-dt@1.4.1
├── datatables.net@2.3.1		
						
npm i datatables.net-colreorder@2.1.0 datatables.net@2.3.1 
npm i datatables.net-colreorder-dt@2.1.0 datatables.net-dt@2.3.1

angular.json
   "node_modules/datatables.net-colreorder/js/dataTables.colReorder.js"
// Some code

import { CurrentCustomer } from 'src/app/models/current-customer';
import { DataTableConfigService } from 'src/app/services/data-table-config.service';

1.   
  disableOrderColumn = [4];  // Disable ordering for the last column
  isForCustomer = true;
  enableEdit = false;
  constructor(
     private dtConfigService: DataTableConfigService
  ) { }
 
2. 
  ngOnInit(): void {
    let isForCustomer = CurrentCustomer.IsCustomer()
    this.enableEdit = this.dtConfigService.hasAdminOrSupervisorAccess();
    if (this.enableEdit) {
      this.disableOrderColumn = [5];
    }
    else {
      this.disableOrderColumn = [4];
    }

    if (!isForCustomer) {
	  this.getRfidList();
    } else {
     // this.getRfidListByCustomerId(CurrentCustomer.CustomerId());
    }
  }

  
3. 
  buildDtOptions() {
    this.dtOptions = this.dtConfigService.buildDtOptions(
      {
        // pageLength: 25
		// order: [[1, 'asc']],
	   // serverSide: true,   ///<<<<<<< Enable server-side processing for paged list
      },
      this.disableOrderColumn,
      {

 //---------------------------------------------------
        data: this.CarList,    //<--- custom property
        columns: [
          { data: 'id', name: 'id', },
          { data: 'rfidNo', name: 'rfidNo' },
          { data: 'serialNo', name: 'serialNo' },
          {
            data: 'isAdmin', name: 'isAdmin',
	   // orderable: false,    ///<<<<< disable orderable
            render: (data: any, type: any, row: any, meta: any) => {
              if (data) {
                return '<div class="text-center text-success"> Yes </div>';
              }
              else {
                return '<div class="text-center text-danger"> No </div>';
              }
            }
          },
          { data: 'rego', name: 'rego' },

  //---------------------------------------------------
          {
            data: null,
            render: (data: any, type: any, row: any, meta: any) => {
             // console.log('✅changed', this.RfidList.size);
              if (this.enableEdit) {
                return (
                  '<div class="text-center operation-3">' +
                  '<button mat-button class="btn btn-outline-warning btn-sm edit-btn">' +
                  '<i class="fa fa-edit" title="Edit"></i>' +
                  '</button><span class="pe-1"></span>' +
                  '<button mat-button class="btn btn-outline-danger btn-sm delete-btn">' +
                  '<i class="fa fa-trash" title="Delete"></i>' +
                  '</button>' +
                  '</div>'
                );
              } else return '<div></div>';
            },
            createdCell: (td, cellData, rowData, row, col) => {
              const self = this;
              $(td)
                .off('click')
                .on('click', '.edit-btn', (e) => {
                  e.stopPropagation(); // Optional: stop event bubbling
                  self.editDialog('Edit', rowData);
                })
                .on('click', '.delete-btn', function (e) {
                  self.deleteDialog(rowData.id, rowData.name);
                });
            },
			   className: 'sticky-col-right',
          },
        ],
     /// below code is only for paged list
	 extraButtons: this.enableEdit ? [
          'copy',
          {
            text: 'CSV',
            extend: 'csvHtml5',
            className: 'btn-success',
            exportOptions: {
              columns: ':visible:not(.noExport)'
            }
          }, 'pdf', 'excel', 'print',
        ] : [], // Add extra buttons only if the user has edit permissions
      }, // <--- custom property
    );
  }

4. 
  getCarList() {
    this.isLoading = true;
    return this.carrierService.getAllCarriers().subscribe({
      next: (res) => {
        this.CarList = res;
        this.buildDtOptions();   ///<<<<<<<<
        this.dtTrigger.next(this.dtOptions);
        this.isLoading = false;
      },
      error: (error) => {
        console.log('Error: retrive Carrier list error - ' + error);
        this.toastr.warning(error.status + '- retrive data error', 'Fail');

      },
    });
  }
// Service

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { ToastrService } from 'ngx-toastr';


@Injectable({
  providedIn: 'root'
})
export class DataTableConfigService {
  constructor(
    private toastr: ToastrService,
    private router: Router
  ) { }

  buildDtOptions(config?: Partial<any>, disableOrderColumn: number[] = [], customProps?: any): any {
    let component = this.getCurrentComponent();
    if (!component) {
      console.error('Component name not found. Please ensure the component is properly configured.');
      return {};
    }
    let component_name = component.name.toLowerCase() + '_table_state'; // Ensure the name is in lowercase and ends with '_table_state'

    return {
      scrollY: 720,
      scrollCollapse: true,
      autoWidth: true,
      columnDefs: [
        { orderable: false, targets: disableOrderColumn, className: 'text-center' },
        { targets: '_all', className: 'text-center' } // Center align all columns
      ],
      pagingType: 'full_numbers',
      pageLength: 15,
      lengthMenu: [10, 15, 20, 25, 50, 100],
      colReorder: true,
      responsive: true,
      stateSave: true,
      fixedHeader: true,
      fixedColumns: true,
      ordering: true,
      processing: true,  ///<<<<<<< Enable processing indicator
      ...config,       // Allow override
      ...customProps,  // Add custom props like datatable_name

      stateSaveCallback: (settings: any, data: any) => {
        const { time, ...dataWithoutTime } = data;
        const newState = JSON.stringify(dataWithoutTime);
        const parsedState = localStorage.getItem(component_name);

        if (parsedState) {
          const existingState = JSON.parse(parsedState);
          const { time, ...existingWithoutTime } = existingState;
          const oldState = JSON.stringify(existingWithoutTime);
          // Compare the new state with the existing state

          if (oldState !== newState) {
            localStorage.setItem(component_name, JSON.stringify(data));
            // console.log('✅changed', newState);
          }
          else {
            // console.log('🔄 no changed');
          }
        } else {
          localStorage.setItem(component_name, JSON.stringify(data));
        }
      },
      stateLoadCallback: (settings: any) => {
        const state = localStorage.getItem(component_name);
        return state ? JSON.parse(state) : null;
      },
      stateDuration: 0, // 1:no time limit for localStorage,  (1day)= 60 * 60 * 24, -1:for sessionStorage,

      dom:
        "<'row'<'col-sm-3'l><'col-sm-6 text-center'B><'col-sm-3 pull-right'f>>" +
        "<'row'<'col-sm-12'tr>>" +
        "<'row'<'col-sm-5'i><'col-sm-7 text-right'p>>",
      buttons:  [
        {
          extend: 'createState',
          text: 'Create State', config: {
            creationModal: true,
            toggle: {
              columns: {
                name: true,
                search: true,
                visible: true,
              },
              length: true,
              order: true,
              paging: true,
              scroller: true,
              search: true,
              searchBuilder: true,
              searchPanes: true,
              select: true,
            },
          }
        },
        'savedStates',
        {
          extend: 'removeAllStates',
          text: 'Remove All States',
          action: (e, dt: any, node, config) => {
            this.toastr.toastrConfig.positionClass = 'toast-top-center';
            this.toastr.clear();
            this.toastr.warning('Reset all statuses to default.', 'Warning');
            dt.colReorder.reset();
            localStorage.removeItem(component_name);
            // Remove all saved states
            const states = dt.stateRestore.states();
            if (states && typeof states === 'object') {
              for (const stateName in states) {
                if (states[stateName]?.remove instanceof Function) {
                  states[stateName].remove();
                }
              }
            }

            // Reset the initial columns visibility
            dt.columns().every((index) => {
              dt.column(index).visible(true);
            });

            // Reset the column reordering
            dt.colReorder.reset();
            localStorage.removeItem(component_name);
            dt.draw(); // Redraw after modification
            this.toastr.toastrConfig.positionClass = 'toast-top-right';
          },
        },
        //'colvis',   // Column visibility button
        {
          extend: 'colvis',
          text: 'Column Visibility',
          className: 'buttons-colvis',
          columns: ':not(.noVis)' // Exclude columns with the class 'noVis'
        },
         ...(customProps?.extraButtons || [])  // Allow additional buttons to be added dynamically
      ]


    };
  };

  getCurrentComponent(): any {
    let route = this.router.routerState.root;
    while (route.firstChild) {
      route = route.firstChild;
    }
    return route.routeConfig?.component ?? null;
  }

  getCurrentComponentName(): string {
    const component = this.getCurrentComponent();
    return component ? component.name.toLowerCase() : '';
  }

  hasAdminOrSupervisorAccess(): boolean {
    let currentRole = sessionStorage.getItem('Role');
    if (currentRole === 'Administrator' || currentRole === 'Supervisor') {
      return true
    }
    else {
      return false;
    }
  }

}

PreviousAngularNextAngular-datatables, dd/MM/yyyy, sorting (no paged list)

Last updated 2 days ago

Was this helpful?

🪤