Link to home
Start Free TrialLog in
Avatar of jsvb1977
jsvb1977

asked on

How to check if values have changed using data grid in .net 2.0

Basically, I am using a data grid to display data from a sql table via a web interface. I have given the viewer of this data the ability to edit and update via an update query. when the user updates the data, i write a 1 in a column in the table called "Modified." This is needed, because i have a stored procedure which runs nightly that identifies rows of data containing the number 1 as updated and then emails our IT department so that we can act on the changes.

Here in lies the problem:

If the end user selects a row of data to edit, and then changes her mind and does not update, but still clicks on the "update" button, my code will still write a 1 in the "Modified" column. Similarly, if the end user selects a row of data, then types in the exact same value that already exists and presses the "update" button, my code will again write a 1 in the "modified" column.

I think the best thing to do would be to only "activate" the "update" button if the end user begins typing in the editable fields. Even more so, upon update, the code should be intelligent enough to only insert the number 1 in the Modified column if the data has changed.

I need help modifying my code so that this intelligence exists. Of course, if there are other methods of how to accomplish what i desire I am willing to try them out. My code is listed below.


<asp:SqlDataSource ID="AssociateIndexDataSource" runat="server" 
        ConnectionString="<%$ ConnectionStrings:AssociateIndexTestConnectionString %>" 
        SelectCommand="SELECT * FROM [FSPI_AssociateIndex] ORDER BY [Status] ASC, [AssociateID] ASC"
        InsertCommand="INSERT INTO [FSPI_AssociateIndex] ([AssociateID], [Name], [SSN], [Code], [Status], [Modified]) VALUES (@AssociateID, @Name, @SSN, @Code, @Status, @Modified)"  
        UpdateCommand="UPDATE [FSPI_AssociateIndex] SET [Name] = @Name, [Code] = @Code, [Status] = @Status, [Modified] = @Modified
        WHERE [AssociateID] = @AssociateID">
        <%--WHERE [AssociateID] = @AssociateID--%>
        <%--DECLARE @AssociateID int--%>
        <%-- InsertCommand="INSERT INTO FSPI_AssociateIndex(AssociateID, Name, SSN, Code, Status) VALUES (,,,,)" --%>
    <UpdateParameters>
        <asp:Parameter Name="AssociateID" Type="Int32" />
        <asp:Parameter Name="Name" Type="String" />
        <asp:Parameter Name="SSN" Type="String" Size="9" />
        <asp:Parameter Name="Code" Type="String" Size="6" />
        <asp:Parameter Name="Status" Type="String" Size="1" />
        <asp:Parameter Name="Modified" Type="Int32" Size="1" DefaultValue="1" />
    </UpdateParameters>
    <InsertParameters>
        <asp:Parameter Name="AssociateID" Type="Int32" />
        <asp:Parameter Name="Name" Type="String" />
        <asp:Parameter Name="SSN" Type="String" />
        <asp:Parameter Name="Code" Type="String" />
        <asp:Parameter Name="Status" Type="String" />
        <asp:Parameter Name="Modified" Type="Int32" />
    </InsertParameters>

       </asp:SqlDataSource>
    
    <asp:TextBox ID="tbRequesterName" runat="server" Visible="false"></asp:TextBox>
    
      <div id="content">
      
    <div id="insert">
    
        <asp:FormView ID="FormView1" runat="server" 
            DataSourceID="AssociateIndexDataSource">
           
            <InsertItemTemplate>
            
            <table>
            <tr>
            <td>AssociateID:</td>
            <td>Name:</td>
            <td>SSN:</td>
            <td>Department:</td>
            <td>&nbsp;<!--Status:--></td>
            <td>&nbsp;<!--Modified:--></td>
            <td>&nbsp;</td>
            </tr>
            <tr>
            <td><asp:TextBox ID="AssociateIDTextBox" runat="server" Text='<%# Bind("AssociateID") %>' Width="80" MaxLength="6" /></td>
            <td><asp:TextBox ID="NameTextBox" runat="server" Text='<%# Bind("Name") %>' Width="300" /></td>
            <td><asp:TextBox ID="SSNTextBox" runat="server" Text='<%# Bind("SSN") %>' Width="90" MaxLength="9" /></td>
            <td><asp:TextBox ID="CodeTextBox" runat="server" Text='<%# Bind("Code") %>' Width="50" MaxLength="5" /></td>
            <td><asp:TextBox ID="StatusTextBox" runat="server" Text='<%# Bind("Status") %>' Width="10" MaxLength="1" Visible="false" >A</asp:TextBox></td>
            <td><asp:TextBox ID="ModifiedtextBox" runat="server" Text='<%# Bind("Modified") %>' Width="1" MaxLength="1" Visible="false" >2</asp:TextBox></td>
            <td><asp:LinkButton ID="InsertButton" runat="server" CausesValidation="True" CommandName="Insert" ><img src="images/Next.png" border="0" alt="Insert" /></asp:LinkButton>
            <asp:LinkButton ID="InsertCancelButton" runat="server" CausesValidation="False" CommandName="Cancel" ><img src="images/Cancel.png" border="0" alt="Cancel" /></asp:LinkButton></td>
            </tr>
            </table>
            </InsertItemTemplate>
            <ItemTemplate>
                <asp:LinkButton ID="NewButton" runat="server" CausesValidation="False" CommandName="New" ><img class="addnewassociateimg" src="images/AddAssociate.png" border="0" alt="Add" /></asp:LinkButton>
            </ItemTemplate>
        </asp:FormView>
        <br />
    </div>
      
      
             <asp:GridView ID="GridView2" runat="server" AllowSorting="True" CssClass="aitable" DataKeyNames="AssociateID"
           AutoGenerateColumns="False" CellPadding="4" 
           DataSourceID="AssociateIndexDataSource" ForeColor="#333333" GridLines="None">
           <RowStyle BackColor="#f6f6f6" ForeColor="#333333" />
           <Columns>
               <%--<asp:CommandField ShowDeleteButton="True" ButtonType="Image" DeleteImageUrl="images/Delete.png" />--%>
               <asp:CommandField ShowEditButton="True" ButtonType="Image" EditImageUrl="images/Edit.png" UpdateImageUrl="images/Next.png" CancelImageUrl="images/Cancel.png" />
               <asp:TemplateField HeaderText="AssociateID" SortExpression="AssociateID">
                   <EditItemTemplate>
                       <asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("AssociateID") %>' Width="60" MaxLength="6"></asp:TextBox>
                   </EditItemTemplate>
                   <ItemTemplate>
                       <asp:Label ID="Label3" runat="server" Text='<%# Bind("AssociateID") %>'></asp:Label>
                   </ItemTemplate>
               </asp:TemplateField>
               <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" >
                   <ControlStyle Width="300px" />
               </asp:BoundField>
