Repeater and add columns to header and itemtemplate on page load

I haven’t used repeaters for much more than showing data from a datatable.

I am building a grid that that shows a list of users and columns of roles that the user has been assigned, shown with checkboxes (shown with true/false below but pretent they are checkboxes).

ex.

|Rep Name|Caller|Closer|Manager|SuperUser|
|Bob           |True  |true   | false      | false |
|Tom          |false  |false  |True       | True |

Basically using it for roles management.

However the roles may change later on so I want to load the roles(headers and items) dynamically into the repeater.

I am not sure how to do this or if it is even possible.

I figure you grab a list of current role possibilities and load them into the headertemplate but I am not sure how to match those with the itemtemplate and how to create checkboxes and place them in the itemtemplate.

Sorry if it is a rudementary question…. I appreciate any advice!

Datatable example of data that I am going to get… though I will also return ids for roles and users that are not shown here.

DataTable dt = new DataTable();
DataColumn dc = new DataColumn();

      dc.DataType = Type.GetType("System.String");
      dc.ColumnName = "RepName";
      dt.Columns.Add(dc);

      dc = new DataColumn(); 
      dc.DataType = Type.GetType("System.Boolean");
      dc.ColumnName = "Caller";
      dt.Columns.Add(dc);

      dc = new DataColumn();
      dc.DataType = Type.GetType("System.Boolean");
      dc.ColumnName = "closer";
      dt.Columns.Add(dc);

      dc = new DataColumn();
      dc.DataType = Type.GetType("System.Boolean");
      dc.ColumnName = "Admin";
      dt.Columns.Add(dc);

      dc = new DataColumn();
      dc.DataType = Type.GetType("System.Boolean");
      dc.ColumnName = "SuperUser";
      dt.Columns.Add(dc);


      DataRow row;

      row = dt.NewRow();

      row["RepName"] = "Joe";
      row["Caller"] = true;
      row["closer"] = false;
      row["Admin"] = true;
      row["SuperUser"] = false;
      dt.Rows.Add(row);

      row = dt.NewRow();

      row["RepName"] = "Bob";
      row["Caller"] = true;
      row["closer"] = false;
      row["Admin"] = true;
      row["SuperUser"] = false;
      dt.Rows.Add(row);


      row = dt.NewRow();

      row["RepName"] = "Tom";
      row["Caller"] = true;
      row["closer"] = false;
      row["Admin"] = true;
      row["SuperUser"] = false;
      dt.Rows.Add(row);

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Use nested Repeaters: the outer Repeater is for rows and has a HeaderTemplate and ItemTemplate which contain inner Repeaters for header and checkbox columns respectively. Something like this:

<asp:Repeater runat="server" ID="rowRepeater" OnItemDataBound="rowRepeater_ItemBound">
    <HeaderTemplate>
        <table>                                
        <tr>
            <asp:Repeater runat="server" ID="headerRepeater">
                <ItemTemplate>
                    <th>
                        <%# Container.DataItem %>
                    </th>
                </ItemTemplate>
            </asp:Repeater>
        </tr>
    </HeaderTemplate>
    <ItemTemplate>
        <tr>
            <td><asp:Label runat="server" ID="lblUserName" Text='<%# Eval("Key") %>' /></td>
            <asp:Repeater runat="server" ID="columnRepeater">
                <ItemTemplate>
                    <td>
                        <asp:HiddenField runat="server" ID="hfRoleIndex" Value='<%# Container.ItemIndex %>' />
                        <asp:CheckBox runat="server" ID="cbColumnValue" Checked='<%# Container.DataItem %>' OnCheckedChanged="cbColumnValue_CheckedChanged" AutoPostBack="true" />
                    </td>
                </ItemTemplate>
            </asp:Repeater>
        </tr>
    </ItemTemplate>
    <FooterTemplate>
        </table>
    </FooterTemplate>
</asp:Repeater>

and in your code behind:

Dictionary<string, bool[]> userRoles = new Dictionary<string, bool[]>(){
    {"Bob", new bool[]{true,true,false,false}},
    {"Tim",new bool[]{false,false,true,true}},
    {"John",new bool[]{false,true,false,true}}
};

string[] headings = { "Rep Name", "Caller", "Closer", "Manager", "SuperUser" };

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        rowRepeater.DataSource = userRoles;
        rowRepeater.DataBind();
    }
}

protected void rowRepeater_ItemBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Header)
    {
        Repeater headerRepeater = e.Item.FindControl("headerRepeater") as Repeater;
        headerRepeater.DataSource = headings;
        headerRepeater.DataBind();
    }
    else if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
    {
        Repeater columnRepeater = e.Item.FindControl("columnRepeater") as Repeater;
        columnRepeater.DataSource = ((KeyValuePair<string, bool[]>)e.Item.DataItem).Value;
        columnRepeater.DataBind();
    }
}

protected void cbColumnValue_CheckedChanged(object sender, EventArgs e)
{
    CheckBox cb = sender as CheckBox;
    HiddenField hf = cb.Parent.FindControl("hfRoleIndex") as HiddenField;
    int roleIndex = int.Parse(hf.Value); // now you have the column identifier

    Label lbl = cb.Parent.Parent.Parent.FindControl("lblUserName") as Label;
    string userName = lbl.Text; //now you have the row identifier

    //now you can update your data source
    userRoles[userName][roleIndex] = cb.Checked;
}

Method 2

I’ll try something like this:

<asp:GridView ID="OrdersGV" runat="server" AutoGenerateColumns="False">
<Columns>
  <asp:BoundField DataField="UserName" />
  <asp:TemplateField>
    <ItemTemplate>
      <asp:ListView ID="NewsLV" runat="server">
        <ItemTemplate>
          <td id="Td1" runat="server" valign="top" style="width: 30px;">
            <asp:Label ID="Label1" runat="server" Text='<%# Eval("RoleName") %>' Visible='<%# Container.DataItemIndex == 0%>'></asp:Label>
            <div style="padding: 2px;">
              <asp:CheckBox ID="CheckBox1" runat="server" Checked='<%# Eval("IsRoleSelected") %>' />
            </div>
          </td>
        </ItemTemplate>
        <LayoutTemplate>
          <table id="Table1" runat="server" border="0" style="">
            <tr id="itemPlaceholderContainer" runat="server">
              <td id="itemPlaceholder" runat="server">
              </td>
            </tr>
          </table>
        </LayoutTemplate>
      </asp:ListView>
    </ItemTemplate>
  </asp:TemplateField>
</Columns>


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x