Я пытаюсь настроить фокус на элемент управления TextBox (который находится внутри UpdatePanel) в приложении ASP.Net (С#). Я пробовал следующее в коде:
tbxName.Focus();
Page.SetFocus(tbxName);
tsmManageTables.SetFocus(tbxName);
Никто из них не работал, поэтому я пошел в Javascript. Здесь моя функция Javascript:
function SetControlFocus(ctrlID) {
var ctrl = document.getElementById(ctrlID);
ctrl.focus();
}
Здесь метод в коде, который вызывает его:
private void SetControlFocus(Control ctrl)
{
StringBuilder focus = new StringBuilder();
focus.AppendLine("<script type='text/javascript'>");
focus.AppendFormat(" SetControlFocus('{0}');" + System.Environment.NewLine, ctrl.ClientID);
focus.AppendLine("</script>");
ClientScript.RegisterStartupScript(this.GetType(), "setControlFocus", focus.ToString(), false);
}
И звонок:
SetControlFocus(tbxName);
Я также пробовал Javascript:
(function($) {
SetControlFocus = function(ctrlID) {
var ctrl = $('<%= ' + ctrlID + ' %>');
ctrl.focus();
};
})(jQuery);
С любой версией функции Javascript я получаю ошибку
"Объект ctl00_MainContent_tbxName не имеет никакого" фокуса "метода"
Что я делаю не так?
ОБНОВЛЕНИЕ:
Я попробовал предложение Карла использовать селектор классов вместо селектора идентификаторов с уродливым <%= =>
, но это не сработало. Теперь у меня другая ошибка:
Uncaught ReferenceError: className не определен
с Javascript:
(function($) {
SetControlFocus = function(ctrlClass) {
var ctrl = $('.' + ctrlClass);
ctrl.focus();
};
})(jQuery);
разметка:
<asp:TextBox ID="tbxName" runat="server" CssClass="className"></asp:TextBox>
метод вызова:
private void SetControlFocus(Control ctrl)
{
StringBuilder focus = new StringBuilder();
focus.AppendLine("<script type='text/javascript'>");
focus.AppendFormat(" SetControlFocus({0});" + System.Environment.NewLine, ctrl.CssClass);
focus.AppendLine("</script>");
ClientScript.RegisterStartupScript(this.GetType(), "setControlFocus", focus.ToString(), false);
}
вызов (С#):
SetControlFocus(tbxName);
и сгенерированный HTML для TextBox:
<input name="ctl00$MainContent$tbxName" type="text" id="ctl00_MainContent_tbxName" class="className" />
ОБНОВЛЕНИЕ 2:
Я немного поиграл с этим и добился прогресса (думаю). Теперь я не получаю никаких сообщений об ошибках, но фокус все еще не идет в TextBox. Здесь моя текущая функция jQuery:
(function($) {
SetControlFocus = function(ctrl) {
//give the control focus
alert(ctrl);
ctrl.focus();
};
})(jQuery);
И здесь метод С#, где я его называю:
private void SetControlFocus(TextBox ctrl)
{
StringBuilder focus = new StringBuilder();
focus.AppendLine("<script type='text/javascript'>");
focus.AppendFormat(" SetControlFocus({0});" + System.Environment.NewLine, ctrl.ClientID);
focus.AppendLine("</script>");
ClientScript.RegisterStartupScript(this.GetType(), "setControlFocus", focus.ToString(), false);
} //end method SetControlFocus
Обратите внимание, что я передаю управляющий идентификатор ClientID функции Javascript. Странно, что Javascript принимает ClientID и фактически "захватывает" объект управления, а не строку, содержащую ClientID. Предупреждение работает, оно дает мне [object HTMLInputElement]
в предупреждении. Какие-нибудь советы?
ОБНОВЛЕНИЕ 3:
Я изменил функцию Javascript:
(function($) {
SetControlFocus = function(ctrlSelector) {
alert(ctrlSelector);
$(ctrlSelector).focus();
};
})(jQuery);
и метод вызова:
private void SetControlFocus(TextBox ctrl)
{
StringBuilder focus = new StringBuilder();
focus.AppendLine("<script type='text/javascript'>");
focus.AppendFormat(" SetControlFocus('{0}');" + System.Environment.NewLine, "#" + ctrl.ClientID);
focus.AppendLine("</script>");
ClientScript.RegisterStartupScript(this.GetType(), "setControlFocus", focus.ToString(), false);
}
(обратите внимание на добавление одинарных кавычек вокруг аргумента - '{0}'
).
Теперь я получаю правильный селектор (предупреждение отвечает с #ctl00_MainContent_txtName
), никаких ошибок, но TextBox по-прежнему не фокусируется.
Наконец я понял, как это сделать! Я переместил SetControlFocus()
jQuery SetControlFocus()
в другую функцию jQuery, которую я вызываю из своего кода. Код метода вызывает MessageDialog()
, который теперь выглядит следующим образом:
(function($) {
MessageDialog = function(title, dialogText, focusID) {
//add the dialog div to the page
$('body').append(String.Format("<div id='messageDialog' title='{0}'><p>{1}</p></div>", title, dialogText));
//create the dialog
$('#messageDialog').dialog({
modal: true,
resizable: false,
draggable: false,
close: function(event, ui) { $('body').find('#messageDialog').remove(); },
buttons:
[{
text: 'OK',
click: function() {
$(this).dialog('close');
//Set focus to the control object in argument #3 (if provided)
if (focusID.length > 0) {
SetControlFocus(focusID);
}
}
}]
});
};
})(jQuery);
SetControlFocus()
остается:
(function($) {
SetControlFocus = function(ctrlSelector) {
$(ctrlSelector).focus();
};
})(jQuery);
И мой метод вызова в С# (который является перегрузкой метода, который у меня уже был):
private void DisplayMessageDialog(string msgTitle, string msgText, string ctrlID)
{
StringBuilder msg = new StringBuilder();
msg.AppendLine("<script type='text/javascript'>");
msg.AppendFormat(" MessageDialog('{0}', '{1}', '{2}');" +
System.Environment.NewLine, msgTitle, msgText, "#" + ctrlID);
msg.AppendLine("</script>");
ClientScript.RegisterStartupScript(this.GetType(), "messageDialog", msg.ToString(), false);
} //end method DisplayMessageDialog (overload #2 - specifies a control to get focus
//after the dialog is dismissed)
Вам не хватает #
для выбора идентификатора.
Либо сделайте это:
var ctrl = $('#<%= ' + ctrlID + ' %>');
Или используйте имя class
в элементе управления ASP.NET TextBox
а именно:
<asp:TextBox id="TextBox1" runat="server" CssClass="TheTextBox" />
Теперь ваш селектор станет следующим:
var ctrl = $('.TheTextBox');
Примечание. Использование селекторов классов и селекторов ID значительно упрощает синтаксис селектора и удаляет синтаксис gnarly embedded code block (<%=... %>
), который вы использовали. Хотя это не так быстро, как селектор идентификаторов, выигрыши более простого и удобного кода, безусловно, стоит того, что я думаю.
ОБНОВИТЬ:
Оберните все значение селектора в одинарных кавычках, например:
var ctrl = $("'." + ctrlClass + "'");
UPDATE:
в моем ответе.
На вашем втором javascript отсутствует знак хэша для обозначения выбора идентификатора.
(function($) {
SetControlFocus = function(ctrlID) {
var ctrl = $('#<%= ' + ctrlID + ' %>');
ctrl.focus();
};
})(jQuery);
Это должно сделать трюк.