Gridview 中的 Select2 插件仅适用于 asp.net 中的最后一行网格

Posted

技术标签:

【中文标题】Gridview 中的 Select2 插件仅适用于 asp.net 中的最后一行网格【英文标题】:Select2 plugin inside Gridview works with only last row of grid in asp.net 【发布时间】:2020-12-26 11:03:32 【问题描述】:

标题 在 asp.net 网页中使用 select2-4.0.13 和 bootstrap v4.4.1

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
    <link href="Styles/Bootstrap v4.4.1/bootstrap.min.css" rel="stylesheet" type="text/css" />
    <link href="Styles/Select2-4.0.13/select2.min.css" rel="stylesheet" type="text/css" />
    <link href="Styles/Select2-4.0.13/select2-bootstrap4.min.css" rel="stylesheet" type="text/css" />
</asp:Content>

ASPX 页面 创建了 3 列的 gridview,其中第一列包含带有 select2 插件的下拉列表,但 select2 仅适用于 gridview 的最后一行,对于其他行,它显示正常的下拉列表

<asp:GridView ID="grdPackingSlipItem" runat="server" AllowPaging="false" AutoGenerateColumns="False"
    CssClass="table-xs table-responsive table-striped table-bordered table-hover p-1"
    EmptyDataText="No rows for the selection criteria." EnableTheming="False" OnRowDataBound="grdPackingSlipItem_RowDataBound">
    <Columns>
        <asp:TemplateField HeaderText="Sl.No" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Left" ItemStyle-Width="50" HeaderStyle-Font-Bold="false">
            <ItemTemplate>
                <%# Container.DataItemIndex + 1 %>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Item Name" HeaderStyle-HorizontalAlign="Left" ItemStyle-HorizontalAlign="Left"
            ItemStyle-Width="220" HeaderStyle-Font-Bold="false" ControlStyle-Width="100%">
            <ItemTemplate>
                <asp:DropDownList runat="server" ID="grdtxtItemName" ClientIDMode="Static" data-
                    CssClass="select2-single input-sm w-100" data-placeholder="Item Name....." AppendDataBoundItems="true">
                </asp:DropDownList>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Pcs" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center"
            ItemStyle-Width="100" HeaderStyle-Font-Bold="false" ControlStyle-Width="100%">
            <ItemTemplate>
                <asp:TextBox ID="grdtxtPcs" runat="server" ClientIDMode="Static" onkeypress="return isIntegerKey(event);"
                    OnPaste="return false" MaxLength="10" BorderStyle="Solid" BorderColor="WhiteSmoke"
                    Text='<%#DataBinder.Eval(Container.DataItem, "QUANTITY")%>'>
                </asp:TextBox>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
    <HeaderStyle Font-Names="Tahoma" Font-Size="9pt" BackColor="#5D7B9D" Font-Bold="false"
        ForeColor="White" HorizontalAlign="Center" />
    <RowStyle Font-Names="Tahoma" Font-Size="10pt" ForeColor="Black" Height="30" />
    <PagerStyle CssClass="GridPager" />
</asp:GridView>

脚本部分 链接所需的脚本 bootstrap4 和 select2 脚本,为 ID 为“.select2-single”的下拉列表初始化 select2

<script src="Scripts/jquery-3.4.1/jquery-3.4.1.min.css" type="text/javascript"></script>
<script src="Scripts/Bootstrap v4.4.1/popper.min.js" type="text/javascript"></script>
<script src="Scripts/Bootstrap v4.4.1/bootstrap.min.js" type="text/javascript"></script>
<script src="Scripts/Bootstrap v4.4.1/bootstrap.bundle.min.js" type="text/javascript"></script>
<script src="Scripts/Select2-4.0.13/select2.full.js" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(function () 
        initSelect2();
    );

    function pageLoad() 
        initSelect2();
    

    function initSelect2() 
        $('.select2-single').select2(
            theme: 'bootstrap4',
            width: 'style',
            containerCssClass: ':all:',
            allowClear: true
        );
    
</script>

代码背后

在页面加载中加载了带有数据表的gridview

private void LoadGridData()

    DataTable dt = new DataTable();
    dt.Columns.Add(new DataColumn("RECORD_ID", typeof(int)));
    dt.Columns.Add(new DataColumn("PRODUCT_ID", typeof(int)));
    dt.Columns.Add(new DataColumn("PRODUCT_NAME", typeof(string)));
    dt.Columns.Add(new DataColumn("QUANTITY", typeof(int)));
    //empty row on if no record
    DataRow dtEmptyrow = dt.NewRow();
    dtEmptyrow["RECORD_ID"] = 1;
    dtEmptyrow["PRODUCT_ID"] = 1;
    dtEmptyrow["PRODUCT_NAME"] = "Apple";
    dtEmptyrow["QUANTITY"] = 100;
    dt.Rows.Add(dtEmptyrow);

    dtEmptyrow = dt.NewRow();
    dtEmptyrow["RECORD_ID"] = 2;
    dtEmptyrow["PRODUCT_ID"] = 5;
    dtEmptyrow["PRODUCT_NAME"] = "Oppo";
    dtEmptyrow["QUANTITY"] = 500;
    dt.Rows.Add(dtEmptyrow);

    dtEmptyrow = dt.NewRow();
    dtEmptyrow["RECORD_ID"] = 3;
    dtEmptyrow["PRODUCT_ID"] = 3;
    dtEmptyrow["PRODUCT_NAME"] = "Samsung";
    dtEmptyrow["QUANTITY"] = 300;
    dt.Rows.Add(dtEmptyrow);


    ViewState["PackingSlipItem"] = dt.Copy(); // original copy
    grdPackingSlipItem.DataSource = dt;
    grdPackingSlipItem.DataBind();

