ASP.NET:在客户端添加控件

时间:2022-04-22 16:01:54

If I have a page with a form (imagine a simple one with just TextBoxes and a submit button) and I want to allow the user to dynamiccally add more TextBoxes to the form via javascript, what is the best way to handle the request server side?

如果我有一个带有表单的页面(想象一个只有TextBoxes和提交按钮的简单页面)并且我想允许用户通过javascript动态地向表单添加更多TextBox,那么处理请求服务器端的最佳方法是什么?

Example: I have a page rendered like the following :

示例:我有一个如下所示的页面:

<input type = "text" id = "control1" name = "control1" />
<input type = "text" id = "control2" name = "control2" />
<input type = "text" id = "control3" name = "control3" />
<input type = "submit" />

The user trigger some Javascript and the page turns out like:

用户触发一些Javascript,页面结果如下:

<input type = "text" id = "control1" name = "control1" />
<input type = "text" id = "control2" name = "control2" />
<input type = "text" id = "control3" name = "control3" />
<input type = "text" id = "control4" name = "control4" />
<input type = "text" id = "control5" name = "control5" />
<input type = "submit" />

What is the best way to handle this kind of situation, or, more generally, working with dynamically generated input both client and server side (eg, how to generate them server side starting from, say, some data taken from a database)?

处理这种情况的最佳方法是什么,或者更一般地说,使用动态生成的客户端和服务器端输入(例如,如何从数据库中获取的某些数据开始生成服务器端)?

6 个解决方案

#1


If you want to be able to access them in the code behind using the FindControl method, the AJAX UpdatePanel is probably your best bet. Just remember that every time you update the UpdatePanel, your going through the entire page life cycle but only getting the pieces that render in the update panel back from the server, so be weary of the overhead.

如果您希望能够使用FindControl方法在后面的代码中访问它们,那么AJAX UpdatePanel可能是您最好的选择。请记住,每次更新UpdatePanel时,您都要经历整个页面生命周期,但只能从服务器获取更新面板中呈现的部分,因此要小心开销。

If you create them dynamically with Javascript you will not be able to use FindControl to get access to them in the code behind because they won't be re-created during the page event life cycle. Also, be careful because if you're creating a lot of them at the same time with some kind of loop it can slow things down, especially in Internet Explorer.

如果使用Javascript动态创建它们,则无法使用FindControl在后面的代码中访问它们,因为它们不会在页面事件生命周期中重新创建。另外,要小心,因为如果你使用某种循环同时创建了很多它们,它可能会减慢速度,特别是在Internet Explorer中。

You may also consider using AJAX and WebServices with WebMethods for submitting the data instead of a post-back if you're creating the controls dynamically with Javascript.

如果您使用Javascript动态创建控件,您还可以考虑使用带有WebMethods的AJAX和WebServices来提交数据而不是回发。

#2


I have done similiar things to this numerous times. My preferred approach is usually to use a Repeater and a Button (labelled Add) inside an UpdatePanel.

我已经无数次地做了类似的事情。我首选的方法通常是在UpdatePanel中使用Repeater和Button(标记为Add)。

For the Button_OnClick event in your code behind do something similiar to this;

对于代码中的Button_OnClick事件,执行与此类似的操作;

 Loop through the Items collection of the Repeater
 Use item.FindControl("txtUserInput") to get the TextBox for that item
 Save the text of each input to List<string> 
 Add an empty string to the the list
 Databind the repeater to this new list

Here's some example code;

这是一些示例代码;

<asp:Repeater runat="server" ID="rptAttendees">
    <ItemTemplate>
        <asp:TextBox runat="server" ID="txtAttendeeEmail" Text='<%# Container.DataItem %>'></asp:TextBox>
    </ItemTemplate> 
</asp:Repeater>



protected void btnAddAttendee_Click(object sender, EventArgs e)
{
    var attendees = new List<string>();

    foreach (RepeaterItem item in rptAttendees.Items)
    {
        TextBox txtAttendeeEmail = (TextBox)item.FindControl("txtAttendeeEmail");
        attendees.Add(txtAttendeeEmail.Text);
    }

    SaveAttendees();
    attendees.Add("");
    rptAttendees.DataSource = attendees;
    rptAttendees.DataBind();
}

#3


On client side, make a JS function for creating the inputs, for example:

在客户端,创建一个用于创建输入的JS函数,例如:

