{% comment %}Include needed stuff in ``<head>`` to make a table orderable

This template file is to be included in the ``<head>`` of an html document.

It will add a ``<script>`` tag to allow orderable table to work, and also ``<link>`` and
``<script src=...>`` tags to load external css and js files.

External files loaded are:
- jquery ui css, minified
- jquery ui js, minified

You can skip loading these two files by passing ``no_jqueryui=True`` in the ``include`` tag.

Once this include is added in the template, simply add the ``orderable`` class to your ``<table>``
and add a column which will hold the ordering stuff:
- in the table head, a cell with the ``orderable-message-holder`` class
- in the table body, on each line, a cell with the ``sort_order_display`` attribute of the object
  that must be an instance a a model inheriting from ``orderable.models.Orderable``.

Note that to render this cell, you must use the ``|safe`` template filter (see example below).

Your ``table`` html tag may contains the following attributes:

- ``data-orderable-post-url``: the url to use to POST via ajax the new order (if not set, the
                               current url will be user)
- ``data-orderable-message-holder``: a selector to pass to jquery that will be used to set the
                                     success or error message after ajax POSTs (if not set,
                                     a element with the class ``orderable-message-holder`` in the
                                     table will be used, and if it doesn't exist, no messages will
                                     be displayed).

This include is better used on a django view that inherits from
``mtp.apps.common.view_utls.OrderableListMixin``, so the saving will be done automatically.

Arguments
---------
no_jqueryui
    Default to ``False``, set it to ``True`` to not include tags to load jquery-ui css and js.

Example
-------

    {% block head %}
        {{ block.super }}
        {% include "cms/includes/orderable-head.html" %}
    {% endblock head %}

    {% block main %}
        <table class="table table-hover table-striped orderable">
            <thead>
                <tr>
                    <th>{% trans 'Name'%}</th>
                    <th class="orderable-message-holder">{% trans 'Order' %}</th>
                </tr>
            </thead>
            <tbody>
                {% for obj in obj_list %}
                    <tr>
                        <td>{{ obj.name }}</td>
                        <td>{{ obj.sort_order_display|safe }}</td>
                    </tr>
                {% endfor %}
            </tbody>
        </table>
    {% endblock main %}


TODO: have a common place in our whole app for jquery-ui

{% endcomment %}

{% load i18n %}

{% if not no_jqueryui %}
    <link rel="stylesheet" href="{{ STATIC_URL }}trainings/js/themes/base/minified/jquery-ui.min.css" type="text/css" media="screen" charset="utf-8" />
    <script type="text/javascript" src="{{ STATIC_URL }}trainings/js/ui/minified/jquery-ui.min.js"></script>
{% endif %}

<script type="text/javascript" charset="utf-8">
(function ($) {
    $(document).ready(function() {

        var activate_orderable = function() {

            var $table = $(this),
                $tbody = $table.children('tbody'),
                $trs = $tbody.children('tr'),
                $msg_holder = $table.data('orderable-message-holder');

            if ($msg_holder) {
                $msg_holder = $(msg_holder);
                if (!$msg_holder.length) { $msg_holder = null; }
            }
            if (!$msg_holder) {
                $msg_holder = $table.find('.orderable-message-holder');
                if (!$msg_holder.length) { $msg_holder = null; }
            }

            // Steal the draghandle's id and apply to the row
            $trs.each(function() {
                var $tr = $(this),
                    $handle = $tr.find('.sorthandle');
                $tr.attr('id', $handle.attr('id'));
                $handle.attr('id', '');
                //take it off the child
            });

            var $handles = $table.find('.sorthandle');
            $handles.html("<img src='{{ STATIC_URL }}admin/img/drag_handle.gif' width='11' height='11' title='{% trans 'Drag to reorder' %}' />")
                    .parent().addClass("sorthandletd").css("cursor", "pointer");

            // Force a width onto all the tds (so they drag nicely)
            $trs.children().each(function() {
                var $td = $(this);
                $td.width($td.width());
            });

            var msg_timer = null;
            var display_message = function(msg, color) {
                if (msg_timer) {
                    clearTimeout(msg_timer);
                }
                if (!$msg_holder) { return; }
                var $span = $msg_holder.children('.orderable-message');
                if (!$span.length) {
                    $span.remove();
                }
                $span = $("<span class='orderable-message' style='margin-left: 1ex; color: " + color + "'>" + msg +  "</span>");
                $msg_holder.append($span);
                msg_timer = setTimeout(function() {
                    $span.fadeOut(200);
                }, 1000);
            };

            // Call `sortable` from jquery-ui to activate the ordering by drag and drop.
            $tbody.sortable({
                'axis': 'y',
                'cursor': 'crosshair',
                'handle': '.sorthandletd',
                'forcePlaceholderSize': true,
                'update': function() {

                    var data = $(this).sortable("serialize", {expression: /^(neworder)\-(.+)$/});
                    data += '&csrfmiddlewaretoken=' + $("input[name=csrfmiddlewaretoken]").val();

                    var ajax_conf = {
                        type: "POST",
                        data: data
                    };

                    var orderable_post_url = $table.data('orderable-post-url');
                    if (orderable_post_url) {
                        ajax_conf['url'] = orderable_post_url;
                    }

                    $.ajax(ajax_conf).success(function() {
                        display_message("({% trans 'saved' %})", 'green');
                    }).error(function() {
                        alert("{% trans 'Failed to save new order. You may want to refresh the page.' %}");
                        display_message("({% trans 'failed' %})", 'red');
                    });

                } // update

            }); // $tbody.sortable

        }; // activate_orderable

        // Activate ordering on each orderable table
        $('table.orderable').each(activate_orderable);

    })})($);
</script>