<%--               <asp:BoundField DataField="SSN" HeaderText="SSN" ReadOnly="false" 
                   SortExpression="SSN" DataFormatString="*********"  >
               
                   <ControlStyle Width="90px" />
               </asp:BoundField>--%>
               <asp:TemplateField HeaderText="SSN" SortExpression="SSN">
                   <EditItemTemplate>
                       <asp:TextBox ID="TextBox4" runat="server" Text='<%# Bind("SSN") %>' Width="90" MaxLength="9"></asp:TextBox>
                   </EditItemTemplate>
                   <ItemTemplate>
                   <asp:Label id="SSNLabel" runat="server" Text='<%# "***-**-" + Eval("SSN").ToString().SubString(5) %>'></asp:Label>
                    
                   </ItemTemplate>
                   <ControlStyle Width="90px" />
               </asp:TemplateField>
               
               <asp:TemplateField HeaderText="Department" SortExpression="Code">
                   <EditItemTemplate>
                       <asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("Code") %>' Width="50" MaxLength="5"></asp:TextBox>
                   </EditItemTemplate>
                   <ItemTemplate>
                       <asp:Label ID="Label2" runat="server" Text='<%# Bind("Code") %>'></asp:Label>
                   </ItemTemplate>
               </asp:TemplateField>
               <asp:TemplateField HeaderText="Status" SortExpression="Status">
                   <EditItemTemplate>
                       <asp:DropDownList ID="DropDownList1" runat="server" Text='<%# Bind("Status") %>' Width="40" MaxLength="1">
                       <asp:ListItem>A</asp:ListItem>
                       <asp:ListItem>T</asp:ListItem>
                       </asp:DropDownList>
                       <%--<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("Status") %>' Width="10" MaxLength="1"></asp:TextBox>--%>
                   </EditItemTemplate> 
                   <ItemTemplate>
                       <asp:Label ID="Label1" runat="server" Text='<%# Bind("Status") %>'></asp:Label>
                       <%--<asp:TextBox ID="UpdateModified" runat="server" Text='<%# Bind("Modified") %>' Visible="false" Width="1" MaxLength="1">1</asp:TextBox>--%>
                   </ItemTemplate>
               </asp:TemplateField>
           </Columns>
           <FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
           <PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
           <SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
           <HeaderStyle BackColor="#006600" Font-Bold="True" ForeColor="White" />
           <AlternatingRowStyle BackColor="White" />
       </asp:GridView>
       </div>
    </form>

