Gridview: Confirmación en el botón/enlace/imagen de eliminar

Cuando asignamos en el Gridview un comando de eliminación para que se encargue "automáticamente" de conversar con el proveedor de datos y enviarle el comando de Delete (o disparar el evento correcto) en ASP.NET agregamos una columna del tipo comando…

image

Al agregarlo nos queda algo así:

<asp:CommandField ShowDeleteButton="True" DeleteText="Eliminar 0"/>

Podemos modificarlo al tipo de "botón", sea enlace, imagen o "botón"

image

 
la pregunta es…

¿Como agregar un evento de JS para que confirme la eliminación?

El famoso:

image
 
Necesitamos asignarle un script del lado del cliente (es decir javascript), pero no tenemos disponible la propiedad OnClientScript que nos sirve para los botones

(lean este articulo Evitar el postback al pulsar un botón en ASP.NET – de José M. Aguilar)

 
Bueno si queremos seguir con la columna del tipo CommandField, tendremos que hacer algo incomodo para el programador… contar en que columna esta exactamente para poder ubicar este control, porque no podemos realizar una búsqueda con FindControl ya que no sabemos ni siquiera un ID (identificador), pero también tenemos otras soluciones.
 

OPCION 1: Utilizando CommandField

Con la columna que nos proporciona el wizard tedremos que ir al codebehind y encontrar el control que renderiza.
<asp:CommandField ShowDeleteButton="True" DeleteText="Eliminar 0"/>

Si sabemos que esta en la 7 columna (y como todo en .NET empieza de 0), y que solamente tenemos este control tendríamos que capturarlo

Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
       Select Case e.Row.RowType
           Case DataControlRowType.DataRow
            
               Dim ctrlEliminar As LinkButton = CType(e.Row.Cells(6).Controls(0), LinkButton)
               ctrlEliminar.OnClientClick = "return confirm('¿Esta seguro de eliminar este registro?');"

       End Select
   End Sub
 
y como sabiamos que era un LinkButton??, bueno porque es por defecto a lo que renderiza el CommandField, si queremos ser mas específicos tendríamos que colocar el tipo expresamente
<asp:CommandField ShowDeleteButton="True" DeleteText="Eliminar 0" ButtonType="Link"/>
 
Y si no me creen, pueden:
Dim ctrl As WebControl = CType(e.Row.Cells(6).Controls(0), WebControl)
ctrl.Attributes.Add("tipoControl", ctrl.GetType.ToString)

Podremos ver el el codigo renderizado el siguiente atributo "tipoControl":

<a tipoControl="System.Web.UI.WebControls.DataControlLinkButton" 
    href="javascript:__doPostBack('ctl00$contenidoCentral$GridView1','Delete$0')">Eliminar 1</a>

Particularmente colocar esta búsqueda "exacta" con numero de celda y posición del control dentro de la misma no es del todo "ortodoxa", ya que a la hora de  modificar.. esto hay que "tocar aquí y allí", para eso la siguiente opción es mas "elegante" (y mucho mas fácil).

OPCION 2: Utilizando TemplateField con el control que queremos

Cuando quiero implementar algo similar utilizo una columna template… y allí podemos insertar un Button o un LinkButton que le asignas un comando… especial en el Gridview (y en la mayoría de los controles que se enlazan a datos) que es el comando delete, simplemente agregándole esta propiedad CommandName="Delete".

Es decir el Gridview disparará/provocará automáticamente los eventos RowDeleting y RowDeleted

<asp:TemplateField HeaderText="Ejemplo Eliminar">
      <ItemTemplate>
         <asp:Button ID="btnDelete" Text="Eliminar 1" runat="server"
              OnClientClick="return confirm('¿Esta seguro de eliminar este registro?');"
              CommandName="Delete" />
</ItemTemplate>
</asp:TemplateField>


 

y si queremos con LinkButton (idem):
<asp:LinkButton ID="linkEliminar" runat="server"
                 OnClientClick="return confirm('¿Esta seguro de eliminar este registro?');"
                CommandName="Delete">Eliminar 2</asp:LinkButton>

(…)El control GridView también provoca otros eventos especializados al hacer click en ciertos botones (botones cuya propiedad CommandName presenta valores como "Delete", "Update" y "Page"). Al utilizar uno de estos botones, se debería considerar la posibilidad de controlar uno de los eventos especializados proporcionados por el control (como RowDeleted o RowDeleting).(…)

 

 

Enlaces:  

