Как упрямо сохранить старый обработчик событий JavaScript на странице веб-формы, перенесенной на ASP.NET MVC?

Рассмотрим одну строку разметки в файле .ASPX следующим образом:

<asp:DropDownList ID="drpdownPayPlan" runat="server" onchange="javascript: document.getElementById('txtPayAmount').value = document.getElementById('drpdownPayPlan').value.replace(',', '');">

Могу ли я сохранить встроенный код обработчика JavaScript и каким образом? Я понимаю, что при переносе приложения WebForms на ASP.NET MVC возникает множество других проблем, но я хотел бы не усложнять задачу и сосредоточиться только на этой строке. В настоящее время ошибка, которую я получаю в этой строке:

Необработанное исключение в строке 410, столбце 115 в http://localhost:3835/Policy/QuotePayments?QN=XYZ-1234567&PN=ABCDEFGHIJ&AC=123456789

0x800a138f — ошибка выполнения JavaScript: невозможно получить значение свойства неопределенной или нулевой ссылки

При отображении исходный код в строке 410 выглядит следующим образом (я понимаю причину искажения имен):

    <select name="ctl00$MainContent$drpdownPayPlan" id="MainContent_drpdownPayPlan" onchange="javascript: document.getElementById(&#39;txtPayAmount&#39;).value = document.getElementById(&#39;drpdownPayPlan&#39;).value.replace(&#39;,&#39;, &#39;&#39;);">

Итак, при всем уважении - не говоря мне проповеди о том, как правильно портировать проект WebForms в MVC (извините, что звучит как мятежный и несговорчивый подросток!) - как я могу решить проблему, с которой я столкнулся? строка разметки?


person ShieldOfSalvation    schedule 06.04.2017    source источник


Ответы (1)


Ошибка 0x800a138f на странице ASPX часто возникает при попытке назначить имя элемента управления на стороне сервера (которого нет на стороне клиента из-за поведения элемента управления сервера по умолчанию, назначающего AutoID) вместо имени на стороне клиента, поэтому document.getElementById('drpdownPayPlan') возвращает undefined.

Есть 2 пути решения:

  1. Назначьте ClientIDMode="Static" каждому задействованному серверному элементу управления (я предположил, что txtPayAmount является серверным элементом управления TextBox, если вы используете буквальное текстовое поле ввода, оставьте txtPayAmount как есть).

    <asp:TextBox ID="txtPayAmount" runat="server" ClientIDMode="Static" />
    <asp:DropDownList ID="drpdownPayPlan" runat="server" ClientIDMode="Static" onchange="javascript: document.getElementById('txtPayAmount').value = document.getElementById('drpdownPayPlan').value.replace(',', '');">
    

    NB: атрибут ClientIDMode доступен в .NET версии 4.0 и более поздних.

  2. Используйте <%= drpdownPayPlan.ClientID %> для ссылки на идентификатор на стороне клиента, сохраняя при этом идентификаторы элементов управления в состоянии AutoID (опять же, я предположил, что txtPayAmount здесь является элементом управления TextBox, оставьте его, если txtPayAmount является буквальным текстовым полем).

    <asp:DropDownList ID="drpdownPayPlan" runat="server" onchange="javascript: document.getElementById('<%= txtPayAmount.ClientID %>').value = document.getElementById('<%= drpdownPayPlan.ClientID %>').value.replace(',', '');">
    

Обратите внимание, что я рекомендую вам отделить часть JS от управления сервером в функции и вызвать имя функции, как указано ниже:

<asp:DropDownList ID="drpdownPayPlan" runat="server" onchange="changePayAmount();">

<script type="text/javascript">
function changePayAmount() {
    document.getElementById('<%= txtPayAmount.ClientID %>').value = document.getElementById('<%= drpdownPayPlan.ClientID %>').value.replace(',', '');
}
</script>

PS: В контексте MVC id для каждого вспомогательного элемента HTML можно легко определить в части атрибутов HTML следующим образом:

@Html.DropDownListFor(model => model.PayPlan, Model.PayPlanList as SelectList, new { id = "drpdownPayPlan" })

Похожие проблемы:

0x800a138f - ошибка времени выполнения JavaScript: невозможно получить свойство 'значение' неопределенной или нулевой ссылки

Ошибка выполнения JavaScript: невозможно получить значение свойства неопределенной или нулевой ссылки

person Tetsuya Yamamoto    schedule 07.04.2017
comment
Спасибо, @Tetsuya-Yamamoto! Ваш первый вариант сработал! Я сам попробовал второй вариант, прежде чем опубликовать вопрос, потому что это все, что я знал, но это не изменит результат. Однако, как вы предложили, назначение ClientIDMode=Static для каждого задействованного серверного элемента управления решило мою проблему! Я установил этот атрибут как в свой контрольный тег txtPayAmount, так и в drpdownPayPlan. Вуаля! Домо аригато годзаимасу! - person ShieldOfSalvation; 07.04.2017