asp.netvb.netlistitem

Disable specific LI element from Page_Load


I have a similar issue to How can I disable a specific LI element inside a UL?, except I want to set whether my LI element is disabled on Page_Load because it depends on the current user logged in.

I have a master page which displays on all the site's pages. In it is a menu for the current user:

<ul class="nav navbar-top-links navbar-right">
  <li class="dropdown">
    <a class="dropdown-toggle" data-toggle="dropdown" href="#">
      <i class="fa fa-user fa-fw"></i> <i class="fa fa-caret-down"></i>
      <asp:Label runat="server" ID="lblUserName" Text="User Name Here" />
    </a>
    <ul class="dropdown-menu dropdown-user">

      <li>
        <a href="ChangeLoggedInUserPassword.aspx" runat="server" id="UserInfoLink">
          <i class="fa fa-user-md fa-fw"></i>
          <asp:Label runat="server" ID="UserInfoStatement" Text=" User information/change password" />
          <!--^^^^^^^^^^^^^^^^^^^^^^^^^I want to disable this^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-->
        </a>
      </li>
      <li>
        <a href="login.aspx">
          <i class="fa fa-sign-out fa-fw"></i>
          <asp:Label runat="server" ID="LogoutLabel" Text=" Logout" />
        </a>
       </li>
     </ul>
   </li>
 </ul>

I want to disable the ability to change the password and display user information when no user exists. I accomplish this on Page_Load:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Not Page.IsPostBack Then
        Dim greetingText As String = "Hello "
        Dim userName As String = "Guest"

        Try
            Dim currentTime As DateTime = DateTime.Now
            Select Case currentTime.Hour
                Case 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
                    greetingText = "Good Morning, "
                Case 12, 13, 14, 15, 16, 17
                    greetingText = "Good Afternoon, "
                Case 18, 19, 20, 21, 22, 23
                    greetingText = "Good Evening, "
            End Select

            Dim memberUser As MembershipUser = Membership.GetUser()
            If memberUser Is Nothing Then
                greetingText = "Please Sign In"
                userName = ""
                UserInfoStatement.Enabled = False
                UserInfoStatement.ForeColor = Drawing.Color.Gray
                LogoutLabel.Text = " Login"
            Else
                UserInfoStatement.Enabled = True
                UserInfoStatement.ForeColor = Drawing.Color.Black
                LogoutLabel.Text = " Logout"
            End If

            Try
                userName = memberUser.UserName
            Catch ex As Exception
                Log(String.Format("Navbar error getting user name: {0}", ex))
            End Try

        Catch ex As Exception
            Log(String.Format("Navbar error creating greeting string: {0}", ex))
        End Try

Problem statement: When the page loads, stepping through the code indicates it does what I want it to. But as soon as the page is done loading, I can use the mouse to find the UserInfoStatement menu item and find it is not disabled; I can click on it just fine.

I have tried disabling both UserInfoStatement and UserInfoLink in code behind, and neither one disables clicking the menu item. I tried adding an OnClick event to the UserInfoLink but it only will allow a client-based event (Javascript). What other options do I have?


Solution

  • Add "id" and a runat="server" to the "li" element.

    Say, like this:

    <li id="muserinfo" runat="server">
        <a href="ChangeLoggedInUserPassword.aspx" runat="server" id="UserInfoLink">
          <i class="fa fa-user-md fa-fw"></i>
          <asp:Label runat="server" ID="UserInfoStatement" Text=" User information/change password" />
          <!--^^^^^^^^^^^^^^^^^^^^^^^^^I want to disable this^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-->
        </a>
      </li>
    

    Then in code behind, you can go:

    mUserInfo.Visible = False
    

    An "li" element can't be disabled, as there's no input to prevent. So, you either hide, or show the element. I suppose you could wrap a div around that li element, and consider that.

    The reason why I suggest "hiding" the menu item is that when you set a control .visible = false, it is NOT rendered at all! (so, a user client side can't hit say f12 to launch the browser dev tools, and even inspect the element, since the element does not even exist).

    And "disabled" elements are confusing to the user - they will still often click on them, and wonder why????

    So, probably best to use/consider .visible, since as noted "li" elements don't have a enable/disable property anyway.

    Edit: you can gray out the text + disable.

    You can do it this way.

    First, add a style class like this on your master page

    Put this up near top - before the menu:

    <style> 
      .mydisable a
      { pointer-events: none;
        cursor: default;
        color:gray !important;
      } 
    </style>
    

    Say this:

      <div class="navbar-collapse collapse">
         <ul id="mainmenu" runat="server" class="nav navbar-nav navbar-left">
           <li id="m1" runat="server"><a runat="server" href="~/">Home</a></li>
           <li id="m2" runat="server"><a runat="server" href="~/Contact">Contact</a></li>
    

    So, say I want to disable m2, then this:

        m2.Attributes.Add("class", "mydisable")
    

    Result is this:

    enter image description here