37 comentarios en “Gridview: Confirmación en el botón/enlace/imagen de eliminar”

  1. El articulo esta muy claro y muy explicativo, pero intentando hacerlo para un control imagebutto en vez del link button logro que ejecute el evento rowdeleting

  2. Hola Felipe
    Seria bueno mirar el codigo que estabas realizando.
    Igualmente mas tarde hago un ejemplo y actualizo el articulo
    (como no tengo tu email vas a tener que volver al articulo para la respuesta!)

  3. Jose paso el codigo con el que quiero implementar el imagebutton

    en la clase

    Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles grillaTitularesTC2.RowDataBound
    Select Case e.Row.RowType
    Case DataControlRowType.DataRow
    Dim ctrlEliminar As ImageButton = CType(e.Row.Cells(9).Controls(0), ImageButton)
    ctrlEliminar.OnClientClick = “return confirm(‘¿Esta seguro de eliminar este registro?’);”
    End Select
    End Sub

    en el html


    lo hice tanto con commandfield como con template y en los 2 casos me pasa lo mismo

    Muchas Gracias
    Saludos
    dejo mi mail: felipedeguevara@bancoroela.com.ar

  4. Hola Felipe
    (el fin de semana te envie un email pero me dio error)
    El código es el correcto, pero me gusta mas en una columna template
    Fijate si el codigo esta escribiendo en la pagina, o sea mira el código fuente (el render HTML) entonces por ahi es un problema de JS…
    Si puedes enviame el codigo HTML resultante de una fila o de la tabla entera
    Saludos

  5. hola Jose
    Logre que funcionara, lo hice en una columna template y ademas en utilice el evento onClick del imageButton en vez del onClientClick y funciono perfecto.
    Muchisimas Gracias por tu ayuda
    Muy buen Blog
    Saludos

  6. Hola a todos.. como están
    Soy nuevo en asp.net y estoy implementando este control GridView y me presenta problemas cuando le hago click al ImageButton “Edit” o “Delete” y me manda este error espero me puedan ayudar

    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    [HttpException (0x80004005): GridView ‘gvAlergiasDelegado’ desencadenó el evento RowUpdating, que no estaba controlado.]
    System.Web.UI.WebControls.GridView.OnRowUpdating(GridViewUpdateEventArgs e) +322
    System.Web.UI.WebControls.GridView.HandleUpdate(GridViewRow row, Int32 rowIndex, Boolean causesValidation) +909
    System.Web.UI.WebControls.GridView.HandleEvent(EventArgs e, Boolean causesValidation, String validationGroup) +809
    System.Web.UI.WebControls.GridView.OnBubbleEvent(Object source, EventArgs e) +163
    System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +56
    System.Web.UI.WebControls.GridViewRow.OnBubbleEvent(Object source, EventArgs e) +119
    System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +56
    System.Web.UI.WebControls.ImageButton.OnCommand(CommandEventArgs e) +107
    System.Web.UI.WebControls.ImageButton.RaisePostBackEvent(String eventArgument) +203
    System.Web.UI.WebControls.ImageButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +31
    System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +32
    System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +72
    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3824

  7. Hola Carlos Arjona
    (no dejaste tu email para enviarte la respuesta aunque sea asi ejemplo{arroba}gmail{punto}com)

    Cuando estableces la propiedad AutoGenerateEditButton en True y enlazas a un proveedor de datos por ejemplo ObjectDataSource, SQLDataSource… puedes hacer uso casi automatico de la actualizacion/edicion de filas sin necesidad de escribir codigo, siempre y cuando este correctamente configurado tu proveedor de datos
    Si enlazas a proveedores que no estan configurados para este tipo de mecanismo automatizado, o que tengan interfaces compatibles, tendras que escribir “manualmente” es decir artesanalmente todo el codigo correspondiente a la edicion/actualizacion de la fila del gridview

    Mira los enlaces que te envio mas abajo si te puedes ayudar…

    O postea en algun grupo de noticias que seguro te podran ayudar mucho mas rapido.
    – Grupo de noticias (news) de ASP.NET en español (visualizacion a traves de la UI de google grupos)
    http://groups.google.com.ar/group/microsoft.public.es.dotnet.aspnet/topics
    – Foro: MSDN ASP.NET y Desarrollo Web Visual
    http://forums.microsoft.com/MSDN-ES/ShowForum.aspx?ForumID=309&SiteID=11

    Enlaces:
    ————
    GridView.RowUpdated (Evento)
    Se produce cuando se hace clic en el botón Actualizar de una fila, pero después de que el control GridView actualice la fila.
    http://msdn2.microsoft.com/es-es/library/system.web.ui.webcontrols.gridview.rowupdated(VS.80).aspx

    GridView.RowUpdating (Evento)
    Se produce cuando se hace clic en el botón Actualizar de una fila, pero antes de que el control GridView actualice la fila.
    http://msdn2.microsoft.com/es-es/library/system.web.ui.webcontrols.gridview.rowupdating.aspx

    GridView.AutoGenerateEditButton (Propiedad)
    Obtiene o establece un valor que indica si una columna de campo CommandField con un botón Editar para cada fila de datos se agrega automáticamente a un control GridView.
    http://msdn2.microsoft.com/es-es/library/system.web.ui.webcontrols.gridview.autogenerateeditbutton(VS.80).aspx

    Un ejemplos
    http://aspnet101.com/aspnet101/tutorials.aspx?id=51
    http://authors.aspalliance.com/aspxtreme/shared/viewsrc.aspx?path=/aspxtreme/sys/web/ui/webcontrols/demos/GridViewAutoGenerateEditButton.aspx.src

    Espero que te sirva de ayuda o guia

  8. Hola muy buen artículo pero yo tengo el siguiente error:

    Specified argument was out of the range of valid values.
    Parameter name: index

    Dim ctrlEliminar As LinkButton = CType(e.Row.Cells(1).Controls(0), LinkButton)

    yo he agregado un CommandfFeld para editar y eliminar dentro del gridview, pero deseo q’ al intentar eliminar primero me confirme la eliminación y no lo logro.

    Gracias por su ayuda.

  9. Hola Lisseth
    Para verificar la posicion:
    e.Row.Cells(1).Controls(0)
    Tienes que copiar la definicion del gridview, asi como indicas estas buscando en la segunda columna.
    Pero para no dar margen al error, copia la deficion de la grilla.

  10. Lisseth
    Cuando estas requiriendo un control de una celda, esta debe existir

    En tu definicion de Gridview, en el codigo de la pagina veras algo asi…



    Si ves en la parte de definicion de columnas, tienes que ver en que cual esta la del boton de eliminar… si es la primer columna, entonces seria asi
    e.Row.Cells(0).Controls(0)
    (las colecciones empiezan desde 0, cero)

  11. Gracias por tu respuesta está es la definición del commandField:

    Supongo que entonces será:

    Protected Sub gv_palabras_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gv_palabras.RowDataBound
    Select Case e.Row.RowType
    Case DataControlRowType.DataRow
    Dim ctrlEliminar As LinkButton = CType(e.Row.Cells(0).Controls(1), LinkButton)
    ctrlEliminar.OnClientClick = “return confirm(‘¿Esta seguro de eliminar este registro?’)”
    End Select
    End Sub

    Pero igual me da el mismo error.

  12. Lisseth
    Prueba primeramente con una columna (en la primer posicion) simplemente con el boton eliminar, algo asi:

    Sino ya te recomenaria que lo hagas con la opcion 2 (que comento en el articulo) entonces no estas buscando sino simplemente lo haces en una columna template

  13. Hola necesito saber si alguien puede ayudarme o poner un ejemplo.

    En el cual al intentar borrar en vez de pedir solo un confirmación, me pida el motivo por el cual decido borrar.. y si el motivo existe entonces que borre si preguntar mas..

    Si alguien me puede ayudar por favor.

  14. Hola Kari
    Interesante tu pedido.. 🙂
    Tendrias que hacer mas cosas que las que dice aqui, implementar una ventana modal con textbox para escribir. Y luego en el aceptar VALIDAR el contenido y si es valido, entonces enviar a ejecutar la accion o sino cancelarla

    Lo de ventana modal hay muchos ejemplos y tal vez puedas utilizar el AJAX Control Toolkit que posee un “modalpopup”…
    Bueno la idea es que luego puedas verificar por javascript (si lo quieres en el cliente) lo cual me gustaria si el contenido de un textbox interno de la ventana modal tiene algo escrito. Y este motivo tendrias que enviarle al evento eliminar? Y si.. o sino no sirve para nada.

    PD: Si puedo me hago un tiempo el fin de semana y armo un ejemplo sencillo. Si tienes mas informacion pasamela por email o escribiendo en contacto en este mismo blog 🙂
    Saludos

  15. Si, mira precisamente al principio me marcaba error por que ya que cerraba la ventana modal me refrescaba el control que guardaba el valor que tecleó el usuario, sin embargo no ejecutaba el Command Delete, ahorita acabo de cambiar la ventana modal por una simple funcion que muestre un promt, y paso el valor de la variable al control siempre y cuando el valor no sea nulo entonces le doy valor de true a la funcion y de lo contrario false y así no hace nada por lo tanto no ejecuta el command delete..

    Muchas gracias de cualquier manera me pondré en contacto contigo y te agradezco cualquier otra opción de realizarlo probablemente tengas una mejor… saludos.

  16. Hola man quien me podria ayudar a colocar un boton eliminar en un Gridview… Ya en el GridView1_RowDataBound.. tengo que poner tres cosa…… para llamar los dato en un List cat List; y cargar los datos en el GridView1.. y de ahy tengo que colocar tres LinkButton..1 para editar,2 el otro para borrar, 3,Actualizar. como hago para poder poner todos eso en el ROWDATABOUND..
    Desde ya mucha gracias…

  17. hola yo uso una columna template con un imagebutton y lo de la confirmacion sale perfecto mi problema es que nose como pasarle el parametro para q elimine en la base de datos, ayuda porfavor

  18. Hola José. estoy con el ejemplo de este página. Ya logro que me ejecute el mensaje en java y cuando le doy aceptar me recarga la pagina (postback). Ahora no logro que me ejecute el procedimiento RowDeleted de la grilla. y no logro ver que es lo que me esta faltando, te dejo mi correo por si me podes ayudar: aavalos_rbasrl@hotmail.com
    Gracias de antemano.

  19. Hola estoy implementando este ejemplo pero me aparece el siguiente error:

    Descripción: Excepción no controlada al ejecutar la solicitud Web actual. Revise el seguimiento de la pila para obtener más información acerca del error y dónde se originó en el código.

    Detalles de la excepción: System.InvalidCastException: No se puede convertir un objeto de tipo ‘System.EventArgs’ al tipo ‘System.Web.UI.WebControls.GridViewRowEventArgs’.

    Este es parte de mi codigo:

    Protected Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GridView1.RowCommand
    Dim index As Integer = Convert.ToInt32(e.CommandArgument)

    Dim row As GridViewRow = GridView1.Rows(index)

    If (e.CommandName = “Editar”) Then
    Response.Write(““)

    Response.Redirect(“EditarIncidencia.aspx?Clv_Incidencia=” & row.Cells(0).Text)
    End If

    If Incidencias.Autorizar_Eliminar(row.Cells(0).Text) Then
    If Incidencias.Eliminar_Incidencia(row.Cells(0).Text) Then
    Response.Redirect(“Notificacion_Cancelar.aspx”)
    End If
    End If

    End Sub

    Protected Sub GridView1_DataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.DataBound
    Select Case e.Row.RowType

    Case DataControlRowType.DataRow

    Dim ctrlEliminar As ImageButton = CType(e.Row.Cells(5).Controls(0), ImageButton)

    ctrlEliminar.OnClientClick = “return confirm(‘¿Esta seguro de eliminar este registro?’);”

    End Select

    End Sub

    Agradeceria mucho su ayuda.

    mi mail es awwihs@hotmail.com

  20. quiero enviar un segunda columna del gridview como variable a la funcion javascript no se como hacerlo sin hacer postback e encontrado este que envia el valor de un checbox yo necesitaria que ademas envie el valor de otro columna del gridview
    //

    es decir
    //

  21. me podrias ayudar a usar el commandfield para eliminar pero en c#…

    tengo que implementar el mensaje de confirmacion para eliminar pero tiene que ser con un commandfield ya que al lado del eliminar pongo un editar y al presionar se oculta el icono de eliminar y eso es lo que necesito.

    Gracias

  22. En página *.asp (v. studio .net 2010) tengo un gridview y en un botón (evento click) un código que hace una consulta a una tabla de una base de datos en sql server 2008. Puedo llevar el resultado de la consulta al gridview sin ningún problema.

    Resulta que necesito ubicar en el mismo gridview, un checkbox para que usuario pueda hacer click y seleccionar el registro. Esta checkbox no guarda ningún vínculo con la base de datos, solo se usa temporalmente para que los registros que se encuentren seleccionados puedan ser leídos para su correspondiente modificación que afectan a la misma y/o otra tabla.

    Preguntas:

    Mediante programación necesito ubicar el checkbox y el usuario pueda elegir.

    Mediante programación como puedo crear filas en gidview vinculados o sin vínculos a un dataset o datable.

    Mediante programación como se puede llamar: GridView1_RowCreated(ByVal sender As Object, ByVal e As GridViewRowEventArgs)

    Mediante programación como se puede llamar: Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As GridViewCommandEventArgs).

    dimurve@hotmail.com

  23. Hola muy bueno tu aporte muchas gracias. Pero no logro que me funcione la confirmación, puse un imagebotton en un template pero no me funciona aca dejo el código. Les agradecería mucho me digan en que fallo. mi mail es pablogre@arnet.com.ar





  24. Hola @pablogre acuérdate que Javascript es sensible a mayúsculas y minúsculas, por esa razon no es lo mismo “Return” que “return”.
    En tu caso cambia como escribes esa parte
    onclientclick=”return confirm(‘Desea Eliminar este Registro ?’);”
    Mira bien el “return” en minúsculas.
    Espero que te sirva de ayuda o guia.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *