common.js 10.9 KB
var hash_interpreted = false;

var common = {};

$(function(){
  "use strict";
  var tabs = $('.tabs');
  tabs.tabs({
    show: function() {
      if (hash_interpreted)
        update_hash();
    }
  });
  $('button').button();
  $('input.datepicker').datepicker($.datepicker.regional.pl);
  $(document).on('mouseover', '.ui-state-default', function() {
    $(this).addClass('ui-state-hover');
  });
  $(document).on('mouseout', '.ui-state-default', function() {
    $(this).removeClass('ui-state-hover');
  });
  if ($dj.paginer || tabs.length > 0) {
    $(window).bind('hashchange', function() {
      var hash = location.hash.substr(1);
      interpret_hash(hash);
      hash_interpreted = true;
    });
    if (!$dj.paginer)
      $(window).trigger('hashchange');
  }
});

$.fn.disable = function() {
  "use strict";
  return this.prop('disabled', true);
};

$.fn.enable = function() {
  "use strict";
  return this.prop('disabled', false);
};

$.fn.value = function() {
  "use strict";
  if (this.is(':checkbox'))
    return this.prop('checked');
  else if (this.is(':radio'))
    return this.prop('checked')? this.val() : null;
  else
    return this.val();
};

$.fn.bind_hover = function(c) {
  "use strict";
  var elem = this;
  this.hover(
    function() {elem.addClass(c);},
    function() {elem.removeClass(c);}
  );
};

// skopiowane z http://jsfiddle.net/DkHyd/
$.fn.togglepanels = function(){
  "use strict";
  return this.each(function(){
    $(this).addClass("ui-accordion ui-accordion-icons ui-widget ui-helper-reset")
      .find("h3")
      .addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-top ui-corner-bottom")
      .hover(function() { $(this).toggleClass("ui-state-hover"); })
      .prepend('<span class="ui-icon ui-icon-triangle-1-e"></span>')
      .click(function() {
        $(this)
          .toggleClass("ui-accordion-header-active ui-state-active ui-state-default ui-corner-bottom")
          .find("> .ui-icon").toggleClass("ui-icon-triangle-1-e ui-icon-triangle-1-s").end()
          .next().slideToggle();
        return false;
      })
      .next()
      .addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom")
      .hide();
  });
};

function multiselect_toggle(select_el, option_value, enable) {
  "use strict";
  var select, widget, option;
  select = $(select_el);
  widget = select.multiselect2("widget");
  option = widget.find('[value="' + option_value + '"]');
  if (enable)
    option.enable();
  else
    option.disable();
  option.parent().toggleClass('ui-state-disabled', !enable);
  option.parent().parent().toggleClass('ui-multiselect-disabled', !enable);
}
common.multiselect_toggle = multiselect_toggle;

function multiselect_enable(select_el, option_value) {
  "use strict";
  var select, widget, option;
  select = $(select_el);
  widget = select.multiselect2("widget");
  option = widget.find('[value="' + option_value + '"]');
  option.enable();
  option.parent().removeClass('ui-state-disabled');
  option.parent().parent().removeClass('ui-multiselect-disabled');
}
common.multiselect_enable = multiselect_enable;

function error_alert(text) {
  "use strict";
  window.alert(text);
}
common.error_alert = error_alert;

// parametry: method, url, data | description, dest, callback, callback_args
$.ajaxJSON = function(params) {
  "use strict";
  var encoded_data = {};
  if (params.save && !before_save())
    return false;
  $.each(params.data, function(key, value) {
    encoded_data[key] = $.toJSON(value);
  });
  $.ajax({
    type: params.method,
    url: params.url,
    dataType: 'json',
    data: encoded_data,
    success: parse_result(params),
    error: params.error_callback
  });
  return true;
};

function blank(str) {
  "use strict";
  var re = /^[\t\n ]*$/;
  return re.test(str);
}
common.blank = blank;

function strip(str) {
  "use strict";
  return str.replace(/^\s+|\s+$/g, '');
}
common.strip = strip;

// parametry: description, dest, callback, callback_args
function parse_result(params) {
  "use strict";
  return function(data, status) {
    if(data.result !== 'ok' || status === 'error') {
      if(data.result === 'logout')
        error_alert("Sesja wygasła - zaloguj się i spróbuj ponownie.");
      else
        if (!params.bad_data_callback || params.bad_data_callback(data.result)) {
          var msg = params.description + ' ' + "nie powiodło się:\n";
          msg += data.result;
          error_alert(msg);
        }
    }
    else { // OK
      if (params.dest) {
        params.dest.html(data.html);
      }
      if (params.callback) {
        if (!params.callback_args)
          params.callback_args = [];
        var args = [data].concat(params.callback_args);
        params.callback.apply({}, args);
      }
    }
  };
}

function debug(content) {
  "use strict";
  var doc = $('#debug').contents().get(0);
  doc.open();
  doc.writeln(content);
  doc.close();
}

$(function() {
  "use strict";
  var debug = $('#debug'), main_menu = $('#main_menu');
  $('#show-debug').click(function() {
    debug.toggle();
  });
  debug.height($(window).height() - main_menu.height());
  debug.css('top', main_menu.height());
});

