Declined
Last Updated: 11 Nov 2020 14:22 by ADMIN
Stephen
Created on: 05 Nov 2020 00:06
Category: Drawer
Type: Bug Report
1
The drawer keeps collapsing by itself immediately after expanding on calling Drawer.ToggleAsync()

I'm using a custom drawer item to handle toggling the drawer open and close. Every time I click on my custom toggle item I call Drawer.ToggleAsync() (which I trigger on the SelectedItemChanged event handler). If the drawer is expanded to begin with, it is correctly collapsed to the mini view. However, if I click the toggle item again, the drawer expands and then immediately re-collapses itself. I put a breakpoint on the code that calls Drawer.ToggleAsync(), and it's only getting hit once for each click. This is very strange behavior. Please help me work out what's going on.

P.S If there is a better way to handle the click on my custom toggle drawer item (rather than using SelectedItemChanged), please let me know.

Code

@inherits LayoutComponentBase

<TelerikRootComponent>

    <div class="page">
        <div class="drawer-container">
            <TelerikDrawer 
                           @ref="@Drawer" 
                           Data="Data" 
                           MiniMode="true"
                           Expanded="true"
                           Mode="@DrawerMode.Push" 
                           SelectedItemChanged="((DrawerItem item) => SelectedItemChangedHandler(item))">
                <Content>
                    <div class="main">
                        <div class="content px-4">
                            @Body
                        </div>
                    </div>
                </Content>
            </TelerikDrawer>
        </div>
    </div>
</TelerikRootComponent>

@code {
    public TelerikDrawer<DrawerItem> Drawer { get; set; }
    public DrawerItem SelectedItem { get; set; }
    public IEnumerable<DrawerItem> Data { get; set; } =
        new List<DrawerItem>
        {
            new DrawerItem { Text = "Item1", Icon = IconName.Inbox },
            new DrawerItem { Text = "Item2", Icon = IconName.Information },
            new DrawerItem { Text = "Item3", Icon = IconName.MarkerPin },
            new DrawerItem { IsSeparator = true },
            new DrawerItem { Text = "Item4", Icon = IconName.Inbox },
            new DrawerItem { Text = "Item5", Icon = IconName.Inbox },
            new DrawerItem { Text = "Toggle", Icon = IconName.ArrowChevronLeft, IsToggle = true },
            };

    protected override Task OnInitializedAsync()
    {
        SelectedItem = Data.First();

        return base.OnInitializedAsync();
    }

    public class DrawerItem
    {
        public string Text { get; set; }
        public string Icon { get; set; }
        public bool IsSeparator { get; set; }
        public bool IsToggle { get; set; }
    }

    private async Task SelectedItemChangedHandler(DrawerItem item)
    {
        SelectedItem = item;

        if (item.IsToggle)
        {
            await Drawer.ToggleAsync();

            if (Drawer.Expanded)
            {
                item.Icon = IconName.ArrowChevronRight;
            }
            else
            {
                item.Icon = IconName.ArrowChevronLeft;
            }
        }
    }
} 


Attached Files:
1 comment
ADMIN
Svetoslav Dimitrov
Posted on: 11 Nov 2020 14:22

Hello Stephen,

When the SelectedItemChanged event is fired we call a CollapseAsync(). To use an item of the Drawer as a button to collapse or expand the drawer you might have to use the Template. Below, I have prepared a code snippet which you could use as a base for your application. If this does not help you could open a support ticket so we can take another look.

I am changing the status here to Declined since this is not a bug, but a different approach.

Code snippet:

<TelerikDrawer @bind-Expanded="@DrawerExpanded"
               Data="@Data"
               MiniMode="true"
               Mode="@DrawerMode.Push"
               @bind-SelectedItem="@SelectedItem"
               @ref="@DrawerRef">
    <Template>
        @* the header *@
        <div>
            @if (DrawerExpanded)
            {
                <div class="text-info" style="border-bottom:solid; font-weight: bold; margin-bottom: 3em; white-space:nowrap">
                    My Custom Navigation
                </div>
            }
            else
            {
                <div class="text-info" style="border-bottom:solid; font-weight: bold;">
                    Nav
                </div>
            }
        </div>

        @* custom items rendering and item selection *@

        <div class="k-drawer-items">
            <ul>
                @if (SelectedItem != null && DrawerExpanded)
                {
                    <li class="k-drawer-item" style="white-space:nowrap">
                        <div>
                            <p><strong>@SelectedItem.Text</strong></p>
                            <p>@SelectedItem.Description</p>
                        </div>
                    </li>
                }

                @foreach (var item in Data)
                {
                    if (item.Text == "Toggle")
                    {

                        <li @onclick="( _ => DrawerExpanded == true ? DrawerRef.CollapseAsync() : DrawerRef.ExpandAsync())"
                            class="k-drawer-item @GetSelectedItemClass(item)" style="white-space:nowrap">
                            <span class="@(DrawerExpanded == true ? "k-icon k-i-arrow-chevron-left" : "k-icon k-i-arrow-chevron-right")" style="margin-right: 8px;"></span>
                            @if (DrawerExpanded)
                            {
                                <div>
                                    Toggle
                                </div>
                            }
                        </li>
                    }
                    else
                    {
                        <li @onclick="@(() => SelectedItem = item)"
                            class="k-drawer-item @GetSelectedItemClass(item)" style="white-space:nowrap">
                            <span class="k-icon k-i-@item.Icon" style="margin-right: 8px;"></span>
                            @if (DrawerExpanded)
                            {
                                <div>
                                    <div>@item.Text</div>
                                </div>
                            }
                        </li>
                    }
                    @* Use onclick to handle manual item selection *@

                }
            </ul>
        </div>

        @* the footer *@
        @if (DrawerExpanded)
        {
            <div style="text-align: center; margin-top: 3em; padding-top: 2em; border-top: 2px solid black; white-space:nowrap">
                <img src="user-avatar.png" alt="my avatar" style="border-radius: 50%; width: 50px; height: 50px;" />
                <br /><br />
                <TelerikButton Icon="@IconName.Logout" Primary="true">Log Out</TelerikButton>
            </div>
        }
    </Template>
    <Content>
        <div class="m-5">Content for @SelectedItem?.Text - @SelectedItem?.Description</div>
    </Content>
</TelerikDrawer>

@code {
    public TelerikDrawer<DrawerItem> DrawerRef { get; set; }
    public DrawerItem SelectedItem { get; set; }
    public bool DrawerExpanded { get; set; } = true;
    public IEnumerable<DrawerItem> Data { get; set; } = new List<DrawerItem>
{
        new DrawerItem {Text = "Shopping Cart", Icon = IconName.Cart, Description = "Items in shopping cart"},
        new DrawerItem {Text = "Settings", Icon = IconName.Gear, Description = "My profile settings"},
        new DrawerItem {Text = "Notifications", Icon = IconName.Notification, Description = "My profile notifications"},
        new DrawerItem {Text = "Calendar", Icon = IconName.Calendar, Description = "My events"},
        new DrawerItem {Text = "Toggle", Icon = IconName.ArrowChevronLeft, IsToggle = true}
    };

    public string GetSelectedItemClass(DrawerItem item)
    {
        if (SelectedItem == null) return string.Empty;
        return SelectedItem.Text.ToLowerInvariant().Equals(item.Text.ToLowerInvariant()) ? "text-info" : "";
    }

    public class DrawerItem
    {
        public string Text { get; set; }
        public string Icon { get; set; }
        public string Description { get; set; }
        public bool IsToggle { get; set; }
    }
}

Regards,
Svetoslav Dimitrov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.