/* * 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 code = protonode.attr('prototype'); var html = decodeURIComponent(code); var $htmlnode = $(html); var $idnodes = $htmlnode.find('[id]'); var $namednodes = $htmlnode.find('[name]'); var genid = deform.randomString(6); 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('.deform-seq'); var $proto_node = $oid_node.find('.deform-proto').first(); var $before_node = $oid_node.find('.deform-insert-before').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('.deform-seq-item'); var $oid_node = $item_node.closest('.deform-seq'); var $before_node = $oid_node.find('.deform-insert-before').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.find('.deform-seq-container').not(oid_node.find('.deform-seq-container .deform-seq-container')); var $lis = $ul.find('.deform-seq-item').not($ul.find('.deform-seq-container .deform-seq-item')); var show_closebutton = now_len > min_len; var show_addbutton = now_len < max_len; $lis.find('.deform-close-button').not($lis.find('.deform-seq-container .deform-close-button')).toggle(show_closebutton); oid_node.find('.deform-seq-add').not(oid_node.find('.deform-seq-container .deform-seq-add')).toggle(show_addbutton); $lis.find('.deform-order-button').not($lis.find('.deform-seq-container .deform-order-button')).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; } };