9

I am not sure if this is something that has already been discussed, I tried searching on the list of issues but could not find anything related to it.

I have a large HTML content that I need to bind using turn.js. The problem I have is that, with turn js, I will have to split the HTML into separate div tags as pages. Is there a way in turn.js to bind the content on a div and it takes care of automatically wrapping to different pages based on the content that is being bound?

Or is there a way to know how much data needs to be bound to each page to get this scenario working.

Haris
  • 12,120
  • 6
  • 43
  • 70
Abishek
  • 11,191
  • 19
  • 72
  • 111

2 Answers2

4

Here is a solution for splitting the content to pages, and than, create a book using turn.js.

The logic of this solution is to check if the next content can be in the current page or we need to create a new page and put the content there.

This code "read" html from a specific div and do the magic ;)

Alse, you can play with the code in jsbin.

var width = 400,
    height = 400,
    padding = 20;

// create a tester div. in this `div` we will put the contents and check if we need a new page
var div = $('<div />').css({
  // divide it by 2 because each page is half from the book
  width: width / 2
}).appendTo(document.body);

var index = 0;
var pages = [];
// get all content from the input html
var contents = $('#text').contents();

while (index < contents.length) {
  var content = contents.eq(index).clone();
  
  div.append(content);
  // check whether the contents exceed the page, if so, remove this content from the page
  if (div.height() > height) {
    content.remove();
    // create a new page
    pages.push(div.clone());
    // reset the tester div's html to check the next content
    div.html('');
  }
  // if this is the last content, push it to a new page and break
  else if (index == contents.length - 1) {
    pages.push(div.clone());
    div.remove();
    break;
  }
  // go to the next content
  else {
    index++;
  }
}

var book = $('#book');
for (var i = 0; i < pages.length; i++) {
  //book.after(pages[i].clone());
  //book.after('<hr />');
  book.append(pages[i]);
}

// init the plugin
book.turn({
  width: width,
  height: height,
  gradients: true, 
  acceleration: true
});
.sample-flipbook .page {
  line-height:1 !important;
  font-size:inherit !important;
}
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script src="http://www.turnjs.com/lib/turn.min.js"></script>
<link href="http://www.turnjs.com/samples/basic/css/basic.css" rel="stylesheet" />

<div id="book" class="sample-flipbook"></div>

<div id="text">
  <p>Lorem ipsum dolor sit amet, sed probatus dissentias cu. Ex liber error vim. Habeo mollis cu qui, eu cum graeco scripta nostrum, est et delenit suscipit. Eius meliore iudicabit per in, pro numquam fabellas id.
  </p>
  <p>blablabla</p>
    <p>blablabla1</p>
    <p>blablabla2</p>
    <p>blablabla4</p>
    <p>blablabla5</p>
    <p>blablabla6</p>
    <p>blablabla7</p>
  <p>
Ponderum gubergren adversarium pri ad. Mea ne veri scribentur. Nam populo conclusionemque te. Ad albucius voluptatum vix, cum id dicta facilis petentium. His no rebum vivendo. Per esse illum nihil eu, eos affert ceteros ne.
  </p>
  <p>
At mea nostro oportere reprimique. Vim veri facilisi deterruisset in, maiorum referrentur id mea. Vel eligendi euripidis ullamcorper eu. Vix eu veri primis sententiae, sumo eligendi conclusionemque ad his. Ea quando luptatum rationibus eam, et dico aliquid eloquentiam his. Mea primis intellegebat ne, ea regione equidem ullamcorper usu.
  </p><p>
Mel in natum recusabo aliquando, tollit probatus qui in. Ex labore pertinax oportere ius, nobis iudico cu quo. Malis dicunt moderatius eum ex, quaeque consetetur duo ne. Ea veri inimicus mei, vim eu constituam consequuntur.
  </p>
  <p>
Per id ancillae efficiantur. Eam platonem recteque euripidis et. Usu tota dolore tibique id, id libris molestiae mel. Cu odio illud appareat mei. Quis vitae ne usu. Ut eos magna prima.</p>
    <p>Lorem ipsum dolor sit amet, sed probatus dissentias cu. Ex liber error vim. Habeo mollis cu qui, eu cum graeco scripta nostrum, est et delenit suscipit. Eius meliore iudicabit per in, pro numquam fabellas id.
  </p>
  <p>
Ponderum gubergren adversarium pri ad. Mea ne veri scribentur. Nam populo conclusionemque te. Ad albucius voluptatum vix, cum id dicta facilis petentium. His no rebum vivendo. Per esse illum nihil eu, eos affert ceteros ne.
  </p>
  <p>
At mea nostro oportere reprimique. Vim veri facilisi deterruisset in, maiorum referrentur id mea. Vel eligendi euripidis ullamcorper eu. Vix eu veri primis sententiae, sumo eligendi conclusionemque ad his. Ea quando luptatum rationibus eam, et dico aliquid eloquentiam his. Mea primis intellegebat ne, ea regione equidem ullamcorper usu.
  </p><p>
