Custom dropdown control in toolbar

Hi,

Is it possible to add a custom dropdown control in the toolbar and an event of which to listen to when the dropdown changes its value?

Kind Regards,
Ced

10 Replies 1 reply marked as answer

BS Balaji Sekar Syncfusion Team June 22, 2020 06:45 AM UTC

Hi Cedric, 
 
Thanks for contacting Syncfusion support. 
 
Query : Is it possible to add a custom dropdown control in the toolbar and an event of which to listen to when the dropdown changes its value? 
 
Yes, it is possible to add a EJ2 Dropdownlist in the grid toolbar. To achieve your requirement, we suggest you to use toolbar template property of the grid. In the template, we have created a dropdownlist with the  change event and required properties. Please refer to the below sample and documentation for your reference. 
 
[index.js] 
export class Searching extends SampleBase { 
    constructor() { 
        super(...arguments); 
        
          this.toolbarOptions = [{template:this.temp}]; 
    } 
     
      temp(props) { 
  
         const items = [ 
          { 
               item: 'Edit', 
               iconCss: 'e-icons e-edit' 
          }, 
          { 
               item: 'Delete', 
               iconCss: 'e-icons e-delete' 
          }, 
          { 
               item: 'Mark As Read', 
               iconCss: 'e-icons e-read' 
          }]; 
        function onChange(args) { 
          console.log(args) 
          // write your code here... 
        } 
      return (         
        <DropDownListComponent id="dropdown" dataSource={items} placeholder="Select" fields= { { text: 'item', value: 'item' }} change={onChange}/>); 
    } 
    render() { 
        return (<div className='control-pane'> 
                <div className='control-section row' > 
                    <GridComponent dataSource={categoryData} toolbar={this.toolbarOptions} allowPaging={true} pageSettings={{ pageSize: 10, pageCount: 5 }}> 
                        <ColumnsDirective> 
                            .        .        .        
                        </ColumnsDirective> 
                        <Inject services={[Toolbar, Page]}/> 
                    </GridComponent> 
                </div> 
            </div>); 
    } 
 
 
 
                                            https://ej2.syncfusion.com/react/documentation/drop-down-list/api-dropDownListComponent.html#properties  
 
Please get back to us if you need further assistance. 
 
Regards, 
Balaji Sekar 


Marked as answer

CE Cedric E June 23, 2020 06:47 AM UTC

Hi Balaji,

Great, it works. 

I found a bug in editSettings, particularlly in headerTemplate and footerTemplate. When you define a value for these two, the output for the footerTemplate is the same with the headerTemplate. My requirement in the footer is to change the order of the buttons and also its style. How can I change it?


BS Balaji Sekar Syncfusion Team June 24, 2020 05:43 AM UTC

Hi Cedric, 

Thanks for your appreciation. 

Before proceeding further, we need addition information about your requirement. Please share the below details to us that will help to validate further. 

