2

This is a part fo php code, which use the contentArray, which is a JSON, and generate the UI to the user, it generate html tags, also, it generate js code too.... It works, but I think the code is pretty difficult to read and maintain, any ideas??? thank you.

for($i = 0; $i < count($contentArray); $i++){  

    if($i %2 == 0){
       echo ("<li class='even_row'>");
    }else{
       echo ("<li class='odd_row'>");
    }  
    $content = $contentArray[$i];    

    echo("<textarea class='userdata' id='user_data_textarea_".$content->{'m_sId'}."'>");
    echo($content->{'m_sDataContent'});  
    echo("</textarea>"); 

echo("</li>");   

    echo("<script type='text/javascript'>");

    echo("$('#user_data_textarea_".$content->{'m_sId'}."').bind('keydown', function(e){");  
    echo("  TypingHandler.handleTypingInUserDataTextArea(".$content->{'m_sId'}.", e);");
    echo(" });");    

    echo("</script>");

}            
Tattat
  • 15,548
  • 33
  • 87
  • 138

11 Answers11

1

first for your odd and even styling there is not need for a class just use css

here is info on that

then in php only echo what you need in one line

$count = count($contentArray);
for($i = 0; $i < $count; $i++){  
    $content = $contentArray[$i];    
    echo('<li><textarea class="userdata" id="user_data_textarea_"'.$content->{'m_sId'}.'">'.$content->{'m_sDataContent'}.'</textarea></li>');   
}

and lets put the jquery in the html page away from php

we get can get every item by using starts with selector

$('[id^=user_data_textarea_]').bind('keydown', function(e){  
    var id = this.id.str_replace("user_data_textarea","");
    TypingHandler.handleTypingInUserDataTextArea(id, e);
});    
mcgrailm
  • 17,469
  • 22
  • 83
  • 129
0

One tip on your "for" loop, you should calculate the count of $contentArray before the loop. Every time the loop executes, it has to call that function.

$count = count($contentArray);

for ($i=0; $i<count; $i++) {
// ...
}
Brett
  • 721
  • 2
  • 10
  • 20
0

jQuery code should be already in the HTML, using some main selector and not binding elements one by one, it not makes sense for me. That should clarify your code.

for($i = 0; $i < count($contentArray); $i++){  
    $content = $contentArray[$i];    

    echo "<li class='" . (($i %2 == 0) ? "even_row" : "odd_row") . ">";
        echo "<textarea class='userdata' id='user_data_textarea_".$content->{'m_sId'}."'>";
        echo $content->{'m_sDataContent'};  
        echo "</textarea>"; 
    echo "</li>";   
}      

ADDED

A generic case:

