PRB: Accessing Data Changes in the OnCellChange Event Procedure (283182)



The information in this article applies to:

  • Microsoft XML 2.0
  • Microsoft XML 2.5
  • Microsoft XML 2.6
  • Microsoft XML 3.0

This article was previously published under Q283182

SYMPTOMS

The oncellchange() event of the XML Data Source Object (DSO) is fired when the value of one of its bound XML data elements is modified. You can access the name of the field that was modified and its original data value before the change by writing code in the DSO's oncellchange event procedure. You can do this by accessing the datafld property of the Window.Event object. However, it is not possible to access the modified field's new data value in the oncellchange event procedure. When it is accessed in this event procedure, the Value property of the datafld object returns the old value of the modified data field.

CAUSE

This behavior is by design. The new data value of a modified field is not accessible in the oncellchange event of an XML DSO.

RESOLUTION

Write code in the onbeforeupdate and onafterupdate event procedures of the HTML elements that are bound to an XML DSO to identify and compare data values before and after the modification.

MORE INFORMATION

Steps to Reproduce Behavior

  1. Open a new empty text file in Microsoft Notepad and save it as oncellchange.htm on your hard drive.
  2. Copy and paste the following code into oncellchange.htm, and then save the changes:
    <SCRIPT LANGUAGE=VBScript>
    
    Option Explicit
    
    Function DataChanged()
      Dim EmpDSOXML
      Dim ModifiedField
    
      EmpDSOXML = "XML : " & vbcrlf & EmpDSO.xml
      MsgBox EmpDSOXML
     
      Set ModifiedField = window.event.recordset(window.event.datafld)
      MsgBox ModifiedField.Name &  " : " & ModifiedField.value
    End Function
    
    </SCRIPT>
    
    <html >
    
    <title>Employee Information</title>
    
    
    <BODY>
    
    <xml id=EmpDSO onCellChange="DataChanged()">
    <Employees>
      <Employee><EmpID>E001</EmpID><EmpName>Jack</EmpName></Employee>
    </Employees>
    </xml>
    
    <INPUT datasrc=#EmpDSO datafld="EmpID" Id="EmpID" Name="EmpId"> <BR>
    <INPUT datasrc=#EmpDSO datafld="EmpName" Id="EmpName" Name="EmpName">
    
    </BODY>
    
    </html>
    					
  3. Open oncellchange.htm in Internet Explorer, and note that the values in the EmpID and EmpName fields from the single record in the XML DSO are displayed in the HTML Textbox elements that are bound to it.
  4. Change the value that is displayed in the HTML Textbox element that is bound to the EmpName field, and then tab out of the textbox. This action causes the oncellchange event of the XML DSO to fire and trigger the execution of the DataChanged() VBScript function. The code in the DataChanged function displays the DSO's XML, followed by the name and value of the datafield that was modified. Note that the XML and the modified field's value reflect the original data that was stored in the EmpName element before you modified the value in the HTML Textbox.
  5. Shut down Internet Explorer.
  6. Open a new empty text file in Notepad, and then save it as BeforeAfterUpdate.htm on your hard drive.
  7. Copy and paste the following code in BeforeAfterUpdate.htm, and then save the changes:
    <SCRIPT LANGUAGE=vbscript>
    Option Explicit
    
    Function BefUpdate()
      
      Dim XMLBefUpdate
      Dim oXMLNode 
      Dim oldValue
      Dim newValue
      Dim output
    
      XMLBefUpdate = "XML Before Update : " &  vbcrlf & EmpDSO.xml
      MsgBox XMLBefUpdate
    
      oldValue = EmpDSO.Recordset.Fields(window.event.srcElement.Name)
      newValue = window.event.srcElement.Value
    
      output = "Modified HTML element : " & window.event.srcElement.Name & vbcrlf
      output = output & "Old Value : " & oldValue & vbcrlf
      output = output & "New Value : " & newValue
    
      MsgBox output
    
    End Function
    
    Function AftUpdate()
      MsgBox "XML after update : " & vbcrlf & EmpDSO.xml
    End Function
    
    </SCRIPT>
    
    <html>
    
    <title>Employee Information</title>
    
    <BODY>
    
    <xml id=EmpDSO>
    <Employees>
      <Employee><EmpID>E001</EmpID><EmpName>Jack</EmpName></Employee>
    </Employees>
    </xml>
    
    <INPUT datasrc=#EmpDSO datafld="EmpID" Id="EmpID" Name="EmpId" onbeforeupdate="BefUpdate" onafterupdate="AftUpdate"> <BR>
    <INPUT datasrc=#EmpDSO datafld="EmpName" Id="EmpName" Name="EmpName" onbeforeupdate="BefUpdate" onafterupdate="AftUpdate">
    
    </BODY>
    
    </html>
    					
  8. Open BeforeAfterUpdate.htm in Internet Explorer, and note that the values in the EmpID and EmpName fields from the single record in the XML DSO are displayed in the bound HTML Textbox elements.
  9. Change the value that are displayed in the HTML Textbox element that are bound to the EmpName field, and then tab out of the textbox. This action causes the BefUpdate and AftUpdate VbScript functions to fire in sequence for the EmpName HTML Textbox element.
  10. The code in the BefUpdate VbScript function first displays the DSO's XML with data that existed before you made the change to the EmpName field. It then displays the name of the data field that was modified (EmpName, in this instance) along with its data before and after the value change. The code uses the DSO's Recordset object to access the field's pre-update value. It then accesses the Value property of the HTML element that raised the onbeforeupdate event (the HTML Textbox element bound to the DSO's EmpName field) to obtain the new value that was entered into the Textbox element. Accessing the new value by using the HTML element that raised the event requires the bound HTML element to be assigned a Name that is identical to the name of the field in the XML DSO. Accessing both the old and new values of a data field before the update is posted makes it possible to implement custom routines to validate the new data and to roll back to the old data if required. For instance, use the BefUpdate VbScript function in the preceding sample to reset the EmpName field back to its original value when the new value is identified to be a blank string, as shown in the following code:
    Function BefUpdate()
      
      Dim oXMLNode 
      Dim oldValue
      Dim newValue
      Dim output
    
      oldValue = EmpDSO.Recordset.Fields(window.event.srcElement.Name)
      newValue = window.event.srcElement.Value
    
      if newvalue = "" then 
         Msgbox "EmpName cannot be blank"
         window.event.srcElement.Value = oldvalue
      End if
    
    End Function
    					
  11. The onafterupdate event that is fired after onbeforeupdate triggers the AftUpdate() VBScript function, which displays the DSO's XML with the modified data.

Modification Type:MajorLast Reviewed:10/12/2001
Keywords:kbDHTML kbDSupport kbMSXMLnosweep kbprb KB283182