RadMenuItem / Client Side / change style properties

6 posts, 0 answers
  1. John
    John avatar
    25 posts
    Member since:
    Jan 2011

    Posted 02 Mar Link to this post

    I have a RadContextMenu implemented within a Radgrid and the options for the context menu are different for each row.  To facilitate this I am using the Client-Side programming for the RadContextMenu and the ClientDataKeyName from the RadGrid to power the conditions.

    This is all working fine.  My problem is that I need some of the RadMenuItems to be Bold or have a different background color, but I see no way to do this through the Client-Side programming.

    Am I missing something obvious here?

    So for example here is where I need to change the Font to bold or Background color of the item

    Snippet:

    // if the item should be displayed, then initialize
    if (isItemDisplayed == 1) {
        var childItem = new Telerik.Web.UI.RadMenuItem();
        var displayText = '';
     
        // Here I need to set childItem to be Bold and a specific background color to stand out
     
        // set menu text
        childItem.set_text(displayText);
     
        // set employeeid identifier
        childItem.set_value(employeeId);
     
        // if we have items in the 'actions menu', then add it to the parent'
        if (parentActionsItem.get_items().get_count() > 0) {
            menu.get_items().insert(0, parentActionsItem);
        }

     

    Any help is greatly appreciated

  2. Peter Milchev
    Admin
    Peter Milchev avatar
    589 posts

    Posted 06 Mar Link to this post

    Hello John,

    You can access the DOM element for the menu item after you add it to the menu. Then, you can use JavaScript to set some CSS to the main element or any of its children elements: 

    // if we have items in the 'actions menu', then add it to the parent'
     
    contextMenu.get_items().insert(0, childItem);
     
    $telerik.$(childItem.get_element()).css("background-color", "greenyellow");
    $telerik.$(childItem.get_element()).find(".rmLink").css("font-weight","bold");


    For further customization and inspection of the elements, you can follow the suggestions in the first two points of the Improve Your Debugging Skills with Chrome DevTools blog post.

    Another option is to set a CSS class to the item after you add it to the menu, and use your stylesheet to change the appearance: 

    contextMenu.get_items().insert(0, childItem);
    childItem.set_cssClass(childItem.get_cssClass() + " important-item");
    //$telerik.$(childItem.get_element()).css("background-color", "greenyellow");
    //$telerik.$(childItem.get_element()).find(".rmLink").css("font-weight","bold");

    <style>
        .important-item {
            background-color: greenyellow;
            font-weight: bold;
        }
    </style>

    Regards,
    Peter Milchev
    Progress Telerik
    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  3. John
    John avatar
    25 posts
    Member since:
    Jan 2011

    Posted 06 Mar in reply to Peter Milchev Link to this post

    Hi Peter -

    Thanks this was helpful.  However it seems any change I make only applies to the last item inserted into the menu hierarchy.

    I've posted a more complete snippet of how it is currently being implemented.  Can you direct me to how I would alter the style/css like you instructed but to affect just one specific item?  The contents of the context menu will be potentially different on each row of the RadGrid it is being implemented on, which also could change the number of items in each instance of it.  I could even locate this item by the menu item text/value associated with it if that helps, but I could not find a good object reference for this object that outlined much of what I am needing to know.

    function RowContextMenu(sender, eventArgs) {
        var menu = $find("<%=menuContext.ClientID %>");
        var evt = eventArgs.get_domEvent();
     
        if (evt.target.tagName == "INPUT" || evt.target.tagName == "A") {
            return;
        }
     
        var index = eventArgs.get_itemIndexHierarchical();
        document.getElementById("hidSelectedRowIndex").value = index;
     
        var selectedItem = sender.get_masterTableView().get_dataItems()[index];
        var employeeId = selectedItem.getDataKeyValue("EmployeeID");
        var statusHeaderId = selectedItem.getDataKeyValue("StatusHeaderID");
        var contextMenuOptions = selectedItem.getDataKeyValue("ContextMenuOptions");
     
        sender.get_masterTableView().selectItem(sender.get_masterTableView().get_dataItems()[index].get_element(), true);
     
        // track changes to menu
        menu.trackChanges();
     
        // clear existing menu items
        menu.get_items().clear();
     
        // initialize parent menu objects
        var parentNewItem = new Telerik.Web.UI.RadMenuItem();
        parentNewItem.set_text('New');
        var parentViewItem = new Telerik.Web.UI.RadMenuItem();
        parentViewItem.set_text('View');
        var parentActionsItem = new Telerik.Web.UI.RadMenuItem();
        parentActionsItem.set_text('Actions');
     
        // loop through items
        for (var i = 0; i < contextMenuOptions.length; i++) {
            // based on the item index, take action
            var isItemDisplayed = contextMenuOptions.charAt(i);
     
            // if the item should be displayed, then initialize
            if (isItemDisplayed == 1) {
                var childItem = new Telerik.Web.UI.RadMenuItem();
                var displayText = '';
     
                // create menu item based on index
                switch (i + 1) {
                    case 1:
                        displayText = "Menu Action 1";
                        break;
                    case 2:
                        displayText = "Menu Action 2";
                        break;
                    case 3:
                        displayText = "Menu Action 3";
                        break;
                }
     
                // set menu text
                childItem.set_text(displayText);
     
                // set menu identifier
                childItem.set_value(employeeId);
     
                switch (i + 1) {
                    case 1:
                        // add to menu 1
                        parentViewItem.get_items().add(childItem);
                        break;
                    case 2:
                        // add to menu 2
                        parentNewItem.get_items().add(childItem);
                        break;
                    case 3:
                        // add to menu 3
                        parentActionsItem.get_items().add(childItem);
                        break;
                    default:
                        // add to 'parent' menu
                        menu.get_items().add(childItem);
                        break;
                }
            }
        }
     
        // if we have items in the 'actions menu', then add it to the parent'
        if (parentActionsItem.get_items().get_count() > 0) {
            menu.get_items().insert(0, parentActionsItem);
        }
     
        // if we have items in the 'view menu', then add it to the parent
        if (parentViewItem.get_items().get_count() > 0) {
            menu.get_items().insert(0, parentViewItem);
        }
     
        // if we have items in the 'new menu', then add it to the parent'
        if (parentNewItem.get_items().get_count() > 0) {
            menu.get_items().insert(0, parentNewItem);
        }
     
        // commit changes to menu
        menu.commitChanges();
     
        // show menu
        menu.show(evt);
     
        evt.cancelBubble = true;
        evt.returnValue = false;
     
        if (evt.stopPropagation) {
            evt.stopPropagation();
            evt.preventDefault();
        }
    }
  4. Peter Milchev
    Admin
    Peter Milchev avatar
    589 posts

    Posted 11 Mar Link to this post

    Hi John,

    I recommend adding the nodes to the nodes collection of the Menu before setting the text, value and any other properties. 

    function RowContextMenu(sender, eventArgs) {
        var menu = $find("<%=menuContext.ClientID %>");
        var evt = eventArgs.get_domEvent();
     
        if (evt.target.tagName == "INPUT" || evt.target.tagName == "A") {
            return;
        }
     
        var index = eventArgs.get_itemIndexHierarchical();
        document.getElementById("hidSelectedRowIndex").value = index;
     
        var selectedItem = sender.get_masterTableView().get_dataItems()[index];
        var employeeId = selectedItem.getDataKeyValue("EmployeeID");
        var statusHeaderId = selectedItem.getDataKeyValue("StatusHeaderID");
        var contextMenuOptions = selectedItem.getDataKeyValue("ContextMenuOptions");
     
        sender.get_masterTableView().selectItem(sender.get_masterTableView().get_dataItems()[index].get_element(), true);
     
        // track changes to menu
        menu.trackChanges();
     
        // clear existing menu items
        menu.get_items().clear();
     
        // initialize parent menu objects
        var parentNewItem = new Telerik.Web.UI.RadMenuItem();
        parentNewItem.set_text('New');
        var parentViewItem = new Telerik.Web.UI.RadMenuItem();
        parentViewItem.set_text('View');
        var parentActionsItem = new Telerik.Web.UI.RadMenuItem();
        parentActionsItem.set_text('Actions');
     
        // Add the parent items before creating the child items
     
        // if we have items in the 'actions menu', then add it to the parent'
        if (parentActionsItem.get_items().get_count() > 0) {
            menu.get_items().insert(0, parentActionsItem);
        }
     
        // if we have items in the 'view menu', then add it to the parent
        if (parentViewItem.get_items().get_count() > 0) {
            menu.get_items().insert(0, parentViewItem);
        }
     
        // if we have items in the 'new menu', then add it to the parent'
        if (parentNewItem.get_items().get_count() > 0) {
            menu.get_items().insert(0, parentNewItem);
        }
     
     
        // loop through items
        for (var i = 0; i < contextMenuOptions.length; i++) {
            // based on the item index, take action
            var isItemDisplayed = contextMenuOptions.charAt(i);
     
            // if the item should be displayed, then initialize
            if (isItemDisplayed == 1) {
                var childItem = new Telerik.Web.UI.RadMenuItem();
                var displayText = '';
     
                // create menu item based on index
                switch (i + 1) {
                    case 1:
                        displayText = "Menu Action 1";
                        break;
                    case 2:
                        displayText = "Menu Action 2";
                        break;
                    case 3:
                        displayText = "Menu Action 3";
                        break;
                }
     
                // Add the child items before setting their text and value
     
                switch (i + 1) {
                    case 1:
                        // add to menu 1
                        parentViewItem.get_items().add(childItem);
                        break;
                    case 2:
                        // add to menu 2
                        parentNewItem.get_items().add(childItem);
                        break;
                    case 3:
                        // add to menu 3
                        parentActionsItem.get_items().add(childItem);
                        break;
                    default:
                        // add to 'parent' menu
                        menu.get_items().add(childItem);
                        break;
                }
     
                // set menu text
                childItem.set_text(displayText);
     
                // set menu identifier
                childItem.set_value(employeeId);
     
            }
        }
         
        // commit changes to menu
        menu.commitChanges();
     
        // show menu
        menu.show(evt);
     
        evt.cancelBubble = true;
        evt.returnValue = false;
     
        if (evt.stopPropagation) {
            evt.stopPropagation();
            evt.preventDefault();
        }
    }


    Then, before showing the menu, you can find the desired item, then get it's element using the API and style it with JavaScript: 



    <div style="width: 100px; float: left; padding-top: 5px;">
        <telerik:RadImageButton ID="btaction" runat="server" OnClientClicking="showcontextmenu" Image-Url="https://via.placeholder.com/34x34" Height="34px" Width="34px"></telerik:RadImageButton>
        <telerik:RadContextMenu ID="cmactions" runat="server" EnableRoundedCorners="True" EnableShadows="True" EnableAriaSupport="True" OnItemDataBound="cmactions_ItemDataBound" RenderMode="Auto">
            <Items>
                <telerik:RadMenuItem Text="Item1"></telerik:RadMenuItem>
                <telerik:RadMenuItem Text="Item2"></telerik:RadMenuItem>
                <telerik:RadMenuItem Text="Item3"></telerik:RadMenuItem>
                <telerik:RadMenuItem Text="Item4"></telerik:RadMenuItem>
            </Items>
        </telerik:RadContextMenu>
    </div>

    <script>
        function showcontextmenu(sender, args) {
            var contextMenu = $find("<%=cmactions.ClientID %>");
            var childItem = new Telerik.Web.UI.RadMenuItem();
            var displayText = '';
     
            // if we have items in the 'actions menu', then add it to the parent'
            contextMenu.get_items().insert(0, childItem);
     
            // set menu text
            childItem.set_text("Custom");
     
            // set employeeid identifier
            childItem.set_value("2123");
            
            // childItem is the client-side object of type RadMenuItem
            // https://docs.telerik.com/devtools/aspnet-ajax/controls/menu/client-side-programming/overview#getting-the-instance-of-a-particular-radmenuitem
            var childItemElement = childItem.get_element()
     
            $telerik.$(childItem.get_element()).css("background-color", "greenyellow")
            $telerik.$(childItem.get_element()).find(".rmLink").css("font-weight","bold")
     
            contextMenu.show(args.get_domEvent());
            args.set_cancel(true);
        }
    </script>

    Please modify the code and screenshot I have provided so that it is more clear what the issue is and what is the difference between the actual and desired appearance.

    Regards,
    Peter Milchev
    Progress Telerik
    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  5. John
    John avatar
    25 posts
    Member since:
    Jan 2011

    Posted 23 Mar in reply to Peter Milchev Link to this post

    Hi Peter -

    I'm not sure this approach will work for me because of two things. 

    1) I have this implemented in a RadGrid so it needs to be dynamic to each row in the grid. 

    2) The items will change depending on the grid row selected, meaning the parent nodes will be potentially different as well.  So Row 1 might have 3 master categories each with children, but Row 2 might have only one master category with some children.

    I am struggling with this implementation here.  Am I doing this wrong altogether?  It feels like it is 90% there but I just can't get this simple styling to apply in the same dynamic manner that I am building the menus.

    So when they click a row on the RadGrid that is when we initialize the menu based on a data item in that row, which indicates all of the options that should be enabled in this instance of the RadContextMenu

    <telerik:RadGrid ID="rgExample" runat="server">
        <ClientSettings>
            <ClientEvents OnRowContextMenu="RowContextMenu" />
            <Selecting AllowRowSelect="true" />
        </ClientSettings>
        <!-- Other Grid Items Here -->
    </telerik:RadGrid>
    <telerik:RadContextMenu ID="menuContext" runat="server" OnItemClick="menuContext_ItemClick" />

     

    Then we have the client side script RowContextMenu which is called on the OnRowContextMenu event which I pasted earlier in the post.  It then reads one of the values from the dataItem so it knows which context parents/children to build for this particular row.

    All of this works perfectly.  I just want to style each particular row slightly different to accentuate a default option for the user, but it will be different on each row.

    From your example it looked like you have a static RadContextMenu which is not the case for me due to the dynamic nature of its implementation in the RadGrid.

    Am I going about this approach wrong?

    Thanks in advance

  6. Eyup
    Admin
    Eyup avatar
    3801 posts

    Posted 27 Mar Link to this post

    Hello John,

    Your approach is valid and perfectly fine. Actually, the correct approach in this scenario is the second option provided by my colleague Peter in his first post. To resolve the "only last item gets styled" issue, you can first set the CSS class of the item before adding it to the collection of the menu. Otherwise, the childItem instance will always be the last item:
    contextMenu.get_items().insert(0, childItem);

    For instance, in the attached sample you can simply add this:
    var newItem = new Telerik.Web.UI.RadMenuItem();
    newItem.set_text("Clicked: " + el.innerHTML);
    newItem.set_cssClass(newItem.get_cssClass() + " important-item");
    sender.get_items().add(newItem);

    CSS:
    .important-item {
        background-color: greenyellow;
        font-weight: bold;
    }

    And you should be ready to go.

    Regards,
    Eyup
    Progress Telerik
    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Back to Top