在gridview行数据绑定的下拉列表项的绑定列表

protected void grdPackingSlipItem_RowDataBound(object sender, GridViewRowEventArgs e)

    try
    
        if (e.Row.RowType == DataControlRowType.DataRow)
        
            //onrowdatabound = true;
            DataTable oDataTableSubCategory = new DataTable();
            oDataTableSubCategory.Columns.Add(new DataColumn("PRODUCT_ID", typeof(int)));
            oDataTableSubCategory.Columns.Add(new DataColumn("PRODUCT_NAME", typeof(string)));

            //empty row on if no record
            DataRow dtEmptyrow = oDataTableSubCategory.NewRow();
            dtEmptyrow["PRODUCT_ID"] = 1;
            dtEmptyrow["PRODUCT_NAME"] = "Apple";
            oDataTableSubCategory.Rows.Add(dtEmptyrow);

            dtEmptyrow = oDataTableSubCategory.NewRow();
            dtEmptyrow["PRODUCT_ID"] = 2;
            dtEmptyrow["PRODUCT_NAME"] = "Microsoft";
            oDataTableSubCategory.Rows.Add(dtEmptyrow);

            dtEmptyrow = oDataTableSubCategory.NewRow();
            dtEmptyrow["PRODUCT_ID"] = 3;
            dtEmptyrow["PRODUCT_NAME"] = "Samsung";
            oDataTableSubCategory.Rows.Add(dtEmptyrow);

            dtEmptyrow = oDataTableSubCategory.NewRow();
            dtEmptyrow["PRODUCT_ID"] = 4;
            dtEmptyrow["PRODUCT_NAME"] = "Nokia";
            oDataTableSubCategory.Rows.Add(dtEmptyrow);

            dtEmptyrow = oDataTableSubCategory.NewRow();
            dtEmptyrow["PRODUCT_ID"] = 5;
            dtEmptyrow["PRODUCT_NAME"] = "Oppo";
            oDataTableSubCategory.Rows.Add(dtEmptyrow);

            DropDownList DropDownList1 = (e.Row.FindControl("grdtxtItemName") as DropDownList);
            DropDownList1.Items.Clear();
            DropDownList1.Items.Insert(0, new ListItem(String.Empty, String.Empty));
            //DropDownList1.SelectedIndex = 0;
            DropDownList1.DataSource = oDataTableSubCategory;
            DropDownList1.DataTextField = "PRODUCT_NAME";
            DropDownList1.DataValueField = "PRODUCT_ID";
            DropDownList1.DataBind();
            string selectedPRODUCTSUBCAT_ID = DataBinder.Eval(e.Row.DataItem, "PRODUCT_ID").ToString();
            string selectedPRODUCTSUBCAT_NAME = DataBinder.Eval(e.Row.DataItem, "PRODUCT_NAME").ToString();
            DropDownList1.Items.FindByText(selectedPRODUCTSUBCAT_NAME).Selected = true;
        
    
    catch (Exception ex)
     

works with last row only for other rows it display normal dropdownlist

【问题讨论】:

【参考方案1】:

您在 GridView 中使用 ClientIDMode="Static"。这将导致多个 DropDownList 和 TextBox 具有相同的 ID。 如果你查看生成的 html,你会发现所有的 DropDownList 都有 ID grdtxtItemName

但是所有元素,无论是否是网络表单,都应该有一个唯一的 ID。 Select2 基于 ID 绑定,因为它们都是相同的,所以只有最后一个是有效的。所以去掉 ClientIDMode。

<asp:DropDownList runat="server" ID="grdtxtItemName" data-
    CssClass="select2-single input-sm w-100" data-placeholder="Item Name....." AppendDataBoundItems="true">
</asp:DropDownList>

【讨论】:

以上是关于Gridview 中的 Select2 插件仅适用于 asp.net 中的最后一行网格的主要内容,如果未能解决你的问题,请参考以下文章

Yii2:Gridview过滤器中的kartik\Select2下拉列表

我的 select2 jquery 仅适用于第一种形式

不加载kartik 的select2 作为GridView 中的过滤器。 Yii2

Jquery 仅适用于 gridview 的第一个条目

jQuery select2 AJAX 不工作

jquery select2 - 不工作