function parse_error(event, request, settings) {
  "use strict";
  debug(request.responseText);
  $('#show-debug').show();
}

//$.ajaxSetup({global: true, error: parse_error});

$(function() {
  "use strict";
  $('#debug').ajaxError(parse_error);
});

$('html').ajaxSend(function(event, xhr, settings) {
  "use strict";
  function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
   }
  if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
    // Only send the token to relative URLs i.e. locally.
    xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
  }
});

// http://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/2117698#2117698
(function($) {
  "use strict";
  $.fn.textMetrics = function() {
    var h, w, el = this;
    var div = document.createElement('div');
    document.body.appendChild(div);
    $(div).css({
      position: 'absolute',
      left: -1000,
      top: -1000,
      display: 'none'
    });
    $(div).html($(el).html());
    var styles = ['font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing'];
    $(styles).each(function() {
     var s = this.toString();
     $(div).css(s, $(el).css(s));
    });
    h = $(div).outerHeight();
    w = $(div).outerWidth();
    $(div).remove();
    return {
     height: h,
     width: w
    };
  };
})(jQuery);

function update_hash() {
  "use strict";
  var new_hash = make_hash();
  old_hash = new_hash;
  location.href = '#' + new_hash;
}
common.update_hash = update_hash;

function make_hash() {
  "use strict";
  var bottom_tabs, tabs, tab_path = [], query, id, data, original_data;
  var paginer_el;
  var are_tabs = $('.tabs').length > 0;
  if (are_tabs) {
    tabs = $('.tabs:visible').first();
    while (tabs.find('.tabs:visible').length > 0) {
      tabs = tabs.find('.tabs:visible').first();
    }
    bottom_tabs = tabs;
    do {
      tab_path.unshift(tabs.children('.ui-tabs-panel:visible')[0].id);
      tabs = tabs.parents('.tabs').first();
    } while (tabs.length > 0);
  } else
    tab_path = [''];
  paginer_el = $('.paginer:visible', bottom_tabs);
  if (paginer_el.length > 0) {
    id = paginer_el[0].id;
    data = $dj.paginer[id][1];
    original_data = $dj.original_paginer[id][1];
    query = [];
    if (data.order_by !== original_data.order_by)
      query.push('order_by=' + data.order_by);
    $.each(data.filters, function(i, filter) {
      if (i >= original_data.filters.length)
        query.push(filter[0] + '-' + filter[1] + '=' + filter[2]);
    });
    if (paginer.get_page_number(id) > 1)
      query.push('page=' + paginer.get_page_number(id));
    tab_path.push(query.join('&'));
  } else
    tab_path.push('');
  return tab_path.join('/');
}

var old_hash = 'not gonna happen';

function interpret_hash(hash) {
  "use strict";
  var data = hash.split('/'), children;
  if (hash === old_hash)
    return;
  var id, paginer_data, original_data, new_order_by, new_filters, new_page;
  var paginer_container, paginer_el;
  if (hash !== '')
    $.each(data.slice(0, data.length - 1), function(i, part) {
      if (part)
        $('#' + part).parents('.tabs').first().tabs('select', '#' + part);
    });
  else {
    paginer_container = $('.ui-tabs-panel').first();
    //hash_interpreted = false; // HACK
    while (paginer_container.length > 0) {
      paginer_container.parents('.tabs').first().tabs(
        'select', '#' + paginer_container[0].id);
      children = $('.ui-tabs-panel', paginer_container);
      if (children.length > 0)
        paginer_container = children.first();
      else
        paginer_container = children;
    }
    hash_interpreted = true; // HACK
  }
  if (window.paginer) {
    if (data[0] !== '')
      paginer_container = $('#' + data[data.length - 2]);
    else { // nie ma tabów (lub pusty hash...)
      paginer_container = $(document.body);
      do {
        children = $('.ui-tabs-panel:visible', paginer_container);
        if (children.length)
          paginer_container = children[0];
      } while(children.length);
    }
    paginer_el = $('.paginer', paginer_container);
    if (paginer_el.length > 0) {
      id = paginer_el[0].id;
      paginer_data = $dj.paginer[id][1];
      original_data = $dj.original_paginer[id][1];
      new_order_by = original_data.order_by;
      new_page = 1;
      new_filters = $.extend([], original_data.filters);
      if (data[data.length - 1])
        $.each(data[data.length - 1].split('&'), function(i, pair) {
          if (pair) {
            var p = pair.split('=', 2);
            var field_lookup = p[0].split('-', 2), value = p[1];
            var field = field_lookup[0], lookup = field_lookup[1];
            if (value === 'false')
              value = false;
            if (value === 'true')
              value = true; // nieodporne na tekstowe filtry (jeśli będą)
            if (p[0] === 'order_by') {
              new_order_by = value;
            } else if (p[0] === 'page') {
              new_page = window.parseInt(value);
            } else { // jakieś sprawdzanie poprawności? w sumie serwer to zrobi...
              new_filters.push([field, lookup, value]);
            }
          }
        });
      paginer_data.order_by = new_order_by;
      paginer_data.filters = new_filters;
      paginer.page_numbers[id] = new_page;
      paginer.update_list(id, true); // protect hash
      paginer.show_order(id);
      paginer.reload_panel(id);
    }
  }
  old_hash = hash;
}