views:

524

answers:

3

I have two arrays: $Forms and $formsShared.

<?php foreach ($Forms as $r): ?>
    $("#shareform<?=$r['Form']['id'];?>").hide();
    $(".Share<?=$r['Form']['id'];?>").click(function () {
        $("#shareform<?=$r['Form']['id'];?>").toggle("show");
    });
<?php endforeach; ?>

Currently, I have this hide and toggle function for each Form in the $Forms array. I want these functions to be enabled for the forms in the $formsShared array also.

If I add another for loop for $formsShared, like this:

<?php foreach ($formsShared as $r): ?>
    $("#shareform<?=$r['Form']['id'];?>").hide();
    $(".Share<?=$r['Form']['id'];?>").click(function () {
        $("#shareform<?=$r['Form']['id'];?>").toggle("show");
    });//.Share click
<?php endforeach; ?>

I achieve what I want, but it seems to be a repetition of the same code.

Is there any way in cakePHP to loop through two arrays in a single foreach loop?

Solution: array_merge() only accepts parameters of type array. So use typecasting to merge other types.

  <?php foreach (array_merge((array)$Forms,(array)$formsShared) as $r): ?>

    $("#shareform<?=$r['Form']['id'];?>").hide();
     $(".Share<?=$r['Form']['id'];?>").click(function () {
        $("#shareform<?=$r['Form']['id'];?>").toggle("show");
    });//.Share click

  <?php endforeach;?>
+4  A: 

It sounds like you don't want to loop over two lists at the same time. You want to loop over two lists separately, executing the same code for each element in either list. So why not concatenate the lists:

foreach (array_merge($Forms, $FormsShared) as $r)
    // do stuff
newacct
+1 That's what I would have suggested, but they're called arrays in PHP, not lists.
too much php
you understood rightly, but the concatenation didn't work.. :(
Angeline Aarthi
your code worked now,had to a typecast the lists to an array before merging..Thanks a lot..
Angeline Aarthi
+2  A: 

Instead of repeating so much JavaScript, you could make use of jQuery's selectors. Instead of using unique classes on your form elements (or in addition to), use a generic class name like form-field. Then you can add a click event to all of them at the same time:

$('.form-field').click(function () {
    // Without knowing your HTML structure, I can't make this accurate, but maybe
    // this will work, assuming #shareform... is the parent <form> element:
    $(this).closest('form').toggle('show');
});

This JavaScript would only need to be output once and would apply to all elements with class="form-field". Note that you can have multiple classes on an element too: class="Share123 form-field" gives the element class Share123 and class form-field.

Blixt
well if I have a generic class name, and apply click function to that class,then if I click one link that Form will be showed for all the other links that I didn't click since they have a common class name.Actually that was the very reason why I attached the id of the form to the class,to distinguish them uniquely.
Angeline Aarthi
While the code inside the `click` event handler is shared for all elements, it's got the `this` reference set to the specific element that was clicked. So if you get the element you want to toggle, relative to `$(this)`, you will only hide the one element you want. This is, arguably how you, should do it, since it'll work dynamically and more efficiently instead of being dependent on PHP output.
Blixt
+1  A: 

You can do that using for() loop, though it looks pretty nasty:

<?php

$arr1 = array('first 1', 'first 2', 'first 3');
$arr2 = array('second 1', 'second 2', 'second 3');

for($c1 = 0, $c2 = 0; $c1 < count($arr1), $c2 < count($arr2); $c1++, $c2++ )
{
    echo $arr1[$c1] . '<br />';
    echo $arr2[$c2] . '<br />';
}

?>

That's just PHP example, but you know how to edit it ;)

Edit:

Karl is right, duplicating indexes is not so great, so another solution, though you have to use @ to avoid warnings:

<?php

$arr1 = array('first 1', 'first 2', 'first 3', 'first 4');
$arr2 = array('second 1', 'second 2', 'second 3');

for($c = 0; $c < max( count($arr1), count($arr2) ); $c++ )
{
    echo @$arr1[$c] . '<br />';
    echo @$arr2[$c] . '<br />';
}

?>
usoban
Youre still duplicating the code in there due to having two indexes, so you might as well just use two individual for blocks.
Karl
You're right, I updated answer with another solution which uses only one index.
usoban
At first I thought this was what the OP wanted too, but what he wants is to loop through the two arrays sequentially (one after the other), but without using two for loops.
Blixt