Aggiunta di una conferma lato client durante l'eliminazione (VB)
Nelle interfacce create finora, un utente può eliminare accidentalmente i dati facendo clic sul pulsante Elimina quando si intende fare clic sul pulsante Modifica. In questa esercitazione verrà aggiunta una finestra di dialogo di conferma sul lato client visualizzata quando si fa clic sul pulsante Elimina.
Introduzione
Nelle ultime esercitazioni è stato illustrato come usare l'architettura dell'applicazione, ObjectDataSource e i controlli Web dati in concerto per fornire funzionalità di inserimento, modifica ed eliminazione. Le interfacce di eliminazione esaminate finora sono state composte da un pulsante Elimina che, quando si fa clic, provoca un postback e richiama il metodo ObjectDataSource s Delete()
. Il Delete()
metodo richiama quindi il metodo configurato dal livello della logica di business, che propaga la chiamata al livello di accesso ai dati, eseguendo l'istruzione effettiva DELETE
al database.
Anche se questa interfaccia utente consente ai visitatori di eliminare i record tramite i controlli GridView, DetailsView o FormView, non dispone di alcuna sorta di conferma quando l'utente fa clic sul pulsante Elimina. Se un utente fa clic accidentalmente sul pulsante Elimina quando ha lo scopo di fare clic su Modifica, il record che intendeva aggiornare verrà invece eliminato. Per evitare questo problema, in questa esercitazione verrà aggiunta una finestra di dialogo di conferma sul lato client visualizzata quando si fa clic sul pulsante Elimina.
La funzione JavaScript confirm(string)
visualizza il parametro di input stringa come testo all'interno di una finestra di dialogo modale fornita con due pulsanti- OK e Annulla (vedere la figura 1). La confirm(string)
funzione restituisce un valore booleano a seconda del pulsante selezionato (true
se l'utente fa clic su OK e false
se fa clic su Annulla).
Figura 1: Il metodo JavaScript confirm(string)
visualizza una finestra di messaggio modale Client-Side
Durante l'invio di un modulo, se viene restituito un valore di false
da un gestore eventi sul lato client, l'invio del modulo viene annullato. Usando questa funzionalità, è possibile fare in modo che il gestore eventi lato onclick
client del pulsante Delete restituisca il valore di una chiamata a confirm("Are you sure you want to delete this product?")
. Se l'utente fa clic su Annulla, confirm(string)
restituirà false, causando l'annullamento dell'invio del modulo. Senza postback, il prodotto su cui è stato fatto clic sul pulsante Elimina non verrà eliminato. Se, tuttavia, l'utente fa clic su OK nella finestra di dialogo di conferma, il postback continuerà senza problemi e il prodotto verrà eliminato. Per altre informazioni su questa tecnica, vedere Uso del metodo s confirm()
JavaScript per controllare l'invio di moduli.
L'aggiunta dello script lato client necessario è leggermente diversa se si usano modelli rispetto all'uso di un campo CommandField. Di conseguenza, in questa esercitazione verrà esaminato sia un esempio formView che gridView.
Nota
Usando tecniche di conferma lato client, come quelle descritte in questa esercitazione, si presuppone che gli utenti visitino i browser che supportano JavaScript e che abbiano JavaScript abilitato. Se una di queste ipotesi non è vera per un determinato utente, facendo clic sul pulsante Elimina verrà immediatamente generato un postback (non viene visualizzata una finestra di messaggio di conferma).
Passaggio 1: Creazione di un controllo FormView che supporta l'eliminazione
Per iniziare, aggiungere un controllo FormView alla ConfirmationOnDelete.aspx
pagina nella EditInsertDelete
cartella, associandolo a un nuovo ObjectDataSource che esegue il pull delle informazioni sul prodotto tramite il ProductsBLL
metodo della GetProducts()
classe . Configurare anche ObjectDataSource in modo che il ProductsBLL
metodo della DeleteProduct(productID)
classe sia mappato al metodo ObjectDataSource Delete()
. Assicurarsi che gli elenchi a discesa INSERT e UPDATE siano impostati su (Nessuno). Infine, selezionare la casella di controllo Abilita paging nello smart tag formView.
Dopo questi passaggi, il nuovo markup dichiarativo di ObjectDataSource sarà simile al seguente:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
DeleteMethod="DeleteProduct" OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProducts" TypeName="ProductsBLL">
<DeleteParameters>
<asp:Parameter Name="productID" Type="Int32" />
</DeleteParameters>
</asp:ObjectDataSource>
Come negli esempi precedenti che non usano la concorrenza ottimistica, è necessario un po' di tempo per cancellare la proprietà ObjectDataSource.OldValuesParameterFormatString
Poiché è stato associato a un controllo ObjectDataSource che supporta solo l'eliminazione, FormView offre ItemTemplate
solo il pulsante Elimina, senza i pulsanti Nuovo e Aggiorna. Il markup dichiarativo di FormView, tuttavia, include un elemento superfluo EditItemTemplate
e InsertItemTemplate
, che può essere rimosso. Dedicare qualche minuto a personalizzare in ItemTemplate
modo che venga visualizzato solo un subset dei campi dati del prodotto. Ho configurato il mio per mostrare il nome del prodotto in un'intestazione <h3>
sopra il relativo fornitore e nomi di categoria (insieme al pulsante Elimina).
<asp:FormView ID="FormView1" AllowPaging="True" DataKeyNames="ProductID"
DataSourceID="ObjectDataSource1" runat="server">
<ItemTemplate>
<h3><i><%# Eval("ProductName") %></i></h3>
<b>Category:</b>
<asp:Label ID="CategoryNameLabel" runat="server"
Text='<%# Eval("CategoryName") %>'>
</asp:Label><br />
<b>Supplier:</b>
<asp:Label ID="SupplierNameLabel" runat="server"
Text='<%# Eval("SupplierName") %>'>
</asp:Label><br />
<asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
CommandName="Delete" Text="Delete">
</asp:LinkButton>
</ItemTemplate>
</asp:FormView>
Con queste modifiche, abbiamo una pagina Web completamente funzionale che consente a un utente di passare i prodotti uno alla volta, con la possibilità di eliminare un prodotto semplicemente facendo clic sul pulsante Elimina. La figura 2 mostra uno screenshot dello stato di avanzamento finora visualizzato tramite un browser.
Figura 2: FormView mostra informazioni su un singolo prodotto (fare clic per visualizzare l'immagine a dimensione intera)
Passaggio 2: Chiamata della funzione confirm(string) dall'evento Delete Buttons Client-Side onclick
Dopo aver creato FormView, il passaggio finale consiste nel configurare il pulsante Elimina in modo che quando viene fatto clic dal visitatore, viene richiamata la funzione JavaScript confirm(string)
. L'aggiunta di script sul lato client a un evento sul lato onclick
client Button, LinkButton o ImageButton può essere eseguita tramite l'uso di OnClientClick property
, che è una novità di ASP.NET 2.0. Poiché si vuole avere il valore della confirm(string)
funzione restituita, è sufficiente impostare questa proprietà su: return confirm('Are you certain that you want to delete this product?');
Dopo questa modifica, la sintassi dichiarativa di Delete LinkButton avrà un aspetto simile al seguente:
<asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
CommandName="Delete" Text="Delete"
OnClientClick="return confirm('Are you certain you want to delete this product?');">
</asp:LinkButton>
Questo è tutto lì! La figura 3 mostra una schermata di questa conferma in azione. Facendo clic sul pulsante Elimina viene visualizzata la finestra di dialogo di conferma. Se l'utente fa clic su Annulla, il postback viene annullato e il prodotto non viene eliminato. Se, tuttavia, l'utente fa clic su OK, il postback continua e viene richiamato il metodo ObjectDataSource Delete()
, che culmina nel record del database da eliminare.
Nota
La stringa passata alla confirm(string)
funzione JavaScript è delimitata da apostrofi (anziché tra virgolette). In JavaScript le stringhe possono essere delimitate usando entrambi i caratteri. In questo caso vengono usati apostrofi in modo che i delimitatori per la stringa passata in confirm(string)
non introducano un'ambiguità con i delimitatori usati per il valore della OnClientClick
proprietà.
Figura 3: Viene visualizzata una conferma quando si fa clic sul pulsante Elimina (fare clic per visualizzare l'immagine a dimensione intera)
Passaggio 3: Configurazione della proprietà OnClientClick per il pulsante Elimina in un campo di comando
Quando si usa un controllo Button, LinkButton o ImageButton direttamente in un modello, è possibile associarvi una finestra di dialogo di conferma semplicemente configurando la relativa OnClientClick
proprietà per restituire i risultati della funzione JavaScript confirm(string)
. Tuttavia, commandField, che aggiunge un campo di pulsanti Elimina a un controllo GridView o DetailsView, non dispone di una OnClientClick
proprietà che può essere impostata in modo dichiarativo. È invece necessario fare riferimento al pulsante Elimina a livello di codice nel gestore eventi appropriato DataBound
di GridView o DetailsView e quindi impostarne la OnClientClick
proprietà.
Nota
Quando si imposta la proprietà del pulsante OnClientClick
Elimina nel gestore eventi appropriato DataBound
, è possibile accedere ai dati associati al record corrente. Ciò significa che è possibile estendere il messaggio di conferma per includere i dettagli relativi al record specifico, ad esempio "Eliminare il prodotto Chai?" Tale personalizzazione è anche possibile nei modelli usando la sintassi databinding.
Per esercitarsi a impostare la OnClientClick
proprietà per i pulsanti Elimina in un campo di comando, aggiungere un controllo GridView alla pagina. Configurare questo controllo GridView per l'uso dello stesso controllo ObjectDataSource usato da FormView. Limitare anche i campi BoundField di GridView in modo da includere solo il nome, la categoria e il fornitore del prodotto. Infine, selezionare la casella di controllo Abilita eliminazione dallo smart tag gridView. Verrà aggiunto un oggetto CommandField all'insieme gridView Columns
con la relativa ShowDeleteButton
proprietà impostata su true
.
Dopo aver apportato queste modifiche, il markup dichiarativo di GridView sarà simile al seguente:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:CommandField ShowDeleteButton="True" />
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category" ReadOnly="True"
SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName" HeaderText="Supplier" ReadOnly="True"
SortExpression="SupplierName" />
</Columns>
</asp:GridView>
CommandField contiene una singola istanza di Delete LinkButton a cui è possibile accedere a livello di codice dal gestore eventi di RowDataBound
GridView. Una volta fatto riferimento, è possibile impostarne la OnClientClick
proprietà di conseguenza. Creare un gestore eventi per l'evento RowDataBound
usando il codice seguente:
Protected Sub GridView1_RowDataBound(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) _
Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
' reference the Delete LinkButton
Dim db As LinkButton = CType(e.Row.Cells(0).Controls(0), LinkButton)
' Get information about the product bound to the row
Dim product As Northwind.ProductsRow = _
CType(CType(e.Row.DataItem, System.Data.DataRowView).Row, _
Northwind.ProductsRow)
db.OnClientClick = String.Format( _
"return confirm('Are you certain you want to delete the {0} product?');", _
product.ProductName.Replace("'", "\'"))
End If
End Sub
Questo gestore eventi funziona con le righe di dati (quelle che avranno il pulsante Elimina) e inizia facendo riferimento a livello di codice al pulsante Elimina. In generale, usare il modello seguente:
Dim obj As ButtonType = _
CType(e.Row.Cells(commandFieldIndex).Controls(controlIndex), ButtonType)
ButtonType è il tipo di pulsante utilizzato da CommandField - Button, LinkButton o ImageButton. Per impostazione predefinita, CommandField usa LinkButtons, ma può essere personalizzato tramite commandField s ButtonType property
. CommandFieldIndex è l'indice ordinale dell'oggetto CommandField all'interno dell'insieme gridViewColumns
, mentre controlIndex è l'indice del pulsante Delete all'interno dell'insieme CommandField.Controls
Il valore controlIndex dipende dalla posizione del pulsante rispetto ad altri pulsanti in CommandField. Ad esempio, se l'unico pulsante visualizzato in CommandField è il pulsante Elimina, usare un indice pari a 0. Se, tuttavia, è presente un pulsante Modifica che precede il pulsante Elimina, usare un indice pari a 2. Il motivo per cui viene usato un indice di 2 è dovuto al fatto che due controlli vengono aggiunti da CommandField prima del pulsante Elimina: il pulsante Modifica e un oggetto LiteralControl utilizzato per aggiungere spazio tra i pulsanti Modifica ed Elimina.
Per questo particolare esempio, CommandField usa LinkButtons e, essendo il campo più a sinistra, ha un commandFieldIndex pari a 0. Poiché non sono presenti altri pulsanti, ma il pulsante Elimina in CommandField, viene usato un controlIndex pari a 0.
Dopo aver fatto riferimento al pulsante Elimina in CommandField, verranno ora recuperate informazioni sul prodotto associato alla riga GridView corrente. Infine, impostiamo la proprietà del pulsante OnClientClick
Elimina sul codice JavaScript appropriato, che include il nome del prodotto. Poiché la stringa JavaScript passata alla confirm(string)
funzione è delimitata usando apostrofi, è necessario eseguire l'escape di eventuali apostrofi che vengono visualizzati all'interno del nome del prodotto. In particolare, qualsiasi apostrofo nel nome del prodotto viene preceduto da "\'
".
Al termine di queste modifiche, facendo clic su un pulsante Elimina in GridView viene visualizzata una finestra di dialogo di conferma personalizzata (vedere la figura 4). Come per la finestra di messaggio di conferma da FormView, se l'utente fa clic su Annulla il postback viene annullato, impedendo così l'eliminazione.
Nota
Questa tecnica può essere usata anche per accedere a livello di codice al pulsante Elimina in CommandField in un controllo DetailsView. Per DetailsView, tuttavia, si crea un gestore eventi per l'evento DataBound
, poiché DetailsView non ha un RowDataBound
evento.
Figura 4: Facendo clic sul pulsante Elimina di GridView viene visualizzata una finestra di dialogo di conferma personalizzata (fare clic per visualizzare l'immagine a dimensione intera)
Uso di TemplateFields
Uno degli svantaggi del CommandField è che i pulsanti devono essere accessibili tramite l'indicizzazione e che l'oggetto risultante deve essere eseguito il cast al tipo di pulsante appropriato (Button, LinkButton o ImageButton). L'uso di "numeri magici" e tipi hardcoded invita i problemi che non possono essere individuati fino al runtime. Ad esempio, se si o un altro sviluppatore, aggiunge nuovi pulsanti al CommandField in un certo momento (ad esempio un pulsante Modifica) o modifica la ButtonType
proprietà, il codice esistente verrà comunque compilato senza errori, ma la visita alla pagina può causare un'eccezione o un comportamento imprevisto, a seconda del modo in cui il codice è stato scritto e quali modifiche sono state apportate.
Un approccio alternativo consiste nel convertire GridView e DetailsView s CommandFields in TemplateFields. In questo modo verrà generato un ModelloField con un ItemTemplate
oggetto che ha un LinkButton (o Button o ImageButton) per ogni pulsante nel CommandField. Queste proprietà dei pulsanti OnClientClick
possono essere assegnate in modo dichiarativo, come illustrato con FormView o possono essere accessibili a livello di codice nel gestore eventi appropriato DataBound
usando il modello seguente:
Dim obj As ButtonType = CType(e.Row.FindControl("controlID"), ButtonType)
Dove controlID è il valore della proprietà del ID
pulsante. Anche se questo modello richiede ancora un tipo hardcoded per il cast, rimuove la necessità di indicizzazione, consentendo al layout di modificare senza generare un errore di runtime.
Riepilogo
La funzione JavaScript confirm(string)
è una tecnica comunemente usata per controllare il flusso di lavoro di invio dei moduli. Quando viene eseguita, la funzione visualizza una finestra di dialogo modale sul lato client che include due pulsanti, OK e Annulla. Se l'utente fa clic su OK, la confirm(string)
funzione restituisce true
. Fare clic su Annulla restituisce false
. Questa funzionalità, associata al comportamento di un browser per annullare un invio di modulo se un gestore eventi durante il processo di invio restituisce false
, può essere usato per visualizzare una casella di messaggio di conferma durante l'eliminazione di un record.
La confirm(string)
funzione può essere associata a un gestore eventi lato onclick
client del controllo Web Button tramite la proprietà del controllo.OnClientClick
Quando si usa un pulsante Elimina in un modello, ovvero in uno dei modelli di FormView o in un ModelloField in DetailsView o GridView, questa proprietà può essere impostata in modo dichiarativo o a livello di codice, come illustrato in questa esercitazione.
Programmazione felice!
Informazioni sull'autore
Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato con le tecnologie Microsoft Web dal 1998. Scott lavora come consulente indipendente, allenatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2,0 in 24 Ore. Può essere raggiunto a mitchell@4GuysFromRolla.com. o tramite il suo blog, che può essere trovato in http://ScottOnWriting.NET.
Commenti e suggerimenti
https://aka.ms/ContentUserFeedback.
Presto disponibile: Nel corso del 2024 verranno gradualmente disattivati i problemi di GitHub come meccanismo di feedback per il contenuto e ciò verrà sostituito con un nuovo sistema di feedback. Per altre informazioni, vedereInvia e visualizza il feedback per