Bizarre SimpleMODAL OSX actions in Foreach Loop

2019-08-25 09:26发布

问题:

I am developing on a Wordpress MU website with a PHPBB3 forum that is merged into the site. On the website there is a page that utilizes SimpleModal OSX Style Modal Dialog that queries some of the website users data. I am also using a plugin that allows you to create custom meta information for each user called Cimy User Extra Fields. Before I go into detail of the problem I want to make sure I am thorough with my explanation as apparently I was not before.

Onto the problem..........

The problem lies in the fact that on the page that utilizes the SimpleModal OSX Style Modal Dialog jquery function. On this page it queries the websites users data and it goes through a Foreach sequance in PHP; displaying the data on the page within div columns. The part of the code that utilizes the SimpleModal OSX Style Modal Dialog is displayed as a button beside each user that is listed in the columns.

When you click the button that activates the Modal window; inside of that modal window is the meta data for that user. The data stored within each modal window is supposed to match each user. Instead it only shows the data for the first user it finds in the system across all modal windows on the page.

Originally I had run the function through a foreach loop and the resulting data that is stored within the MODAL windows is the same data - rather than it being unique to each user that the function queries from the database.

An Example would be that there are 10 users on the website and so the foreach loop would return 4 users on this page listed within columns. You can see a visual representation here.

If you are looking at the page you will see that there are 4 users listed. For each user it displays their Avatar image, Display Name, Rank, a button to view toons, a challenge button and a link to email them. The View Toons button is where the problem lies.

As I said above originally it displayed the same data in the modal window over and over for each button - rather than that data being unique to each user. With the help of baba he gave me the slap on the forehead moment with what was wrong with the script. Unfortunately, I could NOT get it to work. Sorry, Baba not quite sure what I'm doing wrong. I went with a different approach that I "felt" like might be an easier solution for my novice mind.

As Baba has mentioned the problem lies in the fact that the Javascript is looking for a specific ID to call the script that creates the modal window. Since this is a foreach loop then in my current case it repeats the View Toons button 4x. Thus, we have 4 buttons that when pushed will popup a Modal window with meta data stored within. When those 4 buttons are clicked the same data was shown in all four. So, the solution? We need to randomize each button's ID somehow and for the jquery function to be able to recognize that it needs to activate on each of these buttons.

I spent a couple of hours trying to utilize Baba's idea and could not get it to work. So I dug around even deeper on the net and came across this question/answer on stackoverflow you can view it here. The exact same problem I was having and the answer was provided by the Developer of SimpleModal. The only problem was that the answer was based upon id's that already existed and not ID's that would be automatically created within a loop.....

My solution.......

I needed a way to generate a random string of numbers and letters. I found this solution here. How I implemented it into my code:

<?php 
    $n = rand(10e16, 10e20);
    $x = base_convert($n, 10, 36);
?>

Now that I had this random string generation working in the code, I needed a way for the Jquery function to be able to recognize these ID's with the radom string of numbers and letters. I needed a wildcard.....This is what I used:

