2 custom controls in DataGrid column

Hi,

We are using the ASP.NET Core with the DataGrid and we do have some custom filters like filtering the time part of the date, like this:

Image_9726_1709027032301

To have it to work, we are using the .FilterBarTemplate(new { write = "endTimeFilterWrite" }) and in the JavaScript function we create and append the TimePicker control. 

We have observed that if we do not have the create function, the DataGrid appends an input element before the write function is called (in our case endTimeFilterWrite)


However, we do have another column where we do want to add 2 controls: NumericTextBox. We had various attempts to do this, in create and write but without success (this is why we opening the ticket).


The way how we do, is we define the .FilterBarTemplate(new { create = "durationColumnCreate" })​ and the JavaScript version:


function durationColumnCreate(args) {

    var container = $("<div class='d-flex duration' />");

    var minContainer = $("<div class='flex-fill min' />");

    var maxContainer = $("<div class='flex-fill max' />");

    container.append(minContainer, maxContainer);


    var minPicker = new ej.inputs.NumericTextBox({

        min: 0,

        placeholder: 'Minimum minutes',

        format: 'min # minutes',

        change: function (args) {

            gridState.durationFilterByValue = args.value;

            onFiltersChanged(args);

        }

    });

    var maxPicker = new ej.inputs.NumericTextBox({

        min: 0,

        placeholder: 'Maximum minutes',

        format: 'max # minutes',

        change: function (args) {

            gridState.durationFilterByValue = args.value;

            onFiltersChanged(args);

        }

    });



    minPicker.appendTo(minContainer[0]);

    maxPicker.appendTo(maxContainer[0]);

    return container[0];

}


This creates the following elements in the DOM, which does not render any NumericTextBox.

Image_1849_1709027630069

We have tried using the create and write and there is the same issue.

The problem is only when we add more than 1 control


Can you advice?


3 Replies

VK Vasanthakumar K Syncfusion Team March 4, 2024 08:42 AM UTC

Hi Daniel Tila,


Greetings from Syncfusion support.


We have validated your query and understand that you are trying to use two controls on the filterbar template, but you are facing issues with the controls not appending properly. We noticed that you are using a div element for appending the numeric text box control, but the numeric text box control should be appended as an input element with type text. This is the root cause of the issue. Based on your requirement, we have prepared a sample. In this sample, we create a div element in the filterbartemplate create and append two numeric text box controls on two different input elements and also append those two elements on the created div element in the filterbartemplate write. You can refer to the below code example, screenshot, and sample for more details.


[code example]

function create1() {

    freightElem = document.createElement('div');

    return freightElem;

};

function destroy1() {

    minPicker.destroy();

    maxPicker.destroy();

};

function write1(args) {

    var container = $("<div class='d-flex duration' />");

    var minContainer = $("<input id='min' type='text' class='flex-fill min' />");

    var maxContainer = $("<input id='max' type='text' class='flex-fill max' />");

    container.append(minContainer, maxContainer);

    // creating Min NumericTextBox filter for Freight column.

    minPicker = new ej.inputs.NumericTextBox({

        min: 0,

        placeholder: 'Minimum minutes',

        format: 'min # minutes',

        change: function (args) {

            // gridState.durationFilterByValue = args.value;

            // onFiltersChanged(args);

        }

    });

    // creating Max NumericTextBox filter for Freight column.

    maxPicker = new ej.inputs.NumericTextBox({

        min: 0,

        placeholder: 'Maximum minutes',

        format: 'max # minutes',

        change: function (args) {

            // gridState.durationFilterByValue = args.value;

            // onFiltersChanged(args);

        }

    });

    minPicker.appendTo(minContainer[0]);

    maxPicker.appendTo(maxContainer[0]);

    args.element.append(container[0]);

};


Screenshot:



Sample: please find the attachment.


Regards,

Vasanthakumar K


Attachment: 186948filterbartemplatecrwd2control_14d827b5.zip


DT Daniel Tila March 13, 2024 12:48 PM UTC

Thank you, this indeed works, however when you click on the Max filter, the focus is moved to the Min filter.


I have tried multiple options, including modifying the write functions as:

 function durationColumnWrite(args) {

     var container = $("<div class='d-flex duration'><div class='flex-fill min'></div> <div class='flex-fill max'></div></div>");

     var minContainer = $("<input id='min' type='text' />");

     var maxContainer = $("<input id='max' type='text' />");

     container.find('.min').append(minContainer);

     container.find('.max').append(maxContainer);



Here I am creating more separated divs, however, the focus is still moved to the Min controller. I attach an image after I released the left button on the Max controller - you can see the focus is back in the Min controller


Image_7138_1710334048673


I am not reattaching a sample, since does reproduce on the sample provided as well.

Can you advice?




VK Vasanthakumar K Syncfusion Team March 19, 2024 06:36 AM UTC

Hi Daniel Tila,


Thanks for your understanding and patience.


We have validated your query and understand that you are facing an issue with clicking on the filterbar template's second element automatically focusing on the first element of the template cell. This is the default behavior of the grid. If you are using templates in the header and content of the grid, focus and all customization functionality of that template must be handled at the application level. We have modified the provided sample to maintain focus properly by customizing it at the application level. Please refer to the code example and sample below for more details.


[code example]

<script>

function write1(args) {

    . . . . . . . . .

    minPicker.appendTo(minContainer[0]);

    maxPicker.appendTo(maxContainer[0]);

    maxPicker.element.classList.add('e-columnheader'); // except first template component element, add 'e-columnheader' class to avoid mouse click focus issue.

    args.element.append(container[0]);

};

 

function created () {

    grid = document.getElementById('Grid').ej2_instances[0];

    grid.on('beforecellfocused', (args) => { // before cell focus grid’s internal event for tab navigation maintain purpose.

        if (!args.byClick) {

            if (args.keyArgs && args.keyArgs.target && args.keyArgs.target.closest('th.e-filterbarcell.e-fltrtemp')) { // check the target focused grid’s template cell.

                var tabCheck = ['min']; // except last template component element id.

                var shiftTabCheck = ['max']; // except first template component element id.

                if(args.keyArgs.action === 'tab' && args.keyArgs.target.id.includes(tabCheck)) { // except last template component element id.

                    args.cancel = true;

                } else if(args.keyArgs.action === 'shiftTab' && args.keyArgs.target.id.includes(shiftTabCheck)) { // except first template component element id.

                    args.cancel = true;

                }

            }

        }

    });

}

</script>


Sample: please find the attachment.


Regards,

Vasanthakumar K


Attachment: 186948filterbartemplatecrwd2control_5b88386a.zip

Loader.
Up arrow icon