(Dashboard Layout)Dynamically change column value depending on MediaQuery

Hello guys, I want to know if there is a way (in Blazor) to dynamically change the value of the columns of Dashboard Layout depending on the Media query.

<SfDashboardLayout @ref="DashboardPanel" MediaQuery="max-width:800px" CellSpacing="@(new double[]{10 , 10})"  Columns="2" >

For example: 
  • if the max-width of the window is 1200px i want the entire layout to be stacked in 8columns
  • if the max-width of the window is 900px i want the entire layout to be stacked in 4 columns
  • if the max-width of the window is 750px i want the entire layout to be stacked in 2 columns
  • if the max-width of the window is 600px the entire layout to be stacked in one column(the panels will be displayed in a vertical column - Default functionality                          that you have now) etc.
Thank you very much for your help!!!

7 Replies 1 reply marked as answer

SP Sowmiya Padmanaban Syncfusion Team December 17, 2020 10:57 AM UTC

Hi Grigoris Berketis,  
 
Greetings from Syncfusion support. 
 
We have checked your requirement with DashboardLayout component. If you want to change the column property of DashboardLayout component based on window mediaQuery then we need to achieve it using JS interop. Because, currently there is no option available to predict the window dimension from Blazor application(Server side). 
 
Please, refer the below solution sample. 
 
<SfDashboardLayout @ref="dashboard" ID="dashboard" CellSpacing="@(new double[]{10 ,10 })" ShowGridLines="true" Columns=@columns> 
    <DashboardLayoutEvents Created="created"></DashboardLayoutEvents> 
    <DashboardLayoutPanels> 
        <DashboardLayoutPanel> 
            <ContentTemplate><div>0</div></ContentTemplate> 
        </DashboardLayoutPanel> 
        <DashboardLayoutPanel SizeX=2 SizeY=2 Col=1> 
            <ContentTemplate><div>1</div></ContentTemplate> 
        </DashboardLayoutPanel> 
        <DashboardLayoutPanel SizeY=2 Col=3> 
            <ContentTemplate><div>2</div></ContentTemplate> 
        </DashboardLayoutPanel> 
        <DashboardLayoutPanel Row=1> 
            <ContentTemplate><div>3</div></ContentTemplate> 
        </DashboardLayoutPanel> 
    </DashboardLayoutPanels> 
</SfDashboardLayout> 
@code { 
    [Inject] 
    public IJSRuntime JSRuntime { get; set; } 
    SfDashboardLayout dashboard; 
    public int columns = 8; 
    public void created() 
    { 
        JSRuntime.InvokeAsync<int>("dashboard"); 
    } 
} 
<script> 
        function dashboard() { 
            displayWindowSize(); 
            window.addEventListener("resize", displayWindowSize); 
        } 
        function displayWindowSize() { 
            var dashboard = document.getElementById("dashboard").ej2_instances[0]; 
            if (window.innerWidth < 1980 && window.innerWidth > 900) { 
                dashboard.columns = 8;              
            } 
            else if (window.innerWidth > 750 && window.innerWidth < 900) { 
                dashboard.columns = 4;            
            } 
            else if (window.innerWidth > 600 && window.innerWidth < 750) { 
                dashboard.columns = 2;             
            } 
            else { 
                dashboard.columns = 8;             
            } 
            dashboard.refresh(); 
        } 
    </script> 
 
If you need to change the panels alignment when parent’s dimension reaches any specific window mediaQuery dimension, then you need to create a panel position JSON and assign in panels property of DashboardLayout component. 
 
Please, refer the sample link with the above suggested solution. 
 
 
Please let us know, if you need any further assistance. 
 
Regards,  
Sowmiya.P 



GB Grigoris Berketis December 20, 2020 07:33 PM UTC

Thak you so much for your answer and the sample.
I noticed that under certain resolutions panel's cards height becomes bigger than what i want.
I tried to determine the height of the card dynamically depending on the window mediaQuery dimension by using CellAspectRatio attribute.
Unfortunately it doesnt seem to work, for example when width is under 600px dashboard panel doesnt take into account cell aspect ratio's value 
Can you propose me the right way to do it?

<SfDashboardLayout @ref="dashboard" ID="dashboard" CellSpacing="@(new double[]{10 ,10 })" CellAspectRatio="@aspectRatio" Columns=@columns>
    <DashboardLayoutEvents Created="created"></DashboardLayoutEvents>
    <DashboardLayoutPanels>
        <DashboardLayoutPanel>
            <ContentTemplate><div>0</div></ContentTemplate>
        </DashboardLayoutPanel>
        <DashboardLayoutPanel SizeX=2 SizeY=2 Col=1>
            <ContentTemplate><div>1</div></ContentTemplate>
        </DashboardLayoutPanel>
        <DashboardLayoutPanel SizeY=2 Col=3>
            <ContentTemplate><div>2</div></ContentTemplate>
        </DashboardLayoutPanel>
        <DashboardLayoutPanel Row=1>
            <ContentTemplate><div>3</div></ContentTemplate>
        </DashboardLayoutPanel>
    </DashboardLayoutPanels>
</SfDashboardLayout>

------------------------------------ CS ------------------------------------------

@code {
    [Inject]
    public IJSRuntime JSRuntime { get; set; }
    SfDashboardLayout dashboard;
    public int columns = 8;
    public double aspectRatio = 2;


    public void created()
    {
        JSRuntime.InvokeAsync<int>("dashboard");
    }
}

