I have found the following useful for creating a useable 'Delete' hyperlink in a DTC grid. It has the following features:
- a client-side confirmation to ensure the delete is wanted
- a server-side delete method
- a method to format the hyperlink
I have tried to make it a generic as possible, and yet it still needs to be adjusted for each grid that you build.
*** 1 - the Server-Side Delete method ***
Create a suitable function that will delete a record from your table/recordset. In this case it uses the internal recordset row number (absolute position), though a primary/unique column would be much better - and an SQL delete rather than a recordset delete would be better still. An SQL Delete is needed for some multi-table recordsets - as otherwise it (ODBC) may try to delete a row from all tables in the join. (An SQL delete is 'Delete from My_Table Where ...' - and you would need to make a connection, string together the SQL and execute it. A recordset delete, shown below, dynamically generates a delete clause - which is often good enough but you have no real control over it.)
function doDelete(i_iItemKey)
'
' Perform the delete
' The underlying table MUST have a Primary (unique) key.
'
on error resume next
rsTable.moveAbsolute cint(i_iItemKey)
rsTable.deleteRecord
if Err.number <> 0 then
Response.Write "Cannot delete this record: " & Err.Description
else
rsTable.requery
end if
end function
Add this function as a 'navigate' method of a PageObject DTC. If you do not have a PageObjectDTC, then add one now! Then pop-up the PageObject properties and pick this delete function name.
This allows the client-side code to 'call' the delete function. You can do this in other ways, but this is probably the easiest. The 'navigate' functions cause a server round-trip - so the grid will be re-built after the delete.
The recordset/grid will be positioned on the first row after the delete - unless you put additional code in after the 'Requery' - ie to make the new 'current' row the one before the deleted row.
Out of interest, the 'execute' PageObject methods do not do a server round-trip (and they use a Java applet to work). Therefore the grid would not be refreshed - but otherwise it would work.
*** 2 - Client-Side Confirmation ***
We need a dialog box to pop-up to confirm the Delete action. Being client-side, it needs to be written in JavaScript. This version simply displays a standard Yes/No confirm box, and if 'Yes' then call the server-side delete function that was coded above - that was easy! VI even pops-up the required parameter list for your function.
The important part about this function is to define sensible parameters
- the 'key' to the record being deleted (to be passed to the server-side delete method)
- some text that describes the row being deleted (to be part of the confirmation message)
In the sample below, I have included this delete-confirm function before a 'beforeserverevent' event handler - as it belongs in the same code block. If you do not understand what the beforeserverevent is for then try seaching the help or this forum.
<script ID="clientEventHandlersJS" LANGUAGE="javascript">
<!--
function doDelete_confirm(i_iEntryKey, i_sConfirmText) {
if (confirm ("Are you sure that you want to delete this entry (" + unescape(i_sConfirmText) + ")") == true) {
thisPage.navigate.doDelete (i_iEntryKey);
}
}
function thisPage_onbeforeserverevent(i_sObject, i_sEvent) {
if (i_sObject == "pbAdd" && i_sEvent == "onclick") {
//validate form...
if (document.thisForm.txtCode.value == ' ) {
...etc...
*** 3 - Adding the Hyperlink to the Grid ***
Now we need to add a hyperlink to the grid that fires off these delete functions. We could type a complete html '<a href=...' tag straight into a grid cell - however, this can cause problems - particularly as the number of single-and-double quotes gives both you and the gridDTC a hard time.
I prefer to add a simple function call to the gridDTC cell, passing the required recordset values. This function returns a string that is then displayed in the table cell.
The html generating function shown here is written in JScript (Server-Side), simply because:
- The grid code is in JScript, so it is slightly faster (no language switching needed)
- The syntax for gluing strings together is much better in JScript than in VB (but you can decide on that)
<script LANGUAGE="javascript" RUNAT="SERVER">
function gridGenerateDeleteLink(i_iItemKey, i_sHTMLToShow, i_sConfirmText) {
// place a link in the grid
// that will cause the entry to be deleted
// this happens in two stages...
// 1. Client side javascript will query if the delete is correct
// 2. Server side will do the delete and refresh this page.
return ('<a href="DeleteEntry" onclick="' +
"doDelete_confirm('" +
i_iItemKey + "', '" + escape(i_sConfirmText ) +
"');return false;\">" + i_sHTMLToShow + "</a>");
}
</script>
All this function does is to generate the following html as a string:
<a href=DeleteEntry onclick="doDelete_confirm('Key', 'Confirm Text');return false;">Delete</a>
with the marked parts being replaced by the parameters that you provide from the grid.
And to call this function, simply add the following to a gridDTC cell
=gridGenerateDeleteLink(this._objDataSource.absolutePosition, "Delete", [COL_Description])
The [COL_Description] is a column from the recordset - change it as required!
The this._objDataSource.absolutePosition is the sequence number for this row in the recordset. DO NOT use this if many different users will be adding or deleting rows - as this assumes that the recordset is identical on each server round-trip. You should really pass the primary key column value, but then the server side code gets more complex (see part 1 above).
And thats it!
If you feel brave, then you can adjust the DATAGRID.ASP to provide a simplified (and VBScript useable) version of the this._objDataSource.absolutePosition value. PS. VBscript does not like the underscore character in "_objDataSource".
1. in function _DG__Prototype() add near the top, with the other 'public methods'
_DataGrid.prototype.rowNumber = _DG_rowNumber; //get the absolute position
2. add the corresponding function a bit further down:
function _DG_rowNumber()
{
// Return the recordset row-numbering row number.
return (this._objDataSource.absolutePosition);
}
Now in the gridDTC cell, you can just type:
=gridGenerateDeleteLink(this.rowNumber(), "Delete", [COL_Description])