$(function() {
    $('.userdata').click(function() {
        some_function($(this).attr('id');
    });
})

That is, bind using a class selector and late use some unique identifier for doing the job.

morgar
  • 2,339
  • 17
  • 16
  • but my jquery is base on different id, to have different behaviour, can u express it more detail? – Tattat May 13 '11 at 17:17
0

You could try real HTML:

<?php
for($i = 0; $i < count($contentArray); $i++){  
  $rowClass = $i %2 == 0 ?'even_row' : 'odd_row';
?>
    <li class='<?= $rowClass ?>'>
      <textarea class='userdata' id='user_data_textarea_<?=$content->{'m_sId'}?>'>
        <?= $content->{'m_sDataContent'} ?>
      </textarea>
    </li>
    <script type='text/javascript'>
    //etc...
    </script>
<?php } ?>
Ed Marty
  • 39,590
  • 19
  • 103
  • 156
0

Separate your content and code using for example smarty. It requires some infrastructure investment in the short term, but improves maintenance in the long run.

Reflecting the comments, let's then treat PHP as a real templating language.

$contentCount = count($contentArray);
for($i = 0; $i < $contentCount; $i++)
{
    $rowType = ( $i % 2 ) ? 'even' : 'odd';
    $content = $contentArray[$i];
    echo <<<EOT
<li class='{$rowType}_row'>
    <textarea class='userdata' id='user_data_textarea_{$content->m_sId}'>
        {$content->m_sDataContent}
    </textarea>

</li>
<script type="text/javascript">
    $('#user_data_textarea_{$content->m_sId}').bind('keydown', function(e)
    {
        TypingHandler.handleTypingInUserDataTextArea({$content->m_sId}, e);
    }
</script>
EOT;
}
Mel
  • 6,077
  • 1
  • 15
  • 12
  • 1
    I'm on the fence about this one. While I've used it before and it's an excellent templating system, there are some very good arguments that php already is a templating system, and adding stuff like Smarty just has you replacing `` with `{ ... }`, with the added downside of increase processing time. – eykanal May 13 '11 at 17:07
  • 1
    interesting point of view but I will say that it is much easier to read a smarty template then "phtml" – mcgrailm May 13 '11 at 17:25
  • I agree with eykanal. Why not separate the template into other file and treat it as a template (separate view from the rest)? And for sure PHP is a templating language itself. It just has to be properly implemented. – Tadeck May 13 '11 at 19:13
0

It should look something like this, for better readability in the IDE.

<?php
foreach($contentArray as $content){
    ?>
    <li>
        <textarea class="userdata" id="user_data_textarea<?php echo htmlentities($content['m_sId']); ?>">
            <?php echo htmlspecialchars($content['m_sDataContent']); ?>
        </textarea>
        <script type="text/javascript">
            $('#user_data_textarea_<?php echo htmlspecialchars($content['m_sId']); ?>').bind('keydown',function(e){
                TypingHandler.handleTypingInUserDataTextArea('<?php echo htmlspecialchars($content['m_sId']); ?>',e);
            });
        </script>
    </li>
<?php
}
EstelS
  • 153
  • 1
  • 6
  • Also, instead of using echo statements, it looks better in the IDE when you break out of PHP using ?> and then writing your HTML. Then re-enter PHP by using php. – EstelS May 13 '11 at 17:10
0

You could remove the ( ) from the echo statements, they're not necessarily needed and might help make it look a little neater...

christian.thomas
  • 1,122
  • 1
  • 8
  • 19
0

That actually looks pretty understandable to me; I could figure out what you're doing without difficulty. The only difference I would suggest would be the use of ternary operators for the row class:

echo "<li class='".( ($i%2 == 0) ? "even" : "odd" )."_row'>";

...but that's just me, some would find that MORE confusing, rather than less. I personally like putting it all in one line.

eykanal
  • 26,437
  • 19
  • 82
  • 113
0

Personnaly, I like to use printf to write html code in php. It could look like:

for($i = 0; $i < count($contentArray); $i++){  

    printf("<li class='%s'>", $i % 2 ? "odd_row" : "even_row"); 
    $content = $contentArray[$i];    

    printf("<textarea class='userdata' id='user_data_textarea_%s'>%s</textarea>",
        $content->{'m_sId'},
        $content->{'m_sDataContent'});

    echo("</li>");   

    echo("<script type='text/javascript'>");

    printf("$('#user_data_textarea_%1$s').bind('keydown', function(e){
        TypingHandler.handleTypingInUserDataTextArea(%1$s, e);
         });",
        $content->{'m_sId'});     

    echo("</script>");

}    
Charles Brunet
  • 21,797
  • 24
  • 83
  • 124
0
<?php
    foreach($contentArray as $content){
        $class = ($i %2 == 0) ? "even_row": "odd_row"; ?>
        <li class="<?php echo $class ?>">
            <textarea class='userdata' id='user_data_textarea_<? echo $content['m_sId'] ?>'>
                <? php echo $content['m_sDataContent'] ?>
            </textarea>
        </li>
        <script type='text/javascript'>
            $('#user_data_textarea_<?php echo content['m_sId'] ?>').bind('keydown', function(e){
                TypingHandler.handleTypingInUserDataTextArea(<?php $content['m_sId'] ?>, e);
            });
        </script>
<?php } // end foreach ?>
rlcabral
  • 1,496
  • 15
  • 39
0

Put everything in arrays, then echo them at the END of your loop.

// Put each item in the array, then echo at the end
$items = array();
$js = array();

// I'm assuming that your content array has numeric keys
// if not, use the for statement from your original code
foreach ($contentArray as $i => $content) 
{
    // using sprintf
    $items[] = sprintf('<li class="%s_row"><textarea class="userdata" id="user_data_textarea_%s">%s</textarea></li>'
        , ($i % 2) ? 'even' : 'odd'
        , $content->m_sId
        , $content->m_sDataContent
    );

    // or just plain old concatenation
    $js[] = "$('#user_data_textarea_{$content->m_sId}').bind('keydown', function(e){TypingHandler.handleTypingInUserDataTextArea({$content->m_sId}, e);});";
}

echo "<ul>" . join("\n", $items) . "</ul>\n"
    . '<script type="text/javascript">' . join("\n", $js) . "</script>\n";