var numCtrl = 1; // depends on how many you have rendered on server side
var addCtrl = function() {
    var in = document.createElement('input');
    in.name = "control" + ++i;
    in.type = "text";
    in.id = "control" + i;
    document.getElementById("yourcontainer").appendChild(in);
}

..on the server side just lookup your HTTP params collection, iterate through it, and select only those matching /control\d*/

..在服务器端只是查找你的HTTP params集合,遍历它,并只选择那些匹配/控制\ d * /

#4


On the server side look into Request.Form["controlN"] where you will find your old and new fields.

在服务器端查看Request.Form [“controlN”],您将在其中找到旧的和新的字段。

On the server side you can add controls dynamically like:

在服务器端,您可以动态添加控件,如:

foreach (Type object in MyDBCollection)
{
   Controls.Add (new TextBox ());
}

#5


In webforms you won't have a lot of choices if you expect the values to postback and be able to access them in typical fashion. What I would suggest is that you use an Ajax UpdatePanel to allow the controls to be registered at the appropriate point of the page lifecycle (before onLoad), this will also make a difference on whether or not you need the boxes to persist across postbacks. The JS methods involved in the other 2 answers will not persist the textboxes through a postback.

在webforms中,如果您期望值以回发方式并且能够以典型方式访问它们,那么您将没有很多选择。我建议你使用Ajax UpdatePanel来允许控件在页面生命周期的适当位置(在onLoad之前)注册,这也会对你是否需要在回发中保留这些框有所不同。其他2个答案中涉及的JS方法不会通过回发保留文本框。

MVC gives you more leeway, since there isn't that crazy page lifecycle, control registration, viewstate, etc to get in your way.

MVC为您提供了更多的余地,因为没有疯狂的页面生命周期,控制注册,viewstate等可以阻挡你。

So the big question is, which model/framework for ASP.Net are you using?

所以最大的问题是,您使用的是ASP.Net的模型/框架?


Since you are indeed using webforms, I really strongly suggest you go with updatepanels if they'll work for you. it will permit you to add controls in such a way that wont get in the way of eventvalidation, etc.

由于您确实使用了webforms,我强烈建议您使用updatepanels,如果它们适合您。它将允许您以不会妨碍事件验证等方式添加控件。

#6


I've begun using jquery in a lot of my webforms applications and have found the combination of dynamic controls and using JSON to communicate with the page's WebMethods give me much more control over how the page is presented and eliminate needless postbacks.

我已经开始在我的很多webforms应用程序中使用jquery,并且已经发现动态控件的组合和使用JSON与页面的WebMethods进行通信使我能够更好地控制页面的呈现方式并消除不必要的回发。

When I want to trigger a postback, I use javascript to populate server controls on the page that are hidden by jquery and then click a server control button. This allows the page to degrade gracefully if the user cannot use javascript.

当我想触发回发时,我使用javascript填充页面上被jquery隐藏的服务器控件,然后单击服务器控件按钮。如果用户无法使用javascript,这将允许页面优雅地降级。

#1


If you want to be able to access them in the code behind using the FindControl method, the AJAX UpdatePanel is probably your best bet. Just remember that every time you update the UpdatePanel, your going through the entire page life cycle but only getting the pieces that render in the update panel back from the server, so be weary of the overhead.

如果您希望能够使用FindControl方法在后面的代码中访问它们,那么AJAX UpdatePanel可能是您最好的选择。请记住,每次更新UpdatePanel时,您都要经历整个页面生命周期,但只能从服务器获取更新面板中呈现的部分,因此要小心开销。

If you create them dynamically with Javascript you will not be able to use FindControl to get access to them in the code behind because they won't be re-created during the page event life cycle. Also, be careful because if you're creating a lot of them at the same time with some kind of loop it can slow things down, especially in Internet Explorer.

如果使用Javascript动态创建它们,则无法使用FindControl在后面的代码中访问它们,因为它们不会在页面事件生命周期中重新创建。另外,要小心,因为如果你使用某种循环同时创建了很多它们,它可能会减慢速度,特别是在Internet Explorer中。

You may also consider using AJAX and WebServices with WebMethods for submitting the data instead of a post-back if you're creating the controls dynamically with Javascript.

如果您使用Javascript动态创建控件,您还可以考虑使用带有WebMethods的AJAX和WebServices来提交数据而不是回发。

#2


I have done similiar things to this numerous times. My preferred approach is usually to use a Repeater and a Button (labelled Add) inside an UpdatePanel.

