We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

How to set a extra condition, using existing cascading dropdownlist. Angular 7+, TypeScript 3+

Hi,

I have a grid with cascading dropdownlists based on your existing code:
https://ej2.syncfusion.com/angular/documentation/grid/how-to/cascading-drop-down-list/

The code works great, but now I would like to add a extra condition to the to the initial editParams. In the params I'm trying to find a way on how to get another field, which isnt a dropdownlist, but a "standard input" to be enabled, based on the initial editParams.
Example:
Grid contains 5 fields, 2 of them are dropdownlists(cascading), the other 3 are just "inputs". One of the input fields needs to be enabled(with a default value and editable) or disabled(and empty & not editable) based on the selection of the "top" dropdownlist.

I have added a sample of code for clarification.

greetings,

Laurens





Attachment: sample_dcafd7da.zip

11 Replies

MF Mohammed Farook J Syncfusion Team December 5, 2018 09:47 AM UTC

Hi Laurens, 
 
Thanks for contacting Syncfusion support. 
 
We have analyzed your requirement. We have added some codes to the code from the documentation to achieve your requirement. We have fetched the corresponding input element to be enabled/disabled in the “change” event handler of dropdown list and added the “e-disabled” class to the corresponding input element. We have prepared a sample for your convenience. Please refer the sample link below, 
 
 
Please refer the code example below,  
 
