Search code examples
c#htmlasp.nethtmltextwriter

HtmlTextWriter adding a class to an element which already has one


I'm processing some objects in batches and generating some markup for them to be used within a carousel.

When I'm on the last item in the batch i'd like to give that item a class so that I can style it accordingly.

I'm able to give the item an inline style to get it how I want however, if i try to add a class to the element (which has already been given a class) it doesn't show in the markup. Very strange - can you not assign more than one class to an element, does it not append the class to the existing one?

Here is the code I'm working with, hopefully someone can advise:

public static string CreateCarouselMarkup(BrandCollection carouselBrands)
{
    StringWriter stringWriter = new StringWriter();
    using (HtmlTextWriter textWriter = new HtmlTextWriter(stringWriter))
    {
        //List items
        textWriter.RenderBeginTag(HtmlTextWriterTag.Li);

        int idx = 0;
        foreach (Brand brand in carouselBrands)
        {
            idx++;
            textWriter.AddAttribute(HtmlTextWriterAttribute.Href, string.Format("/brands/{0}/", brand.SeoInfo.SeoUrl));
            textWriter.RenderBeginTag(HtmlTextWriterTag.A);

            textWriter.AddAttribute(HtmlTextWriterAttribute.Class, "carousel-image");
            textWriter.AddAttribute(HtmlTextWriterAttribute.Src, brand.Logo);
            textWriter.AddAttribute(HtmlTextWriterAttribute.Alt, brand.Title);

            //If we are on the last item or last item for this batch
            if (idx == carouselBrands.Count())
            {
                textWriter.AddAttribute(HtmlTextWriterAttribute.Class, "last-img");
            }
            textWriter.RenderBeginTag(HtmlTextWriterTag.Img);

            textWriter.RenderEndTag();//End Img tag
            textWriter.RenderEndTag();//End A tag
        }

        textWriter.RenderEndTag();//End Li tag
    }

    return stringWriter.ToString();
}

Here is a small sample of the markup that is rendered:

<ul class="bjqs" style="height: 80px; width: 100%; display: block;">
   <li class="bjqs-slide" style="height: 80px; width: 100%; display: list-item;">
      <a href="/brands/kaldewei/">
          <img class="carousel-image" src="/Images/Brands/Logos/kaldewei_logo_02.png" alt="Kaldewei">
      </a>
      <a href="/brands/iotti/">
          <img class="carousel-image" src="/Images/Brands/Logos/Iotti-logo.jpg" alt="Iotti">
      </a>
      <a href="/brands/ellis/">
          <img class="carousel-image" src="/Images/Brands/Logos/Ellis-logo.jpg" alt="Ellis">
      </a>
      <a href="/brands/burgbad/">
          <img class="carousel-image" src="/Images/Brands/Logos/Burgbad-logo.png" alt="Burgbad">
      </a>
  </li>
  <li class="bjqs-slide" style="height: 80px; width: 100%; display: none;">
     <a href="/brands/pura/">
         <img class="carousel-image" src="/Images/Brands/Logos/Pura-logo.png" alt="Pura">  
     </a>
  </li>
</ul>

I'm expecting the class last-img to be applied to the last images in each batch (i don't want to use a CSS3 property for this). In the above example, it would be applied to burgbad and pura.


Solution

  • Well, the interesting thing for me when running your code is that it renders class attribute twice:

    <ul>
        <li>
            <a href="/brands/uno/"><img class="carousel-image" src="uno" alt="uno" /></a>
            <a href="/brands/dos/"><img class="carousel-image" src="dos" alt="dos" /></a>
            <a href="/brands/tres/"><img class="carousel-image" src="tres" alt="tres" class="last-img" /></a>
        </li>
    </ul>
    

    In any case, it is adding the attribute, though the rendered markup is "off". So:

    textWriter.AddAttribute(HtmlTextWriterAttribute.Class, idx == carouselBrands.Count() ? "carousel-image last-img" : "carousel-image");
    

    renders:

    <ul>
        <li>
            <a href="/brands/uno/"><img class="carousel-image" src="uno" alt="uno" /></a>
            <a href="/brands/dos/"><img class="carousel-image" src="dos" alt="dos" /></a>
            <a href="/brands/tres/"><img class="carousel-image last-img" src="tres" alt="tres" /></a>
         </li>
    </ul>
    

    Hth....