Open in new window

Avatar of silemone
silemone
Flag of United States of America image

When you first load the page, you would:  go through the grid, and add them to a ViewState i guess using row num as the ID, and value as the value
pseudocode
i.e. ViewState(grid.rowNum) = "false";

if you update a row and fully commit the update to the grid, you would look it up by grid.rowNum and change it to true...

check if any of the values in the ViewState == true...if so mark it 1 for modified

When you first load the page, you would:  go through the grid, and add them to a ViewState i guess using row num as the ID, and value as the value
pseudocode
i.e. ViewState(grid.rowNum) = "false";

if you update a row and fully commit the update to the grid, you would look it up by grid.rowNum and change it to true...
ViewState(grid.rowNum) = "true";

check if any of the values in the ViewState == true...if so mark it 1 for modified
or similarly, you could on pageload

ViewState(grid.rowNum = gridRowValue....

so upon updating grid,

see if the current value == ViewState value of that row  if not, mark as modified...update Viewstate to = the new value --
Corrected --

or similarly, you could on pageload

ViewState(grid.rowNum = gridRowValue....

so upon updating grid,

see if the current value == ViewState value (the original value at pageload) of that row -- if not, mark as modified...then update Viewstate to = the new value so that the value is up to date  --
      
Avatar of jsvb1977
jsvb1977

ASKER

silemone,

your logic is sound. i know not how to implement the logic, though. I see that you have given me a line of code as an example, but i am hoping you could help me with the actual code as well. I have been plugging away at this here and there -- but i am by no means an expert in asp.net / sql.

Can you help me create this logic in my code based on what i have completed so far?
Currently, I do not have a row ID in this table. Will this be required?
Are you willing to help me through this bit by bit?

Let me know if there is anything I can do to help you help me. I posted the entire asp code above, but i am happy to chunk out specific pieces so you dont have to weed through everything on your own.

Jason
there is a itemdatabound example...
protected void itemDataBound(object sender,DataGridItemEventArgs e)        
{                  
	if  (e.Item.ItemType!=ListItemType.Header && e.Item.ItemType!=ListItemType.Footer)                 
	{
	          e.Item.Add("ID", [name]);    //<--[name] can be example: "ID" + e.Item.Cells[1].Text

                                               // if that cell is unique like ID passed back from db
                  ViewState.Add([name], (e.Item.Cells[1].Text));

        }
 
}

Open in new window

Corrected:  

I don't see your code.

there is a itemdatabound example...



protected void itemDataBound(object sender, DataGridItemEventArgs e)        
{                  
	if  (e.Item.ItemType!=ListItemType.Header && e.Item.ItemType!=ListItemType.Footer)                 
	{
	          e.Item.Attributes.Add("ID", [name]);    //<--[name] can be example: "ID" + e.Item.Cells[1].Text

// if that cell is unique like ID passed back from db
                  ViewState.Add([name], (e.Item.Cells[1].Text));

        }
 
}

Open in new window

remember in the example:

1) [name] is not the real parameter...you will create this with a combination of "ID" + a unique cell...the cells are all the row fields...look over them and find one thats unique...usually ID cell from db...if not, you will have to randomly add some text, numbers...this will be ok because you don't have to know the exact ID, you just have to make sure your Viewstate also has that same name...

2)  ViewState.Add([name], (e.Item.Cells[1].Text)) <-- e.item.Cells[1].Text...the number should reflect the cell that has the data that will be updated so.  remember first cell would be 0, 2nd cell would be 1,..., row n = n-1...
looking at your code, i see you're statically creating each row in your Grid...and this is a gridview...same things apply, but since the data isn't being binded, you can't use itemDataBound event...
silemone:

Well, maybe a better approach would be to try to dynamically display the "update Button" based on if the end user changes the data.

I dont know if this is a simpler way, but i will be honest and say the following:

1. I have little confidence that I will be able to integrate what you have proposed. I'm sorry, I just dont understand how to implement it. I understand what you are saying, but i dont have the skills to code it.
2. I am using VB not C# [The online converter I normally use will not convert your example]

It may take me a little while to try and implement your solution.

