Solved

Prompt user when leaving a Gridview row in edit mode

Posted on 2008-10-08
29
2,112 Views
Last Modified: 2013-11-07
If a user is editing a row in my gridview and they decide to navigate away from the row without confirming the update (such as if they click edit on another row) I want to prompt them and confirm if they wish to "exit the row without saving". What is the best way to do this?

Adding javascript to the Cancel button of the row won't accomplish my task because users do not always click Cancel before they attempt to navigate away from the row.

I thought about gvMuniData.RowCancelingEdit, but that event doesn't fire unless they click Cancel on the row. I also tried:

e.Row.Attributes.Add("onblur", "javascript:return confirm('You haven't saved this record. Are you sure you want to exit this row without saving?')")

but I couldn't get the onblur event to fire. Onmouseout fired fine, but I don't want to use that javascript function.
0
Comment
Question by:CitySec
  • 13
  • 13
  • 3
29 Comments
 
LVL 7

Expert Comment

by:ASPSQLServerCOM
ID: 22671905
could it be possible for you to paste the code
0
 
LVL 2

Author Comment

by:CitySec
ID: 22672024

<asp:UpdatePanel ID="updGridview" runat="server">

    <ContentTemplate>                

        <asp:GridView ID="gvMuniData" DataKeyNames="ID" runat="server" AllowPaging="True" AutoGenerateColumns="False" DataSourceID="sqlGridview" AllowSorting="True" OnRowCommand="gvMuniData_RowCommand">            

            <Columns>               

                <asp:BoundField DataField="ID" Visible="False" />

                <asp:TemplateField HeaderText="ID" SortExpression="ID" Visible="False">

                    <EditItemTemplate>

                        <asp:Label runat="server" ID="lblID" Text='<%# Bind("ID") %>'></asp:Label>

                    </EditItemTemplate>

                    <ItemTemplate>  

                        <asp:Label runat="server" ID="lblID" Text='<%# Bind("ID") %>'></asp:Label>

                    </ItemTemplate>

                </asp:TemplateField>

                <asp:TemplateField>

                    <EditItemTemplate>

                        <asp:Panel runat="server" ID="gridPopupEdit" CssClass="gridPopupEdit">

                            <div class="floatleft"><asp:imagebutton ID="btnUpdate" runat="server" CommandArgument='<%# Bind("ID") %>' commandname="Update" ImageUrl="images/check.gif" CausesValidation="true" AlternateText="Save Changes" /></div>

                            <div class="floatleft"><asp:imagebutton ID="btnDetails" runat="server" CommandArgument='<%# Bind("ID") %>' commandname="Select" ImageUrl="images/arrow.gif" CausesValidation="false" AlternateText="Details"/></div>

                            <div class="floatleft"><asp:imagebutton ID="btnCancel" runat="server" CommandArgument='<%# Bind("ID") %>' commandname="Cancel" ImageUrl="images/cancel.gif" CausesValidation="false" AlternateText="Cancel Editing"/></div>

                            <div class="floatleft"><asp:imagebutton ID="btnDeleteEdit" runat="server" CommandArgument='<%# Bind("ID") %>' commandname="Delete" ImageUrl="images/delete.gif" CausesValidation="false" AlternateText="Delete"/></div>                        

                        </asp:Panel>                                            

                    </EditItemTemplate>

                    <ItemTemplate>

                        <asp:Panel runat="server" ID="gridPopupNonEdit" CssClass="gridPopup"> 

                            <div class="floatleft"><asp:imagebutton ID="btnEdit" runat="server" CommandArgument='<%# Bind("ID") %>' commandname="Edit" ImageUrl="images/edit.gif" CausesValidation="false" AlternateText="Edit" /></div>

                            <div class="floatleft"><asp:imagebutton ID="btnDetails" runat="server" CommandArgument='<%# Bind("ID") %>' commandname="Select" ImageUrl="images/arrow.gif" CausesValidation="false" AlternateText="Details"/></div>

                            <div class="floatleft"><asp:imagebutton ID="btnDeleteNonEdit" runat="server" CommandArgument='<%# Bind("ID") %>' commandname="Delete" ImageUrl="images/delete.gif" CausesValidation="false" AlternateText="Delete"/></div>                        

                        </asp:Panel>

                    </ItemTemplate>

                </asp:TemplateField>
 
 

