Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Henrik Vincent 122 posts 616 karma points
    Dec 01, 2017 @ 10:52
    Henrik Vincent
    0

    Different CSS classes on each element in a foreach loop

    Hi guys

    I'm making a news site, where I have 7 focus posts on the frontpage. Each of these have different Bootstrap CSS classes.

    How can I add these classes when doing a foreach loop in my partial view?

    My markup:

    <div class="row focusGallery">
        <div class="col-lg-8 col-md-12 col-sm-12 focusGalleryItem">
            <div class="focusGalleryItemImage">
                <img src="http://via.placeholder.com/370x370" alt="Placeholder">
            </div>
            <div class="focusGalleryItemContent">
                <a href="#">Post title</a>
            </div>
        </div>
        <div class="col-lg-4 col-md-6 col-sm-6 focusGalleryItem">
            <div class="focusGalleryItemImage">
                <img src="http://via.placeholder.com/370x370" alt="Placeholder">
            </div>
            <div class="focusGalleryItemContent">
                <a href="#">Post title</a>
            </div>
        </div>
        <div class="col-lg-4 col-md-6 col-sm-6 focusGalleryItem">
            <div class="focusGalleryItemImage">
                <img src="http://via.placeholder.com/370x370" alt="Placeholder">
            </div>
            <div class="focusGalleryItemContent">
                <a href="#">Post title</a>
            </div>
        </div>
        <div class="col-lg-8 col-md-12 col-sm-12 focusGalleryItem">
            <div class="focusGalleryItemImage">
                <img src="http://via.placeholder.com/370x370" alt="Placeholder">
            </div>
            <div class="focusGalleryItemContent">
                <a href="#">Post title</a>
            </div>
        </div>
        <div class="col-lg-4 col-md-4 col-sm-12 focusGalleryItem">
            <div class="focusGalleryItemImage">
                <img src="http://via.placeholder.com/370x370" alt="Placeholder">
            </div>
            <div class="focusGalleryItemContent">
                <a href="#">Post title</a>
            </div>
        </div>
        <div class="col-lg-4 col-md-4 col-sm-12 focusGalleryItem">
            <div class="focusGalleryItemImage">
                <img src="http://via.placeholder.com/370x370" alt="Placeholder">
            </div>
            <div class="focusGalleryItemContent">
                <a href="#">Post title</a>
            </div>
        </div>
        <div class="col-lg-4 col-md-4 col-sm-12 focusGalleryItem">
            <div class="focusGalleryItemImage">
                <img src="http://via.placeholder.com/370x370" alt="Placeholder">
            </div>
            <div class="focusGalleryItemContent">
                <a href="#">Post title</a>
            </div>
        </div>
    </div>
    

    My view (just a basic list elements with "post" doctype, so far).

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
    @using Umbraco.Web
    
    @{
        var selection = Umbraco.TypedContentAtXPath("//post").OrderBy("UpdateDate desc").Take(7);
    }
        <div class="row focusGallery">
        @foreach(var item in selection){
            <div class="focusGalleryItem">
                <div class="focusGalleryItemImage">
                    <img src="http://via.placeholder.com/370x370" alt="Placeholder">
                </div>
                <div class="focusGalleryItemContent">
                    <a href="#">@item.Name</a>
                </div>
            </div>
        }
        </div>
    

    How would you suggest adding the specific Bootstrap col-classes to each of the seven elements.

    Would it be possible making some sort of array, and then adding those based on i++ or something like that?

    Thanks in advance

    Best

    Henrik

  • Steve Morgan 1348 posts 4457 karma points c-trib
    Dec 01, 2017 @ 11:35
    Steve Morgan
    2

    Hi,

    I'd just use a quick switch - something like

    var boostrapClass = "";
    var i = 1;
         foreach (var item in selection)
            {
               switch (i)
                {
                    case 1:
                    case 3:
                        bootstrapClass = "col-md-9";
                        break;
                    case 2:
                    case 4:
                        bootstrapClass = "col-md-6 col-sm-6";
                        break;
                    // 5,6,7 
                    default:
                        bootstrapClass = "col-md-4 col-sm-12";
                        break;
                }
                i++;
    
                <div class="@bootstrapClass focusGalleryItem">
                    <p>Magic here </p>
                </div>
            }
    

    Change the cases to meet your requirements.. make the default all others. The above sets 1,3 and 2,4 and lets 5,6,7 fall to the default.

    hope that helps

    Steve

    UPDATED To init var in the correct place!

  • Henrik Vincent 122 posts 616 karma points
    Dec 01, 2017 @ 12:10
    Henrik Vincent
    100

    Hi Steve!

    Thanks alot for the quick reply and fix.

    I did some minor tweaking to your example, since I kept getting the same classes on every element.

    Figured out it was because i=1 was set inside the foreach loop, which made the switch start over at each element.

    My final code look as follows:

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
    @using Umbraco.Web
    
    @{
        var selection = Umbraco.TypedContentAtXPath("//post").OrderBy("UpdateDate desc").Take(7);
        var boostrapClass = "";
        var i = 1;
    }
        <div class="row focusGallery">
        @foreach(var item in selection){
                switch (i)
                {
                    case 1:
                    case 4:
                        boostrapClass = "col-lg-8 col-md-12 col-sm-12";
                        break;
                    case 2:
                    case 3:
                        boostrapClass = "col-lg-4 col-md-6 col-sm-6";
                        break;
                    default:
                        boostrapClass = "col-lg-4 col-md-4 col-sm-12";
                        break;
                }
                i++;
            <div class="@boostrapClass focusGalleryItem">
                <div class="focusGalleryItemImage">
                    <img src="http://via.placeholder.com/370x370" alt="Placeholder">
                </div>
                <div class="focusGalleryItemContent">
                    <a href="@item.Url">@item.Name</a>
                </div>
            </div>
        }
        </div>
    

    Thanks a whole lot for showing me this example. Haven't worked with switches before, but it works like a charm!

    Have a great friday and weekend :)

    Best

    Henrik

    PS: I'm marking this post as the solution, for the future users, so future users will place the i=1 outside the foreach loop.

  • Steve Morgan 1348 posts 4457 karma points c-trib
    Dec 01, 2017 @ 13:33
    Steve Morgan
    1

    Nice spot - that will teach me for posting untested code :) - I've updated my post so nobody copies the error.

  • Henrik Vincent 122 posts 616 karma points
    Dec 01, 2017 @ 14:05
    Henrik Vincent
    0

    Hehe happens. The switch in itself still worked like a charm.

    I very much appreciate you taking your time to post the code.

    Switches are super awesome. I can see myself using those for a lot of different things in the future.

    So you didn't just solve my problem, but gave me a really great tool for other projects as well.

    So once again. Thank you!

  • George 3 posts 73 karma points
    Dec 01, 2017 @ 15:41
    George
    0

    While a switch seems to do the job just fine, you can also iterate over your collection using an IsHelper, which allows you to modify items in your collection based on the index or other properties of the current item. A quick example is shown in the documentation:

    <ul>
    @foreach(var item in CurrentPage.Children)
    {
        <li class="@item.IsFirst("first","not-first")">@item.Name</li>
    }
    </ul>
    
  • Steve Morgan 1348 posts 4457 karma points c-trib
    Dec 01, 2017 @ 15:59
    Steve Morgan
    1

    George - that's a good tip but from the original post :

    "..7 focus posts on the frontpage. Each of these have different Bootstrap CSS classes."

    I read as there's a different size on some of the seven, not necessarily just the first item.

    It's also probably worth noting that once you start getting to lots of logic in your view it might be time to hijack the route and create some custom view models to keep the view clean.

  • Henrik Vincent 122 posts 616 karma points
    Dec 08, 2017 @ 13:21
    Henrik Vincent
    0

    Hi George

    Thanks for the tip. It will definitely by useful in other cases. But as Steve also mentions, in this case I need three different CSS classes added:

    col-lg-8 col-md-12 col-sm-12

    col-lg-4 col-md-6 col-sm-6

    col-lg-4 col-md-4 col-sm-12

    Are there others of there.

    .IsOdd and .IsEven perhaps. I'd see those being really usefull in other cases.

    Best

    Henrik

  • Steve Morgan 1348 posts 4457 karma points c-trib
    Dec 08, 2017 @ 21:52
    Steve Morgan
    0

    Hi Henrik,

    The easiest thing to do here is to do a modulus (think of as a divide and check the remainder) check. https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/modulus-operator

    List<int> someList = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8
        , 9, 10 };
    foreach(var someItem in someList)
    {
        Console.WriteLine("****    " + someItem + " ******");
        if(someItem % 2 == 0)
            // it's even
            Console.WriteLine("it's even");
    
        if(someItem % 2 == 1)
            // it's odd
            Console.WriteLine("it's odd");
    
        if(someItem % 3 == 0)
            // it's a multiple of three
            Console.WriteLine("it's a multiple of three");
    }
    
Please Sign in or register to post replies

Write your reply to:

Draft