Como Confirmar un UPDATE en DevExpress o que Cancelando sí lo detenga






Post — Confirmar un UPDATE en DevExpress (y que Cancelar sí lo detenga)

Qué resuelve esta vista (UpdateConfirmation)

Una pantalla de Grupos con dos modos:

  1. Elegir el grupo activo (no se crean grupos nuevos). Lista con checkbox, un solo activo.
  2. Administrar departamentos y categorías de cada grupo con el + (DataRow / master-detail), igual que GruposAdmin.

Al guardar un cambio de activo:

  • El grupo debe tener al menos 1 departamento y 1 categoría.
  • Solo un grupo activo a la vez (los demás pasan a inactivo).
  • Si el usuario pasa de inactivo → activo, sale confirmación. Si cancela, no hay UPDATE.

Tablas: Grupos, Departamentos, Categorias, GruposDepartamentos, GruposCategorias.


1. Por qué confirm() en ClientSideEvents no cancela el update

Errores típicos en DevExpress 13:

Qué se hizoQué pasa
confirm() en BeginCallback
Ese evento no se cancela. El callback ya va al servidor.
Click="onGuardarClick" y el script abajo
Al pintar el botón busca la función y sale Uncaught ReferenceError: onGuardarClick is not defined. El clic queda muerto.
UseSubmitBehavior="True" (default)
El botón hace submit clásico y e.processOnServer = false a veces no alcanza.

Regla: el botón Guardar no debe pegar a servidor. El UPDATE solo lo dispara un botón oculto, y ese botón solo se pulsa si eligen .


2. El patrón que sí funciona (lo más importante del post)

Tres piezas:

A) Guardar nunca postea

<dx:ASPxButton ID="btnGuardar" runat="server" Text="Guardar"
AutoPostBack="False" UseSubmitBehavior="False">
<ClientSideEvents Click="function(s, e) { window.onGuardarClick(s, e); }" />
</dx:ASPxButton>

B) Botón oculto que SÍ guarda
Usar ClientVisible="False" (se renderiza, DoClick() existe).
Visible="False" no se renderiza y DoClick() falla.

<dx:ASPxButton ID="btnGuardarConfirmado" runat="server"
ClientInstanceName="btnGuardarConfirmado" ClientVisible="False"
AutoPostBack="True" UseSubmitBehavior="False"
OnClick="btnGuardarConfirmado_Click" />

C) Popup: Sí dispara el update, Cancelar no

window.onGuardarClick = function (s, e) {
e.processOnServer = false; // Guardar nunca actualiza
// ... si eligió otro grupo:
popupConfirm.Show();
};
window.onConfirmarSi = function (s, e) {
e.processOnServer = false;
popupConfirm.Hide();
btnGuardarConfirmado.DoClick(); // único postback que escribe en BD
};
window.onConfirmarNo = function (s, e) {
e.processOnServer = false;
popupConfirm.Hide();
window.restaurarCheckboxes(); // vuelve al activo original
};

Namespaces a registrar: ASPxEditors, ASPxPopupControl, ASPxClasses, ASPxGridView.


3. JS: colgar funciones de window y ANTES de los botones

DevExpress inicializa el cliente al renderizar el control. Si el <script> va al final, onGuardarClick is not defined.

Datos a tomar en cuenta:

  • Script arriba del markup, colgando de window.
  • En ClientSideEvents usar wrapper: function(s, e) { window.onGuardarClick(s, e); } (se resuelve al clic, no al pintar).
  • UseSubmitBehavior="False" en todos los ASPxButton de este flujo.

4. Checkboxes que se comportan como radio

Los compañeros pidieron checkbox, pero solo uno activo. En CheckedChanged: si marcas uno, desmarcas los demás; si desmarcas el último, se vuelve a marcar.

Cada checkbox recibe ClientInstanceName = "chkGrupo" + id en ItemDataBound. El servidor arma un JSON para el cliente:

GrupoChecksJson = "[{id:1,name:'chkGrupo1',nombre:'Grupo A'}, ...]"
IdGrupoActivo = 3

En C#:

GrupoChecksJson = "[{id:1,name:'chkGrupo1',nombre:'Grupo A'}]";
IdGrupoActivo = 3;

El id elegido se guarda en un HiddenField antes de abrir el popup, para que el postback de “Sí” ya traiga el valor.


5. Validación en servidor (aunque hayan confirmado)

btnGuardarConfirmado_Click es el único método que escribe. Orden:

  1. Leer hfGrupoSeleccionado.
  2. Contar departamentos y categorías del grupo.
  3. Si alguno es 0 → mensaje de error, no actualizar.
  4. Transacción:
    UPDATE Grupos SET activo = 0
    UPDATE Grupos SET activo = 1 WHERE idGrupos = @id

Así, si alguien salta el popup, el servidor igual exige depto + categoría y un solo activo.


6. DataRow (+) para departamentos y categorías

No se crea el departamento/categoría: se gestiona la tabla puente con combo.

<SettingsDetail ShowDetailRow="True" AllowOnlyOneMasterRowExpanded="True" />

Antes de consultar el detalle:

Protected Sub DetailGrid_BeforePerformDataSelect(sender As Object, e As EventArgs)
Dim grid As ASPxGridView = DirectCast(sender, ASPxGridView)
Session("idGrupos") = grid.GetMasterRowKeyValue()
End Sub
protected void DetailGrid_BeforePerformDataSelect(object sender, EventArgs e)
{
ASPxGridView grid = (ASPxGridView)sender;
Session["idGrupos"] = grid.GetMasterRowKeyValue();
}

Los SqlDataSource del detalle usan <asp:SessionParameter SessionField="idGrupos" />.

CRUD de la relación:

  • Nuevo: INSERT en GruposDepartamentos / GruposCategorias.
  • Editar: cambia el id elegido en el combo.
  • Eliminar: borra el vínculo, no el catálogo.

El maestro no tiene Nuevo (no crean más grupos). El activo se cambia por el formulario de checkboxes, no editando la fila.


7. Checklist al armarlo en C# (el trabajo)

En el @ Page:

  • Language="C#", CodeBehind="UpdateConfirmation.aspx.cs", AutoEventWireup="true".

El markup (grids, popup, script) es el mismo. Solo cambia el code-behind.

Ojo con:

  • Inherits / namespace del proyecto real.
  • activo si en BD es bit o int (el código acepta ambos al leer; el UPDATE usa 0/1).
  • Columna desciprion en Departamentos (typo de la BD).
  • ClientVisible="False"Visible="False" en el botón de confirmar.

8. Mini mapa mental

Editar grupos → checkboxes (un activo)
Guardar → processOnServer = false
¿Mismo grupo? → no hace nada
¿Otro grupo? → popup
Cancelar → cierra + restaura checks (sin postback)
Sí → DoClick del botón oculto
Servidor: ¿tiene depto y categoría?
No → error, no UPDATE
Sí → todos inactivos, este activo

El + del grid es independiente: abre el CRUD de relaciones de ese grupo.




Comentarios

Entradas más populares de este blog

Sacando aceleracion de un vehiculo en c++

Ejemplo de suma Pascal

Gráfica de Seno y Coseno en C++ | Código C++