Jason
unfortunately, gridviews/datagrids, etc. will require some work for what you want...I guess there is one last approach...you could add editable row twice to the row...i.e.

cellID   cellEditableRow cellBlah1 cellBlah2 ....      cellRepeated  <--- a row in a grid...

in this, CellRepeated can hold the same value as cellEditableRow.

Then to see if row really has been changed, you compare the two cells...

cellRepeated should probably be hidden
it should be updated to = same value as cellEditableRow when row is found modified
unfortunately, gridviews/datagrids, etc. will require some work for what you want...I guess there is one last approach...you could add editable cell twice to the row...i.e.

cellID   cellEditableRow cellBlah1 cellBlah2 ....      cellRepeated  <--- a row in a grid...

in this, CellRepeated can hold the same value as cellEditableRow.

Then to see if row really has been changed, you compare the two cells...

cellRepeated should probably be hidden
it should be updated to = same value as cellEditableRow when row is found modified
OK, well i am willing to take a stab at it -- i just need more help and a little time.

As for your post: 12/17/09 03:06 PM, ID: 26074999
You said, "but since the data isn't being binded, you can't use itemDataBound event."

Does this mean that the example you provided does not apply to me as a viable solution? If not, is there anything else I can do to achieve my goal?

Jason
Avatar of codingbeaver
There is a simple way to do it.
I assume you use EditTemplate for those fields that need to be updated. If not, then convert those BoundField to TemplateField, then follow the steps below:
1. For each TextBox control in the EditTemplate field, add this line to the TextBox definition:
onchnage="markDirty()"
markDirty is a JavaScript function, and I will talk about it later.
2. Add a HiddenField control on your page, say call it "hdnFlag"
3. Add a JavaScript function called "markDirty" as the attached code:
4. Then in your code behind where handles "Update", you can check if the value of the HiddenField is changed to "Yes", if so, it means user modified at least one of the TextBox fields. If not, user didn't madify anything. Then you can go from there.
function markDirty()
{
    var hdn = document.getElementById('<%=hdnFlag.ClientID%>');
    hdn.value = "Yes";
}

Open in new window

codingbeaver:

nice. I will try it. since this app will be used on our intranet i am totally ok with using javascript without worry that it would be disabled in the end users browser.

I will post my results in the morrow. Thanks!

Jason
codingbeaver,

I think i have made it to step 4 as you describe above. Code snippets of the changes I have made a listed below.

I am stuck on step 4. There is no code behind for update. All updates are being handled through an update query which is part of a datagrid.

I need assistance with step 4.
               <asp:TemplateField HeaderText="Department" SortExpression="Code">
                   <EditItemTemplate>
                       <asp:TextBox OnChange="markDirty()" ID="TextBox2" runat="server" Text='<%# Bind("Code") %>' Width="50" MaxLength="5"></asp:TextBox>
                   </EditItemTemplate>
                   <ItemTemplate>
                       <asp:Label ID="Label2" runat="server" Text='<%# Bind("Code") %>'></asp:Label>
                   </ItemTemplate>
               </asp:TemplateField>


================================================================

<asp:HiddenField ID="hdnFlag" runat="server" />
 <script type="text/javascript">
 function markDirty()
{
    var hdn = document.getElementById('<%=hdnFlag.ClientID%>');
    hdn.value = "Yes";
}
 </script>

Open in new window

Here is some additional code. The first part is the sql data source and update parameters. The second part is the only code behind code that references the data grid i am using on the asp page.

 
<asp:SqlDataSource ID="AssociateIndexDataSource" runat="server" 
        ConnectionString="<%$ ConnectionStrings:AssociateIndexTestConnectionString %>" 
        SelectCommand="SELECT * FROM [FSPI_AssociateIndex] ORDER BY [Status] ASC, [AssociateID] ASC"
        InsertCommand="INSERT INTO [FSPI_AssociateIndex] ([AssociateID], [Name], [SSN], [Code], [Status], [Modified]) VALUES (@AssociateID, @Name, @SSN, @Code, @Status, @Modified)"  
        UpdateCommand="UPDATE [FSPI_AssociateIndex] SET [Name] = @Name, [Code] = @Code, [Status] = @Status, [Modified] = @Modified
        WHERE [AssociateID] = @AssociateID">
    <UpdateParameters>
        <asp:Parameter Name="AssociateID" Type="Int32" />
        <asp:Parameter Name="Name" Type="String" />
        <asp:Parameter Name="SSN" Type="String" Size="9" />
        <asp:Parameter Name="Code" Type="String" Size="6" />
        <asp:Parameter Name="Status" Type="String" Size="1" />
        <asp:Parameter Name="Modified" Type="Int32" Size="1" DefaultValue="1" />
    </UpdateParameters>
    <InsertParameters>
        <asp:Parameter Name="AssociateID" Type="Int32" />
        <asp:Parameter Name="Name" Type="String" />
        <asp:Parameter Name="SSN" Type="String" />
        <asp:Parameter Name="Code" Type="String" />
        <asp:Parameter Name="Status" Type="String" />
        <asp:Parameter Name="Modified" Type="Int32" />
    </InsertParameters>
       </asp:SqlDataSource>