$("[id^=osx-modal-content]").modal({

With this, I thought for sure it would work! It did not......

Strangely enough, it did really weird things that I'm not sure I can explain well in writing and it would be much better if you visually look at what it produces as I try and explain it. You can view the page here.

So these little red x characters appear below each View button. These little red x characters represent this part of the code:

<div id="osx-modal-content<?php echo $x;?>">

Ah! these are the div's that contain the meta data within each modal window. Why the red x appears I have no clue. What is even more strange is when you click any of the 4 View Buttons. Not only does the modal window not fully expand out but it is like a garage door that has become possessed. It comes down a bit and then goes right back up. In the process of it sliding down you cannot see the meta data either. This just might be due to the fact that the modal window does not fully expand down though.

Then another problem occurs after you click the view toon button. Those little red x's that appear under each Toon button reposition themselves directly under the first View toon button. Now the DIV.ID for osx-modal-content(random string) that I listed above. All four of those divs are now UNDER the first view toon button. WTH???

That's where I am at guys. I hope I am on the right path with this code and I'm sorry Baba I could not get your solution to work and I hope that this is enough information for you other guys that are willing to help to understand what I'm doing.

================================================================================== Update: As Pointy mentioned that I am using IDs in a loop when it should be Classes, I looked in the style sheets and noticed this line of code:

#osx-modal-content, #osx-modal-data {display:none;}

Since I am adding random alphanumerical strings at the end of #osx-modal-content. It was not registering the style for display:none. I added this to the code:

<div id="osx-modal-content<?php echo $x;?>" style="display:none">

This made those pesky little red x's disappear. Thanks for that Pointy! I am currently in the process of trying to change the DIV's their appropriate ID/Classes that are within the loop - to see if that will make a difference.

Update 2: I changed line 18 in the jquery function which originall was this:

$("osx").click(function (e) {

to this:

$("[id^=osx]").click(function (e) {

This caused the crazy, possessed garage door effect to stop. It now slides out and displays the meta info for each user. However, when you click the View toon button it shows ALL users meta info within the box now instead of just the selected "user". Also, when you click each of the buttons it lists the users in ASC order based upon that users ID number.

Update 3: I am almost positive the problem with why the Modal window displays all of the users info is because of the wildcard I setup. It opens based upon any div that starts with osx-modal-content which will cause it to display each users meta info. I need a different solution for the jquery function.

Those of you that are willing to take a look at this and help me out. I've listed the full code, query function and Jquery function below:

The custom function to query website users meta data:

<?php
    function roster()
    {
        $members    = get_users('blog_id=15&exclude=array(1)');
        foreach ($members as $user) 
        { 

            $item['login']      = $user->display_name;
            $item['email']      = $user->user_email;
            $item['picture']    = get_cimyFieldValue($user->ID, 'picture'); 
            $item['rank']       = get_cimyFieldValue($user->ID, 'guild_rank'); 
            $item['game']       = get_cimyFieldValue($user->ID, 'game'); 
            $item['avatar']     = get_cimyFieldValue($user->ID, 'avatar');
            $item['toon_name'] = get_cimyFieldValue($user->ID, 'character_name');
            $item['faction']    = get_cimyFieldValue($user->ID, 'faction');
            $item['class']  = get_cimyFieldValue($user->ID, 'class'); 
            $item['role']       = get_cimyFieldValue($user->ID, 'role');
        } 
        unset($members);
        return $ret;
    }
?>

The Loop for each user called from the Function:

<?php 
    $ret = roster(); 

    if ( ! empty($ret))
    {
        foreach($ret as $v)
        { ?>

            <div id = "roster_container">
                <div id="left_col">
                    <div id="first_left_col">
                        <h4>Avatar</h4>
                        <?php echo '<li><img src="' . $v['picture'] . '" alt="" /></li>';?>
                    </div>

                    <div id="second_left_col">
                        <h4>Username</h4>
                        <?php echo '<li>' . $v['login'] . '</li>';?>
                    </div>

                    <div id="third_left_col">
                        <h4>Rank</h4>
                        <?php echo '<li>' . $v['rank'] . '</li>';?>
                    </div>
                </div>

                <div id="right_col">        
                    <div id="first_right_col">
                        <h4>Toons</h4>
                        <li>
                            <div id='osx-modal'>
                                <?php 
                                    $n = rand(10e16, 10e20);
                                    $x = base_convert($n, 10, 36);
                                ?>

                                <input type="button" name="osx<?php echo $x;?>" value="View" class="osx<?php echo $x;?>" id="osx<?php echo $x;?>"/>
                            </div>

                            <div id="osx-modal-content<?php echo $x;?>" style="display:none;">
                                <div class="close"><a href="#" class="simplemodal-close">x</a></div>
                                <div id="osx-modal-data">                                   
                                    <div id="toon_title">Game Characters</div>
                                    <div id="toon_game">                                    
                                        <?php echo '<h3>' . $v['game'] . '</h3>';?>
                                    </div>

                                    <div id="toon_box">
                                        <div id="toon_name"><?php echo $v['toon_name'];?></div>
                                        <div id="toon_avatar"><?php echo '<img src="' . $v['avatar'] . '" alt="" />';?></div>       
                                        <div id="toon_faction"><?php echo $v['faction'];?></div>
                                        <div id="toon_class"><?php echo $v['class'];?></div>
                                        <div id="toon_role"><?php echo $v['role'];?></div>
                                    </div>

                                    <p><button class="simplemodal-close">Close</button></p>
                                </div>
                            </div>
                        </li>
                    </div>
                    <div id="second_right_col">
                        <h4>Challenge</h4>
                        <?php echo '<li><a href="#" class="CHALLENGE">Challenge</a></li>';?>
                    </div>

                    <div id="third_right_col">
                        <h4>Email</h4>
                        <?php echo '<li><a href="mailto:' . $v['email'] . '"><img src="http://conspirators.websitedesignbyneo.com/wp-content/themes/conspirators/css/dark-red/img/email-icon.gif" style="height:15px;width:20px;margin-top:5px;margin-left:7px;"></a></li>';?>
                    </div>
                </div>
            </div>
        <?php
        }
    }
    ?>

And Finally The SimpleModal OSX Style Modal Dialog Jquery:

/*
* SimpleModal OSX Style Modal Dialog
* http://www.ericmmartin.com/projects/simplemodal/
* http://code.google.com/p/simplemodal/
*
* Copyright (c) 2010 Eric Martin - http://ericmmartin.com
*
* Licensed under the MIT license:
*   http://www.opensource.org/licenses/mit-license.php
*
* Revision: $Id: osx.js 238 2010-03-11 05:56:57Z emartin24 $
*/

jQuery(function ($) {
var OSX = {
    container: null,
    init: function () {
            $("[id^=osx]").click(function (e) {
            e.preventDefault(); 
            $("[id^=osx-modal-content]").modal({
                overlayId: 'osx-overlay',
                containerId: 'osx-container',
                closeHTML: null,
                minHeight: 80,
                opacity: 65, 
                position: ['0',],
                overlayClose: true,
                onOpen: OSX.open,
                onClose: OSX.close
            });
        });
    },
    open: function (d) {
        var self = this;
        self.container = d.container[0];
        d.overlay.fadeIn('slow', function () {
            $("[id^=osx-modal-content]", self.container).show();
            var title = $("#osx-modal-title", self.container);
            title.show();
            d.container.slideDown('slow', function () {
                setTimeout(function () {
                    var h = $("#osx-modal-data", self.container).height()
                        + title.height()
                        + 20; // padding
                    d.container.animate(
                        {height: h}, 
                        200,
                        function () {
                            $("div.close", self.container).show();
                            $("#osx-modal-data", self.container).show();
                        }
                    );
                }, 300);
            });
        })
    },
    close: function (d) {
        var self = this; // this = SimpleModal object
        d.container.animate(
            {top:"-" + (d.container.height() + 20)},
            500,
            function () {
                self.close(); // or $.modal.close();
            }
        );
    }
};

OSX.init();

});

回答1:

The variable $ret does not seem to contain anything?

1- please use ULs around your LIs 2- please use classes instead of IDs

So, I am not very sure what you're trying to achieve with the random number, and I don't know what the overlayId and containerId should refer to, but this looks like a much better way of doing things:

<?php 
    $ret = roster(); 

    if ( ! empty($ret))
    {
        foreach($ret as $v)
        { ?>

            <div class="roster_container">
                <div class="left_col">
                    <div class="first_left_col">
                        <h4>Avatar</h4>
                        <?php echo '<li><img src="' . $v['picture'] . '" alt="" /></li>';?>
                    </div>

                    <div class="second_left_col">
                        <h4>Username</h4>
                        <?php echo '<li>' . $v['login'] . '</li>';?>
                    </div>

                    <div class="third_left_col">
                        <h4>Rank</h4>
                        <?php echo '<li>' . $v['rank'] . '</li>';?>
                    </div>
                </div>

                <div class="right_col">        
                    <div class="first_right_col">
                        <h4>Toons</h4>
                        <ul>
                          <li>
                              <div class='osx-modal'>
                                  <?php 
                                      $n = rand(10e16, 10e20);
                                      $x = base_convert($n, 10, 36);
                                  ?>

                                  <input type="button" name="osx" value="View" class="osx" class="osx"/>
                              </div>

                              <div class="osx-modal-content" style="display:none;">
                                  <div class="close"><a href="#" class="simplemodal-close">x</a></div>
                                  <div class="osx-modal-data">                                   
                                      <div class="toon_title">Game Characters</div>
                                      <div class="toon_game">                                    
                                          <?php echo '<h3>' . $v['game'] . '</h3>';?>
                                      </div>

                                      <div class="toon_box">
                                          <div class="toon_name"><?php echo $v['toon_name'];?></div>
                                          <div class="toon_avatar"><?php echo '<img src="' . $v['avatar'] . '" alt="" />';?></div>       
                                          <div class="toon_faction"><?php echo $v['faction'];?></div>
                                          <div class="toon_class"><?php echo $v['class'];?></div>
                                          <div class="toon_role"><?php echo $v['role'];?></div>
                                      </div>

                                      <p><button class="simplemodal-close">Close</button></p>
                                  </div>
                              </div>
                          </li>
                        </ul>
                    </div>
                    <div class="second_right_col">
                        <h4>Challenge</h4>
                        <ul>
                          <?php echo '<li><a href="#" class="CHALLENGE">Challenge</a></li>';?>
                        </ul>
                    </div>

                    <div class="third_right_col">
                        <h4>Email</h4>
                        <ul>
                          <?php echo '<li><a href="mailto:' . $v['email'] . '"><img src="http://conspirators.websitedesignbyneo.com/wp-content/themes/conspirators/css/dark-red/img/email-icon.gif" style="height:15px;width:20px;margin-top:5px;margin-left:7px;"></a></li>';?>
                        </ul>
                    </div>
                </div>
            </div>
        <?php
        }
    }
    ?>

<script>
  jQuery(function ($) {
  var OSX = {
      container: null,
      init: function () {
              $("[name=osx]").click(function (e) {
                e.preventDefault(); 
                $(this).parent().next().modal({
                    overlayId: 'osx-overlay',
                    containerId: 'osx-container',
                    closeHTML: null,
                    minHeight: 80,
                    opacity: 65, 
                    position: ['0',],
                    overlayClose: true,
                    onOpen: OSX.open,
                    onClose: OSX.close
                });
            });
      },
      open: function (d) {
          var self = this;
</script>