Skip to content
This repository has been archived by the owner on Dec 5, 2018. It is now read-only.

Commit

Permalink
Use a custom deform.js file
Browse files Browse the repository at this point in the history
Allows us to fix :
Pylons/deform#276
Pylons/deform#275 ( for task forms only )
  • Loading branch information
G.Tjebbes committed Jul 17, 2015
1 parent d7d96d0 commit 718c025
Show file tree
Hide file tree
Showing 5 changed files with 232 additions and 17 deletions.
6 changes: 3 additions & 3 deletions autonomie/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@
from autonomie.models.config import get_config
from autonomie.utils.avatar import get_groups
from autonomie.utils.avatar import get_avatar
from autonomie.utils.renderer import (
customize_renderers,
)
from autonomie.utils.session import get_session_factory


Expand Down Expand Up @@ -180,6 +177,9 @@ def base_configure(config, dbsession, **settings):
for module in AUTONOMIE_ADMIN_MODULES:
config.include(module)

from autonomie.utils.renderer import (
customize_renderers,
)
customize_renderers(config)
return config

Expand Down
26 changes: 15 additions & 11 deletions autonomie/deform_templates/tasklines_sequence.pt
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
<div class="col-md-offset-9">
<button
type='button'
class="btn btn-info"
class="btn btn-info taskline-add"
id="${field.oid}-seqAdd"
onclick="javascript: return addTaskLine(this); ">
<small id="${field.oid}-addtext">${add_subitem_text}</small>
Expand All @@ -72,25 +72,23 @@
<!-- end custom -->

<script type="text/javascript">
var field_oid = "${field.oid}";
deform.addCallback(
'${field.oid}',
field_oid,
function(oid) {
oid_node = $('#'+ oid);
deform.processSequenceButtons(oid_node, ${min_len},
${max_len}, ${now_len},
${orderable});
}
)
<tal:block condition="orderable">
$( "#${oid}-orderable" ).sortable({
$( "#" + field_oid + "-orderable" ).sortable({
handle: ".deformOrderbutton, .panel-heading",
containerSelector: "#${oid}-orderable",
containerSelector: "#" + field_oid + "-orderable",
itemSelector: ".deformSeqItem",
placeholder: '<span class="glyphicon glyphicon-arrow-right placeholder"></span>',
start: function(e, ui){
$(this).find('textarea.tinymce').each(function(){
// On retrouve la hauteur l'instance de tinymce (qui est
// juste avant le textarea)
var height = $(this).prev().height();
tinyMCE.execCommand( 'mceRemoveEditor', false, $(this).attr('id') );
$(this).height("15px");
$(this).height(height);
});
},
stop: function(e, ui){
Expand All @@ -117,6 +115,12 @@
}
});
</tal:block>
oid_node = $('#'+ oid);
deform.processSequenceButtons(oid_node, ${min_len},
${max_len}, ${now_len},
${orderable});
}
);
</script>
</div>
<hr/>
Expand Down
10 changes: 8 additions & 2 deletions autonomie/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@

lib_autonomie = Library("fanstatic", "static")

# ui_dialog.depends.add(bootstrap_js)


def get_resource(filepath, minified=None, depends=None):
"""
Expand All @@ -59,6 +57,14 @@ def get_resource(filepath, minified=None, depends=None):
)


# ui_dialog.depends.add(bootstrap_js)
# To fix https://github.com/Pylons/deform/issues/276
# https://github.com/Pylons/deform/issues/275 (only in the case of task forms
# because we use custom templates)
# We use a custom deform js
custom_deform_js = get_resource("js/custom_deform.js")


def get_main_group():
"""
Return the main resource Group that will be used on all pages
Expand Down
196 changes: 196 additions & 0 deletions autonomie/static/js/custom_deform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
/*
* Register a top-level callback to the deform.load() function
* this will be called when the DOM has finished loading. No need
* to include the call at the end of the page.
*/

$(document).ready(function(){
deform.load();
});


var deform_loaded = false;