  1. Share code definition of footertemplate and headerTemplate.
  2. You have mentioned that footer is change the order of the button and also its style so, please ensure that footer template items change in initial render or dynamically. If dynamically to change it, when it will start the changes to buttons
  3. Share the video demonstrate of the concern if possible
  4. Share a screenshot with us, what you expect exact requirement
 
Regards, 
Balaji Sekar 



CE Cedric E June 24, 2020 01:21 PM UTC

Hi,

Ok. First of, my requirements in the dialog footer in the grid are:
1. Change the order of the button.
2. Change the style of the button

As for the bug I found the the edit settings of the grid, here's a screenshot of the dialog with same header and footer:



As you can see, the header and footer of the dialog is the same. Here's a snippet of the code:

import React, { Component } from 'react'
import { GridComponentColumnsDirectiveColumnDirectivePageToolbarEditInject } from '@syncfusion/ej2-react-grids';
import { data as orderData } from './data';
import { DataUtil } from '@syncfusion/ej2-data';
import { Browserextend } from '@syncfusion/ej2-base';

import '../../node_modules/@syncfusion/ej2-base/styles/material.css';  
import '../../node_modules/@syncfusion/ej2-buttons/styles/material.css';  
import '../../node_modules/@syncfusion/ej2-calendars/styles/material.css';  
import '../../node_modules/@syncfusion/ej2-dropdowns/styles/material.css';  
import '../../node_modules/@syncfusion/ej2-inputs/styles/material.css';  
import '../../node_modules/@syncfusion/ej2-navigations/styles/material.css';
import '../../node_modules/@syncfusion/ej2-popups/styles/material.css';
import '../../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css';
import "../../node_modules/@syncfusion/ej2-react-grids/styles/material.css";

export class DialogTemplate extends Component {
    constructor() {
        super(...arguments);
        this.toolbarOptions = ['Add''Edit''Delete'];
        this.editSettings = { 
            allowEditing: trueallowAdding: trueallowDeleting: truemode: 'Dialog'
            template: this.dialogTemplate,
            headerTemplate: '<div>Dialog Header</div>',
            footerTemplate: '<div>Dialog footer</div>'
        };
        this.validationRules = { required: true };
        this.orderidRules = { required: truenumber: true };
        this.pageSettings = { pageCount: 5 };
    }
    dialogTemplate(props) {
        return (<DialogFormTemplate {...props}/>);
    }
    actionComplete(args) {
        if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
            if (Browser.isDevice) {
                args.dialog.height = window.innerHeight - 90 + 'px';
                args.dialog.dataBind();
            }
        }
    }
    render() {
        return (<div className='control-pane'>
        <div className='control-section'>
          <GridComponent dataSource={orderData} toolbar={this.toolbarOptions} allowPaging={true} editSettings={this.editSettings} pageSettings={this.pageSettings} 
            actionComplete={this.actionComplete.bind(this)}>
            <ColumnsDirective>
              <ColumnDirective field='OrderID' headerText='Order ID' width='120' textAlign='Right' validationRules={this.orderidRules} isPrimaryKey={true}></ColumnDirective>
              <ColumnDirective field='CustomerName' headerText='Customer Name' width='150' validationRules={this.validationRules}></ColumnDirective>
              <ColumnDirective field='Freight' headerText='Freight' width='120' format='C2' textAlign='Right'></ColumnDirective>
              <ColumnDirective field='OrderDate' headerText='Order Date' format='yMd' width='170'></ColumnDirective>
              <ColumnDirective field='ShipCountry' headerText='Ship Country' width='150'></ColumnDirective>
            </ColumnsDirective>
            <Inject services={[PageToolbarEdit]}/>
          </GridComponent>

        </div>
      </div>);
    }
}
export class DialogFormTemplate extends React.Component {
    constructor(props) {
        super(props);
        this.shipCityDistinctData = DataUtil.distinct(orderData'ShipCity'true);
        this.shipCountryDistinctData = DataUtil.distinct(orderData'ShipCountry'true);
        this.state = extend({}, {}, propstrue);
    }
    onChange(args) {
        let key = args.target.name;
        let value = args.target.value;
        this.setState({ [key]: value });
    }
    componentDidMount() {
        let state = this.state;
        // Set initail Focus
        state.isAdd ? this.orderID.focus() : this.customerName.focus();
    }
    render() {
        let data = this.state;
        return (<div>
            <div className="form-row">
                <div className="form-group col-md-6">
                    <div className="e-float-input e-control-wrapper">
                        <input ref={input => this.orderID = input} id="OrderID" name="OrderID" type="text" disabled={!data.isAdd} value={data.OrderID} onChange={this.onChange.bind(this)}/>
                        <span className="e-float-line"></span>
                        <label className="e-float-text e-label-top"> Order ID</label>
                    </div>
                </div>
                <div className="form-group col-md-6">
                    <div className="e-float-input e-control-wrapper">
                        <input ref={input => this.customerName = input} value={data.CustomerName} id="CustomerName" name="CustomerName" type="text" onChange={this.onChange.bind(this)}/>
                        <span className="e-float-line"></span>
                        <label className="e-float-text e-label-top">Customer Name</label>
                    </div>
                </div>
            </div>
            <div className="form-row">
                <div className="form-group col-md-12">
                    <div className="e-float-input e-control-wrapper">
                        <textarea id="ShipAddress" name="ShipAddress" value={data.ShipAddress} onChange={this.onChange.bind(this)}></textarea>
                        <span className="e-float-line"></span>
                        <label className="e-float-text e-label-top">Ship Address</label>
                    </div>
                </div>
            </div>
        </div>);
    }
}


CE Cedric E June 29, 2020 06:52 AM UTC

Hi,

Any updates regarding my inquiry?

Kind Regards,
Ced


MS Manivel Sellamuthu Syncfusion Team June 29, 2020 03:27 PM UTC

Hi Cedric, 

Thanks for your update. 

Yes, you can customize the footer of the edit Dialog in the actionComplete event of the Grid. Please refer the below code example and sample for more information. 

export class DialogEdit extends SampleBase { 
    constructor() { 
        super(...arguments); 
        this.toolbarOptions = ['Add''Edit''Delete']; 
        this.editSettings = { 
           allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Dialog', 
           headerTemplate: '<div>Dialog Header</div>', 
            }; 
        this.editparams = { params: { popupHeight: '300px' } }; 
        this.validationRules = { required: true }; 
        this.orderidRules = { required: truenumbertrue }; 
        this.pageSettings = { pageCount: 5 }; 
    } 
 
