An alternate way of alternating row colors



  • I'm in the middle of refactoring a really heinous mess of PHP code -- it's so totally awful that picking out just one WTF from it wouldn't do it justice.

    Because it's SO bad, it's possible that I've gone overboard on making its replacement just as clean and minimal as possible. Take, for example, the means I hit upon to alternate row colors in the template files. I named the css styles "row0" and "row1" so that I could do this:

        <tr class="row<?=$counter++%2?>">


    As it turns out, one of the other programmers that I'm working with either didn't look at any of my code before jumping into working on part of the project, or just didn't grok my logic. His templates have code like this all throughout them:

        <?php
    $row = 0;
    foreach($lines as $k=>$v) {
    if($row % 2 == 0) {
    $class = 'row0';
    } else {
    $class = 'row1';
    }
    $row++;

    ?>
    <tr class="<?=$class?>">
    // row data here
    </tr>
         <?php } ?> 

    The truly painful thing is, this is still at least 1000% better than the code we started with. <*sigh*>



  • And you instanced $counter where, exactly?

    I laud your attempt to clean up the app, but honestly, it's not the most readable thing in the world.  I wonder whether the maintenance developers will immediately grok it.  Oh, wait--we have an example that they don't.  As much as I hate to throw this back at you, I have to say that there's such a thing as being too clever. 

     



  • You know you don't need scripting of any sort to alternate row style, don't you?



  • Neither of those look like a WTF to me. I must admit if it was me I'd probably make it a function for <?= GetRowCSS($counter++, "therelevanttable") ?>, which is more code than your dodgy way, but more maintainable imo.

    Tchize, assuming you mean you can do it with just HTML/CSS (and you're not gonna use javascript or something) I'd love to see your answer that works on a dynamically generated table of data...



  • @tchize said:

    You know you don't need scripting of any sort to alternate row style, don't you?

    Does this method work in real-world browsers, or only in a hypothetical browser that correctly implements all of CSS and HTML?



  • @fyjham said:

    Tchize, assuming you mean you can do it with just HTML/CSS (and you're not gonna use javascript or something) I'd love to see your answer that works on a dynamically generated table of data...

    For that matter, I'd love to see your answer for generating dynamic table data without using script.  In this case, I assume script to include php, since the Tchize's post was referring to php when stating that it's unnecessary to use script to do what the OP accomplished with script.

     

    ...or something like that.



  • Why does everyone use the %2 method? This is what I use:

    <?php
        odd = false;
        foreach($lines as $k=>$v) {
          echo '<tr class="'.($odd ? 'odd' : '').'">data</tr>';
          $odd = !$odd;
        }
    ?>
    


  • @mrprogguy said:

    And you instanced $counter where, exactly?


    In the file that serves as the controller for the application. The overall architecture's basically MVC, with the template files I'm talking about serving as the view.

    I will admit that I'm pretty old-school as to how I define "template": something with placeholders in it that a graphic designer can easily understand & modify (not that there's a graphic designer doing the work NOW, but who knows, there may be in the future). I don't consider "code with some HTML in it" to be a true template, but I'll grant that not everyone sees the distinction.

     

    @mrprogguy said:

    I wonder whether the maintenance developers will immediately grok it.  Oh, wait--we have an example that they don't.

    Um, nope. "B" (the coder who's work I referenced in the first post) is an application developer, not a maintainer (and is incidentally one of the people responsible for the million-line mess I'm cleaning up in the first place). The two n00bs that have been brought in since the rewrite project started have both raved about how simple and easy to work with the new codebase is.

    BTW I'm not kidding about the million lines I started with. The application has been completely re-architected and is now down to about 1/8 of its original size although several major new features have been added. (There's still about 60K lines awaiting rewrite but those will probably total < 5K when I'm done -- they're the worst of the lot, which is why they have been left until last.) Hundreds of pre-existing bugs have so far been fixed in the rewrite. And it's remained constantly in production throughout.

    And no -- I didn't get rid of  800K of cruft just by compressing if/elses into cryptic one-line echo statements. <*g*>




  • And you instanced $counter where, exactly?

    PHP doesn't require you to instance variables before using them. It's not good form, but the code's perfectly valid. I'm not sure if it even throws a warning.

     



  • I honestly prefer the second way, as clumsy as it is.  "row0" and "row1" are not very good CSS class names and use of the <?= shorthand makes me puke.  Meh, it's your app, though. 



  • Couple things.

    1. "row0" and "row1" aren't the best class names to use here. They accurately describe the first two rows, but once you get down to, say, rows 45 and 46, applying a class of "row0" doesn't make much sense. This is why people generally use classes named "even" and "odd" for this kind of thing – it is immediately understandable and semantically correct.
    2. Although your little snippet is quite clever, it strikes me as being a bit too clever. It is hard to read, partly because it's so succinct, but also because the class names don't give any hint as to what the code is trying to accomplish. You're also totally locked into using row0 and row1 as your class names. And what happens if you want to go to a two-on, two-off design?

    I'll admit that these are somewhat picky criticisms. But while compact and clever, I think your solution has some maintenance issues.



  •  

     @movzx said:

    Why does everyone use the %2 method? This is what I use:

    <?php
    odd = false;
    foreach($lines as $k=>$v) {
    echo '<tr class="'.($odd ? 'odd' : '').'">data</tr>';
    $odd = !$odd;
    }
    ?>

    And if you want to stripe every three rows?

     

    use of the <?= shorthand makes me puke

    Under

    what circumstance is this a good and bad device to use?  I find <td
    class="<?=$class?>"> easier than <?php print '<td
    class="' . $class . '">'?> to read and type frankly.



  •  Short tags are pretty much always a bad idea to use, be it for portability or if you suddenly decided to output an XML page and then wonder why PHP is flinging errors your way like a monkey with bowel problems.

    Also, why would you want to stripe every 3 rows? It seems to me that'd go against any form of usability as it'd just confuse people.



  • @movzx said:

    Why does everyone use the %2 method? This is what I use:

    <?php
        odd = false;
        foreach($lines as $k=>$v) {
          echo '<tr class="'.($odd ? 'odd' : '').'">data</tr>';
          $odd = !$odd;
        }
    ?>
    


    Interesting method, probably faster than doing a mod every loop too.  The only issue I could see if that if you're doing additional logic, such as excluding a row, things could get hairy if you didn't flip-flop your $odd variable at the right time.


  • @elbekko said:

    Also, why would you want to stripe every 3 rows? It seems to me that'd go against any form of usability as it'd just confuse people.

     

    Probably. But the issue isn't "why would you want to stripe three rows", it's "would you ever want to do it differently". This method has zero flexibility.



  • @Carnildo said:

    Does this method work in real-world browsers, or only in a hypothetical browser that correctly implements all of CSS and HTML?

    Come on. I'm not very experienced in PHP and CSS, but I got a servey site running with nicely css-configurable tables that works with Safari, Firefox and IE 7. Alternating colors worked immediately, I only needed to tweak things a bit of tweaking for the borders. They would not look exactly equal in all browsers, but the row0/row1 code cannot do that either.

     For good examples, take a look here: http://icant.co.uk/csstablegallery/, and you can see the effect in your browser immediately.



  • @TGV said:

    For good examples, take a look here: http://icant.co.uk/csstablegallery/, and you can see the effect in your browser immediately.

    @http://icant.co.uk/csstablegallery/ said:
    <tr class="odd">

    Tchize appeared to be claiming that you don't even need server-side scripting to make tables with alternating row styles. Your example still requires that the odd rows are marked with a separate class.
    Your challenge is to produce a table with alternating row styles where the HTML for every row is identical, not use Javascript and have it work in the browsers you listed.



  •  @venutip said:

    @elbekko said:

    Also, why would you want to stripe every 3 rows? It seems to me that'd go against any form of usability as it'd just confuse people.

     

    Probably. But the issue isn't "why would you want to stripe three rows", it's "would you ever want to do it differently". This method has zero flexibility.

    True, but it is the most efficient one.



  • If you're doing such a major refactoring job, why not just go the whole hog and use a proper templating engine (e.g. Smarty)? It certainly makes maintaining / changing things far easier for future developers, and has the added bonus of completely separating application logic from display.



  •   tr, tr + tr + tr, tr + tr + tr + tr + tr{ background-color:red; }
      tr + tr, tr + tr + tr + tr, tr + tr + tr + tr + tr + tr {background-color:green; }

     Just limit your table to outputonly 6 rows at a time, and this will work fine.  It can also be expanded if you need more rows.



  • @durnurd said:

      tr, tr + tr + tr, tr + tr + tr + tr + tr{ background-color:red; }
      tr + tr, tr + tr + tr + tr, tr + tr + tr + tr + tr + tr {background-color:green; }

     Just limit your table to outputonly 6 rows at a time, and this will work fine.  It can also be expanded if you need more rows.


    Now that's far easier to read! Maybe we should put our loop in the CSS file instead!



  • Why even bother doing this server side? i just use javascript for stuff like this, just get a stripe method online or write one yourself and then pass it the table body and the colours you want. I think it's neater because i like to keep all that display/formatting stuff out of the server side layer. Just worry about the data server side and worry about colours, layout etc client side.
    of course this assumes the client has javascript but i think these days unless you're devving for some obscure device that's a a pretty safe bet.


  • Garbage Person

    @element[0] said:

    Why even bother doing this server side? i just use javascript for stuff like this, just get a stripe method online or write one yourself and then pass it the table body and the colours you want. I think it's neater because i like to keep all that display/formatting stuff out of the server side layer. Just worry about the data server side and worry about colours, layout etc client side. of course this assumes the client has javascript but i think these days unless you're devving for some obscure device that's a a pretty safe bet.
     

    <font size="7">NO.</font>

    I will never fucking understand why the fucktwat bitchtits that call themselves developers these days will PREFER to rely upon clientside behaviors everywhere they fucking can. It's like a bastardized fucking attempt at MVC in which you end up with MVVC or MV(VC) instead. The PHP that generates the fucking HTML is *ALREADY* the view module and is ALREADY generating "display/formatting" stuff REGARDLESS OF WHAT YOU THINK IT'S DOING. HTML is VIEW. Period. It's too tightly coupled to display logic to be anything else, regardless of what W3C fundies swear and profess about it being "Like XML and with no stipulations on how it's displayed." Javascript is NOT a given - in fact, Javascript was more likely to run in any randomly sampled Netscape 3 era browser than it is today. Users disable it ALL THE FUCKING TIME because they're being misled about how it's an attack vector against them (when in reality the attack vector is their own idiocy, but that's a different matter).

     Basically, you have a choice - you can rely on clientside behavior and have it work most of the time, or you can do it serverside and have it work ALL of the time. The choice is fucking obvious as far as I'm concerned - user experience is crucially more important than a tiny bit of "maintainability" (which is arguable because Javascript is so non-uniform in its implementation that it's a collossal PITA to maintain anyway)

     In short, if you'd do this in Javascript, FUCK YOU and I pray you and I never have to work together because I'll eat your fucking liver.



  • %2? Check out this nightmare:

    	$cat = "";
    	for ($i = 0; $i < db_num_rows($result); $i++) {
    		$row = db_fetch_assoc($result);
    		if ($cat != $row['category']) {
    			rawoutput("");
    			output($row['category']);
    			rawoutput(":");
    			$cat = $row['category'];
    		}
    
    	rawoutput("");
    	rawoutput("");
    	output_notl("`&amp;%s`0", $row['formalname']);
    	rawoutput("",true);
    	output_notl("`^%s`0", $row['version']);
    	rawoutput("");
    	output_notl("`^%s`0", $row['moduleauthor'], true);
    	rawoutput("");
    [ ... snip ... ]
    


  • If you're running a respectable site where clients knowingly go to get a service, then you generally can require javascript without too much complaint.  Or would you prefer the internet to continue to look like 1995 vomited all over it?

    But yeah, run-time client-side design is a little silly.



  • @Weng said:

    ...I pray you and I never have to work together because I'll eat your fucking liver.

    Sorry, man, I dibbsed it a couple of days ago for when I get my next transplant. 



  • @Weng said:

    rant

    I think you'll find many major sites these days rely heavily on client side javascript for their websites to run properly.

    For example look at AJAX and major sites like gmail, facebook, digg etc.

    Sure it's good practice to support clients on mobile devices etc but this can be done via css mostly. Also delivering a decent user experience without javascript is difficult, and by good user experience i don't mean just working, i mean nice to use. Relying on traditional methods like posting forms etc provides a very clunky and disconnected user experience because of page refreshes / re-rendering. It is also difficult to create decent server side implementations of features like sortable tables and many interface elements not natively supported by html.

    Your attitude belongs back in the 90's quite frankly, you will need to update your web skills to encompass the emerging web 2.0 technologies which are becoming very prevalent these days or you will soon find it difficult to get jobs as a web application programmer.

    @Weng said:

    FUCK YOU and I pray you and I never have to work together because I'll eat your fucking liver.

    Quite the contrary, FUCK YOU, i hope i never have to work with your outdated shitty code. Get with the times it's 2008.



  • @element[0] said:

    Quite the contrary, FUCK YOU, i hope i never have to work with your outdated shitty code. Get with the times it's 2008.

    Now calm down!  Don't git 'ur liver all work'd up all on account 'a some dopey Wurl'WhyyWebb conflag'ration!  'Ur gizzards gots to be talk'd quiet-like to 'em, s'as not 'ta excite the biles!


  • Garbage Person

    If you're writing a fucking web 2.0 newfag application that depends on AJAX for its user experience anyway, then go ahead and use fucking Javascript.

    However outside the pretty world of Web 2.0, most applications don't need sortable tables, or rich user interfaces. Most real world applications (like "this application runs our whole fucking business and we actually make money" applications) consist primarily of telling the computer to fucking do things - i.e. filling out forms, which is something HTML is very bloody fucking good at all by itself. On the other end, it spits out the information you need in EXACTLY the format you need it, no wasting time sorting columns or creating custom views bullshit. Leave the development work to the fucking developers, and give the users what they want, not the tools to take what you give them and translate it into what they actually want.

    I couldn't give a rat's ass about supporting mobile platforms because bloody fucking nobody actually uses their fucking mobile device to do work beyond reading fucking email. In the RARE instance a device is used to accomplish actual work, it's invariably running Windows Mobile with a .Net app running aboard, because mobile web browsers are so fucking gimptastic (yes, even your bloody goddamn iPhone).

     This business is about providing the customer what they need, not evangelising a technology and shoehorning it into everything you do. If an application will benefit THAT MUCH from Javascript, then yes, it's a place for Javascript to be used - but there's not a damn fucking reason for Javascript to be used more than sparingly for anything that can be just as well accomplished with some HTML and a form. OH GOD NO THE PAGE REFRESHES AFTER THE USER SUBMITS THE FORM! THE FUCKING FORM HAS TO GO AWAY ANYWAY! GOD FUCKING FORBID WE ACTUALLY GO TO A NEW PAGE ACKNOWLEDGING THE SUBMISSION INSTEAD OF PUSHING THE FORM CONTENTS UPSTREAM WITH AJAX AND REWRITING THE CURRENT PAGE TO ACKNOWLEDGE THE SUBMISSION.



  •  wow, you're just sad. while i concur with you on the point that forms do accomplish many tasks without the need for javascript and they are useful, many applications require something beyond the ugly backend applications i'm guessing you write. User experience is not something to be neglected and treated as flippantly as you seem to. and when you say html returns "EXACTLY the format you need" who are you talking about? that the user needs? if they needed to see for example order by time, and then by state, would you make a server trip to do that? that's pretty lame when 1 javascript include would accomplish the same job, for all the different columns in any order without a page refresh.

    Also things like form validation are better achieved client side, sure they should be checked again before they go into the db but it is a lot more user friendly checking client side than doing a round trip in terms of user experience. If you want to continue writing old fashioned web pages feel free to but in the end you will be left behind. What i'm reading from your post is more of a "I don't know anything web programming newer than 2003 and i'm kind of scared of it". i think next time you are writing a a page yo should really think about usability as well as stability and reliability.

    I think you need to expand your thinking a bit and realise web pages can be something more than just a page of information, they can be more like applications in terms of the way people interact with them, using technologies like AJAX and JSON give you a lot of flexibility in interface design.

    Also dude, calm down, it sounds like you have some personal grudge with web 2.0

    P.S. you can stop writing in uppercase by pressing the "Caps-Lock" key, it's up on the left hand side of your keyboard



  • @durnurd said:

      tr, tr + tr + tr, tr + tr + tr + tr + tr{ background-color:red; }
      tr + tr, tr + tr + tr + tr, tr + tr + tr + tr + tr + tr {background-color:green; }

     Just limit your table to outputonly 6 rows at a time, and this will work fine.  It can also be expanded if you need more rows.

    You don't need neither scripting nor CSS for alternating row colors. Just write the table directly with different formatting for each row into a database. The table will already be properly colored when you retrieve it.



  • @element[0] said:

    @Weng said:
    rant

    I think you'll find many major sites these days rely heavily on client side javascript for their websites to run properly.

    For example look at AJAX and major sites like gmail, facebook, digg etc.

    Sure it's good practice to support clients on mobile devices etc but this can be done via css mostly. Also delivering a decent user experience without javascript is difficult, and by good user experience i don't mean just working, i mean nice to use. Relying on traditional methods like posting forms etc provides a very clunky and disconnected user experience because of page refreshes / re-rendering. It is also difficult to create decent server side implementations of features like sortable tables and many interface elements not natively supported by html.

    Your attitude belongs back in the 90's quite frankly, you will need to update your web skills to encompass the emerging web 2.0 technologies which are becoming very prevalent these days or you will soon find it difficult to get jobs as a web application programmer.

    @Weng said:

    FUCK YOU and I pray you and I never have to work together because I'll eat your fucking liver.

    Quite the contrary, FUCK YOU, i hope i never have to work with your outdated shitty code. Get with the times it's 2008.

    Wow. Major WTF on the both of you...

    JavaScript has its place. Replacing CSS is not that place.

    If you have multiple technologies available, and you either:
    1. Use the wrong one for a given task
    2. Insist on refusing to use a technology even where it's useful or required
    3. Think any technology on the list is the only solution/never a solution for any problem

    Then you're a /bin/fscking idiot.

    I hope I get to work with the both of you someday! The record for me canning someone is 5 hours after hire, and I'd love to break it with good cause.



  • I somehow forgot :nth-child selector is not supported yet, sorry.



  • In my eyes the boolean 'odd'/'even' method is the best way to go, and just do it server side. With the '%' way sure you can go 'what if I want a differently coloured row every 3 rows'? But then I say 'what if I want 2 white rows, 2 gray rows, then 3 white rows, then again 2 gray, 2 white, 2 gray, 3 white, 2 gray, 2 white, 2 gray, 3 white,... etc' (2-2-3-2-2-2-3-2-2-2-3-...). It's not a common use case, while for a general representation of data an 'odd'/'even' approach is more than common. If it's not general data, but some special data which requires special markup, sure you should write a special routine for that specific case.

    Doing this client-side with Javascript is just horrible, though. That's wasting the user's computing power every time the page loads, while when doing this server side there's a good chance the page is either buffered/cached server or client side or it takes way less computing time on the server side.

    Sorting tables and other interactive Web 2.0 goodies however. Yes, Javascript is nice for that.



  •     $("table.displayTable tr").each( function(i) {
            if (i % 2 == 0) {
                $(this).css("background-color", "#dedede");
            }
            else
            {
                $(this).css("background-color", "#ffffff");
            }
            });

    Wow, that was really hard to alternate colors of the rows with JSP and JavaScript.  



  • @elbekko said:

    Also, why would you want to stripe every 3 rows? It seems to me that'd go against any form of usability as it'd just confuse people.

    Why would it be confusing? I've seen that done in print books before, and it is still easy to read. Actually, I've seen a variety of striping schemes. I've never seen any comparisons to decide which is the optimal one, though.



  • Striping is often seen as a reading aid, although the actual effects are hard to measure: Zebra, Zebra Followup

    Mostly it just looks pretty, and that's enough for me.

    Adding a longer stripe pattern can be a way of adding more relevant information to the table, but as with all additions you can make, it should be done with care.



  • @tchize said:

    I somehow forgot :nth-child selector is not supported yet, sorry.
    Almost fell in the same boat. TRWTF is that CSS 3 doesn't allow XPath for selectors.☺



  • @elbekko said:

    Also, why would you want to stripe every 3 rows?

    Because that's how they did the stat charts in the AD&D first edition rulebooks.

    (Braces for stampede of TDWTF readers racing to bookshelves)



  • @dhromed said:

    Striping is often seen as a reading aid, although the actual effects are hard to measure: Zebra, Zebra Followup

    Mostly it just looks pretty, and that's enough for me.

    Adding a longer stripe pattern can be a way of adding more relevant information to the table, but as with all additions you can make, it should be done with care.

     

    The researcher, and much of the research audience for the second article are from Australia. They prefer Zebra's, because they are used to them walking around.

    I myself prefer dotted data tables, because there are leopards nearby.



  • @venutip said:

    Probably. But the issue isn't "why would you want to stripe three rows", it's "would you ever want to do it differently". This method has zero flexibility.

     

    I was initially going to agree with you :-) but point out that in this case I have pretty much 100% control over the appearance of this particular app. Then I started thinking about it, and have to disagree with the "zero" flexability assessment. For instance, if on some pages I wanted to have three different row colors alternating, all I'd have to do is to add a row2 class and use  mod 3 instead of mod2. Or I could define color0 and color1 if I wanted to use different alternating colors elsewhere.

    Overly clever? Yeah, well, maybe a bit. (This is why I like bouncing stuff off other people.) I can't remember who it was that said "if you think you've written something very clever and are very proud of it, better rip it out because it's a sure bet that it's bad" (paraphrased). OTOH that's definitely not going to happen in this case -- my bosses would have my ass if I spent any time rewriting stuff that works perfectly well. Que sera sera -- that's life in the real world.



  • @Weng said:

    <font size="7">NO.</font>

    I will never fucking understand why the fucktwat bitchtits ...REGARDLESS OF WHAT YOU THINK IT'S DOING. ...ALL THE FUCKING TIME ...FUCK YOU and I pray you and I never have to work together because I'll eat your fucking liver.

     

    Welcome to the the troll excluding javascript list along with mobius winter or whatever his name was.



  • @ActionMan said:

    Welcome to the the troll excluding javascript list along with mobius winter or whatever his name was.

    Nobody cares who you put in your ignore list. Nobody has ever cared who anyone else puts in their ignore list.



  •  OMG! What do you mean that no-one cares?!?!? It's the internet, how can you not care!!!

    ...

    </sarcasm>

    ...

     It's just another way of saying "STFU Troll", isn't it? I thought this way was better, seeing that it uses JavaScript :P



  • @fyjham said:

    Tchize, assuming you mean you can do it with just HTML/CSS (and you're not gonna use javascript or something) I'd love to see your answer that works on a dynamically generated table of data...

     

    tr:nth-child(odd) {
     /* Alt row styles here */
    } 
     
    How's that? 

     



  • @SuperousOxide said:

    @ActionMan said:

    Welcome to the the troll excluding javascript list along with mobius winter or whatever his name was.

    Nobody cares who you put in your ignore list. Nobody has ever cared who anyone else puts in their ignore list.

    Says the guy who clearly isn't on anyone's ignore list...  For fuck's sake, he even remembered my name wrong!

     

    WILTERS!  IT'S MORBIUS WILTERS YOU HEARTLESS, HEARTLESS MAN!!



  • All you guys using %2 are going to be sorry once there are more then 2^32 records in the table (or 2^64 if you are running a 64 bit machine).


Log in to reply