This is a migrated thread and some comments may be shown as answers.

RadMenuItem / Client Side / change style properties

5 Answers 349 Views
Menu
This is a migrated thread and some comments may be shown as answers.
Robert
Top achievements
Rank 1
Robert asked on 02 Mar 2019, 08:10 PM

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

5 Answers, 1 is accepted

Sort by
0
Peter Milchev
Telerik team
answered on 06 Mar 2019, 02:51 PM
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.
0
Robert
Top achievements
Rank 1
answered on 06 Mar 2019, 11:42 PM

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();
    }
}
0
Peter Milchev
Telerik team
answered on 11 Mar 2019, 12:12 PM
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.
0
Robert
Top achievements
Rank 1
answered on 23 Mar 2019, 06:50 PM

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

0
Eyup
Telerik team
answered on 27 Mar 2019, 05:56 PM
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.
Tags
Menu
Asked by
Robert
Top achievements
Rank 1
Answers by
Peter Milchev
Telerik team
Robert
Top achievements
Rank 1
Eyup
Telerik team
Share this question
or