        actionComplete(args) {  
        if (args.requestType === 'beginEdit' || args.requestType === 'add') {  
            // here You can customize the footer of the dialog  
            args.dialog.footerTemplate = "<div>Customized Footer</div>" 
        }  
        } 
 
    render() { 
        return (<div className='control-pane'> 
        <div className='control-section'> 
          <GridComponent dataSource={data} toolbar={this.toolbarOptions} actionComplete={this.actionComplete.bind(this)}  
allowPaging={true} editSettings={this.editSettings} pageSettings={this.pageSettings}> 
            <ColumnsDirective> 
              . . . 
                          </ColumnsDirective> 
            <Inject services={[PageToolbarEdit]}/> 
          </GridComponent> 
        </div> 
      </div>); 
    } 
} 
 
render(<DialogEdit />, document.getElementById('sample')); 


Please let us know, if you need further assistance. 

Regards, 
Manivel 



CE Cedric E June 30, 2020 01:33 AM UTC

Hi Manivel,

Got it. So, my next question would be, given I had already created the customized footer and put 2 buttons(Cancel and Save) in it. How can I close the dialog template after clicking save or cancel? or maybe trigger the onActionComplete event after saving or cancelling the edit mode? The purpose of this is, I wanted to add validation before saving the data and prompt it to the user before closing the dialog.

Kind Regards,
Ced


BS Balaji Sekar Syncfusion Team June 30, 2020 05:06 AM UTC

Hi Cedric, 
 
Query:  I wanted to add validation before saving the data and prompt it to the user before closing the dialog 

We have built-in support for validation in Grid CRUD actions using column.validationRules property. Column validation allows you to validate the edited or added row data and it display errors for invalid fields before saving data. Please refer the below code example, demo sample and Help Documentation for more information. 
[Index.js] 
export class DialogTemplate extends SampleBase { 
    constructor() { 
        super(...arguments); 
        this.toolbarOptions = ['Add', 'Edit', 'Delete']; 
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Dialog', template: this.dialogTemplate }; 
        this.validationRules = { required: true }; 
        this.orderidRules = { required: true, number: true };  
    } 
render() { 
        return (<div className='control-pane'> 
       <GridComponent dataSource={orderData} toolbar={this.toolbarOptions} allowPaging={true} editSettings={this.editSettings} pageSettings={this.pageSettings} 
            actionComplete={this.actionComplete.bind(this)}> 
            <ColumnsDirective> 
              <ColumnDirective field='OrderID' headerText='Order ID' width='120' textAlign='Right' validationRules={this.orderidRules} isPrimaryKey={true}></ColumnDirective> 
              <ColumnDirective field='CustomerName' headerText='Customer Name' width='150' validationRules={this.validationRules}></ColumnDirective> 
              <ColumnDirective field='Freight' headerText='Freight' width='120' format='C2' textAlign='Right'></ColumnDirective> 
              <ColumnDirective field='OrderDate' headerText='Order Date' format='yMd' width='170' ></ColumnDirective> 
              <ColumnDirective field='ShipCountry' headerText='Ship Country' width='150' ></ColumnDirective> 
            </ColumnsDirective> 
            <Inject services={[Page, Toolbar, Edit]} /> 
          </GridComponent> 
</div>); 
    } 
 
 

                                       https://ej2.syncfusion.com/react/documentation/form-validator/validation-rules/ 

Please get back to us, if you need further assistance. 

Regards, 
Balaji Sekar 



CE Cedric E July 1, 2020 01:43 AM UTC

Hi Balaji,

That's really helpful. But I'm looking for a way to prevent the dialog from closing while waiting for the response of the server, what's happening currently is upon clicking on the save button the dialog closes. I want it to stay open until the server returned with a success or fail response.

Kind Regards,
Ced


BS Balaji Sekar Syncfusion Team July 1, 2020 11:04 AM UTC

Hi Cedric, 
 
Query: Prevent the dialog from closing while waiting for the response of the server 

We can prevent the default save operation in actionBegin event with save requestType in the Grid. In below code example, we have prevented the save action using cancel option as true. it will break the save action. Since we you can achieve your requirement in dialogTemplate editing and save the change once get the server response using endEdit method of Grid. Please refer the below code example for more information 
[index.js] 
this.isSave = false; 

actionBegin(args) { 
    if (args.requestType == "save" && !this.isSave) {       
      this.isSave=false; 
      args.cancel=true;      //Prevent the save action 
     } 
  } 
  success(){ 
 // if you get response from the server, call endEdit method to manually save to Grid 
    this.isSave=true; 
    this.grid.endEdit(); 
  } 
 
Please get back to us, if you need further assistance. 
 
Regards, 
Balaji Sekar 


Loader.
Up arrow icon