cloudfour/SimpleSlideView

Need some help here, how to accomplish this?

reypm opened this issue · 5 comments

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?

@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!

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:

  • First call to the page, first DIV is showed with values, if I click any of those values (represented by "a.step") and it have values then I should build a new DIV with new values coming from JSON results and forward to the newest DIV created and at this point I should show and enable navigation buttons meaning backward is enable because I can go back and pick another category in case of I made any mistake.
  • In the other side I want to active forward step only if data.length = 0 meaning no results get from JSON

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

untitled-1

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:

  • When you click the "Previous" link, "pop" the view with an ID of nav.
  • When you click the "Next" link, "push" the view with an ID of how.

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.

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?

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.