如果我有一个带有表单的页面(想象一个只有TextBoxes和提交按钮的简单页面)并且我想允许用户通过javascript动态地向表单添加更多TextBox,那么处理该表单的最佳方法是什么?请求服务器端?
示例:我的页面呈现如下:
<input type = "text" id = "control1" name = "control1" />
<input type = "text" id = "control2" name = "control2" />
<input type = "text" id = "control3" name = "control3" />
<input type = "submit" />
用户触发一些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" />
处理这种情况的最佳方法是什么,或者更一般地说,在客户端和服务器端使用动态生成的输入(例如,如何从数据库中获取的某些数据开始生成服务器端) )?
答案 0 :(得分:2)
如果您希望能够使用FindControl方法在后面的代码中访问它们,那么AJAX UpdatePanel可能是您最好的选择。请记住,每次更新UpdatePanel时,您都要经历整个页面生命周期,但只能从服务器获取更新面板中呈现的部分,因此要小心开销。
如果使用Javascript动态创建它们,您将无法使用FindControl在后面的代码中访问它们,因为它们不会在页面事件生命周期中重新创建。另外,要小心,因为如果你使用某种循环同时创建了很多它们,它可能会减慢速度,特别是在Internet Explorer中。
如果您使用Javascript动态创建控件,您也可以考虑使用带有WebMethods的AJAX和WebServices来提交数据而不是回发。
答案 1 :(得分:2)
我已经多次做过类似的事了。我首选的方法是在UpdatePanel中使用Repeater和Button(标记为Add
)。
对于代码中的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
这是一些示例代码;
<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();
}
答案 2 :(得分:1)
在客户端,创建一个用于创建输入的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);
}
..在服务器端只需查找你的HTTP params集合,遍历它,并只选择那些匹配/控制\ d * /
答案 3 :(得分:0)
在服务器端查看Request.Form [“controlN”],您可以在其中找到旧字段和新字段。
在服务器端,您可以动态添加控件,如:
foreach (Type object in MyDBCollection)
{
Controls.Add (new TextBox ());
}
答案 4 :(得分:0)
在webforms中,如果您期望值以回发方式并且能够以典型方式访问它们,那么您将没有很多选择。我建议你使用Ajax UpdatePanel来允许控件在页面生命周期的适当位置注册(在 onLoad之前),这也会对你是否需要有所帮助在回发中持续存在的方框。其他2个答案中涉及的JS方法不会通过回发来保留文本框。
MVC为您提供了更多的余地,因为没有那个疯狂的页面生命周期,控制注册,视图状态等可以阻挡您。
所以最大的问题是,您使用的是ASP.Net的模型/框架?
由于您确实使用的是webforms,我强烈建议您使用updatepanels,如果它们适合您。它将允许您以不会妨碍事件验证等方式添加控件。
答案 5 :(得分:0)
我已经开始在我的很多webforms应用程序中使用jquery,并且发现了动态控件的组合并使用JSON与页面的WebMethods进行通信,这让我可以更好地控制页面的显示方式并消除不必要的回发。 / p>
当我想触发回发时,我使用javascript填充页面上被jquery隐藏的服务器控件,然后单击服务器控件按钮。如果用户无法使用javascript,这将允许页面优雅地降级。