pagination snippets

Paginating a list in Java

Tagged java, pagination  Languages java

Not fully tested, but the idea works.

List list = ....;                           // Example: page size is 5
int originalSize = list.size();             // original size: 24
int start = Math.min(list.size(), Math.abs(currentPage * pageSize));      // start: 5
list.subList(0, start).clear();             // list now contains: 5, 6, 7, 8, 9,..., 23

int size = list.size();                     // size is now: min(listSize, originalSize - pageSize) = 19
int end = Math.min(pageSize, size);         // end: 5
list.subList(end, size).clear();            // list now contains: 5, 6, 7, 8, 9

boolean hasNext = (end < size);             // has next: 5 < 19
boolean hasPrevious =  (start > 0);         // has previous: 5 > 0

Will Paginate pagination helper

Tagged will_paginate, pagination, helper  Languages ruby
module ApplicationHelper
  def paginate(collection)
    if collection.previous_page && !collection.next_page
      will_paginate collection, :page_links => true, :next_label => "", :prev_label => "&laquo; Previous"
    elsif collection.next_page && !collection.previous_page
      will_paginate collection, :page_links => true, :next_label => "Next &raquo;", :prev_label => ""
    else
      will_paginate collection, :page_links => true, :next_label => "Next &raquo;", :prev_label => "&laquo; Previous"
    end
  end
end

NoSQL, Pagination and Search with Mongoid, Kaminari and Tire

Tagged mongoid, kaminari, tire, elasticsearch, pagination  Languages ruby

This example uses Mongoid, Kaminari and Tire (ElasticSearch):

require 'kaminari/models/mongoid_extension'

class Product
  include Mongoid::Document
  include Mongoid::Paranoia
  include Mongoid::Timestamps

  index :application_id, :unique => true

  # NOTE Best to include after Mongoid
  include Tire::Model::Search
  include Tire::Model::Callbacks

  include Kaminari::MongoidExtension::Criteria
  include Kaminari::MongoidExtension::Document
end

Now you can paginate and search all you want:

# Search and paginate
Product.tire.search :page => 1, :per_page => 100, :load => true do
    query             { string "Ho ho" }
    #sort              { by     :rating, 'desc' }
end
# Paginate
Product.page(1).per(100)

Gotchas

* Use Model.tire.search/index, instead of Model.search which conflicts with Mongoid's index/search methods. * Use :load => true to return an array containing the model you're searching for instead of Tire::Result::Items. * Use :per_page and :page with Model.tire.search, not the page/per methods. * Mongoid queries are not the same as ActiveRecord queries, see http://mongoid.org/docs/querying/criteria.html#where * MongoDB URL http://localhost:28017/ * ElasticSearch URL http://localhost:9200/products/_mapping * Boolean queries are difficult https://gist.github.com/1263816

How to use WillPaginate with Sinatra

Tagged sinatra, will_paginate, pagination  Languages ruby
require 'will_paginate'
require 'will_paginate/active_record'
require 'will_paginate/view_helpers/sinatra'

class App < Sinatra::Base
  helpers WillPaginate::Sinatra::Helpers

  helpers do
    def paginate(collection)
       options = {
         #renderer: BootstrapPagination::Sinatra,
         inner_window: 0,
         outer_window: 0,
         previous_label: '&laquo;',
         next_label: '&raquo;'
       }
      will_paginate collection, options
    end
  end
end

Also see will_paginate-bootstrap.

Pagination with Phoenix and Ecto

Tagged ecto, elixir, pagination, phoenix  Languages elixir

Tested with Ecto 2.2 and Phoenix 1.3.

This module allows you to perform pagination with Phoenix and Ecto:

defmodule Pagination do
  import Ecto.Query
  alias Snippets.Repo
  #
  # ## Example
  #
  #    Snippets.Snippet
  #    |> order_by(desc: :inserted_at)
  #    |> Pagination.page(0, per_page: 10)
  #
  def page(query, page, per_page: per_page) when is_nil(page) do
    page(query, 0, per_page: per_page)
  end

  def page(query, page, per_page: per_page) when is_binary(page) do
    page = String.to_integer(page)
    page(query, page, per_page: per_page)
  end

  def page(query, page, per_page: per_page) do
    count = per_page + 1
    result = query
             |> limit(^count)
             |> offset(^(page*per_page))
             |> Repo.all
    has_next = (length(result) == count)
    has_prev = page > 0
    total_count = Repo.one(from t in subquery(query), select: count("*"))
    page = %{
      has_next: has_next,
      has_prev: has_prev,
      prev_page: page - 1,
      next_page: page + 1,
      page: page,
      first: page*per_page+1,
      last: Enum.min([page+1*per_page, total_count]),
      count: total_count,
      list: Enum.slice(result, 0, count-1)
    }
  end
end

Usage:

Snippets.Snippet
|> order_by(desc: :inserted_at)
|> Pagination.page(0, per_page: 10)

View helper

defmodule PaginationHelpers do
  import Phoenix.HTML
  import Phoenix.HTML.Form
  import Phoenix.HTML.Link
  import Phoenix.HTML.Tag

  def pagination_text(list) do
    ~e"""
    Displaying <%= list.first %>-<%= list.last %> of <%= list.count %>
    """
  end

  def pagination_links(conn, list, route) do
    content_tag :div, class: "pagination" do
      children = []
      if list.has_prev do
        children = children ++ link "Previous", to: route.(conn, :index, page: list.prev_page), class: "btn btn-secondary col-md-1"
      end
      if list.has_next do
        children = children ++ link "Next", to: route.(conn, :index, page: list.next_page), class: "btn btn-secondary col-md-1"
      end
      children
    end
  end
end

Usage:

<%= pagination_text(@snippets) %>
<%= pagination_links(@conn, @snippets, &snippet_path/3) %>