1/** 2 * DokuWiki Plugin TagSections (JavaScript Component) 3 * 4 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 5 * @author gamma 6 */ 7 8(function() { 9 10 var currentNamespace = JSINFO['namespace']; 11 var $currentButton = null; 12 var init = function() { 13 14 jQuery('form.sectiontag__form').submit(function(event){ 15 16 $currentButton = jQuery(this); 17 request({availableTags: true, tagsForSection: true}, showTagSelection); 18 return false; 19 20 // Move the Tag button up to the header. Or close to it. 21 }).parent().css('margin-top', function(){ 22 23 var $tgt = jQuery(this), 24 nr = $tgt.attr('class').match(/(\s+|^)editbutton_(\d+)(\s+|$)/)[2], 25 $highlight = jQuery(); 26 27 // Walk the dom tree in reverse to find the sibling which is or contains the section edit marker 28 while($tgt.length > 0 && !($tgt.hasClass('sectionedit' + nr) || $tgt.find('.sectionedit' + nr).length)) { 29 $tgt = $tgt.prev(); 30 $highlight = $highlight.add($tgt); 31 } 32 // insert the section highlight wrapper before the last element added to $highlight 33 return $tgt.offset().top - $highlight.filter(':last').offset().top; 34 }); 35 }; 36 37 var showTagSelection = function(data) { 38 39 data = JSON.parse(data); 40 var $dialog = getDialog('open').html(''); 41 var $accordeon = jQuery('<div class="tagsections__accordeon"/>').appendTo($dialog); 42 data.availableTags = jQuery.extend( true, data.availableTags, data.tagsForSection); 43 44 if ( typeof data.availableTags[''] == 'undefined' ) { 45 data.availableTags[''] = {}; 46 } 47 48 var needsEmptySection = true; 49 jQuery.each(data.availableTags, function(namespace, entries){ 50 // namespaces 51 52 var $accordeonContent = jQuery('<div/>'); 53 54 needsEmptySection = false; 55 var checked = 0; 56 jQuery.each(entries, function(tag){ 57 58 var check = typeof data.tagsForSection != 'undefined' && 59 typeof data.tagsForSection[namespace] != 'undefined' && 60 typeof data.tagsForSection[namespace][tag] != 'undefined'; 61 creeateCheckBox(namespace, tag, check).appendTo($accordeonContent); 62 checked += check ? 1 : 0; 63 }); 64 65 // Add an input box to add new tags 66 additionalRows(namespace, $accordeonContent); 67 68 // Add new accordeon entry 69 $accordeon.append(createHeader(namespace, checked, Object.keys(entries).length)); 70 $accordeonContent.appendTo($accordeon); 71 }); 72 73 if ( needsEmptySection ) { 74 $accordeon.append(createHeader(null, 0, 0)); 75 76 var $content = jQuery('<div/>').appendTo($accordeon); 77 additionalRows(null, $content); 78 } 79 80 $accordeon.accordion({heightStyle: 'content',collapsible:true}); 81 }; 82 83 var createHeader = function(namespace, checked, entries) { 84 return jQuery('<h3/>').text(((namespace||LANG.plugins.tagsections['empty namespace']) + ' ' + checked + '/'+entries).trim() ); 85 }; 86 87 var creeateCheckBox = function(namespace, tag, checked) { 88 var tagName = (namespace||'').length > 0 ? namespace+':'+tag : tag; 89 var $element = jQuery('<input type="checkbox" class="tagsections__tag"/>').attr('name', tagName).val('1').attr('id', tagName).prop('checked', checked); 90 return jQuery('<label/>').attr('for', tagName).text(tag).append($element); 91 }; 92 93 var additionalRows = function(namespace, $root) { 94 95 var $newTagLine = jQuery('<hr/>').appendTo($root); 96 var $element = jQuery('<input class="tagsections__tag__new"/>').attr('id', namespace + '_newTag'); 97 var $button = jQuery('<input class="edit" type="submit"/>').val(LANG.plugins.tagsections['add']); 98 var $form = jQuery('<form/>').append($element).append($button); 99 jQuery('<label class="newTag"/>').attr('for', namespace + '_newTag').text(LANG.plugins.tagsections['new tag']).append($form).appendTo($root); 100 101 $form.submit(function(){ 102 103 var tag = $element.val(); 104 $newTagLine.before(creeateCheckBox(namespace, tag, true)); 105 $element.val(''); 106 107 return false; 108 }); 109 }; 110 111 var request = function(data, success) { 112 data['call'] = 'tagsections'; 113 data['id'] = JSINFO['id']; 114 data['ns'] = currentNamespace; 115 data['range'] = $currentButton.find('input.sectiontag_button').attr('range'); 116 return jQuery.post(DOKU_BASE + 'lib/exe/ajax.php', data, success); 117 }; 118 119 var saveTags = function() { 120 121 var newTags = []; 122 var elements = getDialog().find(".tagsections__accordeon input:checked").toArray(); 123 for(var i=0;typeof(elements[i])!='undefined';newTags.push(elements[i++].getAttribute('name'))); 124 125 request({tags:newTags, saveTags:true}, function(){ 126 request({contentOfPage:true}, function(data){ 127 128 var $toRemove = $currentButton.parent().parent().children(), 129 $tmpWrap = jQuery('<div style="display:none"></div>').html(data); // temporary wrapper 130 131 // insert the section highlight wrapper before the last element added to $tmpStore 132 $toRemove.filter(':last').before($tmpWrap); 133 // and remove the elements 134 $toRemove.detach(); 135 136 // Now remove the content again 137 $tmpWrap.before($tmpWrap.children().detach()); 138 // ...and remove the section highlight wrapper 139 $tmpWrap.detach(); 140 141 // Close Dialog. 142 getDialog('close'); 143 // Re-Init the page for edit buttons. 144 dw_page.init(); 145 init(); 146 }); 147 }); 148 }; 149 150 var getDialog = function(action) { 151 152 if(!jQuery('#tagsections__dilaog').length){ 153 jQuery('body').append('<div id="tagsections__dilaog" position="absolute" border=1 height="800px"><div id="tagsections__dialog_div"></div></div>'); 154 jQuery( "#tagsections__dilaog" ).dialog({title:LANG.plugins.tagsections['choose tags'], 155 height:600, 156 width: Math.min(700,jQuery(window).width()-50), 157 autoOpen:true, 158 buttons:[ 159 {text:LANG.plugins.tagsections['closeDialog'],click: function() { getDialog('close') }}, 160 {text:LANG.plugins.tagsections['save'],click: saveTags}, 161 ], 162 }); 163 } 164 165 if ( action ) { 166 return jQuery('#tagsections__dilaog').dialog(action); 167 } 168 169 return jQuery('#tagsections__dilaog'); 170 }; 171 172 jQuery(document).ready(init); 173})();