Иногда возникает задача, когда на какую-либо «командную» кнопку (т.е. кнопку, имющую значение CommandName “Edit”, “Delete” и т.д.) в строке GridView необходимо поцепить JavaScript. Самая распространенная из этих ситуаций – это поцепить яваскрипт на кнопку, которая выполняет команду Delete. Во избежание ошибочного удаления записи из хранилища данных было бы неплохо спросить пользователя что-то вроде «Вы уверены, что хотите удалить эту строку?» и предоставить возможность выбора (т.е. вызвать клиентский window.confirm).
GridView предоставляет несколько возможностей создания кнопки с CommandName=”Delete”:
1. Указать в свойствах грида AutoGenerateDeleteButton="true". В этом случае всегда будет генерироваться LinkButton с CommandName=”Delete”.
2. Создать свою кнопку (это может быть как LinkButton, так и просто Button или ImageButton) и прописать ей CommandName=”Delete”.
3. Использовать CommandField. У CommandField есть свойство ButtonType, что также позволяет указать тип кнопки (LinkButton, ImageButton или Button)
Я всегда использовал LinkButton и для того, чтобы поцепить на него яваскрипт добавлял следующий код в RowDataBound:
protected void grid1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow &&
(e.Row.RowState == DataControlRowState.Normal || e.Row.RowState == DataControlRowState.Alternate))
{
if (e.Row.Cells[gridColumn].Controls[0] is LinkButton)
{
((LinkButton)e.Row.Cells[gridColumn].Controls[0]).Attributes.Add("onclick", "return confirm('are you sure?')");
}
}
}
И все работало J
Тут мне пришлось использовать ImageButton (а точнее CommandField, с ButtonType=”Image”). Попытка использовать аналогичный код не увенчалась успехом – при ответе «НЕТ» ничего не происходит (а ничего и не должно происходить), а вот при ответе «ДА» происходит постбек без удаления записи. Это сначала ввело меня в небольшое замешательство, но исследование клиентского кода все поставило на свои места J Грид генерирует следующие варианты кода :
для LinkButton :
<a onclick="return confirm('are you sure?');" href="javascript :__doPostBack('ctl00$ContentPlaceHolder1$grid1','Delete$1')">Delete</a>
для ImageButton :
<input type="image" src="…" alt="Delete" onclick="return confirm('are you sure?');javascript :__doPostBack('ctl00$ContentPlaceHolder1$grid1','Delete$1')" style="border-width:0px;" />
Отсюда видим, что GridView генерирует __doPostBack для «a» на href, а для «input» на onclick, т.е., цепляя какой-либо скрипт на onclick в RowDataBound Grid «закроет» этот яваскрит (чтобы не было открытых блоков вроде if как в данном случае) и только потом добавит к нему __doPostBack. Нажав на «ДА» window.confirm сразу вызывает постбек, не передав параметры в страницу (т.е. до вызова __doPostBack дело не доходит).
Решается это очень просто – использованием следующего кода:
((ImageButton)e.Row.Cells[gridColumn].Controls[0]).Attributes.Add("onclick", "if(!confirm('are you sure?')) return false;");
Т.е. в случае с «ДА» скрипт продолжит свое выполнение.