frank billy
frank billy

Reputation: 365

Formatting C# Bulleted List like Facebooks comments

I have a requirement where I need to display comments on a web page much like Facebook does (at least formatted as such). I am returning 3 things: User who posted comment, the actual comment, and date posted.

I have everything working fine. I'm getting all the right information from my database and i'm printing it to the screen using an asp Butteted List. I'm starting to believe that this is the incorrect way to do something like this. Ideally, I'd just like to use JavaScript and CSS to format everything but it's all returned in a div with list items.

So right now, my return is this:

User Name comments.... 7/3/2001 05:45:02 PM

I want it to print as:

User Name
comments...
7/3/2001 05:45:02 PM

Here is my c#:

        List<String> theComments = Fetcher.getImageComments(commentsConnectionString, imagePath, 2);
        List<String> theUser = Fetcher.getImageComments(commentsConnectionString, imagePath, 0);
        List<String> theDate = Fetcher.getImageComments(commentsConnectionString, imagePath, 3);


        if (theComments.Count >= 0)
        {


            for (var i = 0; i < theComments.Count; i++)
            {

                commentsList.Items.Add(theUser[i] + "\n" + theComments[i] + "\n" + theDate[i]);
            }
        }

ASP.NET:

<div id="commentsArea">
    <span class="style1">Comments</span><br />
    <asp:TextBox ID="txtComments" runat="server" TextMode="MultiLine" Width="501px" 
        Height="50px"></asp:TextBox>
    <br />
    <asp:ImageButton ID="btnPostComment" runat="server" ImageUrl="~/Images/Post.png" onclick="btnPostComment_Click" />
    <br />
    <br />
    <asp:BulletedList ID="commentsList" runat="server" Font-Names="Calibri" Style="text-align: center" Width="501px">
    </asp:BulletedList>
</div>

I have tried using Environment.NewLine and \n but no luck. I am using CSS to word-wrap which helps, but still doesn't format it correct. Am I going down the right path? I appreciate any helpful advice

Upvotes: 2

Views: 594

Answers (2)

Jon P
Jon P

Reputation: 19772

Assuming you can get a consolidated list of Comments, wrong tool for the job basically.

I'd recomend an ASP.net repeater

ASPX:

<asp:Repeater ID="rptComments" runat="server">
    <HeaderTemplate>
        <ul class="comments">
    </HeaderTemplate>
    <ItemTemplate>
        <li>
            <div class="user"><%# DataBinder.Eval(Container.DataItem, "User") %></div>                                                
            <div class="comment"><%# DataBinder.Eval(Container.DataItem, "Comment") %></div>
            <div class="date"><%# DataBinder.Eval(Container.DataItem, "Date") %></div>
        </li>
    </ItemTemplate>
    <FooterTemplate>
        </ul>
    </FooterTemplate>
</asp:Repeater>

You'll need to adjust "User", "Comment" & "Date", dpending on the Comment object.

C#

List<Comment> comments = //Get Comments List
//Maybe: Fetcher.getImageComments(commentsConnectionString, imagePath);

rptComments.DataSource = comments;
rptComments.DataBind();

Plan B if you cant get a consolidated list.

Use HTML as a control by adding an ID and runat=server

ASPX

<ul id="lstComments" runat="server">
    <li id="lstTemplate" runat="server" visible="false">
        <div class="user">{0}</div>
        <div class="comment">{1}</div>
        <div class="date">{2}</div>
    </li>
</ul>  

C#

List<String> theComments = Fetcher.getImageComments(commentsConnectionString, imagePath, 2);
List<String> theUser = Fetcher.getImageComments(commentsConnectionString, imagePath, 0);
List<String> theDate = Fetcher.getImageComments(commentsConnectionString, imagePath, 3);

string template = lstTemplate.InnerHtml;
StringBuilder innerItems = new StringBuilder();

if (theComments.Count >= 0)
{
   for (var i = 0; i < theComments.Count; i++)
   {
      innerItems.AppendFormat(template, theUser[i], theComment[i], theDate[i]);
   }

   lstComments.InnerHtml = innerItems.ToString();

}

Maker sure you have using System.Text as part of your using statements, this is required for StringBuilder.

Upvotes: 1

Omer Iqbal
Omer Iqbal

Reputation: 2293

First thought

Initially, I thought you could force a line break by using a br or put p inside your li:

commentsList.Items.Add("<p>" + theUser[i] + "</p><p>" + theComments[i] + "</p><p>" + theDate[i] + "</p>");

or

commentsList.Items.Add(theUser[i] + "<br/>" + theComments[i] + "<br/>" + theDate[i]);

In first case, a line break will be added before the text and after. In the second, a line break will be added after text.

The best though would be to have your li contain divs:

commentsList.Items.Add("<div>" + theUser[i] + "</div><div>" + theComments[i] + "</div><div>" + theDate[i] + "</div>");

And then mark that div as block div by putting the following in css for your div:

display:block

This would ideally force div to behave pretty much like a p. Div is preferable because in the future it allows you more control over changing the layout as opposed to p or br.

BUT - Doesn't work

However, as you experimented and I found out, the asp:BulletedList encodes the HTML tag, and thus you do not get a line break, you instead get encoded html :-)

Other solutions

Either do not use a list item, and instead just put in divs for each comment, and format it. Pretty much. This is doable by adding the display property in css on the div and make it list-item:

display: list-item;

The other would have to be just make bulleted list not encode html. However, ASP.NET treats li to be a single line item and thus encodes the HTML. I searched around, including on StackOverflow, looks like there isn't a workaround for this. So your best bet would be to see if you can use another HTML element instead of the bullet list.

EDIT: I updated to show the actual code based on additional comments so it will provide more clarify on the solution.

Upvotes: 1

Related Questions