如何解决处理客户端和服务器端的 GridView 和自定义验证
我不太确定如何解决这个问题。
我想做什么: 浏览具有多行的 gridview,如果某些文本框或下拉列表保留默认值,则强制用户输入特定值。
我尝试了什么:
var row = $(this).closest('tr');
var text = $(row).find("input[name*='txtCurriculum']").val('enter lesson/unit name here');
var ddl = $(row).find("select[name*='ddlCurrAdditions']");
$(ddl).focusout(function () {
if (ddl.val == "-select curriculum name-") {
$(ddl).focus();
alert("select a curriculum name before moving on");
}
});
$(text).focusout(function () {
if (text.val == 'enter lesson/unit name here') {
$(text).focus();
alert('enter in a lesson or unit name before moving on');
}
});
它从未正确发射。 ddl focusout 会触发,但在我退出并返回页面之前不会停止触发。文本焦点永远不会触发。
protected void cv1_ServerValidate(object source,ServerValidateEventArgs args)
{
CustomValidator cv = ((CustomValidator)(source));
GridViewRow gvr;
//if (FormCGrid.Rows)
foreach (GridViewRow row in FormCGrid.Rows)
{
//string ddl = ((DropDownList)row.FindControl("ddlCurrAdditions")).SelectedItem.Text;
string txtC = ((TextBox)row.FindControl("txtCurriculum")).Text;
bool ddl = ((DropDownList)row.FindControl("ddlCurrAdditions")).Visible;
if (txtC == "enter lesson/unit name here")
{
args.IsValid = false;
cv.ErrorMessage = string.Format("Please enter the Additional program name on row {0}",row.RowIndex);
}
else if (ddl == true)
{
cv.ErrorMessage = string.Format("Enter your lesson or unit for the curriculum selected on row {0}",row.RowIndex);
args.IsValid = false;
}
}
}
我试图在这里遍历 gridview 的行,检查命名下拉列表的可见性(隐藏直到另一个下拉列表显示它,取决于那里选择的值)和默认值的文本框,但这也不起作用.它根本没有开火。欢迎提出任何建议。
我对大多数编程/编码问题一般都没有问题,但我发现使用 asp.net gridview 时,我的所有技术都被抛到了窗外。
解决方法
好的,有两种方法可以做到这一点,在这里你可以很容易地使用 js。但是,让我们使用 100% 的服务器端代码。我认为坚持使用服务器端代码更容易。
接下来呢?我实际上强烈建议在您计划编辑数据时使用列表视图代替网格视图。原因很简单 - ListView 不需要为您想要在该网格显示中放置/拥有的每个 asp.net 控件一遍又一遍地要求那些“令人讨厌的”“项目模板”。现在公平地说,说 2-3 个控件 - 然后网格视图还可以,但是对于更多,我真的发现列表视图在这里开始大获全胜(不需要项目模板)。 listview 的“技巧”当然是在网页上设置一个数据源,让它生成标记,然后吹掉(删除)除项目模板之外的所有模板。然后删除页面上的datasource1项,并从列表视图中删除datasource1设置。
但是,让我们使用网格视图 - 因此这将是一些“更混乱”的东西
所以,我们要填写网格 - 并说我们想要一个城市组合框 - 必须被选中。让我们做一个基本的检查,说姓氏也必须输入。
所以,我们有一个城市组合框(数据库驱动)。并说让我们为酒店评级(1-5)添加下拉菜单 - 但这只有 5 种选择 - 所以我们在下拉列表中添加了标记。 (所以有两个组合示例来说明这是如何工作的)。
所以,假设我们有一个这样的网格,我们点击保存,我们得到了这个结果:
现在,我们当然会喜欢那个消息框区域。事实上,我们可以很容易地放入 jQuery.UI 并让右边那个可爱的 div 出现在一个对话框中(我们甚至可以从我们的服务器端代码中触发那个框 + jQuery.UI 对话框显示 - 但让我们尝试并保持简短 - 但我会喜欢那个错误消息区域)。
好的,首先是标记:
只是一个简单的网格,但由于那些“项目模板”而“有点乱” - (如果你没有弄清楚,我真的不喜欢那些模板东西!!! - 使用列表视图你不需要它们!! - 只需为网格添加纯粹干净的 asp.net 控件。无论如何:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ID">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
<asp:TemplateField HeaderText="HotelName" >
<ItemTemplate><asp:TextBox id="HotelName" runat="server" Text='<%# Eval("HotelName") %>' /></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="FirstName" >
<ItemTemplate><asp:TextBox id="FirstName" runat="server" Text='<%# Eval("FirstName") %>' /></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="LastName" >
<ItemTemplate><asp:TextBox id="LastName" runat="server" Text='<%# Eval("LastName") %>' /></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="City">
<ItemTemplate>
<asp:DropDownList ID="cboCity" runat="server" DataTextField="City"
DataValueField = "City" Width="110px">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Active">
<ItemTemplate><asp:CheckBox id="Active" runat="server" Checked = '<%# Eval("Active") %>' /></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Rating">
<ItemTemplate>
<asp:DropDownList ID="cboRating" runat="server" SelectedValue = '<%# Eval("Rating") %>' >
<asp:ListItem Value="1">Poor</asp:ListItem>
<asp:ListItem Value="2">Just Ok</asp:ListItem>
<asp:ListItem Value="3">Ok</asp:ListItem>
<asp:ListItem Value="4">Good</asp:ListItem>
<asp:ListItem Value="5">Excellent</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
<div id="ErrorDialog" style="display:normal;float:left;padding-left:30px;width:20%" runat="server">
<asp:TextBox ID="txtErrors" runat="server" TextMode="MultiLine" Style="width:100%" Rows="20" ></asp:TextBox>
</div>
<div style="clear:both;padding-top:20px">
<asp:Button ID="cmdSave" runat="server" Text="Save" />
<asp:Button ID="cmdUnDo" runat="server" Text="UnDo" Style="margin-left:20px"/>
</div>
好的,现在开始吗?哎呀,这大约是我一次性发布的总最大标记 - 除了上面之外,我们接近了“不太好”的发布区域。
好的,让我们看看加载这个网格的代码。我们有这个代码:
public class EditHotelsG : System.Web.UI.Page
{
private DataTable rstTable = new DataTable();
private DataTable rstCity = new DataTable();
protected void Page_Load(object sender,System.EventArgs e)
{
if (System.Web.UI.Page.IsPostBack == false)
{
ErrorDialog.Visible = false;
LoadGrid();
ViewState["rstTable"] = rstTable;
ViewState["rstCity"] = rstCity;
}
else
{
rstTable = ViewState["rstTable"];
rstCity = ViewState["rstCity"];
}
}
public void LoadGrid()
{
// load up our drop down list from database (city)
string strSQL;
strSQL = "SELECT City from tblCity Order by City";
using (SqlCommand cmdSQL = new SqlCommand(strSQL,new SqlConnection(My.Settings.TEST3)))
{
cmdSQL.Connection.Open();
rstCity.Load(cmdSQL.ExecuteReader);
// now load up main grid view
strSQL = "SELECT ID,FirstName,LastName,HotelName,City,Active,Rating from tblHotels ORDER BY HotelName";
cmdSQL.CommandText = strSQL;
rstTable.Load(cmdSQL.ExecuteReader);
GridView1.DataSource = rstTable;
GridView1.DataBind();
}
}
protected void GridView1_RowDataBound(object sender,GridViewRowEventArgs e)
{
// set combo box data source
if (e.Row.RowType == DataControlRowType.DataRow)
{
// setup city drop down list
DropDownList cboDrop = e.Row.FindControl("cboCity");
cboDrop.DataSource = rstCity;
cboDrop.DataBind();
cboDrop.Items.Insert(0,new ListItem(string.Empty)); // add blank row
cboDrop.Text = rstTable.Rows(e.Row.RowIndex).Item("City").ToString;
}
}
}
好的,现在代码不多了。一个很好的部分是设置那个组合框。由于 cbo 框(下拉列表)是数据库驱动的,所以我们必须为每一行绑定 + 设置。因此,这花费了我们大量的编码时间。
但是请注意我们如何持久化数据库源(表)。我们这样做,因为我们想用更少的代码,一次性更新整个数据库。通过持久化该表,我们
Transfer data from Grid to table
Save the table to database in one shot
因此,这大大减少了我们的编码工作。
保存我们数据的代码,因此变成了这个宝石: (并注意我们还如何输入验证代码)。
protected void cmdSave_Click(object sender,EventArgs e)
{
// pull gride rows back to table.
bool bolDataOk = true;
txtErrors.Text = "";
foreach (GridViewRow rRow in GridView1.Rows)
{
int RecordPtr = rRow.RowIndex;
DataRow OneDataRow;
OneDataRow = rstTable.Rows(RecordPtr);
OneDataRow.Item("HotelName") = rRow.FindControl("HotelName") as TextBox.Text;
OneDataRow.Item("FirstName") = rRow.FindControl("FirstName") as TextBox.Text;
OneDataRow.Item("LastName") = rRow.FindControl("LastName") as TextBox.Text;
OneDataRow.Item("City") = rRow.FindControl("cboCity") as DropDownList.Text;
OneDataRow.Item("Active") = rRow.FindControl("Active") as CheckBox.Checked;
OneDataRow.Item("Rating") = rRow.FindControl("cboRating") as DropDownList.SelectedValue;
// check for missing City,or LastName
if (IsDBNull(OneDataRow("City")) | OneDataRow("City") == "")
{
bolDataOk = false;
if (txtErrors.Text != "")
txtErrors.Text += Constants.vbCrLf;
txtErrors.Text += "Missing City on row = " + (rRow.RowIndex + 1).ToString;
}
if (IsDBNull(OneDataRow("LastName")) | OneDataRow("LastName") == "")
{
bolDataOk = false;
if (txtErrors.Text != "")
txtErrors.Text += Constants.vbCrLf;
txtErrors.Text += "Missing lastName on row = " + (rRow.RowIndex + 1).ToString;
}
}
ErrorDialog.Visible = !(bolDataOk);
// now send table back to database with updates
if (bolDataOk)
{
string strSQL = "SELECT ID,Rating from tblHotels WHERE ID = 0";
using (SqlCommand cmdSQL = new SqlCommand(strSQL,new SqlConnection(My.Settings.TEST3)))
{
cmdSQL.Connection.Open();
SqlDataAdapter daupdate = new SqlDataAdapter(cmdSQL);
SqlCommandBuilder cmdBuild = new SqlCommandBuilder(daupdate);
daupdate.Update(rstTable);
}
}
}
现在,再一次,上面的代码片段有点长 - 并且是 SO 的代码片段的最大大小。我可能会考虑将上述最后一段代码分解为 2 个甚至 3 个例程。
但是,总而言之,上面展示了很多技巧和方法。
如前所述,我将发布如何使用客户端代码进行验证,但是使用一次数据库更新保存整个网格的总体想法?好吧,我会将这个技巧与列表视图、网格视图一起使用,即使我正在做客户端 js 验证?我仍然会使用上面的大部分设计模式。
还有取消按钮?好吧,我从未完成那部分 - 但它只会调用与第一页加载相同的代码(回发 - 错误,您只需从数据库源重新绑定网格以用于取消按钮。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。