Solved

Embedding Forms in a GridView

Posted on 2007-03-28
8
354 Views
Last Modified: 2008-01-09
Hi,

I have an ASP.NET 2.0 page with a GridView on it, populated programmatically from the code-behind.

Each GridView row displays a unique object. I'd like each row of the GridView to have it's own little form that submits to another page, where a user can edit the object.

To accomplish this, I've inserted the following code into one of the template fields:

            <asp:TemplateField>
                <ItemTemplate>
                    <form id="frmEditObject<%# Eval("ObjectID") %>" action="editObject.aspx" method="POST">
                    <input type="hidden" name="ObjectID" value="<%# Eval("ObjectID") %>" />
                    </form>
                    <a href="javascript: document.forms['frmEditObject<%# Eval("ObjectID") %>'].submit();" class="edit">EDIT</a>
                </ItemTemplate>
            </asp:TemplateField>

This works great, EXCEPT for two things:

First, the first row's EDIT button throws the following JavaScript error:

Error: 'document.forms.frmEditObject1' is null or not an object.

I know its there because I can see it in the page source after the page loads.

Second, I have a custom footer with alphabet letters A - Z that allow the user to display only objects of one letter at a time. Like, they click on A and see Apple, Airplane, Angle, Aurora, etc. These links BREAK when I add form code to the GridView rows, and when you click on them, they throw this error:

Invalid postback or callback argument.  Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%@ Page EnableEventValidation="true" %> in a page.  For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them.  If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.


Here's what I think: I think that the form code I've inserted into the rows is interfering with the parent ASP.NET page form. So, when the page gets to the first row, it's already seen <form name="aspnetForm"> and now it's seeing <form id="frmEditObject1"> and it's getting confused. Then, it sees the </form> in my first row, and afterwards everything is fine (all the subsequent rows work), but, this breaks the aspnetForm, and so my alphabet links at the bottom, which are postbacks, also break.

Whew, long post.

Anyhow, what's the solution for this problem? Is it even correct to embed HTML forms in a GridView, or is there a different way I should be doing this?
0
Comment
Question by:CMES-IT
  • 5
  • 3
8 Comments
 
LVL 37

Expert Comment

by:samtran0331
Comment Utility
>>Is it even correct to embed HTML forms in a GridView, or is there a different way I should be doing this?
No, not really.  the ASP.Net model allows for one form with runat=server tag...and it's all you should really need...

what is your dynamic form doing?
                    <form id="frmEditObject<%# Eval("ObjectID") %>" action="editObject.aspx" method="POST">
                    <input type="hidden" name="ObjectID" value="<%# Eval("ObjectID") %>" />
                    </form>

does editObject.aspx do some processing based on the ObjectID?
Why can't you just do the processing on the same page?
0
 

Author Comment

by:CMES-IT
Comment Utility
The form should take the user to the editObject.aspx page that I've already created. This GridView only displays some basic info - Object Name, Object ID, etc. the editObject.aspx page allows the user to edit all of the objects' properties, about 50. There are multiple ways to get to the editObject.aspx page, and it's already somewhat complicated itself, so I don't want to embed all of it's functionality in this GridView page.

What I want is a list of the objects, each in a row, with basic information, and a button that says "Edit" and goes to the edit page, passing the ObjectID, which doesn't seem like it should be a big deal. I don't really care how I accomplish that functionality, as long as the two pages stay separate, so if there's a better way than embedding forms, please let me know.
0
 
LVL 37

Expert Comment

by:samtran0331
Comment Utility
>>What I want is a list of the objects, each in a row, with basic information, and a button that says "Edit" and goes to the edit page, passing the ObjectID

How does the editObject.aspx page catch the ObjectID variable?
querystring, session, request("ObjectID") etc...
0
 

Author Comment

by:CMES-IT
Comment Utility
It does a Request("ObjectID").

0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 

Author Comment

by:CMES-IT
Comment Utility
I can use a built-in object, and use the PostBackURL behavior to change where the form goes, but then I don't know a good way to get the ObjectID to the new page.

