ClientID MenuItem - PullRequest
       12

ClientID MenuItem

4 голосов
/ 08 декабря 2011

У меня есть элемент на странице, у которого в качестве элементов меню есть серия MenuItem (динамически генерируемых из базы данных).

Каждый элемент меню отображается как

<a class="ctl00_cphContent_cphMainContentTitle_uxHeaderMenu_menuPageNav_1 button ctl00_cphContent_cphMainContentTitle_uxHeaderMenu_menuPageNav_3" style="border-style:none;font-size:1em;" href="SomeURLHere.aspx">

Однако я хотел бы получить ClientID этой ссылки (мы используем внешнюю библиотеку Javascript для всплывающих страниц в модальных фреймах лайтбокса). Одним из требований этого является то, что нам нужно идентифицировать «кликабельный идентификатор объекта», чтобы мы могли настроить его для запуска события при щелчке.

везде на нашем сайте у нас есть

OurSite.SetupDialogueBoxForOpen('<%= HyperLink.ClientID =>');

Однако по какой-то причине для пункта меню, похоже, не назначено свойство ClientID. Что делает невозможным установку идентификатора клиента в JavaScript.

Кто-нибудь знает, как получить ClientID элемента меню (просто для пояснения, пункт меню имеет тип System.Web.UI.WebControls.MenuItem

Заранее спасибо!

Ответы [ 7 ]

3 голосов
/ 20 декабря 2011

Если вы хотите изменить способ визуализации элементов в элементе управления, вы можете использовать свойства StaticMenuItemTemplate и DynamicMenuItemTemplate. В моем примере я буду использовать только первое (статическое, для элементов верхнего уровня):

<asp:Menu runat="server" ...>
  <StaticMenuItemTemplate>
    <a id="<%# GetSuitableClientId(Container) %>"><%# Eval("Text") %></a>
  </StaticMenuItemTemplate>
</asp:Menu>

Свойство StaticMenuItemTemplate имеет тип ITemplate и, как часто бывает в случае с такими свойствами шаблона, оно украшено TemplateContainer приписывать. Это указывает контейнер, в котором должен быть создан экземпляр шаблона, обычно контейнер предоставляет доступ к некоторому контексту, который может вам понадобиться при рендеринге. В этом случае он имеет тип MenuItemTemplateContainer, который реализует IDataContainer и, таким образом, дает доступ к элементу данных.

Таким образом, мы передаем этот контейнер методу на нашей странице, и в этом методе мы создаем идентификатор по своему усмотрению. Мы могли бы использовать элемент данных для глубины и контейнер для индекса, например:

protected string GetSuitableClientId(MenuItemTemplateContainer container)
{
  MenuItem item = (MenuItem)container.DataItem;
  return String.Format("menuItem-{0}-{1}", item.Depth, container.ItemIndex);
}

Я предполагаю, что при построении этого ответа вы можете настроить свой JavaScript для привязки к событиям клика по элементу <a id="menuItem-2-4">Text</a>, поскольку теперь у вас есть предсказуемые идентификаторы на стороне клиента.

Редактировать: вы также можете использовать следующее в своем шаблоне и позволить ASP.NET позаботиться о создании уникального идентификатора на стороне клиента, но это менее предсказуемо ...

<asp:HyperLink ID="MenuItem" runat="server" NavigateUrl='<%# Eval("NavigateUrl") %>' />
1 голос
/ 16 декабря 2011

Как насчет получения списка каждого тега привязки в DOM и итераций по ним, просматривая .class, пока не найдете класс == "what_Nav_ID_or_flag_you_entered_or_somehow_can_tell_this_element_apart" и затем используя .id для присвоения ему идентификатора?Что-то вроде: не проверено

var anchors = document.getElementsByTagName("a");
for(int i = 0; i < anchors.length()){
    if(anchors[i].class=="testClass"){
        anchors[i].id = "targetThisAnchor";
        break;
    }
}

РЕДАКТИРОВАТЬ: во время рендеринга вы можете использовать условное выражение, чтобы увидеть, является ли новый пункт меню тем, который вы ищете?

<%
  if (MenuItem.flag == menuItemToTarget)
  {
      //set MenuItem id
  }
%>
1 голос
/ 08 декабря 2011

Попробуйте, измените selector $("menu > a").bind('click',function(){}));

0 голосов
/ 20 декабря 2011

Большинство из этих ответов дают отличную идею для нацеливания на определенную ссылку и что-то с ней сделать.Проблема в том, что вы не знаете, какие ссылки будут создавать базы данных, и у них нет установленного идентификатора клиента для выбора.

Вам может не понравиться ответ, но в конечном итоге вам нужно реализовать что-то, что будетпозволять вам идентифицировать ссылки, будь то свойство class или id, в конечном итоге не имеет значения.

Грубые идеи могут быть следующими:

  • Соглашение по нумерации / именованию на стороне клиента.Например, на странице готовности используйте jQuery для синтаксического анализа якорей, возможно их значений класса или href, и используйте эти данные для традиционной установки идентификатора клиента.

  • Измените схему БД, чтобы позволить клиентуИдентификатор, который будет сохранен с деталями ссылки.Это потребовало бы наибольшей работы, потому что это означает изменение схемы, объектов, методов и т. Д., Но это не должно быть слишком сложно и, вероятно, будет вашим самым безопасным и чистым решением.

Я уверен, что есть и другие варианты, но ключ в том, что вам нужно как-то идентифицировать свои ссылки, прежде чем скрипт вообще вам поможет.

0 голосов
/ 16 декабря 2011

Asp: меню предоставляет набор свойств CSS, например hoverCss / SelectCss.

если вы выберете (mouseOver / click) один пункт меню, добавит ли класс cssclass элемент управления html (a)?

, если ответ «Да», тогда используйте

$ ('. Thecssclassuspecified'). Live ('click', function () {

                                $(this)....

                              });

или 'No', боюсь, вы должны использовать что-то вродеприведенный ниже код, элементы управления caz asp до VS 2010 не идеальны для js и jquery.

$ ('menu> a'). live ('click', function () {

                       $(this)... 

               });
0 голосов
/ 15 декабря 2011

При связывании меню (OnMenuItemDataBound) вы, вероятно, можете добавить пользовательский атрибут с некоторым идентификатором, который впоследствии можно будет использовать в JavaScript.

Обновление : MenuItem не имеет свойства Attributes, поэтому это тупик. Кроме того, так как MenuItem запечатан, нет места для изменений. Но Меню - публичный класс, так что, возможно, это можно сделать там. Весь этот Menu / MenuItem не подходит для модификации, поэтому я думаю, что вы должны написать много собственного кода.

Или используйте Адаптеры для него.

Если бы это зависело от меня, я бы бросил меню asp.net и написал его полностью на заказ.

0 голосов
/ 08 декабря 2011

Вы попадаете в пункт меню так:

OurSite.SetupDialogueBoxForOpen('<%= uxHeaderMenu.FindControl("menuPageNav_3").ClientID %>');

Поскольку вы не опубликовали ни одного кода, я не могу сказать вам, как конкретно выбрать третий (в приведенном выше случае) .... но это должно работать.

Вам необходимо использовать FindControl, потому что MenuItem является дочерним элементом меню, а не дочерним элементом страницы или пользовательского элемента управления.

...