$.widget("wpj.blocks", { options: { acn: 'edit', isSuperuser: false, itemsOuterContainerSelector: '#pageBlocksOuterContainer', defaultItemSelector: '[data-form-item="0"]', addRootItemBtnSelector: '[data-form-custom-add-root]', $inputRelations: $(''), newItemIndex: 0, ckeditorConfig: { customConfig: '/admin/static/js/ckeditor.js', "autoGrow_maxHeight": 0, "autoGrow_onStartup": true, toolbar: "BasicTable", filebrowserBrowseUrl: '/_ckfinder/browse/', filebrowserImageBrowseUrl: '/_ckfinder/browse/?rsrcType=Obrázky', filebrowserUploadUrl: '/ckfinder/connector?command=QuickUpload&type=Soubory', filebrowserImageUploadUrl: '/ckfinder/connector?command=QuickUpload&type=Obrázky' } }, _create: function () { this._super(); // append hidden input with block relations to closest form // value of this input will also change on successful drag&drop or after adding new item this.element.closest('form').append(this.options.$inputRelations); // save initial relations to hidden input this.refreshRelations(); // assign default item for creating new items this.$defaultItem = $(this.options.defaultItemSelector); var that = this; // initialize nestedSortable this.element.nestedSortable({ listType: 'ul', forcePlaceholderSize: true, handle: 'span.drag-drop-mover', helper: 'clone', items: 'li.blockItem', opacity: .6, placeholder: 'placeholder', revert: 250, tabSize: 25, tolerance: 'pointer', toleranceElement: '> div', update: function (event, ui) { that.refreshRelations(); // TODO fix freezing after drop - maybe think of sth better then recreating ckeditor var $item = $(ui.item); that.reinitializeCkeditor($item); $item.find('[data-form-item]').each(function(i,e) { that.reinitializeCkeditor($(e)); }); } }); initForm({ selector: this.options.itemsOuterContainerSelector, beforeAdd: this.postAddInit }); // add nested items this.element.on('click', '[data-form-custom-add]', function(event) { event.preventDefault(); var $item = $(this).closest('[data-form-item]'); var $container = $item.children('ul:last'); if (!$container.length) { $container = $(''); $item.append($container); } that.postAddInit(function() { return that.addItem($container) }); return false; }); // add root items $(this.options.addRootItemBtnSelector).on('click', function(event) { event.preventDefault(); that.postAddInit(function() { return that.addItem(that.element); }); }); // refresh block name this.element.on('input', 'input[name$="][name]"]', function(event) { var $input = $(this); var $item = $input.closest('[data-form-item]'); var $blockHeading = $item.children('.panel-heading'); $blockHeading.find('[data-block-heading-name]').text($input.val() == '' && !$item.is('[data-form-item-id]') ? '[Nový blok]' : $input.val()); }); this.element.on('keydown', null, 'ctrl+enter', function (e) { var data = e.data; if (data.modif == "ctrl+" && data.special == "return") { that.addItem(that.element); return false; } }); if (this.options.isSuperuser) { // refresh block identifier this.element.on('input', 'input[name$="][identifier]"]', function (event) { var $input = $(this); var $blockHeading = $input.closest('[data-form-item]').children('.panel-heading'); $blockHeading.find('[data-block-heading-identifier]').text($input.val() == '' ? '' : $input.val()); }); } // initialize ckeditor when block is being opened this.element.on('show.bs.collapse', '.blockItem', function(event) { var $item = $(event.currentTarget); var $textarea = $item.find('[name="data[blocks][' + $item.attr('data-form-item') + '][content]"]'); if (!$textarea.length || $textarea.attr('name') in CKEDITOR.instances ) { return; } CKEDITOR.replace($textarea.attr('name'), that.options.ckeditorConfig) }); // focus ckeditor after opening block animation this.element.on('shown.bs.collapse', '.blockItem', function(event) { var $item = $(event.currentTarget); var $textarea = $item.find('[name="data[blocks][' + $item.attr('data-form-item') + '][content]"]'); if (!$textarea.length) return; if ($textarea.attr('name') in CKEDITOR.instances ) { CKEDITOR.instances[$textarea.attr('name')].focus(); } }); this.element.find('.blockItem:not([data-form-index="0"])').each(function(index, el) { that.initPhotos($(el)); }); }, refreshRelations: function() { var relations = { }; this.element.find('[data-form-index]').each(function(index, el) { var $item = $(el); var $parentItem = $item.parent('ul').parent('[data-form-item]'); // parentID for already existing blocks, parentIndex (data-form-item) for new blocks if ($parentItem.length && !$parentItem.is('[data-form-item-id]')) { relations[$item.attr('data-form-item')] = { 'parentIndex': $parentItem.attr('data-form-item') }; } else { relations[$item.attr('data-form-item')] = { 'parentID': $parentItem.length ? $parentItem.data('form-item-id') : null, 'parentIndex': $parentItem.length ? $parentItem.attr('data-form-item') : null }; } }); relations = JSON.stringify(relations); this.options.$inputRelations.val(relations); }, reinitializeCkeditor: function($item) { var $textarea = $item.find('[name="data[blocks][' + $item.attr('data-form-item') + '][content]"]'); if (!$textarea.length) return; var $newTextarea = $textarea.clone(); var $textareaContainer = $textarea.parent(); for (var instanceName in CKEDITOR.instances) { if (CKEDITOR.instances[instanceName]['name'] == $textarea.attr('name')) { $newTextarea.html(CKEDITOR.instances[instanceName].getData()); CKEDITOR.remove(CKEDITOR.instances[instanceName]); break; } } $textareaContainer.html($newTextarea); CKEDITOR.replace($newTextarea.attr('name'), this.options.ckeditorConfig); }, initPhotos: function($item) { $item.find('.photo-select:first').chosen({ width: '100%', placeholder_text_multiple: 'Vyberte obrázky' }); }, addItem: function($container) { var newItemIndex = --this.options.newItemIndex; unstyleFormInputs(this.$defaultItem); var $newItem = this.$defaultItem.clone(); $newItem.attr('data-form-item', newItemIndex); $newItem.children('[data-target="#collapse_0"]').attr('data-target', '#collapse_' + newItemIndex); $newItem.children('#collapse_0').attr('id', 'collapse_' + newItemIndex); $newItem.find('[name="data[blocks][0][delete]"]').attr('name', 'data[blocks][' + newItemIndex + '][delete]'); $newItem.find('[name="data[blocks][0][name]"]').attr('name', 'data[blocks][' + newItemIndex + '][name]'); $newItem.find('[name="data[blocks][0][identifier]"]').attr('name', 'data[blocks][' + newItemIndex + '][identifier]'); $newItem.find('[name="data[blocks][0][content]"]').attr('name', 'data[blocks][' + newItemIndex + '][content]'); $newItem.find('[name="data[blocks][0][photos][]"]').attr('name', 'data[blocks][' + newItemIndex + '][photos][]'); $container.append($newItem); this.refreshRelations(); $newItem.slideDown(150, function() { // animate block form $newItem.find('> .panel-heading:first').trigger('click'); }); styleFormInputs($newItem); this.initPhotos($newItem); return $newItem; }, postAddInit: function(original, $container) { var $form = original(); var name = $form.find('textarea').attr('name'); if (name) CKEDITOR.replace(name, this.options.ckeditorConfig); // scroll to new item $('html,body').animate({ scrollTop: $form.offset().top }); } });