For instance:

            <asp:TemplateField HeaderText="&#160;">
                <ItemTemplate>
                    <asp:LinkButton ID="btnChooseObject" runat="server" CssClass="edit" PostBackUrl="editObject.aspx">EDIT</asp:LinkButton>
                    <input type="hidden" name="ObjectID" value="<%# Eval("ObjectID") %>" />
                </ItemTemplate>
            </asp:TemplateField>

That would work fine, except that it doesn't have a way of posting a unique ObjectID to the editObject.aspx page. For instance, if there are 5 objects in the GridView, with IDs from 1 to 5, the value of the hidden ObjectID field posted to the editObject.aspx page will be "1,2,3,4,5" instead of a single value.

If we could overcome that hurdle, then I could work within the constraints of the single-form model.
0
 

Author Comment

by:CMES-IT
Comment Utility
For instance, one solution to that might be to have a radio button for each GridView row, and then put a "Submit" button at the bottom of the page, but that adds an extra click to everything.

Another solution might be to make the Edit button be a link, where the objectID is passed via the Query String. But that's a little less secure, and a lot less elegant.

I know there needs to be a way to do this with a single form-based button. I'm just too new to .NET to know the solution.
0
 
LVL 37

Accepted Solution

by:
samtran0331 earned 500 total points
Comment Utility
sorry...I haven't had time to work up an example for you...but this can be done using a linkbutton in your templatefield instead of the "forms"...the linkbutton renders as an html link, but it gives you codebehind access "onclick" event to which, you would do a server.transfer to your editObject.aspx page.
Using server.transfer retains the variables on the gridview page and passes the same variables to the edit page...which lets you continue using request("...")
also..your objectid (if it is a primary key from the database) you can use the datakey property to pass the value...
sorry...all that might not make sense...lol...but maybe it's enough keywords for you to look into until I can work up a basic example?
google things like:
"gridview linkbutton"
"asp.net server.transfer"
"gridview datakeys"
0
 

Author Comment

by:CMES-IT
Comment Utility
I've solved this in a much easier manner than all that. It's not the most elegant... but it works.

Here's what I did:

At the top of the form, I added this:

    <input type="hidden" name="ObjectID" value="" />
    <asp:LinkButton ID="lbRedirect" runat="server" PostBackUrl="editObject.aspx" />

For the Edit Button field, in the GridView, I have this:

            <asp:TemplateField HeaderText="&#160;" >
                <ItemTemplate>
                    &nbsp;<a href="javascript: editObject(<%# Eval("ObjectID") %>);" class="edit">EDIT</a>
                </ItemTemplate>
            </asp:TemplateField>

Then, I added this JavaScript at the bottom of the page:
    <script language="JavaScript" type="text/javascript">
    <!--
        function editObject(intObjectID) {
            theForm.ObjectID.value = intObjectID;
            WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions('lbRedirect', '', false, '', 'editObject.aspx', false, true));
        }
    // -->
    </script>


I started with having the LinkButton be in the GridView, and then trying to have the JavaScript trigger the LinkButton using the Click() command, but for some reason, I couldn't get JavaScript to find it via getElementById or otherwise. So, I just looked in the code to see the structure of Microsoft's PostBack code, and added it to my JavaScript code. I tried to do the whole thing without the LinkButton, but that object is required for some reason, and even though I'm not using it, it has to be on the page for the PostBack to work.

I'm closing this out, but I'll give you the points for helping me.

Thanks.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

One of the pain points with developing AJAX, JavaScript, JQuery, and other client-side behaviors is that JavaScript doesn’t allow for cross domain request for pulling content. For example, JavaScript code on www.johnchapman.name could not pull conte…
Sometimes in DotNetNuke module development you want to swap controls within the same module definition.  In doing this DNN (somewhat annoyingly) swaps the Skin and Container definitions to the default admin selections.  To get around this you need t…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

763 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

8 Experts available now in Live!

Get 1:1 Help Now