var deform = {
callbacks: [],

addCallback: function (oid, callback) {
deform.callbacks.push([oid, callback]);
},

clearCallbacks: function () {
deform.callbacks = [];
},

load: function() {
$(function() {
if (!deform_loaded) {
deform.processCallbacks();
deform.focusFirstInput();
deform_loaded = true;
}});
},


processCallbacks: function () {
$(deform.callbacks).each(function(num, item) {
var oid = item[0];
var callback = item[1];
callback(oid);
}
);
deform.clearCallbacks();
},

addSequenceItem: function (protonode, before) {
// - Clone the prototype node and add it before the "before" node.
// Also ensure any callbacks are run for the widget.

// In order to avoid breaking accessibility:
//
// - Find each tag within the prototype node with an id
// that has the string ``deformField(\d+)`` within it, and modify
// its id to have a random component.
// - For each label referencing an change id, change the label's
// for attribute to the new id.

var fieldmatch = /deformField(\d+)/;
var namematch = /(.+)?-[#]{3}/;
var jsvarmatch = /var field_oid = "deformField(\d+)";/;
var code = protonode.attr('prototype');
var html = decodeURIComponent(code);
var genid = deform.randomString(6);
html = html.replace(jsvarmatch, "var field_oid = \"deformField$1-" + genid + "\";");
var $htmlnode = $(html);
var $idnodes = $htmlnode.find('[id]');
var $namednodes = $htmlnode.find('[name]');
var idmap = {};

// replace ids containing ``deformField`` and associated label for=
// items which point at them

$idnodes.each(function(idx, node) {
var $node = $(node);
var oldid = $node.attr('id');
var newid = oldid.replace(fieldmatch, "deformField$1-" + genid);
$node.attr('id', newid);
idmap[oldid] = newid;
var labelselector = 'label[for=' + oldid + ']';
var $fornodes = $htmlnode.find(labelselector);
$fornodes.attr('for', newid);
});

// replace names a containing ```deformField`` like we do for ids

$namednodes.each(function(idx, node) {
var $node = $(node);
var oldname = $node.attr('name');
var newname = oldname.replace(fieldmatch, "deformField$1-" + genid);
$node.attr('name', newname);
});

$htmlnode.insertBefore(before);

$(deform.callbacks).each(function(num, item) {
var oid = item[0];
var callback = item[1];
var newid = idmap[oid];
if (newid) {
callback(newid);
}
});

deform.clearCallbacks();
var old_len = parseInt(before.attr('now_len')||'0', 10);
before.attr('now_len', old_len + 1);
// we added something to the dom, trigger a change event
var e = jQuery.Event("change");
$('#deform').trigger(e);
},

appendSequenceItem: function(node) {
var $oid_node = $(node).closest('.deformSeq');
var $proto_node = $oid_node.find('.deformProto').first();
var $before_node = $oid_node.find('.deformInsertBefore').last();
var min_len = parseInt($before_node.attr('min_len')||'0', 10);
var max_len = parseInt($before_node.attr('max_len')||'9999', 10);
var now_len = parseInt($before_node.attr('now_len')||'0', 10);
var orderable = parseInt($before_node.attr('orderable')||'0', 10);

if (now_len < max_len) {
deform.addSequenceItem($proto_node, $before_node);
deform.processSequenceButtons($oid_node, min_len, max_len,
now_len + 1, orderable);
}
return false;
},

removeSequenceItem: function(clicked) {
var $item_node = $(clicked).closest('.deformSeqItem');
var $oid_node = $item_node.closest('.deformSeq');
var $before_node = $oid_node.find('.deformInsertBefore').last();
var min_len = parseInt($before_node.attr('min_len')||'0', 10);
var max_len = parseInt($before_node.attr('max_len')||'9999', 10);
var now_len = parseInt($before_node.attr('now_len')||'0', 10);
var orderable = parseInt($before_node.attr('orderable')||'0', 10);
if (now_len > min_len) {
$before_node.attr('now_len', now_len - 1);
$item_node.remove();
deform.processSequenceButtons($oid_node, min_len, max_len,
now_len-1, orderable);
}
// we removed something from the dom, trigger a change event
var e = jQuery.Event("change");
$('#deform').trigger(e);
return false;
},

processSequenceButtons: function(oid_node, min_len, max_len, now_len,
orderable) {
orderable = !!orderable; // convert to bool
var has_multiple = now_len > 1;
var $ul = oid_node.children('.deformSeqContainer:not(.deformSeq .deformSeqContainer)');
var $lis = $ul.find('.deformSeqItem:not(.deformSeqContainer .deformSeqItem)');
var show_closebutton = now_len > min_len;
var show_addbutton = now_len < max_len;
$lis.find('.deformClosebutton').toggle(show_closebutton);
oid_node.find('.deformSeqAdd').toggle(show_addbutton);
$lis.find('.deformOrderbutton').toggle(orderable && has_multiple);
},

focusFirstInput: function (el) {
el = el || document.body;
var input = $(el).find(':input')
.filter('[id ^= deformField]')
.filter('[type != hidden]')
.first();
if (input) {
var raw = input.get(0);
if (raw) {
if (raw.type === 'text' || raw.type === 'file' ||
raw.type == 'password' || raw.type == 'text' ||
raw.type == 'textarea') {
if (!input.hasClass("hasDatepicker")) {
input.focus();
}
}
}
}
},

randomString: function (length) {
var chr='0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz';
chr = chr.split('');

if (! length) {
length = Math.floor(Math.random() * chr.length);
}

var str = '';
for (var i = 0; i < length; i++) {
str += chr[Math.floor(Math.random() * chr.length)];
}
return str;
}

};
11 changes: 10 additions & 1 deletion autonomie/utils/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
from pyramid.threadlocal import get_current_request


log = logging.getLogger(__name__)
logger = logging.getLogger(__name__)


class CustomRenderer(ZPTRendererFactory):
Expand Down Expand Up @@ -128,6 +128,14 @@ def set_export_blacklist():
BLACKLISTED_KEYS = ('_acl', 'password', 'parent_id', 'parent', 'type_')


def set_custom_deform_js():
from js import deform
from autonomie.resources import custom_deform_js
logger.debug(u"Overriding the default deform_js resource")
deform.deform_js = custom_deform_js
deform.resource_mapping['deform'] = [custom_deform_js]


def customize_renderers(config):
"""
Customize the different renderers
Expand All @@ -139,3 +147,4 @@ def customize_renderers(config):
# Exporters
set_export_formatters()
set_export_blacklist()
set_custom_deform_js()

0 comments on commit 718c025

Please sign in to comment.