...
 
 
 

                <asp:TemplateField HeaderText="Competitive/ Negotiated" SortExpression="CompetitiveNegotiated">

                    <EditItemTemplate>

                        <div class="gvLabel">Comp/Neg</div>

                        <asp:DropDownList runat="server" ID="ddlCompetitiveNegotiated" CssClass="gvDropDownList"></asp:DropDownList>

                        <asp:HiddenField runat="server" ID="hdCompetitiveNegotiated" value='<%# Bind("CompetitiveNegotiated") %>' /> 

                    </EditItemTemplate>

                    <ItemTemplate> 

                        <div title="header=[Competitive/ Negotiated] fade=[off] fadespeed=[.3] cssbody=[boxoverBody] cssheader=[boxoverHeader compNeg]">                           

                            <asp:Label ID="lblCompetitiveNegotiated" runat="server" Text='<%# Bind("CompetitiveNegotiated") %>'></asp:Label>

                        </div>                           

                    </ItemTemplate>

                </asp:TemplateField>           

            </Columns>

        </asp:GridView>

    </ContentTemplate> 

</asp:UpdatePanel>
 
 
 

    Private Sub gvMuniData_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvMuniData.RowDataBound
 

        If e.Row.RowType = DataControlRowType.DataRow Then
 

            If (e.Row.RowState And DataControlRowState.Edit) > 0 Then
 

                e.Row.Attributes.Add("onblur", "javascript:return confirm('You haven't saved this record. Are you sure you want to exit without saving?')")
 

            End If
 

        End If
 

    End Sub

Open in new window

0
 
LVL 7

Expert Comment

by:ASPSQLServerCOM
ID: 22672123
many times browser are very specific to javascript , try onBlur

http://forums.asp.net/t/1228965.aspx

 if (e.Row.RowType == DataControlRowType.DataRow)
            {
                Button btn = e.Row.FindControl("Button1") as Button;
                string script = Page.GetPostBackEventReference(btn, "");

                e.Row.Attribute.add("onblur",script);
             }


Also colud it be possible for you to copy paste the browser view source of page
also try change onblur with onfocus and see that event is getting fired
0
 
LVL 2

Author Comment

by:CitySec
ID: 22673290
I have an onclick event and an onfocus event in the row. Here's the VB:

e.Row.Attributes.Add("onclick", ClientScript.GetPostBackClientHyperlink(Me.gvMuniData, "Edit$" + e.Row.RowIndex.ToString))

e.Row.Attributes.Add("onfocus", "javascript:return confirm('You gave focus to this row.')")

And here's the page source for a row:

<tr id="gvMuniData_ctl03" onclick="javascript:__doPostBack('gvMuniData','Edit$0')" onfocus="javascript:return confirm('You gave focus to this row.')" style="background-color:#F0F0F0;">

The click works fine but the focus does not work.
0
 
LVL 5

Expert Comment

by:harwantgrewal
ID: 22675564
Hi CitySec I dont thnk tr has a onblur function its for the form fields.
You have to add the onblur in the formfields

Harry
0
 
LVL 2

Author Comment

by:CitySec
ID: 22678922
OK, so what is the best way to prompt a user when leaving a Gridview row? Basically what I need is a way for the user to be notified when they have left a Gridview row that is in edit mode without saving it. What would be even better is if it would do an autosave when they leave the row. Any way of doing this is appreciated.
0
 
LVL 7

Expert Comment

by:ASPSQLServerCOM
ID: 22678948
hi, <TR will not give you onblur , best is use on your form control like text box
0
 
