2
votes

I'm building a custom gallery that utilizes WordPress and Zurb Foundation:

  • The template shows a paged archive of custom posts; a custom query populates the page with a grid of linked thumbnails.
  • Uses the Reveal modal plugin in Foundation 4, along with WordPress' AJAX to append content to the reveal-modal div.
  • Clicking on a .previous-sketch, .next-sketch link in the modal window will bring up the corresponding adjacent post.

I've managed to get the above working, but find that after opening one modal window and cycling through the posts, things start to go out of sync. The dark background, .reveal-modal-bg is not displayed when a modal window is shown, and things behave somewhat strangely.

I thank you in advance if you have any particular insights into this problem.

UPDATE: I was able to work on this some more, and for the most part it seems to work. Though I feel that my solution isn't the most elegant.

My jQuery code is below.

(function($) {

 $.fn.displayPost = function() {
    event.preventDefault();
    var post_id = $(this).data("id");
    var id = "#" + post_id;

    // Check if the reveal modal for the specific post id doesn't already exist by checking for it's length
    if($(id).length == 0 ) {
        // We'll add an ID to the new reveal modal; we'll use that same ID to check if it exists in the future.
        var modal = $('<div>').attr('id', post_id ).addClass('reveal-modal').appendTo('body');
        var ajaxURL = MyAjax.ajaxurl;
         $.ajax({
            type: 'POST',
            url: ajaxURL,
            data: {"action": "load-content", post_id: post_id },
            success: function(response) {
                modal.empty().html(response).append('<a class="close-reveal-modal">&#215;</a>').foundation('reveal', 'open');

                modal.bind('opened', function() {
                    // Trigger window resize to reset the left margin.  
                    $(window).trigger('resize');
                    var left;
                    left = Math.max($(window).width() - $(id).outerWidth(), 0) / 2;
                    $(id).css({
                        left:left + $(window).scrollLeft()
                    });

                return false;
                });
            }
        });
    }
     //If the div with the ID already exists we'll just open it.
     else {
         $(id).foundation('reveal', 'open');
     }

     // Recalculate left margin on window resize
     $(window).resize(function(){
        var left;
        left = Math.max($(window).width() - $(id).outerWidth(), 0) / 2;
        $(id).css({
            left:left + $(window).scrollLeft()
        });
     });
}

})(jQuery);

// Apply the function when we click on the .reveal link
jQuery(document).on("click", ".reveal,.secondary", function() {
    jQuery(this).displayPost();
});

// Use Reveal's built in function to close the div when we click our paging links
jQuery(document).on("click", ".secondary", function() {
    var id = jQuery(this).closest("div").attr("id");
    jQuery(id).foundation('reveal', 'close');

});
1

1 Answers

1
votes

I figure that someone here probably knows a much better way to do this, but for the sake of anyone else that is trying to figure this out, I managed to kludge a solution. It works, though I haven't tested it thoroughly.

The function extends Foundation 4 Reveal's functionality in a few ways:

  • Uses WordPress AJAX to dynamically pull in content to populate a modal div.
  • Centers the modal div and allows it to be variable width.
  • Adds paging navigation from the modal window that when triggered will close the open modal window, then open the previous/next modal content.

Here's the code:

(function($) {

    $.fn.displayPost = function() {

    event.preventDefault();

    var post_id = $(this).data("id");
    var id = "#" + post_id;

    // Check if the reveal modal for the specific post id doesn't already exist by checking for it's length
    if($(id).length == 0 ) {
        // We'll add an ID to the new reveal modal; we'll use that same ID to check if it exists in the future.
        var modal = $('<div>').attr('id', post_id ).addClass('reveal-modal').appendTo('body');
        var ajaxURL = MyAjax.ajaxurl;
         $.ajax({
            type: 'POST',
            url: ajaxURL,
            data: {"action": "load-content", post_id: post_id },
            success: function(response) {
                modal.empty().html(response).append('<a class="close-reveal-modal">&#215;</a>').foundation('reveal', 'open');
                modal.bind('opened', function() {
                    // Reset visibility to hidden and set display: none on closed reveal-modal divs, for some reason not working by default when reveal close is triggered on .secondary links  
                    $(".reveal-modal:not('.reveal-modal.open')").css({'visibility': 'hidden', 'display' : 'none'})
                    // Trigger resize 
                    $(window).trigger('resize');
                return false;
                });
            }
        });
    }
     //If the div with the ID already exists just open it.
     else {
         $(id).foundation('reveal', 'open');
     }

     // Recalculate left margin on window resize to allow for absolute centering of variable width elements
     $(window).resize(function(){
         var left;
            left = Math.max($(window).width() - $(id).outerWidth(), 0) / 2;
            $(id).css({
                left:left + $(window).scrollLeft()
            });
     });
    }

     })(jQuery);

     // Apply the function when we click on the .reveal link
     // (document).ready won't work on any reveal-modal divs added subsequently
     // after page load via AJAX so use .on instead.
     jQuery(document).on("click", ".reveal,.secondary", function() {
      jQuery(this).displayPost();

     });

      // Close open modal via secondary paging links; target parent div id.
      jQuery(document).on("click", ".secondary", function() {
        var id = jQuery(this).closest("div").attr("id");
      jQuery(id).foundation('reveal', 'close');
      });

UPDATE: Added php function for loading AJAX content

  public function __construct() {
        add_action( 'wp_ajax_load-content', array($this, 'load_ajax_content' ));
        add_action( 'wp_ajax_nopriv_load-content', array($this, 'load_ajax_content' ));
    }



        /**
         * Function to call the content loaded for logged-in and anonymous users
        */
        public function load_ajax_content ( $post_id ) {

            $post_id = $_POST[ 'post_id' ];

            if (has_post_thumbnail($post_id)) {
                $sketch_id = get_post_thumbnail_id($post_id);  
                $attachment = get_post( $sketch_id );
                $caption = $attachment->post_excerpt;
                $response = '<figure>'. get_the_post_thumbnail($post_id, 'large-sketch') .'<figcaption><p>'. $caption .'</p></figcaption></figure>' . $this->paging_link_nav( $post_id );
                echo $response;
            }

            die(1);
         }

Hopefully someone else finds this useful...