Fix datepicker arrows style on hover
[cds-indico.git] / indico / MaKaC / webinterface / tpls / ConfModifBadgeDesign.tpl
blobafa21ff2468e46b4dde4a833f58cca0c98705850
1 <script type="text/javascript">
3     <%block name="defaults">
4         TPL_DEFAULT_SIZE = [425, 270];
6         // "Zoom factor" - ratio between font
7         // size on screen and on paper
8         var zoom_factor = 1;
9         var numeric_mode = false;
10     </%block>
12     var snapToGrid = false;
14     // Dimensions of the template space, in pixels
15     var templateDimensions;
17     // Previous dimensions of the template space, in cm
18     var previousTemplateDimensions;
20     // Number of pixels per cm
21     var pixelsPerCm = 50 * zoom_factor;
23     // Id of the background used
24     var backgroundId = -1;
25     var backgroundPos;
27     // Number of pixels, both horizontal and vertical, that are between the top left corner
28     // and the position where items are inserted
29     var initialOffset = pixelsPerCm;
31     // Id of the next element to be inserted
32     var itemId = -1;
34     // Common parts of many elements
35     var elementCommon1 = '<table border="2" cellpadding="0" cellspacing="0" style="cursor:move;" width="200"><tbody><tr><td align="center">';
36     var elementCommon2 = '</td></tr></tbody></table>';
38     // Last selected item (holds the div for that item)
39     var lastSelectedDiv = null;
41     // Translation dictionary from key to name in current language.
42     var translate = ${translateName};
44     // List of template items
45     var items = [];
47     // Pointer for the jQuery-UI tabs later.
48     var controlTabs = null;
50     // Item class
51     function Item(itemId, key) {
52         this.id = itemId;
53         this.key = key;
54         this.x = initialOffset;
55         this.y = initialOffset;
56         this.fontFamily = "Times New Roman";
57         this.bold = false;
58         this.italic = false;
59         this.textAlign = "Center";
60         this.color = "black";
61         this.fontSize = "25pt";
62         this.width = 400;
63         this.text = $T("Fixed text");
65         // The following attributes have no meaning to the server
66         this.selected = false;
67         this.fontFamilyIndex = 0;
68         this.styleIndex = 0;
69         this.textAlignIndex = 2; //Center
70         this.colorIndex = 0;
71         this.fontSizeIndex = 11; //Medium
72     }
74     Item.prototype.toHTML = function () {
75         return '<table border="2" cellpadding="0" cellspacing="0"' +
76                ' width="' + this.width + '"'  +
77                ' style="background-color: '+(this.selected ? "#ccf" : "#fff")+';cursor:move; font-weight:' + (this.bold ? 'bold' : 'normal') + '; font-style:' + (this.italic ? 'italic' : 'normal') +
78                '; text-align: ' + this.textAlign.replace('Justified', 'justify') + ';"' +
79                '><tbody><tr><td><span style="color:' + this.color + '; font-family: ' + this.fontFamily + '; font-size:' + this.fontSize + ';">' +
80                (this.key == "Fixed Text" ? this.text : translate[this.key]) +
81                '</span></td></tr></tbody></table>';
82     }
84     // Dimensions class
85     function Dimensions(width, height) {
86         this.width = width
87         this.height = height
88     }
90     // This function creates a new draggable div
91     function createDiv() {
92         // Each div has:
93         // -a unique id, which is a natural number (0, 1, 2, ...)
94         // -a type (stored in the name attribute)
95         // -absolute x,y position
96         // -an inner HTML with its content
97         itemId++;
99         var newDiv = $('<div/>', {
100             id: itemId
101         }).css({
102             position: 'absolute',
103             left: initialOffset + 'px',
104             top: initialOffset + 'px',
105             zIndex: itemId + 10
106         }).appendTo('#templateDiv');
108         newDiv.draggable({
109             containment: '#templateDiv',
110             stack: '#templateDiv > div',
111             opacity: 0.5,
112             drag: function(e, ui) {
113                 if (snapToGrid) {
114                     ui.position.left = Math.floor(ui.position.left / 10) * 10;
115                     ui.position.top = Math.floor(ui.position.top / 10) * 10;
116                 }
117             },
118             stop: function(e, ui) {
119                 items[this.id].x = ui.position.left;
120                 items[this.id].y = ui.position.top;
121             }
122         });
124         return newDiv;
125     }
127     // This function inserts the selected element in the blank space where template designing takes place
128     function insertElement() {
129         var newDiv = createDiv();
130         // We set the inner html of the div depending on the type of item inserted
131         switch($('#elementList').val()) {
132             ${ switchCases }
133         }
135         if (!lastSelectedDiv) {
136             markSelected(newDiv);
137         }
139         initialOffset += 10;
140     }
142     function removeElement() {
143         if (lastSelectedDiv) {
144             items[lastSelectedDiv.attr('id')] = false;
145             lastSelectedDiv.remove();
146             $('#selection_text').html('');
147             lastSelectedDiv = null;
148             $('#modify_panel').hide();
149             $('#tab_format').hide();
150             controlTabs.tabs('option', 'active', 0);
152         }
153     }
155     function markSelected(newSelectedDiv) {
156         // Change the text that says which item is selected
157         var id = newSelectedDiv.attr('id');
158         $('#selection_text').html(translate[items[id].key]);
160         // Bring highlight to the element modification tab.
161         if (controlTabs) controlTabs.tabs('option', 'active', 1);
163         // TODO: add check to see if there's a table inside and not an image
165         // Change the background color of the old selected item and the new selected item
166         if (lastSelectedDiv) {
167             var lastId = lastSelectedDiv.attr('id');
168             items[lastId].selected = false;
169             lastSelectedDiv.find('> table').css('backgroundColor', '#fff');
170         }
172         var newSelectedItem = items[id];
173         newSelectedItem.selected = true;
174         newSelectedDiv.find('> table').css('backgroundColor', '#ccf');
175         lastSelectedDiv = newSelectedDiv;
177         $('#modify_panel').show();
178         $('#tab_format').show();
179         // Change the selectors so that they match the properties of the item
180         $('#alignment_selector').prop('selectedIndex', newSelectedItem.textAlignIndex);
181         $('#font_selector').prop('selectedIndex', newSelectedItem.fontFamilyIndex);
182         $('#size_selector').prop('selectedIndex', newSelectedItem.fontSizeIndex);
183         $('#style_selector').prop('selectedIndex', newSelectedItem.styleIndex);
184         $('#color_selector').prop('selectedIndex', newSelectedItem.colorIndex);
185         $('#width_field').val(newSelectedItem.width / pixelsPerCm);
187         if (newSelectedItem.key == "Fixed Text") {
188             $('#fixedTextContainer').fadeIn();
189             $('#fixed_text_field').val(newSelectedItem.text);
190         } else {
191             $('#fixedTextContainer').fadeOut();
192             $('#fixed_text_field').val("");
193         }
194     }
196     function inlineEdit(div) {
197         var id = div.attr('id');
198         var selectedItem = items[id];
200         // Handle the individual cases as required.
201         if (selectedItem.key == "Fixed Text") {
202             var text = prompt("Enter fixed-text value", selectedItem.text);
204             if (text) {
205                 selectedItem.text = text;
206                 div.html(selectedItem.toHTML());
208                 markSelected(div); // Update the fixed-text field
209             }
210         }
211     }
213     function updateRulers() {
214         if (templateDimensions.width > previousTemplateDimensions.width) {
215             var hRuler = $('#horizontal_ruler');
216             for (var i = Math.ceil(previousTemplateDimensions.width / pixelsPerCm); i < Math.ceil(templateDimensions.width / pixelsPerCm); i++) {
218                 $('<div class="marking"/>', {
219                      id: 'rulerh' + i
220                 }).css({
221                     width: pixelsPerCm + 'px',
222                     left: (i * pixelsPerCm) + 'px',
223                     top: 0
224                 }).html(i + 1).appendTo(hRuler);
225             }
226         }
227         else if (templateDimensions.width < previousTemplateDimensions.width) {
228             for (var i = Math.ceil(previousTemplateDimensions.width / pixelsPerCm); i > Math.ceil(templateDimensions.width / pixelsPerCm); i--) {
229                 $('#horizontal_ruler' + (i - 1)).remove();
230             }
231         }
233         if (templateDimensions.height > previousTemplateDimensions.height) {
234             var vRuler = $('#vertical_ruler');
235             for (var i = Math.ceil(previousTemplateDimensions.height / pixelsPerCm); i < Math.ceil(templateDimensions.height / pixelsPerCm); i++) {
236                 $('<div class="marking"/>', {
237                     id: 'rulerv' + i
238                 }).css({
239                     'line-height': pixelsPerCm/2.0 + 'px',
240                     height: pixelsPerCm  + 'px',
241                     left: 0,
242                     top: (i * pixelsPerCm) + 'px'
243                 }).html(i + 1).appendTo(vRuler);
244             }
245         }
246         else if (templateDimensions.height < previousTemplateDimensions.height) {
247             for (i = Math.ceil(previousTemplateDimensions.height / pixelsPerCm); i > Math.ceil(templateDimensions.height / pixelsPerCm); i--) {
248                 $('#vertical_ruler > #rulerv' + (i - 1)).remove();
249             }
250         }
251     }
253     // This function displays all the items in the 'items' array on the screen
254     // If there are already some items being displayed, it does not erase them
255     function displayItems() {
256         $.each(items, function(i, item) {
257             var newDiv = createDiv();
258             newDiv.css({
259                 left: item.x + 'px',
260                 top: item.y + 'px'
261             });
262             item.fontSize = zoom_font(zoom_factor, item.fontSize);
263             newDiv.html(item.toHTML());
264             if (item.selected) {
265                 markSelected(newDiv);
266             }
267         });
268     }
271     function changeTemplateSize() {
272         var tpl = $('#templateDiv');
273         tpl.width($('#badge_width').val() * pixelsPerCm);
274         tpl.height($('#badge_height').val() * pixelsPerCm);
275         previousTemplateDimensions.width = templateDimensions.width;
276         previousTemplateDimensions.height = templateDimensions.height;
277         templateDimensions = new Dimensions($('#badge_width').val() * pixelsPerCm, $('#badge_height').val() * pixelsPerCm);
278         updateRulers();
279         if (backgroundId != -1) {
280             var url = $('#background').attr('src');
281             $('#background').remove();
282             displayBackground(url);
283         }
284     }
286     var moveFuncs = {
287         left: function() {
288             if (lastSelectedDiv) {
289                 lastSelectedDiv.css('left', 0);
290                 items[lastSelectedDiv.attr('id')].x = 0 + "px";
291             }
292         },
293         right: function() {
294             if (lastSelectedDiv) {
295                 lastSelectedDiv.css('left', (templateDimensions.width - lastSelectedDiv.width() - 1) + "px"); // -1 because of the table border
296                 items[lastSelectedDiv.attr('id')].x = (templateDimensions.width - lastSelectedDiv.width() - 1) + "px";
297             }
298         },
299         center: function() {
300             if (lastSelectedDiv) {
301                 lastSelectedDiv.css('left', ((templateDimensions.width - lastSelectedDiv.width() - 1) / 2) + "px");
302                 lastSelectedDiv.css('top', ((templateDimensions.height - lastSelectedDiv.height() - 1) / 2) + "px");
303                 items[lastSelectedDiv.attr('id')].x = ((templateDimensions.width - lastSelectedDiv.width() - 1) / 2) + "px";
304                 items[lastSelectedDiv.attr('id')].y = ((templateDimensions.height - lastSelectedDiv.height() - 1) / 2) + "px";
305             }
306         },
307         top: function() {
308             if (lastSelectedDiv) {
309                 lastSelectedDiv.css('top', 0);
310                 items[lastSelectedDiv.attr('id')].y = 0 + "px";
311             }
312         },
313         bottom: function() {
314             if (lastSelectedDiv) {
315                 lastSelectedDiv.css('top', (templateDimensions.height - lastSelectedDiv.height() - 1) + "px");
316                 items[lastSelectedDiv.attr('id')].y = (templateDimensions.height - lastSelectedDiv.height() - 1) + "px";
317             }
318         }
319     };
321     var attrFuncs = {
322         font: function() {
323             if (lastSelectedDiv) {
324                 var item = items[lastSelectedDiv.attr('id')];
325                 item.fontFamily = $('#font_selector').val();
326                 item.fontFamilyIndex = $('#font_selector').prop('selectedIndex');
327                 lastSelectedDiv.html(item.toHTML());
328             }
329         },
330         color: function() {
331             if (lastSelectedDiv) {
332                 var item = items[lastSelectedDiv.attr('id')];
333                 item.color = $('#color_selector').val();
334                 item.colorIndex = $('#color_selector').prop('selectedIndex');
335                 lastSelectedDiv.html(item.toHTML());
336             }
337         },
338         alignment: function() {
339             if (lastSelectedDiv) {
340                 var item = items[lastSelectedDiv.attr('id')];
341                 item.textAlign = $('#alignment_selector').val();
342                 item.textAlignIndex = $('#alignment_selector').prop('selectedIndex');
343                 lastSelectedDiv.html(item.toHTML());
344             }
345         },
346         size: function() {
347             if (lastSelectedDiv) {
348                 var item = items[lastSelectedDiv.attr('id')];
349                 item.fontSize = zoom_font(zoom_factor, $('#size_selector').val());
350                 item.fontSizeIndex = $('#size_selector').prop('selectedIndex');
351                 lastSelectedDiv.html(item.toHTML());
352             }
353         },
354         style: function() {
355             if (lastSelectedDiv) {
356                 var item = items[lastSelectedDiv.attr('id')];
357                 switch($('#style_selector').val()) {
358                     case "normal":
359                         item.bold = false;
360                         item.italic = false;
361                         break;
362                     case "bold":
363                         item.bold = true;
364                         item.italic = false;
365                         break;
367                     case "italic":
368                         item.bold = false;
369                         item.italic = true;
370                         break;
372                     case "bold_italic":
373                         item.bold = true;
374                         item.italic = true;
375                         break;
376                 }
378                 item.styleIndex = $('#style_selector').prop('selectedIndex');
379                 lastSelectedDiv.html(item.toHTML());
380             }
381         },
382         text: function() {
383             if (lastSelectedDiv) {
384                 var item = items[lastSelectedDiv.attr('id')];
385                 item.text = unescapeHTML($('#fixed_text_field').val());
386                 $('#fixed_text_field').val(item.text);
387                 lastSelectedDiv.html(item.toHTML());
388             }
389         },
390         width: function() {
391             if (lastSelectedDiv) {
392                 var item = items[lastSelectedDiv.attr('id')];
393                 item.width = $('#width_field').val() * pixelsPerCm;
394                 lastSelectedDiv.html(item.toHTML());
395             }
396         }
397     };
399     function zoom_font(zfact, fontSize) {
400         if (numeric_mode) {
401             var pattern = /([0-9.]+)pt/g
402             var ftsize = pattern.exec(fontSize)[1];
403             return (ftsize * zfact) + 'pt';
404         } else {
405             return fontSize;
406         }
407     }
409     function save() {
410         if ($('#template_name').val() == '') {
411             new AlertPopup($T("Warning"), $T("Please choose a name for the template")).open();
412             return;
413         }
414         var template = [];
415         template.push($('#template_name').val());
416         template.push(templateDimensions, pixelsPerCm);
417         template.push(backgroundId);
419         $.each(items, function(i, item) {
420             if (item != false) {
421                 item.fontSize = zoom_font(1/zoom_factor, item.fontSize);
422             }
423         });
425         template.push(items);
426         $('#templateData').val(Json.write(template));
427         $('#saveForm').submit();
428     }
430     function setBackgroundPos(mode) {
431         var background = $('#background');
432         var hiddenField = $('#bgPosition');
433         var bgPosStretch = $('#bgPosStretch');
434         var bgPosCenter = $('#bgPosCenter');
436         if (mode == 'Stretch') {
437             background.css({
438                 left: 0,
439                 top: 0
440             });
441             background.height(templateDimensions.height);
442             background.width(templateDimensions.width);
443             bgPosStretch.prop('checked', true);
444             bgPosCenter.prop('checked', false);
445         }
446         else if (mode == 'Center') {
447             background.height(background.prop('naturalHeight'));
448             background.width(background.prop('naturalWidth'));
450             if (background.width() > templateDimensions.width || background.height() > templateDimensions.height) {
451                 if (background.width() > templateDimensions.width) {
452                     var ratio = templateDimensions.width / background.width();
454                     background.width(templateDimensions.width);
455                     background.height(background.height() * ratio);
456                     background.css({
457                         left: 0,
458                         top: (templateDimensions.height/2.0 - background.height()/2.0) + 'px'
459                     });
460                 }
462                 if (background.height() > templateDimensions.height) {
463                     var ratio = templateDimensions.height / background.height();
465                     background.width(background.width() * ratio);
466                     background.height(templateDimensions.height);
468                     background.css({
469                         left: (templateDimensions.width/2.0 - background.width()/2.0) + 'px',
470                         top: 0
471                     });
472                 }
473             }
474             else {
475                 background.css({
476                     left: (templateDimensions.width/2 - background.prop('naturalWidth')/2) + 'px',
477                     top: (templateDimensions.height/2 - background.prop('naturalHeight')/2) + 'px'
478                 });
479             }
481             bgPosStretch.prop('checked', false);
482             bgPosCenter.prop('checked', true);
483         }
484      }
486     function displayBackground(backgroundURL) {
487         $('<img/>', {
488             id: 'background',
489             src: backgroundURL
490         }).css({
491             position: 'absolute',
492             left: 0,
493             top: 0,
494             height: templateDimensions.height + 'px',
495             width: templateDimensions.width + 'px',
496             zIndex: 5
497         }).on('load', function() {
498             $('#loadingIcon').hide();
499             $('#removeBackground').removeClass('hidden');
500             setBackgroundPos(backgroundPos);
501         }).appendTo('#templateDiv');
502     }
504     function removeBackground() {
505         if (backgroundId != -1) {
506             backgroundId = -1;
507             $('#background').remove();
508             $('#removeBackground').addClass('hidden');
509         }
510     }
512     function unescapeHTML(str) {
513         // taken from Prototype
514         return str.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '').replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
515     }
517     $(document).ready(function() {
519         $('#bgForm input[type="file"]').on('change', function() {
520           var $this = $(this);
521           if ($this.val()) {
522             $('#uploadBackground').removeClass('hidden');
523           } else {
524             $('#uploadBackground').addClass('hidden');
525           }
527         });
530         if (backgroundId != -1) {
531             $('#removeBackground').removeClass('hidden');
532         }
534         // select and inline edit
535         $('#templateDiv').on('mousedown', 'div', function() {
536             markSelected($(this));
537         }).on('dblclick', 'div', function() {
538             inlineEdit($(this));
539         });
541         $('#uploadBackground').click(function() {
542             $('#bgForm').submit();
543             return false;
544         });
546         // toggle grid/snap mode
547         $('#snap_checkbox').change(function() {
548             snapToGrid = this.checked;
549         }).change();
551         $('#bgForm').ajaxForm({
552             dataType: 'json',
553             iframe: true,
554             success: function(data) {
555                 if(data.status != 'OK') {
556                     new AlertPopup($T("Error"), $T("An error occurred")).open();
557                     $('#loadingIcon').hide();
558                     return;
559                 }
560                 if (backgroundId != -1) {
561                     $('#background').remove();
562                 }
563                 backgroundId = data.id;
564                 backgroundPos = data.pos;
565                 displayBackground(data.url);
566             },
567             beforeSubmit: function() {
568                 $('#loadingIcon').show();
569             }
570         });
572         $('#removeBackground').click(function(e) {
573             e.preventDefault();
574             removeBackground();
575         });
577         $('.moveButton').click(function(e) {
578             e.preventDefault();
579             var dir = $(this).data('direction');
580             moveFuncs[dir]();
581         });
583         $('.attrButton').click(function(e) {
584             e.preventDefault();
585             var attr = $(this).data('attr');
586             attrFuncs[attr]();
587         });
589         $('.attrSelect').change(function() {
590             var attr = $(this).data('attr');
591             attrFuncs[attr]();
592         });
594         $('#changeTemplateSize').click(function(e) {
595             e.preventDefault();
596             changeTemplateSize();
597         });
599         $('#insertButton').click(function(e) {
600             e.preventDefault();
601             insertElement();
602         });
604         $('#removeButton').click(function(e) {
605             e.preventDefault();
606             removeElement();
607         });
609         $('#saveButton').click(function(e) {
610             e.preventDefault();
611             save();
612         });
614         controlTabs = $('#controlTabs').tabs();
615     });
616 </script>
618 <!-- CONTEXT HELP DIVS -->
619 <div id="tooltipPool" style="display: none">
620     <!-- Where is key? -->
621     <div id="features" class="tip">
622         <b>FullName can have four different formats:</b><br>
623         - <b>FullName</b>: Mr. DOE, Jonh<br>
624         - <b>Full Name (w/o title)</b>: DOE, Jonh<br>
625         - <b>FullName B</b>: Mr. Jonh Doe<br>
626         - <b>FullName B Full Name (w/o title)</b>: Jonh Doe<br>
627     </div>
628 </div>
629 <!-- END OF CONTEXT HELP DIVS -->
631 <div style="width:100%">
632     <div class="groupTitle">
633         ${titleMessage}
634     </div>
636     <!-- Save Document Options -->
637     <div class="overflow">
638       ${_('Once you have finished designing, you may either save or discard your changes here.')}
639       <div style="float:right;">
640           <input class="i-button accept" name="Save Template Button" value="${ _("Save Template")}" type="button" id="saveButton" />
641           <input class="i-button" name="Cancel Button" value="${ _("Cancel")}" type="button" onclick="location.href='${cancelURL}'" />
643           <form id="saveForm" action="${saveTemplateURL}" method="POST">
644               <input name="templateId" value="${templateId}" type="hidden">
645               <input id="templateData" name="templateData" type="hidden">
646           </form>
647       </div>
648       <div class="toolbar-clearer"></div>
649     </div>
651     <!-- Tabulated controls -->
652     <div id="controlTabs">
653         <ul>
654             <li><a href="#tabsGeneral">${_('General Settings &amp; Layout')}</a></li>
655             <li id="tab_format"><a href="#tabsFormatting">${_('Element Formatting')}</a></li>
656         </ul>
658         <!-- Tab for badge paramaters -->
659         <div id="tabsGeneral" class="tab">
660             <div class="left panel">
661                 <i class="icon-wrench left" title="${_("Template settings")}"></i>
662                 <div class="content">
663                   <h4>${_('Template Name')}</h4>
664                   <input id="template_name" size="30" name="Template Name" />
665                 </div>
666             </div>
667             <div class="left panel">
668               <i class="icon-rulers left" title="${_("Template dimensions")}"></i>
669                 <div class="content">
670                   <div class="left">${_('Width')} <input id="badge_width" name="Badge Width" size="5" style="margin-left: 0.5em;"></div>
671                   <div class="left clear">${_('Height')}<input id="badge_height" name="Badge Height" size="5" style="margin-left: 0.5em;"></div>
672                   <div class="clear"></div>
673                   <div class="text-not-important" style="margin-top: 1em;">${_("Dimensions are in cm, decimals are allowed.")}</div>
674                   <div style="margin-top: 1em;"><input id="snap_checkbox" type="checkbox"/><label for="snap_checkbox">${ _("Snap to grid")}</label></div>
675                 </div>
676             </div>
678             <div class="left panel">
679               <i class="icon-image left" title="${_("Background")}"></i>
680               <form id="bgForm" action="${ saveBackgroundURL }" method="POST" enctype="multipart/form-data" class="left">
681                 <input name="file" type="file" style="margin-bottom: 1em;" />
682                 <%block name="background_options">
683                 </%block>
684                 <div class="toolbar">
685                   <div class="group">
686                     <a class="i-button icon-upload icon-only hidden" id="uploadBackground" title="${_("Upload file")}"></a>
687                     <a class="i-button icon-remove icon-only hidden" id="removeBackground" title="${_("Remove background")}"></a>
688                       </div>
689                 </div>
690               </form>
691               <img id="loadingIcon" src=${loadingIconURL} style="display:none; width: 20px; height: 20px;" />
692             </div>
694         </div>
695         <!-- Tab for element formatting -->
696         <div id="tabsFormatting" class="tab">
697             <div class="left panel">
698                 <i class="icon-font-size left" title="${_("Font definitions")}"></i>
699                 <!-- Font Face -->
700                 <div class="content">
701                     <select id='font_selector' name="Template Element Font" class="attrSelect" data-attr="font">
702                       <optgroup label="${ _('Normal Fonts') }">
703                         <option>Times New Roman</option>
704                         <option>Courier</option>
705                         <option>Sans</option>
706                       </optgroup>
707                       <optgroup label="${ _('Special Character Fonts') }">
708                         <option>LinuxLibertine</option>
709                         <option>Kochi-Mincho</option>
710                         <option>Kochi-Gothic</option>
711                         <option>Uming-CN</option>
712                       </optgroup>
713                     </select>
714                     <!-- Font Colour -->
715                     <select id='color_selector' name="Template Element Color" class="attrSelect" data-attr="color">
716                       <option value="black"> ${ _("black")}</option>
717                       <option value="red"> ${ _("red")}</option>
718                       <option value="blue"> ${ _("blue")}</option>
719                       <option value="green"> ${ _("green")}</option>
720                       <option value="yellow"> ${ _("yellow")}</option>
721                       <option value="brown"> ${ _("brown")}</option>
722                       <option value="gold"> ${ _("gold")}</option>
723                       <option value="pink"> ${ _("pink")}</option>
724                       <option value="gray"> ${ _("gray")}</option>
725                       <option value="white"> ${ _("white")}</option>
726                     </select>
727                     <!-- Font Style -->
728                     <select id='style_selector' name="Template Element Style" class="attrSelect" data-attr="style">
729                       <option value="normal"> ${ _("Normal")}</option>
730                       <option value="bold"> ${ _("Bold")}</option>
731                       <option value="italic"> ${ _("Italic")}</option>
732                       <option value="bold_italic"> ${ _("Bold &amp; Italic")}</option>
733                     </select>
734                     <!-- Font Size -->
735                     <select id='size_selector' name="Template Element Size" class="attrSelect" data-attr="size">
736                         <%block name="font_sizes">
737                             <option value="xx-small"> ${ _("xx-small")}</option>
738                             <option value="x-small"> ${ _("x-small")}</option>
739                             <option value="small"> ${ _("small")}</option>
740                             <option value="medium" SELECTED> ${ _("medium")}</option>
741                             <option value="large"> ${ _("large")}</option>
742                             <option value="x-large"> ${ _("x-large")}</option>
743                             <option value="xx-large"> ${ _("xx-large")}</option>
744                         </%block>
745                 </select>
746                 <!-- Font Alignment -->
747                 <select id='alignment_selector' name="Template Element Alignment" class="attrSelect" data-attr="alignment">
748                     <!-- Note: the value of the options is used directly in the style attribute of the items -->
749                     <option value="Left"> ${ _("Left")}</option>
750                     <option value="Right"> ${ _("Right")}</option>
751                     <option value="Center"> ${ _("Center")}</option>
752                     <option value="Justified"> ${ _("Justified")}</option>
753                 </select>
754             </div>
755         </div>
757             <div class="left panel">
758               <i class="icon-rulers left" title="${_("Element dimensions")}"></i>
759               <div class="content">
760               Width <input id="width_field" size="5" name="Element Size" />
761               <h4>${ _("Positioning")}</h4>
762               <table width="90%">
763                 <tbody>
764                   <tr>
765                     <td></td>
766                     <td align="center">
767                       <input name="Move Template Element Top Button" class="btn moveButton" value="${ _("Top")}" type="button" data-direction="top" />
768                     </td>
769                     <td></td>
770                   </tr>
771                   <tr>
772                     <td align="center">
773                       <input name="Move Template Element Left Button" class="btn moveButton" value="${ _("Left")}" type="button" data-direction="left"/>
774                     </td>
775                     <td align="center">
776                       <input name="Move Template Element Center Button" class="btn moveButton" value="${ _("Center")}" type="button" data-direction="center"/>
777                     </td>
778                     <td align="center">
779                       <input name="Move Template Element Right Button" class="btn moveButton" value="${ _("Right")}" type="button" data-direction="right"/>
780                     </td>
781                   </tr>
782                   <tr>
783                     <td></td>
784                     <td align="center">
785                       <input name="Move Template Element Bottom Button" class="btn moveButton" value="${ _("Bottom")}" type="button" data-direction="bottom"/>
786                     </td>
787                    <td></td>
788                   </tr>
789                 </tbody>
790               </table>
791               </div>
792             </div>
794             <div class="left panel" id="fixedTextContainer" style="display:none; margin-left: 1em;">
795               <i class="icon-type left" title="${_("Text")}"></i>
796               <input id="fixed_text_field" size="30" name="Element Text" placeholder="${_("Insert your text here")}"/>
797             </div>
798           </div>
799           <!-- End of formatting tab -->
800         </div>
802   <table class="groupTable" border="0" cellpadding="0" cellspacing="0">
803     <tbody>
804       <tr>
805         <td rowspan="2" id="controls"> <!-- Width attribute necessary so that the template design space doesn't move depending on selection text-->
807         <!-- Insert Elements -->
808         <div class="panel">
809             <h3>${_('Insert Elements')}</h3>
810               <select name="Template Elements List" id="elementList">
811                 ${selectOptions}
812               </select>
813             <a id="insertButton" class="i-button icon-plus right icon-only" title="${ _("Insert")}"></a>
814         </div>
815         <!-- Modify Selected Element -->
816         <div id="modify_panel" class="panel overflow clear" style="display: none;">
818           <div class="overflow">
819             <h3>${_('Selected Element')}</h3>
820             <div id="selection_text" class="left">
821             </div>
822             <a id="removeButton" class="right i-button icon-remove icon-only" title="${ _("Remove Element")}"></a>
823           </div>
824         </td>
826         <td></td>
828         <td align="left" valign="bottom" height="22px"> <!-- height of the horizontal ruler images -->
829             <div id="horizontal_ruler" class="ruler">
830             </div>
831         </td>
832       </tr>
834       <tr>
835         <td valign="top" align="right" width="22px"> <!-- width of the vertical ruler image -->
836             <div id="vertical_ruler" class="ruler">
837             </div>
838         </td>
840         <td align="left" valign="top">
841           <div id="templateDiv" style="width:425px;height:270px;position:relative;left:0px;top:0px"> <!-- put here the initial dimensions of templateDiv -->
842             <table border="1" style="border-style: none;" width="100%" height="100%" cellspacing="0" cellpadding="0">
843               <tbody>
844                 <tr><td></td></tr>
845               </tbody>
846             </table>
847           </div>
849         </div>
851         </td>
852       </tr>
853     </tbody>
854   </table>
856   <script type="text/javascript">
857     // We load the template if we are editing a template
858     if (${ editingTemplate }) {
859         var template = ${ templateData };
860         $('#template_name').val(template[0]);
861         $('#templateDiv').width(template[1].width).height(template[1].height);
862         items = template[4];
863         // We give the toHTML() method to each of the items
864         $.each(items, function(i, item) {
865             item.toHTML = Item.prototype.toHTML;
866         });
867         templateDimensions = new Dimensions(template[1].width, template[1].height);
868     } else {
869         templateDimensions = new Dimensions(TPL_DEFAULT_SIZE[0], TPL_DEFAULT_SIZE[1]);
870     }
872     previousTemplateDimensions = new Dimensions(0,0);
874     $('#badge_width').val(templateDimensions.width / pixelsPerCm);
875     $('#badge_height').val(templateDimensions.height / pixelsPerCm);
877     $('#badge_width, #badge_height').on('keyup', function() {
878         changeTemplateSize();
879     });
881     $('#width_field').on('keyup', function() {
882         attrFuncs['width']();
883     });
885     $('#fixed_text_field').on('keyup', function() {
886         attrFuncs['text']();
887     });
889     updateRulers(); // creates the initial rulers
890     changeTemplateSize();
892     // This function displays the items, if any have been loaded, on the screen
893     displayItems();
895     if (${ editingTemplate } && ${ hasBackground }) {
896         backgroundId = ${ backgroundId };
897         backgroundPos = '${ backgroundPos }';
898         displayBackground("${ backgroundURL }");
899     }
901   </script>
903 </div>