LVL 2

Author Comment

by:CitySec
ID: 22678962
OK, so what is the best way to prompt a user when leaving a Gridview row? Basically what I need is a way for the user to be notified when they have left a Gridview row that is in edit mode without saving it. What would be even better is if it would do an autosave when they leave the row. Any way of doing this is appreciated.
0
 
LVL 7

Expert Comment

by:ASPSQLServerCOM
ID: 22678996
hi,
**********editing a row in my gridview and they decide to navigate away from the row
does your form has any textbox where they are going to change the value then attach event on to that text box, if other control where user is going to change the value then attach event to that control and not to TR
0
 
LVL 2

Author Comment

by:CitySec
ID: 22679050
There are around 20 textboxes and dropdownlists in each row. If I attach an event to each of these, it will prompt them to save as they are moving between each input box, right?
0
 
LVL 7

Expert Comment

by:ASPSQLServerCOM
ID: 22679102
use
My suggestion is to put one button in edit template and set it's commandname equals update.

Then you can write some code in RowDataBound event javascript onfocus where it will fire the update button click event

   
0
 
LVL 7

Expert Comment

by:ASPSQLServerCOM
ID: 22679208
in this case, best logic, for every row, attach onfocus/onblur event, assign one constant id value paramter to all the controls for each row
 .......Attributes.Add("onfocus", "javascript:checkFocus(RowNumber')")