[normal-edit.component.ts] 
 
  export class NormalEditComponent implements OnInit { 
      public data: Object[]; 
      @ViewChild('Grid') 
      public grid:GridComponent; 
      ... 
      ngOnInit(): void { 
          ... 
          this.countryParams = { 
              ... 
              write:()=>{ 
                  this.countryObj = new DropDownList({ 
                  dataSource: this.country, 
                  fields: { value: 'countryId', text: 'countryName' }, 
                  change: (args:any) => { 
                    //Code to fetch the input element. Here we have disabled/enabled the input element in the “CustomerID” column. 
                    let inputelem: any = document.getElementById(this.grid.element.id + "CustomerID").parentNode;  
                    if(this.countryObj.text == "Australia") { 
                       inputelem.classList.add("e-disabled")          //Make the input as disabled when “Australia” is selected. 
                    } 
                    else if(this.countryObj.text == "United States" && inputelem.classList.contains("e-disabled")) { 
                       inputelem.classList.remove("e-disabled")       //Make the input enabled when “United States” is selected. 
                    } 
                  this.stateObj.enabled = true; 
                  ... 
              }, 
              ... 
          }}; 
          this.stateParams = { 
              ... 
          }} 
      } 
  } 
 
 
 
Please get back to us if you need further assistance. 
 
Regards, 
J Mohammed Farook 
 



LA Laurens Albers January 3, 2019 12:15 PM UTC

Hi,

Thank you for the example!

But there is a issue and two questions that i have based on the example:
1. Your sample using a 'class' disables the field, but does not prevent the user from typing data into the column. It needs to be blocked from editing.
2. the field needs to be blocked (by default)upon initialization of editing, since the initial dropdown is empty as well.
3. I've been trying to to adjust the type in the HtmlInputElement, but this.inputElem.type = 'number'; does not work. Any idea?

Thanks in advance!

greetings,

Laurens

sample:
 inputElem: HTMLInputElement;
  typeElem: HTMLElement;
  typeObj: DropDownList;
  formatElem: HTMLElement;
  formatObj: DropDownList;
  typeParams: IEditCell = {
    create: () => {
      this.typeElem = document.createElement('input');
      return this.typeElem;
    },
    read: () => {
      return this.typeObj.text;
    },
    destroy: () => {
      this.typeObj.destroy();
    },
    write: () => {
      this.typeObj = new DropDownList({
        dataSource: this.myTypes,
        fields: { value: 'id', text: 'type' },
        change: () => {
          this.inputElem = document.getElementById(this.grid2.element.id + "decimals").parentNode;
          if (this.typeObj.text === "Decimal" || this.typeObj.text === "Double") {
            this.inputElem.classList.add("e-disabled");
          } else {
            this.inputElem.classList.remove("e-disabled");
          }
          this.formatObj.enabled = true;
          const tempQuery = new Query().where('id', 'equal', this.typeObj.value);
          this.formatObj.query = tempQuery;
          this.formatObj.dataBind();
        },
        placeholder: 'Select a Type',
        floatLabelType: "Never"
      });
      this.typeObj.appendTo(this.typeElem);
    }
  };
  formatParams: IEditCell = {
    create: () => {
      this.formatElem = document.createElement('input');
      return this.formatElem;
    },
    read: () => {
      return this.formatObj.text;
    },
    destroy: () => {
      this.formatObj.destroy();
    },
    write: () => {
      this.formatObj = new DropDownList({
        dataSource: this.myFormat,
        fields: { value: 'idFormat', text: 'format' },
        enabled: false,
        placeholder: 'Select a Format',
        floatLabelType: 'Never'
      });
      this.formatObj.appendTo(this.formatElem);
    }
  };



PS Pavithra Subramaniyam Syncfusion Team January 4, 2019 09:43 AM UTC

Hi Laurens, 
 
Query #1 &2:  Your sample using a 'class' disables the field, but does not prevent the user from typing data into the column. It needs to be blocked from editing. 
 the field needs to be blocked (by default)upon initialization of editing, since the initial dropdown is empty as well. 
 
We have analyzed the above queries and we suspect that you would like to keep the column in disabled state initially when editing. So we suggest to set the allowEditing property to false for that column and it will be changed to editable state only when a required value is selected from the dropdown. Please refer to the below sample for your reference, 
 
Code Example:  
 
[.ts] 
... 
write:()=>{ 
                  this.countryObj = new DropDownList({ 
                  dataSource: this.country, 
                  fields: { value: 'countryId', text: 'countryName' }, 
                  change: (args:any) => { 
                    let inputelem: any = document.getElementById(this.grid.element.id + "CustomerID").parentNode; 
                    if(this.countryObj.text == "Australia") { 
                    inputelem.classList.add("e-disabled") 
                    } 
                    else if(this.countryObj.text == "United States" && inputelem.classList.contains("e-disabled")) { 
                    inputelem.classList.remove("e-disabled"); 
                    inputelem.firstElementChild.classList.remove("e-disabled"); 
                    inputelem.firstElementChild.removeAttribute("disabled"); 
                    inputelem.firstElementChild.type = 'number'; 
                    } 
                  this.stateObj.enabled = true; 
                  let tempQuery: Query = new Query().where('countryId', 'equal', this.countryObj.value); 
                  this.stateObj.query = tempQuery; 
                  this.stateObj.text = null; 
                  this.stateObj.dataBind(); 
              }, 
              placeholder: 'Select a country', 
              floatLabelType: 'Never' 
              }); 
              this.countryObj.appendTo(this.countryElem); 
          } 
... 
 
Query #2:  I've been trying to to adjust the type in the HtmlInputElement, but this.inputElem.type = 'number'; does not work. Any idea? 
 
We have analyzed your query and we suggest to set the type property to the input element. Please refer to the below sample for your reference, 
 
Code Example:  
 
[.ts] 
... 
if(this.countryObj.text == "Australia") { 
                    inputelem.classList.add("e-disabled") 
                    } 
                    else if(this.countryObj.text == "United States" && inputelem.classList.contains("e-disabled")) { 
                    ... 
                    inputelem.firstElementChild.type = 'number';   //set type to the input element 
                    } 
... 
 
 
Please get back to us for further assistance. 
 
Regards, 
Pavithra S. 
 



LA Laurens Albers January 4, 2019 10:26 AM UTC

Hi,

Thank you for your feedback, It helped!

greetings,

Laurens Albers


PS Pavithra Subramaniyam Syncfusion Team January 4, 2019 11:28 AM UTC

Hi Laurens, 
 
Thanks for your update. 
 
We are happy to hear that the provided solution helps you. 
 
Please get back to us for further assistance. 
 
Regards, 
Pavithra S. 
 



LA Laurens Albers April 9, 2019 08:07 AM UTC

Hi,

1. Do you have any suggestion on how to set the existing value(if there is any) into the column type & format each with editType: dropdownedit(see .ts), instead of the "placeholder".
example: if type had the value "varchar", it should show value that in the editdialog instead of the placeholder.

2. I would also like if possible to sync both grids(in a mat-tab-group) using the scrollbars, but i don't think you guys support this, right? So i tried selecting the row,
-> https://ej2.syncfusion.com/angular/documentation/grid/scrolling/#scroll-to-selected-row, but this does not trigger the scrollbar to correct position, even though the selection is correct.
example: selecting bottom row in grid1 in tab1 should select the bottomrow in grid2(does work) in tab2 and set the scrollbar to the to the correct position(does not work).

.HTML
<mat-tab-group>
          <!--TAB INPUT-->
          <mat-tab label="Input">
            <div class="flex-row" style="margin-top: 10px">
              <div class="flex-content">
                <ejs-grid #grid1 id="grid1" height="375px"
                          [columns]='columns1'
                          [dataSource]='dataSource1'
                          [selectedRowIndex]="rowIndex1"
                          [rowHeight]='30'
                          [selectionSettings]='selectionOptions'>
                </ejs-grid>
              </div>
            </div>
          </mat-tab>
          <!--TAB OUTPUT-->
          <mat-tab label="Output">
            <div class="flex-row" style="margin-top: 10px">
              <div class="flex-content">
                <ejs-grid #grid2 id="grid2" height="310px"
                          [columns]='columns2'
                          [selectedRowIndex]="rowIndex2"
                          [dataSource]='dataSource2'
                          [rowHeight]='30'
                          [editSettings]='editSettings'
                          (actionComplete)="change($event)"
                          [selectionSettings]='selectionOptions'>
                </ejs-grid>
              </div>
            </div>
            <div class="flex-row" style="margin-top: 10px">
              <div class="flex-column" style="margin-right: 10px">
                <button mat-stroked-button color="primary" (click)="stripTable()">STRIP TABLE NAME</button>
              </div>
              <div class="flex-column">
                <mat-form-field>
                  <input type="text" matInput placeholder="Row sequence column name:" formControlName="columnName" />
                </mat-form-field>
              </div>
            </div>
          </mat-tab>
        </mat-tab-group> 


.TS
  editSettings: object = { allowEditing: true, mode: 'Dialog' };

  columns1: object[] = [
    { field: 'name', headerText: 'Name', textAlign: 'Left', width: 40 },
    { field: 'type', headerText: 'Type', textAlign: 'Left', width: 20 },
    { field: 'length', format: 'N', headerText: 'Length', textAlign: 'Center', width: 15 },
    { field: 'decimals', headerText: 'Decimals', textAlign: 'Center', width: 15 },
    { field: 'format', headerText: 'Format', textAlign: 'Left', width: 25 }
  ];
  columns2: object[] = [
    { field: 'id', visible: false, isPrimaryKey: true },
    { field: 'name', headerText: 'Name', textAlign: 'Left', width: 40, validationRules: { required: true } },
    { field: 'type', headerText: 'Type', textAlign: 'Left', width: 20, editType: 'dropdownedit', edit: this.typeParams, validationRules: { required: true } },
    { field: 'length', headerText: 'Length', format: 'N', textAlign: 'Center', width: 15, validationRules: { required: true, number: true } },
    { field: 'decimals', allowEditing: false, headerText: 'Decimals', textAlign: 'Center', width: 15, validationRules: { number: true } },
    { field: 'format', headerText: 'Format', textAlign: 'Left', width: 20, editType: 'dropdownedit', edit: this.formatParams },
    { field: 'change', headerText: 'Changed', textAlign: 'Left', headerTemplate: "${headerText}", width: 15, isIdentity: true }
  ];

typeElem: HTMLElement;
  typeObj: DropDownList;
  formatElem: HTMLElement;
  formatObj: DropDownList;
  typeParams: IEditCell = {
    create: () => {
      this.typeElem = document.createElement('input');
      return this.typeElem;
    },
    read: () => {
      return this.typeObj.text;
      },
    destroy: () => {
      this.typeObj.destroy();
    },
    write: () => {
      this.typeObj = new DropDownList({
        dataSource: this.myTypes,
        fields: { value: 'id', text: 'type' },
        change: (args: any) => {
          let inputElem: any = document.getElementById(this.grid2.element.id + "decimals").parentNode;
          if (this.typeObj.text === "Decimal" || this.typeObj.text === "Double") {
            inputElem.classList.remove("e-disabled");
            inputElem.firstElementChild.classList.remove("e-disabled");
            inputElem.firstElementChild.removeAttribute("disabled");
            inputElem.firstElementChild.type = 'number';
          } else {
            inputElem.classList.add("e-disabled");
            inputElem.firstElementChild.classList.add("e-disabled");
            inputElem.firstElementChild.disabled = true;
            inputElem.firstElementChild.type = 'number';
          }
          this.formatObj.enabled = true;
          const tempQuery = new Query().where('id', 'equal', this.typeObj.value);
          this.formatObj.query = tempQuery;
          this.formatObj.dataBind();
        },
        placeholder: 'Select a Type',
        floatLabelType: "Never"
      });
      this.typeObj.appendTo(this.typeElem);
    }
  };
  formatParams: IEditCell = {
    create: () => {
      this.formatElem = document.createElement('input');
      return this.formatElem;
    },
    read: () => {
      return this.formatObj.text;
    },
    destroy: () => {
      this.formatObj.destroy();
    },
    write: () => {
      this.formatObj = new DropDownList({
        dataSource: this.myFormat,
        fields: { value: 'idFormat', text: 'format' },
        enabled: false,
        placeholder: 'Select a Format',
        floatLabelType: 'Never'
      });
      this.formatObj.appendTo(this.formatElem);
    }
  };

 this.dataSource1 = this.data;
    //Need a seperate clone of data in dataSource1
    var clone = JSON.parse(JSON.stringify(this.data));
    this.dataSource2 = this.checkExisting(clone);


PS Pavithra Subramaniyam Syncfusion Team April 12, 2019 09:21 AM UTC

Hi Laurens, 
 
Query#1: Do you have any suggestion on how to set the existing value(if there is any) into the column type & format each with editType: dropdownedit(see .ts), instead of the "placeholder". example: if type had the value "varchar", it should show value that in the editdialog instead of the placeholder. 
 
Yes, You can set value property for customer dropDownlist component inside the  edit.write” method to achieve your requirement. 
 
 
Query#2: selecting bottom row in grid1 in tab1 should select the bottom row in grid2(does work) in tab2 and set the scrollbar to the to the correct position(does not work). 
 
We have validated your query and you can achieve your requirement by rendering Grid into ng-template. Please find the below sample for your reference. 
 
[group.html] 
<mat-tab-group> 
              <mat-tab label='tab1'> 
    <ng-template matTabContent> 
                             <default1-content></default1-content> 
    </ng-template> 
              </mat-tab> 
              <mat-tab label='tab2'> 
    <ng-template matTabContent> 
                             <default2-content> </default2-content> 
    </ng-template> 
              </mat-tab> 
</mat-tab-group> 
 
[default1.html] 
<ejs-grid #grid height="400" id="grid"  
                [columns]='columns1' 
                [selectedRowIndex]="20" 
                [dataSource]='dataSource1' 
                [allowSelection]='true'> 
      </ejs-grid> 
 
[default2.html] 
<ejs-grid #grid1 height="400" id="grid1"  
                [columns]='columns3' 
                [selectedRowIndex]="20" 
                [dataSource]='dataSource3' 
                [allowSelection]='true'> 
      </ejs-grid> 
 
 
Please get back to us if you need any further assistance on this. 
 
Regards, 
Pavithra S. 



LA Laurens Albers April 12, 2019 10:00 AM UTC

Query#1: Do you have any suggestion on how to set the existing value(if there is any) into the column type & format each with editType: dropdownedit(see .ts), instead of the "placeholder". example: if type had the value "varchar", it should show value that in the editdialog instead of the placeholder. 
 
Yes, You can set value property for customer dropDownlist component inside the  edit.write” method to achieve your requirement. 
 
 
Your example does not work/is broken in the demo(see zip and your own url (above -> preview tab), the field is empty. I also tried setting value in my own code, but it doesn't do anything. See below for my example.


Does not work, even though value is passed to the edit.write -> value
write: (args) => {
      console.log(args),
        this.typeObj = new DropDownList({
          value: args.rowData.type,
          dataSource: this.myTypes,
          fields: { value: 'id', text: 'type' },
          change: (args: any) => {
//etc etc



Attachment: demo_example_37e52cf7.zip


PS Pavithra Subramaniyam Syncfusion Team April 15, 2019 06:49 AM UTC

Hi Laurens, 
 
Sorry for the inconvenience caused. 
 
We have already logged a task for documentation correction and it will be refreshed in any of our upcoming release. Also We have validated your requirement and By default dropDownList will not show the value that is not its dataSource. So we suggest you use the below way to achieve your requirement. 
 
App.component.ts 
 
write: (args) => { 
      this.dropData.push(args.rowData.ShipCountry);    // push the value to the dropdownlist datasource 
      this.formatObj = new DropDownList({ 
        dataSource: this.dropData, 
        fields: { value: 'idFormat', text: 'format' }, 
        value: args.rowData.ShipCountry,  //assigned the value to the dropdownList 
      }); 
 
 
In the above code snippet we have pushed the edited row’s  ShipCountry value to the dropDownList’s datasource. 
We have prepared a sample based on your requirement. 
 
 
Please get back to us if you need any further assistance on this. 
 
Regards, 
Pavithra S. 



LA Laurens Albers April 15, 2019 11:50 AM UTC

I changed my personal datasource from object[] with its values to string[] and it works fine without pushing data. 
Im guessing the dropdownlist obj with its property dataSource  isnt too happy working with objects[], when using value.

As long as the value args.rowdata."whatever" exists in datasource this will work.
dataSource: string[] = ["somestring"];
/////////
write: (args) => {
    this.typeObj = new DropDownList({
        dataSource: this.myTypes,
        fields: { value: 'id', text: 'type' },
        value: args.rowData.whatever, //"somestring"
        change: (args: any) => {
////////////etc


Thanks for your stackblitz example.
greetings and have a nice day!

Laurens


PS Pavithra Subramaniyam Syncfusion Team April 15, 2019 12:27 PM UTC

Hi Laurens, 
 
Thanks for sharing the details with us. 
 
We are happy to hear that you have found a solution to achieve your requirement. 
 
Please get back to us if you need any further assistance on this.  
 
Regards, 
Pavithra S. 


Loader.
Live Chat Icon For mobile
Up arrow icon