Mel in natum recusabo aliquando, tollit probatus qui in. Ex labore pertinax oportere ius, nobis iudico cu quo. Malis dicunt moderatius eum ex, quaeque consetetur duo ne. Ea veri inimicus mei, vim eu constituam consequuntur.
  </p>
  <p>
Per id ancillae efficiantur. Eam platonem recteque euripidis et. Usu tota dolore tibique id, id libris molestiae mel. Cu odio illud appareat mei. Quis vitae ne usu. Ut eos magna prima.</p>
  </div>

It's important to say that this solution is a direction for you. The most chance that you need to add more code to fit this exactly to your need but I did for you the most of the way.

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
  • This `while (index < contents.length)` goes in infinite loop and the script crashes. Is there something wrong? – Haris Nov 19 '15 at 08:52
  • I can't see it. Do you talking about the `snippet`? The `jsbin` demo? – Mosh Feu Nov 19 '15 at 09:01
  • So, it dosn't `goes in infinite loop` but `potential infinite loop`. Well, true, it **potential**, but it's not. I was checked. Also, the script actually works and do his job. So we are OK. – Mosh Feu Nov 19 '15 at 09:36
  • Actually, when I run this on a browser, the tab crashes saying that `unresponsive script`. So i feel there is a loop that is not completing. – Haris Nov 19 '15 at 09:38
  • What browser do you use? – Mosh Feu Nov 19 '15 at 09:49
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/95538/discussion-between-mosh-feu-and-haris). – Mosh Feu Nov 19 '15 at 09:50
  • 1
    @SaurabhVerma I changed the height of the "book" because one of the `p` was with a lot of text. Now it's working in the bin and the snippet. If you have a lot of text, you should split it in the code of course. – Mosh Feu Oct 09 '16 at 08:11
1

According with the documentation (http://www.turnjs.com/docs/Method:_addPage) you can add dinamically pages. So when the page is loaded you can custom split your pages and add them dinamically. Something like this.

Imagine this HTML:

<div class="page">
    <h2>Title</h2>
    <p>Content</p>
</div>
<div class="page">
    <h2>Title</h2>
    <p>Content</p>
</div>
<div class="page">
    <h2>Title</h2>
    <p>Content</p>
</div>
<div class="page">
    <h2>Title</h2>
    <p>Content</p>
</div>
<div id="flipbook"></div>

We have here 4 pages but there are all in the same page, and the last element is where flipbook will be constructed. So when we load the page let's split them in Javascript:

$(document).ready(function() {
    // initialize the flipbook
    $("#flipbook").turn({page: 1, acceleration: true, gradients: true});

    // first we declare an array to store pages contents
    var pagesArray = [];
    $('.page').each(function() {
        // iterate through all pages and store the HTML inside
        pagesArray.push($(this).html());
    });

    // iterate the array and add pages dinamically
    for(var i in pagesArray) {
        // add the element within a div with the content that store before
        var element = $("<div />").html(pagesArray[i]);
        // add the page with the counter + 1 (first page is 1 not 0)
        $("#flipbook").turn("addPage", element, (i+1));
    }
});

And that's all.

Tell us if this fits with your requirements. If not, please, share with us your html structure to view how to solve the problem.

Marcos Pérez Gude
  • 21,869
  • 4
  • 38
  • 69
  • Can you explain me somethings here.. by doing `pagesArray.push($(this).html());` you are getting the content of the first tag.. So if its `` then the whole page content is saved in `pagesArray`. And then you are putting this in `
    `. But what i want is slicing this source html page into different `
    ` based on the contents that can fit into a page of flipbook.
    – Haris Nov 14 '15 at 09:35
  • No. Body's content is not saved entirely. There are a loop that iterates through all divs with `page` classname. `$(this).html()` refers to the content of every page, so if you have 5 page divs, `pagesArray` will have 5 items (a page each item) – Marcos Pérez Gude Nov 14 '15 at 10:26
  • I dont have pages created already.. My problem is to create page from a html page... For example I may have `

    something1

    something2 something3

    ` I have to put in `
    something1
    somthing2
    something3
    ` (creating pages)
    – Haris Nov 14 '15 at 10:37
  • Then my answer fits with your requirements. See the html and read the comments in the javascript – Marcos Pérez Gude Nov 14 '15 at 10:53
  • The mapping is not one div to one page.. The html may not contain div tags also.. For the example mentioned above there are 2 tags but 3 pages... – Haris Nov 14 '15 at 11:24
  • By that way is impossible to view where one page starts and ends. You must to adapt your html structure to separate the pages in a bulletproof way – Marcos Pérez Gude Nov 14 '15 at 12:06
  • 1
    That is my problem statement.. To divide the html page to different pages and to know the amount of data that can be put in a page.. As i dont have pictures in my page i can go with counting lines or words.. But i was hoping for a better solution.. – Haris Nov 14 '15 at 12:14