means in first row all your text box and drop down control will have id 1, second row all control has id 2 and so on
now in declare one global variable which will hold the current rownumber like
<script = javascript ..........>
var currentEditRowNum=0
now in checkFocus javascript function (RowNum)
{
if currentEditRowNum<> RowNum
......make your prompt
currentEditRowNum= RowNum


i think this will be best way to implement

0
 
LVL 2

Author Comment

by:CitySec
ID: 22681795
I was able to implement that but it does not accomplish the task of prompting a user when they leave a gridview row. What it does is it prompts a user when they leave the first control of a new gridview row. It is not able to recognize when the user leaves the row.

The user might leave the row and attempt to do something else besides edit another row (like sort the columns, add a new row, or search the gridview).

Any more ideas?
0
 
LVL 7

Assisted Solution

by:ASPSQLServerCOM
ASPSQLServerCOM earned 400 total points
ID: 22682072
Hi,

I think you used the onblur event, use onfocus event, also add logic like
<script = javascript ..........>
var currentEditRowNum=0
now in checkFocus javascript function (RowNum)
{
if currentEditRowNum==0
{
currentEditRowNum=RowNum
}
if currentEditRowNum<> RowNum
{
......make your prompt
currentEditRowNum= RowNum
}
try this code, it has to work, or could it be possible for you to paste the code
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 2

Author Comment

by:CitySec
ID: 22682228
I was using onblur - you're right. I will give it a shot tomorrow morning. Thanks for all your help. I still think this won't work unless all my gridview rows are in edit mode to begin with, but I'll still give it a try tomorrow.
0
 
LVL 5

Assisted Solution

by:harwantgrewal
harwantgrewal earned 100 total points
ID: 22682979
Hi CitySec
I have got a different proposition for the solution. Make a global javascript variable call it EditMode = 0 which means nothing there to edit or no edit it clicked. and on the edit onClick javascript even set this variable to 1 that means somthing is in the edit mode and before doing that check if the value of the variable
if its 1 that means somthing is already in edit mode then prompt your confirm box asking whether they want to cancel or proceed. And in the update or Cancle update button click make this EditMode to 0 again.

I can give you rough flow chart if you need to understand what I just said.

THanks

Harry
0
 
LVL 2

Author Comment

by:CitySec
ID: 22687345
Good job - much closer! Now I just have one last problem and I will mark the solution(s). I already have an onclick event on the row click event which puts the row into edit mode:

e.Row.Attributes.Add("onclick", ClientScript.GetPostBackClientHyperlink(Me.gvMuniData, "Edit$" + e.Row.RowIndex.ToString))

How can I add another click event when there is already one there? It overwrites the first one. The new row click even I would be adding is this:

e.Row.Attributes.Add("onclick", "javascript:return checkEditMode('on')")

And here is the javascript function I came up with based on your solution:

//global variable for edit mode - default is off
var currentEditMode="off";

function checkEditMode(mode) {
    if (currentEditMode=="on") {      //there is currently a row in edit mode
        var answer = confirm("You haven't saved your changes to this row. Are you sure you wish to exit?");
        if (answer){          //we are leaving without saving  
            if (mode=="off") {
                currentEditMode="off";
            } else {
                currentEditMode="on";
            }
        } else {         //we decided not to leave yet
            return false
        }
    } else {      //there is not currently a row in edit mode
        if (mode=="off") {
            currentEditMode="off";
        } else {
            currentEditMode="on";
        }
    }
}

I got all this to work correctly using the Edit button in the row, but I still want to enable clickable rows and have this functionality. I don't want the user to have to click on the edit button to edit the row.

Thanks - so close to the solution!
0
 
LVL 7

Expert Comment

by:ASPSQLServerCOM
ID: 22687388
try
e.Row.Attributes.Add("onclick", "javascript:return checkEditMode('on');" & ClientScript.GetPostBackClientHyperlink(Me.gvMuniData, "Edit$" + e.Row.RowIndex.ToString))
0
 
LVL 2

Author Comment

by:CitySec
ID: 22688994
When I tried that it didn't put the row into edit mode, it only performed the checkEditMode function. Anything else you can think of?
0
 
LVL 7

Expert Comment

by:ASPSQLServerCOM
ID: 22689066
could you please paste the view source
0
 
LVL 2

Author Comment

by:CitySec
ID: 22689109
Sure:

<tr id="gvMuniData_ctl03" onclick="javascript:return checkEditMode('on');javascript:__doPostBack('gvMuniData','Edit$0')" onmouseover="javascript:ShowPopup('gvMuniData_ctl03_gridPopupNonEdit','gvMuniData_ctl03')" onmouseout="javascript:HidePopup('gvMuniData_ctl03_gridPopupNonEdit','gvMuniData_ctl03','#f0f0f0')" style="background-color:#F0F0F0;">
0
 
LVL 7

Accepted Solution

by:
ASPSQLServerCOM earned 400 total points
ID: 22690549
Here your final view source will be something like

<tr id="gvMuniData_ctl03" onclick="javascript:if(checkEditMode('on')){javascript:__doPostBack('gvMuniData','Edit$0')}"

style="background-color:#F0F0F0;,alert('nothing happ-en')};">

<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">

var currentEditMode="off";
 

function checkEditMode(mode) {

    if (currentEditMode=="on") {      //there is currently a row in edit mode

        var answer = confirm("You haven't saved your changes to this row. Are you sure you wish to exit?");

        if (answer){          //we are leaving without saving  

            if (mode=="off") {

                currentEditMode="off";

            } else {

                currentEditMode="on";

            }

return true;

        } else {         //we decided not to leave yet            	return false;

        }

    } else {      //there is not currently a row in edit mode

        if (mode=="off") {

            currentEditMode="off";

        } else {

            currentEditMode="on";

        }

return true;

    }

}
 

e.Row.Attributes.Add("onclick", "javascript:if(return checkEditMode('on')){" & ClientScript.GetPostBackClientHyperlink(Me.gvMuniData, "Edit$" + e.Row.RowIndex.ToString) & "}" & )

Open in new window

0
 
LVL 7

Expert Comment

by:ASPSQLServerCOM
ID: 22690569
use this javascript, with above script problem with return false

function checkEditMode(mode) {
    if (currentEditMode=="on") {      //there is currently a row in edit mode
        var answer = confirm("You haven't saved your changes to this row. Are you sure you wish to exit?");
        if (answer){          //we are leaving without saving  
            if (mode=="off") {
                currentEditMode="off";
            } else {
                currentEditMode="on";
            }
return true;
        } else {         //we decided not to leave yet
                  return false;
        }
    } else {      //there is not currently a row in edit mode
        if (mode=="off") {
            currentEditMode="off";
        } else {
            currentEditMode="on";
        }
return true;
    }
0
 
LVL 5

Expert Comment

by:harwantgrewal
ID: 22699007
Hi CitySec
You are going good. Just for the information, Whenever you put return in the javascript function it goes to next function only if the first function returns true.

So make sure every return true if you want to move to the next function.

Harry

PS: Guys I think the function written is bit messy to me have a look into my code.
var currentEditMode="off";

 

function checkEditMode() 

{

    if (currentEditMode=="on") 

    {   //there is currently a row in edit mode

        if (confirm("You haven't saved your changes to this row. Are you sure you wish to exit?"))

        {   //we are leaving without saving  

            currentEditMode="off";

            return true;    

        } 

        else 

        {   //we decided not to leave yet

            return false;

        }

    }

}

Open in new window

0
 
LVL 2

Author Comment

by:CitySec
ID: 22711707
I am good with my javascript function. My question still remains as to how to give two javascript functions to one row's onclick event.

This line of code isn't well-formatted:

e.Row.Attributes.Add("onclick", "javascript:if(return checkEditMode('on')){" & ClientScript.GetPostBackClientHyperlink(Me.gvMuniData, "Edit$" + e.Row.RowIndex.ToString) & "}" & )

It should be this instead:

e.Row.Attributes.Add("onclick", "javascript:if(return checkEditMode('on')){" & ClientScript.GetPostBackClientHyperlink(Me.gvMuniData, "Edit$" + e.Row.RowIndex.ToString) & "}")

without the ampersand before the closing parenthesis. And I still don't think this is what I need. To reiterate, I want

1) clicking on a row sends it into edit state
2) clicking on a row checks to see if another row is already in edit state and prompts user if so

I can accomplish each of these requirements solo, but I can't combine the two into one onclick event. How do I do this? How do I add to onclick attributes to a row programmatically?
0
 
LVL 2

Author Comment

by:CitySec
ID: 22711848
This line of code: e.Row.Attributes.Add("onclick", "javascript:if(return checkEditMode('on')){" & ClientScript.GetPostBackClientHyperlink(Me.gvMuniData, "Edit$" + e.Row.RowIndex.ToString) & "}")

Causes this Javascript error at runtime:

syntax error

javascript:if(return checkEditMode('on')){javascript:__doPostBack('gvMuniData','Edit$12')}
---------------^
0
 
LVL 7

Expert Comment

by:ASPSQLServerCOM
ID: 22711984
Hi,

Yes,
e.Row.Attributes.Add("onclick", "javascript:if(return checkEditMode('on')){" & ClientScript.GetPostBackClientHyperlink(Me.gvMuniData, "Edit$" + e.Row.RowIndex.ToString) & "}")

so in this case return checkEditMode('on')
when user click first time at that time the grid is not in edit mode then it will not do any thing, but I think at that time also you have to return true for the row event to fire and to set the grid in edit mode and when second time user clicks on the row in which case grid is already in edit mode then it will prompt the user and if user click Ok then it will call the
ClientScript.GetPostBackClientHyperlink(Me.gvMuniData, "Edit$" + e.Row.RowIndex.ToString) & "}") correct

in this case could you please send me code where in when user click on row and it will set the grid in edit mode - or give both aspx and .vb/C# code
0
 
LVL 7

Assisted Solution

by:ASPSQLServerCOM
ASPSQLServerCOM earned 400 total points
ID: 22712051
hi,

remove return and it will work

javascript:if(checkEditMode('on')){javascript:__doPostBack('gvMuniData','Edit$12')}
0
 
LVL 2

Author Comment

by:CitySec
ID: 22712721
That did it. Thanks!
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now