cloudfour / SimpleSlideView

A nifty little jQuery or Zepto plugin for the simplest of sliding views.
http://blog.cloudfour.com/simpleslideview/
258 stars 33 forks source link

Need some help here, how to accomplish this? #7

Closed reypm closed 8 years ago

reypm commented 11 years ago

I want to use your amazing plugin for a categories picker, what this mean? For example in first view I want to display all the categories, then when I click on any I'll move to second view with categories that have the picked category as parent. This code isn't a problem since I have it developed using PHP. The problem comes in how to create the second and n-views on the fly using jQuery and of course setting the right previous & next buttons, any advice in how to get this done?

tylersticka commented 11 years ago

@paquitodev Sorry to hear you've encountered some issues!

It might help for me to see an example of the markup your PHP is outputting so I can get an idea of what SimpleSlideView is attempting to interact with. In theory, something like this should work, but it's hard for me to tell from your description alone:

<div class="views">
  <div class="view" id="picker">
    <ul>
      <li><a href="#category-1" data-pushview>First category</a></li>
      <li><a href="#category-2" data-pushview>Second category</a></li>
      <li><a href="#category-3" data-pushview>Third category</a></li>
    </ul>
  </div>
  <div class="view" id="category-1">
    <h3>First category!</h3>
    <!-- etc. -->
    <ul>
      <li><a href="#picker" data-popview>&laquo; Previous</a></li>
      <li><a href="#category-2" data-pushview>Next &raquo;</a></li>
    </ul>
  </div>
  <div class="view" id="category-2"><!-- etc. --></div>
  <div class="view" id="category-3"><!-- etc. --></div>
</div>

If that example isn't helpful, please describe in further detail (preferably with code samples) what you're trying to do. Thanks!

reypm commented 11 years ago

Thanks for your fast reply. See I have this HTML markup in my template:

<div id="ccontainer">
    <div id="categories-picker">
        <div class="view" id="cstep1">
            <h2>Seleccione una categoría</h2>
            <ul id="step1" class="circle">
            {% for entity in entities %}
                <li><a href="#" class="step" data-id="{{ entity.getId }}">{{ entity.getName }}</a></li>
            {% endfor %}
            </ul>
            <ul class="view-nav clearfix">
                <li class="view-nav-contents pull-left"><a href="#nav" data-popview>Previous</a></li>
                <li class="view-nav-next pull-right"><a href="#how" data-pushview>Next</a></li>
            </ul>
        </div>
    </div>
</div>

When I call the template for first time the div#cstep1 get values coming from PHP function that handle this part. This has not problem and it works. I've added this jQuery code:

$(function() {
    var k = 1;
    $("#categories-picker").simpleSlideView({duration: 250});

    $("#categories-picker").on("click", "a.step", function() {
        var id = $(this).attr('data-id');
        $.ajax({
            type: 'GET',
            url: Routing.generate('category_subcategories', {parent_id: id}),
            dataType: "json",
            success: function(data) {
                if (data.length != 0) {
                    $("#cstep" + k).after('<div class="view" id="cstep' + (k + 1) + '"><ul id="step' + (k + 1) + '"></ul></div>');
                    var LIs = "";
                    $.each(data, function(index, value) {
                        $.each(value, function(i, v) {
                            LIs += '<li><a class="step" data-id="' + i + '" href="#">' + v + '</a></li>';
                        })
                    });
                    $('#step' + (k + 1)).html(LIs);
                    k++;
                }
            }
        });
    });
});  

That code take care of creation of new DIV and assign correct class and ids of course if the function called via AJAX return values. Now the logic, as I'm thinking is as follow:

I've attached a image describing the process and hope you can help me on this one since I stucked here :-(

untitled-1

tylersticka commented 11 years ago

Thanks for the greater detail.

SimpleSlideView was written with in-page content in mind and hasn't been tasted with dynamically-loaded content via AJAX. That doesn't mean it won't work, it just means you're in slightly uncharted territory. Just something to keep in mind.

I notice in your template you have the following lines:

<ul class="view-nav clearfix">
  <li class="view-nav-contents pull-left"><a href="#nav" data-popview>Previous</a></li>
  <li class="view-nav-next pull-right"><a href="#how" data-pushview>Next</a></li>
</ul>

What that's telling SimpleSlideView is this:

But you don't have elements with IDs of nav or how, so this won't work. You need to point these to the correct elements (#cstep1, #cstep2, etc.).

You can also do this in JavaScript if you'd rather manage the actions there. Here's a highly simplified example:

<div id="ccontainer">
  <div class="view" id="cstep1"><!-- etc. --></div>
  <div class="view" id="cstep2"><!-- etc. --></div>
  <div class="view" id="cstep3"><!-- etc. --></div>
  <ul>
    <li><a href="#" id="previous">Previous</a></li>
    <li><a href="#" id="next">Next</a></li>
  </ul>
</div>
// Store the instance of SimpleSlideView so we can refer to it later
var slideView = $('#ccontainer').simpleSlideView({duration: 250});

// When the "previous" link is clicked
$('#previous').on('click', function (event) {
  // Stop the browser default
  event.preventDefault();
  // Get the previous sibling of the active view with a class of "view"
  var $previousView = slideView.$activeView.prev('.view');
  // If the previous view exists, pop to it
  if ($previousView.length) slideView.popView($previousView);
});

// When the "next" link is clicked
$('#next').on('click', function (event) {
  // Stop the browser default
  event.preventDefault();
  // Get the next sibling of the active view with a class of "view"
  var $nextView = slideView.$activeView.next('.view');
  // If the next view exists, push to it
  if ($nextView .length) slideView.pushView($nextView);
});

Consult the README for more info on the available options and methods and how to use them.

reypm commented 11 years ago

Hi, I'm trying to use in this way: // Made scroll appears if DIV contents grow ups var slideView = $("#categories-picker").simpleSlideView();

    $("#categories-picker").on("click", "button#next_step", function(event) {
        $("#categories-picker").append('<div class="view product-left" id="product-select"></div>');
        $("#product-select").load(Routing.generate('product_new_form'));

        // Stop the browser default
        event.preventDefault();
        // Get the next sibling of the active view with a class of "view"
        var $nextView = slideView.$activeView.next('.view');
        // If the next view exists, push to it
        if ($nextView.length) {
            slideView.pushView($nextView);
        }
    });

But the event isn't triggered, why?

tylersticka commented 11 years ago

Currently, the plugin is only designed for content that is already in-page when the plugin is activated. In this case, $activeView.next will probably return a zero-length collection because when $activeView was created, it didn't have a next sibling.

I've labeled this issue as an "enhancement" and we will consider changing this behavior in the future.