我已经无数次地做了类似的事情。我首选的方法通常是在UpdatePanel中使用Repeater和Button(标记为Add)。

For the Button_OnClick event in your code behind do something similiar to this;

对于代码中的Button_OnClick事件,执行与此类似的操作;

 Loop through the Items collection of the Repeater
 Use item.FindControl("txtUserInput") to get the TextBox for that item
 Save the text of each input to List<string> 
 Add an empty string to the the list
 Databind the repeater to this new list

Here's some example code;

这是一些示例代码;

<asp:Repeater runat="server" ID="rptAttendees">
    <ItemTemplate>
        <asp:TextBox runat="server" ID="txtAttendeeEmail" Text='<%# Container.DataItem %>'></asp:TextBox>
    </ItemTemplate> 
</asp:Repeater>



protected void btnAddAttendee_Click(object sender, EventArgs e)
{
    var attendees = new List<string>();

    foreach (RepeaterItem item in rptAttendees.Items)
    {
        TextBox txtAttendeeEmail = (TextBox)item.FindControl("txtAttendeeEmail");
        attendees.Add(txtAttendeeEmail.Text);
    }

    SaveAttendees();
    attendees.Add("");
    rptAttendees.DataSource = attendees;
    rptAttendees.DataBind();
}

#3


On client side, make a JS function for creating the inputs, for example:

在客户端,创建一个用于创建输入的JS函数,例如:

var numCtrl = 1; // depends on how many you have rendered on server side
var addCtrl = function() {
    var in = document.createElement('input');
    in.name = "control" + ++i;
    in.type = "text";
    in.id = "control" + i;
    document.getElementById("yourcontainer").appendChild(in);
}

..on the server side just lookup your HTTP params collection, iterate through it, and select only those matching /control\d*/

..在服务器端只是查找你的HTTP params集合,遍历它,并只选择那些匹配/控制\ d * /

#4


On the server side look into Request.Form["controlN"] where you will find your old and new fields.

在服务器端查看Request.Form [“controlN”],您将在其中找到旧的和新的字段。

On the server side you can add controls dynamically like:

在服务器端,您可以动态添加控件,如:

foreach (Type object in MyDBCollection)
{
   Controls.Add (new TextBox ());
}

#5


In webforms you won't have a lot of choices if you expect the values to postback and be able to access them in typical fashion. What I would suggest is that you use an Ajax UpdatePanel to allow the controls to be registered at the appropriate point of the page lifecycle (before onLoad), this will also make a difference on whether or not you need the boxes to persist across postbacks. The JS methods involved in the other 2 answers will not persist the textboxes through a postback.

在webforms中,如果您期望值以回发方式并且能够以典型方式访问它们,那么您将没有很多选择。我建议你使用Ajax UpdatePanel来允许控件在页面生命周期的适当位置(在onLoad之前)注册,这也会对你是否需要在回发中保留这些框有所不同。其他2个答案中涉及的JS方法不会通过回发保留文本框。

MVC gives you more leeway, since there isn't that crazy page lifecycle, control registration, viewstate, etc to get in your way.

MVC为您提供了更多的余地,因为没有疯狂的页面生命周期,控制注册,viewstate等可以阻挡你。

So the big question is, which model/framework for ASP.Net are you using?

所以最大的问题是,您使用的是ASP.Net的模型/框架?


Since you are indeed using webforms, I really strongly suggest you go with updatepanels if they'll work for you. it will permit you to add controls in such a way that wont get in the way of eventvalidation, etc.

由于您确实使用了webforms,我强烈建议您使用updatepanels,如果它们适合您。它将允许您以不会妨碍事件验证等方式添加控件。

#6


I've begun using jquery in a lot of my webforms applications and have found the combination of dynamic controls and using JSON to communicate with the page's WebMethods give me much more control over how the page is presented and eliminate needless postbacks.

我已经开始在我的很多webforms应用程序中使用jquery,并且已经发现动态控件的组合和使用JSON与页面的WebMethods进行通信使我能够更好地控制页面的呈现方式并消除不必要的回发。

When I want to trigger a postback, I use javascript to populate server controls on the page that are hidden by jquery and then click a server control button. This allows the page to degrade gracefully if the user cannot use javascript.

当我想触发回发时,我使用javascript填充页面上被jquery隐藏的服务器控件,然后单击服务器控件按钮。如果用户无法使用javascript,这将允许页面优雅地降级。