Search code examples
htmlcss.netbootstrap-4webforms

How to select a group of elements in codeBehind in Web Forms without generating a wrapper element


I have a Webform page with a html form in it. A group of fields are for customer data and another is for product data, and others are neither of these two groups.

I need to hide the whole group of products fields or customer fields in PageLoad or some other event handlers based on some backend logic. The problem is in .NET Framework, I need to hide them one by one by ID which requires a huge bunch of code and I need to change the code anytime I add a new product or customer related field.

Grouping them into a wrapper and hide this wrapper instead breaks some CSS selectors as shown below where even display:contents won't help.

Is there anyway to "Pseudo Group" these elements in .NET Framework so that I can refer the group of elements in codeBeind either using for loop or whatever way to hide them, while the generated HTML won't actually have that extra wrapper layer? I'm not looking to rewrite the CSS selectors, as below is just an example and there are actually way more.

ProductFieldGroup.Visible = false;

.spaced-form>.input-group:not(:first-child) {
  margin-top: 1rem;
}

/*wrapper that breaks some CSS selector*/
.product-fields {
  display:content;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">

<div class="form-group spaced-form">
  <div class="input-group">
    <div class="input-group-prepend">
      <span class="input-group-text">Other Field 1</span>
    </div>
    <input runat="server" id="OtherField1" type="text" class="form-control form-control-lg" />
  </div>
  <div class="input-group">
    <div class="input-group-prepend">
      <span class="input-group-text">Customer Field 1</span>
    </div>
    <input runat="server" id="Customer1" type="text" class="form-control form-control-lg" />
  </div>
  <div class="input-group">
    <div class="input-group-prepend">
      <span class="input-group-text">Customer Field 2</span>
    </div>
    <input runat="server" id="Customer2" type="text" class="form-control form-control-lg" />
  </div>
  <div class="product-fields" id="ProductFieldGroup">
    <div class="input-group">
      <div class="input-group-prepend">
        <span class="input-group-text">Product Field 1</span>
      </div>
      <input runat="server" id="Product1" type="text" class="form-control form-control-lg" />
    </div>
    <div class="input-group">
      <div class="input-group-prepend">
        <span class="input-group-text">Product Field 2</span>
      </div>
      <input runat="server" id="Product2" type="text" class="form-control form-control-lg" />
    </div>
    <div class="input-group">
      <div class="input-group-prepend">
        <span class="input-group-text">Other Field 2</span>
      </div>
      <input runat="server" id="OtherField1" type="text" class="form-control form-control-lg" />
    </div>
  </div>

</div>


Solution

  • Probably, you are looking for the Panel component.

    It allows you to show/hide a group of controls/markup by setting the panel's Visible property in code-behind, among other things.

    In your example, the group of product fields can be declared as:

    <asp:Panel ID="ProductFieldsPanel" runat="server">
        <div class="input-group">
            <div class="input-group-prepend">
                <span class="input-group-text">Product Field 1</span>
            </div>
            <input runat="server" id="Product1" type="text" class="form-control" />
        </div>
        <div class="input-group">
            <div class="input-group-prepend">
                <span class="input-group-text">Product Field 2</span>
            </div>
            <input runat="server" id="Product2" type="text" class="form-control" />
        </div>
    </asp:Panel>
    

    To hide those fields, in code-behind, you can write:

    ProductFieldsPanel.Visible = false;
    

    For hidden panels no markup is generated. On the other hand, the above panel generates the following markup when visible:

    <div id="MainContent_ProductFieldsPanel">
    

    UPDATE:

    The PlaceHolder component can be used if no markup should be generated.

    Hope it helps.