JSFiddle - React, Tailwind, and code Playground

by traditio

HTML

<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="http://backbonejs.org/backbone-min.js"></script>
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<div></div>
<script type="text/html" id="template-pages">
    <div class="pagination pagination-small">
        <ul>
            {% if (!inLeadingRange) { %}
            {% _.each(pagesOutsideTrailingRange, function(n) { %}
            <li><a href="#" data-id="{%= n %}">{%= n %}</a></li>
            {% }); %}
            <li class="disabled"><a href="#">...</a></li>
            {% } %}

            {% _.each(pageNumbers, function (pn) { %}
            {% if (currentPage === pn) { %}
            <li class="disabled"><a href="#">{%= pn %}</a></li>
            {% } else { %}
            <li><a href="#" data-id="{%= pn %}">{%= pn %}</a></li>
            {% }}) %}

            {% if (!inTrailingRange) { %}
            <li class="disabled"><a href="#">...</a></li>
            {% _.each(pagesOutsideLeadingRange.reverse(), function(n) { %}
            <li><a href="#" data-id="{%= n %}">{%= n %}</a></li>
            {% }); %}
            {% } %}
        </ul>
    </div>
</script>

<script type="text/html" id="template-list">
    <p>Total object count: {%= objects.totalCount %}</p>

    <p>Random number list:</p>
    <ul>
        {% objects.each(function (o){ %}
        <li>{%= o.get('key') %}</li>
        {% }) %}
    </ul>
    <div class="pages"></div>
</script>

CoffeeScript

eventBus =
  publish: ->
    @trigger arguments...
  subscribe: ->
    @on arguments...
_.extend(eventBus, Backbone.Events)


PagesView = Backbone.View.extend(
  #settings
  leadingPageRangeDisplayed: 10
  trailingPageRangeDisplayed: 10
  leadingPageRange: 8
  trailingPageRange: 8
  numPagesOutsideRange: 3
  adjacentPages: 2
  pageSize: 10
  #/settings

  #state
  totalCount: 0
  currentPage: 1
  #/state

  events:
    'click a': 'changePage'

  initialize: (totalCount) ->
    @totalCount = totalCount

  changePage: (e) ->
    e.preventDefault()
    oldPage = @currentPage
    id = $(e.target).data('id')
    if id? and id != @currentPage
      @currentPage = id
      eventBus.publish 'page:changed',
        currentPage: id
        oldPage: oldPage
        pageSize: @pageSize

  render: ->
    @recount()
    @$el.html _.template $('#template-pages').html(),
      pageNumbers: @pageNumbers
      currentPage: @currentPage
      inLeadingRange: @inLeadingRange
      pagesOutsideTrailingRange: @pagesOutsideTrailingRange
      inTrailingRange: @inTrailingRange
      pagesOutsideLeadingRange: @pagesOutsideLeadingRange

  recount: ->
    @inLeadingRange = false
    @inTrailingRange = false
    @pagesOutsideLeadingRange = _.range(0)
    @pagesOutsideTrailingRange = _.range(0)
    numPages = Math.ceil @totalCount / @pageSize
    
    if numPages <= @leadingPageRangeDisplayed + @numPagesOutsideRange + 1
      @inLeadingRange = @inTrailingRange = true
      @pageNumbers = _.filter(_.range(1, numPages + 1), (n) ->
        n > 0 and n <= numPages
      , this)
    else if @currentPage <= @leadingPageRange
      @inLeadingRange = true
      @pageNumbers = _.filter(_.range(1, @leadingPageRangeDisplayed + 1), (n) ->
        n > 0 and n <= numPages
      , this)
      @pagesOutsideLeadingRange = _.map(_.range(0, -1 * @numPagesOutsideRange, -1), (n) ->
        n + numPages
      , this)
    else if @currentPage > numPages - @trailingPageRange
      @inTrailingRange = true
     ...