---------------------------JS--------------------------------------

    <script>
        function dashboard() {
            displayWindowSize();
            window.addEventListener("resize", displayWindowSize);
        }
        function displayWindowSize() {
            var dashboard = document.getElementById("dashboard").ej2_instances[0];
            if (window.innerWidth < 1980 && window.innerWidth > 900) {
                dashboard.columns = 8;             
            }
            else if (window.innerWidth > 750 && window.innerWidth < 900) {
                dashboard.columns = 4;           
            }
            else if (window.innerWidth > 600 && window.innerWidth < 750) {
                dashboard.columns = 2; 
                dashboard.aspectRatio = 3;
            }
            else if (window.innerWidth < 600) {
                dashboard.aspectRatio = 3;
            }
            else {
                dashboard.columns = 8;            
            }
            dashboard.refresh();
        }
    </script>


SP Sowmiya Padmanaban Syncfusion Team December 21, 2020 09:55 AM UTC

Hi Grigoris Berketis,  
 
We have checked your attached code sample, we found out that you have not properly mapped the cellAspectRatio property in DashboardLayout component. 
 
Please, refer the below code snippet. 
 
<script> 
        function dashboard() { 
            displayWindowSize(); 
            window.addEventListener("resize", displayWindowSize); 
        } 
        function displayWindowSize() { 
            var dashboard = document.getElementById("dashboard").ej2_instances[0]; 
            if (window.innerWidth < 1980 && window.innerWidth > 900) { 
                dashboard.columns = 8; 
            } 
            else if (window.innerWidth > 750 && window.innerWidth < 900) { 
                dashboard.columns = 4; 
            } 
            else if (window.innerWidth > 600 && window.innerWidth < 750) { 
                dashboard.columns = 2; 
                dashboard.cellAspectRatio = 3; 
            } 
            else if (window.innerWidth < 600) { 
                dashboard.cellAspectRatio = 3; 
            } 
            else { 
                dashboard.columns = 8; 
            } 
            dashboard.refresh(); 
        } 
    </script> 
 
Please, refer the sample with the above solution. 
 
 
Please let us know, if you need any further assistance. 
 
Regards,  
Sowmiya.P 



GB Grigoris Berketis December 22, 2020 12:52 PM UTC

Hello again,
I implemented the suggested changes but due to the complexity of the card's content(charts and autorefresh) the performance of the suggested solution is dreadful.
Thank you again for your help.
Regards
Grigoris.


SP Sowmiya Padmanaban Syncfusion Team December 23, 2020 07:32 AM UTC

Hi Grigoris Berketis,  
 
Sorry for the inconvenience. 
 
Unfortunately, we were unable to understand the exact issue which you are facing with DashboardLayout from your shared limited details. Please share us the more details regarding your reported problem with DashboardLayout component. 
 
·         Share us screenshot/video footage of your reported problem. 
 
·         Share us the exact issue details and steps to replicate it at our end. 
 
·         Explain us your requirement and real-time use case scenario. 
 
·         If possible, share us the issue replicated sample. 
 
This information would help us to be provide you the prompt solution. 
 
Please let us know, if you need any further assistance. 
 
Regards,  
Sowmiya.P 



MA Michael Aston March 8, 2021 12:17 PM UTC

I'm trying to get the code you supplied to Grigoris to work for me. Seems to work fine in your example with 18.3.0.52 but fails with 18.4.0.46. The line that is the problem is:

var dashboard = document.getElementById("dashboard").ej2_instances[0]; 

seems that .ej2_instances[0];  does not exist in 18.4.0.46


SP Sowmiya Padmanaban Syncfusion Team March 9, 2021 11:48 AM UTC

Hi Michael Aston,  
 
In 18.4 version, we have not accessed the component instance in JS interop. To resolve your problem, you need to set the cellAspectRatio and Columns in server side. 
 
Please ,refer to the below code snippet. 
 
<SfDashboardLayout @ref="dashboard" ID="dashboard" CellSpacing="@(new double[] { 10, 10 })" CellAspectRatio="@aspectratio" ShowGridLines="true"  Columns=@columns> 
    <DashboardLayoutEvents Created="created"></DashboardLayoutEvents> 
    </DashboardLayoutPanels> 
</SfDashboardLayout> 
 
public void created() 
   { 
        jsRuntime.InvokeAsync<string>("dashboard", new object[] { DotNetObjectReference.Create<object>(this) }); 
    } 
 
  [JSInvokable] 
    public void CSCallBackMethod(int col, int aspectratio) 
    { 
        // update the column and cell aspect ratio 
        this.columns = col; 
        this.aspectratio = aspectratio; 
        this.StateHasChanged(); 
    } 
[Host.Cshtml] 
  
<script> 
        window.dashboard = (args) => { 
            displayWindowSize(args); 
            window.addEventListener("resize", displayWindowSize.bind(this, args)); 
        }; 
        function displayWindowSize(args) { 
            if (window.innerWidth < 1980 && window.innerWidth > 1300) { 
                var col = 6; 
                var aspectratio = 2; 
                // call the method from client to server side. 
                args.invokeMethodAsync('CSCallBackMethod', col, aspectratio); 
            } 
            else if (window.innerWidth > 750 && window.innerWidth <= 1300) { 
                var col = 4; 
                var aspectratio = 2; 
                args.invokeMethodAsync('CSCallBackMethod', col, aspectratio); 
            } 
            else if (window.innerWidth > 600 && window.innerWidth <= 750) { 
                var col = 2; 
                var aspectratio = 2; 
                args.invokeMethodAsync('CSCallBackMethod', col, aspectratio); 
            } 
            else { 
                var col = 6; 
                var aspectratio = 3; 
                args.invokeMethodAsync('CSCallBackMethod', col, aspectratio); 
            } 
        } 
    </script> 
 
Please, refer to the sample link. 
 
 
Please let us know, if you need any further assistance. 
 
Regards,  
Sowmiya.P 


Marked as answer
Loader.
Up arrow icon