1

I'm using ng2-smart-table to display some data, i've set the selectMode to 'multi' in order to have checkboxes on the left side. In the data i have an array of objects which come with a property "set" which is a boolean and can either be true or false, how do i disable the checkbox if the set property is true? Is there a way to do this?

I've already tried making a new renderComponent etc but then i lose the selectAll functionality plus with a renderComponent the selectRow works different.

Here's a link: https://stackblitz.com/edit/angular-ndmxxg

Akber Iqbal
  • 14,487
  • 12
  • 48
  • 70
Dusan
  • 53
  • 1
  • 9

1 Answers1

0

I have put a button on the Top, which is initialized to true, when you press it, it will disable all the checkboxes;

NOTE: I have set this on click of a button so that you see it in action; If you want to do it after getting a boolean variable from the parent or by-default, you'd have to do this inside ngAfterViewInit()... since we'd have to wait for the ng2-smart-table to be rendered and ready; i left a comment in my stackblitz about it also;

relevant HTML:

<h3>
    Event Response in Console
</h3>
<button (click)="onClick()"> Disable checkbox </button>
<hr/>
<ng2-smart-table [settings]="settings" [source]="data" (deleteConfirm)="onDeleteConfirm($event)" (editConfirm)="onSaveConfirm($event)"
 (createConfirm)="onCreateConfirm($event)" (userRowSelect)="onRowSelect($event)"> 

relevant TS:

import { Component, Renderer2, ElementRef, ViewChild } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  selectedMode: boolean = true;
  // This will contain selected rows
  selectedRows: any;

  constructor(private renderer2: Renderer2, private e: ElementRef) { }

  ngAfterViewInit() { }

  disableCheckboxes() {
    var checkbox = this.e.nativeElement.querySelectorAll('input[type=checkbox]');
    checkbox.forEach((element, index) => {

      /* disable the select all checkbox */
      if (index ==0){this.renderer2.setAttribute(element, "disabled", "true");}

      /* disable the checkbox if set column is false */
      if (index >0 && this.data[index-1].set == false) {
        this.renderer2.setAttribute(element, "disabled", "true");
      }
    });
  }

  settings = {
    selectMode: 'multi',
    delete: {
      confirmDelete: true,

      deleteButtonContent: 'Delete data',
      saveButtonContent: 'save',
      cancelButtonContent: 'cancel'
    },
    add: {
      confirmCreate: true,
    },
    edit: {
      confirmSave: true,
    },
    columns: {
      id: {        title: 'ID',      },
      name: {        title: 'Full Name',      },
      email: {        title: 'Email',      },
      set: {        title: 'Set',      }
    },
  };

  data = [
    {
      id: 1,
      name: "Leanne Graham",
      email: "Sincere@april.biz",
      set: true
    },
    {
      id: 2,
      name: "Ervin Howell",
      email: "Shanna@melissa.tv",
      set: false
    },
    // ... list of items
    {
      id: 11,
      name: "Nicholas DuBuque",
      email: "Rey.Padberg@rosamond.biz",
      set: false
    }
  ];

  // UserRowSelected Event handler
  onRowSelect(event) {
    this.selectedRows = event.selected;
  }

  // Get Selected button click handler
  onClick() {
    // It will console all the selected rows
    this.selectedMode = false;
    this.disableCheckboxes();
  }

  onDeleteConfirm(event) {
    console.log("Delete Event In Console")
    console.log(event);
    if (window.confirm('Are you sure you want to delete?')) {
      event.confirm.resolve();
    } else {
      event.confirm.reject();
    }
  }

  onCreateConfirm(event) {
    console.log("Create Event In Console")
    console.log(event);
  }

  onSaveConfirm(event) {
    console.log("Edit Event In Console")
    console.log(event);
  }
}

complete working stackblitz here

Update (in light of questioner's comment below):

relevant CSS:

::ng-deep table tr td:nth-of-type(1),
::ng-deep table tr th:nth-of-type(1)
{ padding:0 !important; display: block;height: 13px; position: relative;}
::ng-deep table tr td:nth-of-type(1) input,
::ng-deep table tr th:nth-of-type(1) input
{ margin:0 !important; position: absolute; top: 15px;}
::ng-deep table tr td:nth-of-type(2),
::ng-deep table tr th:nth-of-type(2)
{ padding: 0 0 0 20px !important;}
Akber Iqbal
  • 14,487
  • 12
  • 48
  • 70
  • They can still be selected/checked even if you disable the checkboxes when you click the box that contains the checkbox. – Dusan Jul 10 '19 at 06:15
  • When you disable checkboxes, then you click next to checkbox (between checkbox and Edit/Delete) it selects the checkbox. – Dusan Jul 10 '19 at 06:25
  • Thank you for helping me Akber, i have one question for your edited solution. I have an application that has alot of data with alot of boolean types that are true/false, is your solution dynamic? I would need the check boxes to be disabled depending on those boolean types. – Dusan Jul 10 '19 at 06:49
  • you can share your appreciation by accepting the answer :-)... for your comment, look at the function `disableCheckboxes()`... here i am getting a reference of all the checkboxes and then disabling them inside the `forEach` loop; you can put a condition there and then decide whether to disable that particular checkbox or not; – Akber Iqbal Jul 10 '19 at 06:58
  • Yes i have tried going through data in forEach and disabling them but it still disabled all of them even. this.data.forEach(x=>{ if (x.set == false) { this.renderer2.setAttribute(element, "disabled", "true"); } }) – Dusan Jul 10 '19 at 07:05
  • does `this.selectedMode` exist for each checkbox? where is this set? – Akber Iqbal Jul 10 '19 at 07:06
  • No, selectedMode does nothing, the data array of objects below has "set" which is a boolean, if "set" value is set to false in the table, then that checkbox needs to be disabled, i edited my comment above. – Dusan Jul 10 '19 at 07:08
  • check the updated function `disableCheckboxes() { var checkbox = this.e.nativeElement.querySelectorAll('input[type=checkbox]'); checkbox.forEach((element, index) => { /* disable the select all checkbox */ if (index ==0){this.renderer2.setAttribute(element, "disabled", "true");} /* disable the checkbox if set column is false */ if (index >0 && this.data[index-1].set == false) { this.renderer2.setAttribute(element, "disabled", "true"); } }); }` – Akber Iqbal Jul 10 '19 at 07:20
  • It works good now, just need another way to disable selecting checkbox when you click on box next to checkbox. Your answer helped me alot. – Dusan Jul 10 '19 at 07:36
  • which box next to the checkbox? – Akber Iqbal Jul 10 '19 at 07:40
  • The one you removed with CSS. – Dusan Jul 10 '19 at 07:45
  • i didn't remove any box... i just removed the padding around the checkbox - this is what was causing the click despite being disabled; you're looking at https://stackblitz.com/edit/angular-ayyeeb right? – Akber Iqbal Jul 10 '19 at 07:51
  • Yes, i know you removed the padding but the problem is i have two tables, it removes padding on the other table too. I think there isn't another way unfortunately. – Dusan Jul 10 '19 at 09:18
  • I created a div which is parent of the table which we do want to modify... made minor changes to the css which is updated on the stackblitz https://stackblitz.com/edit/angular-ayyeeb – Akber Iqbal Jul 10 '19 at 09:26