==============================================================

Protected Sub GridView1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles GridView2.SelectedIndexChanged

    End Sub

Open in new window

OK, I see. You are using SqlDataSource to update your record.

I believe there is a Updating event handler for the SqlDataSource, you will need to add this event to your code behind, then you check the value of the HiddenField, if the value is not "Yes", then you can cancel the Update process by set e.Cancel = true; If "Yes", then just pass through the event handler without doing anything.

Let me know if this helps.
It did help, i think. I am following this article based on your last post.

http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.sqldatasource.updating.aspx

Am i headed in the right direction?
Yes. You are on the right track.
Are you using C# or VB.net?
VB
Click on your SqlDataSource, then click the Event icon in the Properties window of VS (the lighting bolt), then double click Updating event to automatically create the Updating event handler in your code behind.
codingbeaver,

I am now stuck [although i feel like we are close]. I have integrated the code and commands as instructed from that site link i posted earlier. You will see in my code behind that I am also trying to grab any insert errors [but you can ignore that - its not working anyway].

My asp code and my code behind are listed in chunks below.

I am stuck on how to check the value of the hidden field from the code behind. I think i need to do something in the On_Sql_Updating Sub.

Thanks for your help!
Jason



'Code Behind:

    Sub On_Click(ByVal source As Object, ByVal e As EventArgs)
        AssociateIndexDataSource.Update()
    End Sub 'On_Click

    Sub On_Sql_Updating(ByVal source As Object, ByVal e As SqlDataSourceCommandEventArgs)
        Dim command As DbCommand
        Dim connection As DbConnection
        Dim transaction As DbTransaction

        command = e.Command
        connection = command.Connection
        connection.Open()
        transaction = connection.BeginTransaction()
        command.Transaction = transaction

    End Sub 'On_Sql_Updating

    Sub On_Sql_Updated(ByVal source As Object, ByVal e As SqlDataSourceStatusEventArgs)

        Dim command As DbCommand
        Dim transaction As DbTransaction

        command = e.Command
        transaction = command.Transaction

        ' In this code example the OtherProcessSucceeded variable represents
        ' the outcome of some other process that occurs whenever the data is 
        ' updated, and must succeed for the data change to be committed. For 
        ' simplicity, we set this value to true. 
        Dim OtherProcessSucceeded As Boolean = True

        If (OtherProcessSucceeded) Then
            transaction.Commit()
            'Me.Server.Transfer("Default.aspx")
            'Label2.Text = "The record was updated successfully!"
        Else
            Me.Server.Transfer("TransactionDenied.aspx")
            transaction.Rollback()
        End If
    End Sub ' On_Sql_Updated

'==================================================
'asp / js:

               <asp:TemplateField HeaderText="Department" SortExpression="Code">
                   <EditItemTemplate>
                       <asp:TextBox OnChange="markDirty()" ID="TextBox2" runat="server" Text='<%# Bind("Code") %>' Width="50" MaxLength="5"></asp:TextBox>
                   </EditItemTemplate>
                   <ItemTemplate>
                       <asp:Label ID="Label2" runat="server" Text='<%# Bind("Code") %>'></asp:Label>
                   </ItemTemplate>
               </asp:TemplateField>


================================================================

<asp:HiddenField ID="hdnFlag" runat="server" />
 <script type="text/javascript">
 function markDirty()
{
    var hdn = document.getElementById('<%=hdnFlag.ClientID%>');
    hdn.value = "Yes";
}
 </script>

Open in new window

ok, following your instructions [and please disregard my last post, i get the following:
Protected Sub AssociateIndexDataSource_Updating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.SqlDataSourceCommandEventArgs) Handles AssociateIndexDataSource.Updating



    End Sub

Open in new window

No. Don't copy and paste the code from the web site. Read my last comment to create the Updating event handler for your case, then put your code in the event handler.

So your event handler should like this:
Protected Sub AssociateIndexDataSource_Updating(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.SqlDataSourceCommandEventArgs) Handles AssociateIndexDataSource.Updating
	'Check the HiddenField
	If (Me.hdnFlag.Value = "Yes") Then
		'Update the record
	Else
		'Don't update the record
		e.Cancel = True
	End If
End Sub

Open in new window

Should be like this instead:
Protected Sub AssociateIndexDataSource_Updating(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.SqlDataSourceCommandEventArgs) Handles AssociateIndexDataSource.Updating
	'Check the HiddenField
	If (Me.hdnFlag.Value <> "Yes") Then
		e.Cancel = True
		'If it is "Yes", then you don't have to do anything
		'because SqlDataSource will continue updating
	End If
End Sub

Open in new window

ok cool. It is working.

now, here is the deal:

if the end user clicks the edit button, DOES NOT touch any of the editable fields, and then clicks on the update button, the record is not updated [as expected].

however, if the end user clicks the edit button, and then types in any of the fields, and then selects the update button, the record IS updated.

Now, i know what you are thinking. You are thinking, why would the end user enter into an editable field if they do not intend to update the record with new data? Well, you are right to think this way, and with any other organization, i would agree with your logic. However, i am never surprised when my end user's do random things such as re-type the exact same data into a field and then hit enter!

So, if you understand my dilemma, is there a way to catch this with the code you supplied to me? It sounds more and more like what i would need to do would be to capture the data into variables and then check each one before sending the update command. I dont know if its even worth it.

Let me know your thoughts,
Jason
To my understanding, if user remove the content in a textbox and then enter the exact same content in the textbox again, "onchange" event should not fire. Are you saying that "onchange" actually fired in your code?
yes, on change fired. in fact, at some point during my testing, it seemed to fire no matter what i did to the editable text boxes. so i closed and cleared by browser cache, and rebuilt the site from within VS2008. tested again, and things seemed to be working.

I will continue to test and attempt to duplicate/confirm the anomalies i have encountered.

Jason
hmmm....

ok, i think i found the bug [no idea where to look to fix it] but here is the deal:

after updating a single record and hitting submit, i think the flag is being stuck at TRUE. so, if i go to any other record to edit it, but dont even touch any data, then submit it, the update query will run.

Does this make sense? I will try to illustrate an example.

Row 1 > Clicked Edit, decided not to change any data, clicked submit | Update query did not run
Row 2 > Edited a record intentionally | update query runs as expected
Row 3 > clicked edit, decided not to change any data, clicked submit | Update query runs, but should not

Let me know your thoughts.
Jason
I acutally thought about this before I gave you the initial comment, but I didn't want to confuse you at that time, so I waited until you understood how it works. Now let's modify the JavaScript a little bit to see if it will solve your problem.
The new JavaScript (with one parameter) will be as the attached code:
Then change onchange on TextBox fields to this:
onchange="markDirty(this)"
function markDirty(box)
{
    var hdn = document.getElementById('<%=hdnFlag.ClientID%>');
    if (box.value != box.oldValue)
    {
        hdn.value = "Yes";
    }    
}

Open in new window

Sorry, forgot to tell you to reset the value of the HiddenField after the update.
Foloow the steps in my previous comment telling you how to add the Updating event handler, add an Updated event handler. SqlDataSource.Updated event fires after the record is updated, in the event handler, set the value of the HiddenField back to emapty. This should fix your problem.
Here is the code in case you need it:
Protected Sub AssociateIndexDataSource_Updating(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.SqlDataSourceCommandEventArgs) Handles AssociateIndexDataSource.Updating
	Me.hdnFlag.Value = String.Empty
End Sub

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of codingbeaver
codingbeaver
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
It looks like i also need to create an updated sub as well, huh? or can i just write the code without using the "properties panel"?.

I will modify the js, asp, and code behind as per your instruction and post back the results.

Jason
Yes, you don't have to use Properties window to write the Updated event handler. Just copy and paste the code in my last comment to your code behind.
cool. looks like the last changes have corrected the issue(s) at hand. That is awesome! [at least to me, it is].

I would say that for all intents and purposes this is the solution. I will leave this question open for a little while longer in case something changes or I get stuck.

Before I close the question and select a solution, i will post all working code in one place for the next person that comes along to benefit from this.

Thanks for your help! Now I am going to start another question about how to capture errors in the Insert Query. I think I can expand on what you taught me today and figure out how to prevent those horrid "Server Errors" from freaking out my end users.

Jason