diff --git a/pom.xml b/pom.xml index 7861c54194facc58253a45bbdeb404646b500ac9..b3f53c7a36f38200812d98b3cfc844a1be28022f 100644 --- a/pom.xml +++ b/pom.xml @@ -247,7 +247,7 @@ <output>${basedir}/src/main/webapp/static/js/js.plugins.min.css</output> <removeIncluded>false</removeIncluded> <includes> - <include>${basedir}/target/jquery/jquery/tagit/jquery.tagit.min.css</include> + <include>${basedir}/target/jquery/jquery/tagsinput/bootstrap-tagsinput.min.css</include> <include>${basedir}/target/jquery/jquery/uilayout/layout-default-latest.min.css</include> <include>${basedir}/target/jquery/jquery/fullcalendar/fullcalendar.min.css</include> <include>${basedir}/src/main/webapp/static/js/jquery/datatables/css/jquery.dataTables.css</include> diff --git a/src/main/java/org/olat/core/commons/fullWebApp/_content/fullwebapplayout.html b/src/main/java/org/olat/core/commons/fullWebApp/_content/fullwebapplayout.html index 847442833a9910180ca0046382e85fbf11f038fc..4426e1c3ba692458bc3ace79ca24501d1d14962e 100644 --- a/src/main/java/org/olat/core/commons/fullWebApp/_content/fullwebapplayout.html +++ b/src/main/java/org/olat/core/commons/fullWebApp/_content/fullwebapplayout.html @@ -104,8 +104,8 @@ function b_start(){ <script type="text/javascript" src='$r.staticLink("movie/player.js")'></script> ## Always loaded -## <link type="text/css" href='$r.staticLink("js/jquery/tagit/jquery.tagit.css")' rel="stylesheet"/> ## <link type="text/css" href='$r.staticLink("js/jquery/uilayout/layout-default-latest.css")' rel="stylesheet"/> +<link type="text/css" href='$r.staticLink("js/jquery/tagsinput/bootstrap-tagsinput.css")' rel="stylesheet"/> <link type="text/css" href='$r.staticLink("js/jquery/fullcalendar/fullcalendar.css")' rel="stylesheet"/> <link type="text/css" href='$r.staticLink("js/jquery/datatables/css/jquery.dataTables.css")' rel="stylesheet"/> ## FIXME:oo10 add plugin min diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextBoxListElementImpl.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextBoxListElementImpl.java index ca03e597bc73198b42ed769fdfd7022514397fdb..b65287c065bb11fa6ad05a9d42dc8b374d96e16e 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextBoxListElementImpl.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextBoxListElementImpl.java @@ -45,11 +45,10 @@ import org.olat.core.util.Util; */ public class TextBoxListElementImpl extends AbstractTextElement implements TextBoxListElement { - /** * the wrapped textBoxListElementComponent */ - private TextBoxListElementComponent component; + private final TextBoxListElementComponent component; public TextBoxListElementImpl(String name, String inputHint, Map<String, String> initialItems, Translator translator) { super(name,true);// we wan't to be an inline-editing element! diff --git a/src/main/java/org/olat/core/gui/components/textboxlist/TextBoxListComponent.java b/src/main/java/org/olat/core/gui/components/textboxlist/TextBoxListComponent.java index 214de503c04b2dce5a3dd191e8ad66af34eae835..0d5d16be33252edd450cacb2e307beb47a5bede0 100644 --- a/src/main/java/org/olat/core/gui/components/textboxlist/TextBoxListComponent.java +++ b/src/main/java/org/olat/core/gui/components/textboxlist/TextBoxListComponent.java @@ -286,11 +286,11 @@ public abstract class TextBoxListComponent extends FormBaseComponentImpl { public void validate(UserRequest ureq, ValidationResult vr) { super.validate(ureq, vr); JSAndCSSAdder jsa = vr.getJsAndCSSAdder(); - //jsa.addRequiredJsFile(TextBoxListComponent.class, "js/multiselect.js"); - jsa.addRequiredStaticJsFile("js/jquery/tagit/tag-it.min.js"); - - if (provider != null) + jsa.addRequiredStaticJsFile("js/jquery/tagsinput/bootstrap-tagsinput.min.js"); + if (provider != null) { + jsa.addRequiredStaticJsFile("js/jquery/typeahead/typeahead.bundle.min.js"); setMapper(ureq); + } } /** diff --git a/src/main/java/org/olat/core/gui/components/textboxlist/TextBoxListRenderer.java b/src/main/java/org/olat/core/gui/components/textboxlist/TextBoxListRenderer.java index c66c32df486ee58b1c90b34dc2a94f8aad640b09..e2c5ddfbb57e0cb549a3c9525461516e62c33225 100644 --- a/src/main/java/org/olat/core/gui/components/textboxlist/TextBoxListRenderer.java +++ b/src/main/java/org/olat/core/gui/components/textboxlist/TextBoxListRenderer.java @@ -19,25 +19,17 @@ */ package org.olat.core.gui.components.textboxlist; -import java.util.Map; -import java.util.Map.Entry; - import org.olat.core.gui.components.Component; -import org.olat.core.gui.components.ComponentRenderer; +import org.olat.core.gui.components.DefaultComponentRenderer; import org.olat.core.gui.components.form.flexible.impl.Form; import org.olat.core.gui.components.form.flexible.impl.FormJSHelper; import org.olat.core.gui.components.form.flexible.impl.elements.TextBoxListElementComponent; import org.olat.core.gui.components.form.flexible.impl.elements.TextBoxListElementImpl; import org.olat.core.gui.render.RenderResult; import org.olat.core.gui.render.Renderer; -import org.olat.core.gui.render.RenderingState; import org.olat.core.gui.render.StringOutput; import org.olat.core.gui.render.URLBuilder; import org.olat.core.gui.translator.Translator; -import org.olat.core.logging.OLog; -import org.olat.core.logging.Tracing; -import org.olat.core.util.StringHelper; -import org.olat.core.util.filter.impl.OWASPAntiSamyXSSFilter; /** * Description:<br> @@ -49,16 +41,7 @@ import org.olat.core.util.filter.impl.OWASPAntiSamyXSSFilter; * * @author Roman Haag, roman.haag@frentix.com, http://www.frentix.com */ -public class TextBoxListRenderer implements ComponentRenderer { - - private static OLog logger = Tracing.createLoggerFor(TextBoxListRenderer.class); - - /** - * default constructor - */ - public TextBoxListRenderer() { - - } +public class TextBoxListRenderer extends DefaultComponentRenderer { /** * @see org.olat.core.gui.components.ComponentRenderer#render(org.olat.core.gui.render.Renderer, @@ -74,11 +57,10 @@ public class TextBoxListRenderer implements ComponentRenderer { TextBoxListComponent tblComponent = (TextBoxListElementComponent) source; if (tblComponent.isEnabled()) { - renderEnabledMode(tblComponent, sb, translator); + renderEnabledMode(tblComponent, sb); } else { renderDisabledMode(tblComponent, sb); } - } /** @@ -86,97 +68,40 @@ public class TextBoxListRenderer implements ComponentRenderer { * * @param tblComponent * the component to render - * @param output + * @param sb * the StringOutput * @param translator */ - private void renderEnabledMode(TextBoxListComponent tblComponent, StringOutput output, Translator translator) { - - /* if in debug mode, create more readable javascript code */ - String lineBreak = ""; - if(logger.isDebug()){ - lineBreak = Character.toString((char)10); - logger.debug("rendering TextBoxListComponent in debug mode, nice JS output."); - } - + private void renderEnabledMode(TextBoxListComponent tblComponent, StringOutput sb) { TextBoxListElementImpl te = ((TextBoxListElementComponent)tblComponent).getTextElementImpl(); Form rootForm = te.getRootForm(); String dispatchId = tblComponent.getFormDispatchId(); String initialValue = tblComponent.getInitialItemsAsString(); - output.append("<input type=\"text\" id=\"textboxlistinput").append(dispatchId).append("\" ") - .append("name='textboxlistinput").append(dispatchId).append("' ") - .append("value='").append(initialValue).append("'") - .append("/>\n"); - - // OO-137 : here, we display the currentItems. (at first render, this is equal to initialItems) - // on succeeding rendering, we want to reflect the current component status + sb.append("<input type='text' id='textboxlistinput").append(dispatchId).append("'") + .append(" name='textboxlistinput").append(dispatchId).append("'") + .append(" value='").append(initialValue).append("' />\n"); - // generate the JS-code for the tagit - output.append(FormJSHelper.getJSStart()); - output.append("jQuery(function(){\n") - .append(" jQuery('#textboxlistinput").append(dispatchId).append("').tagit({\n") - .append(" allowDuplicates:").append(tblComponent.isAllowDuplicates()).append(",\n") - .append(" autocomplete: {\n") - .append(" delay: 100,"); + String o_ffEvent = FormJSHelper.getJSFnCallFor(rootForm, dispatchId, 2); + // generate the JS-code for the bootstrap tagsinput + sb.append(FormJSHelper.getJSStart()) + .append("jQuery(function(){\n") + .append(" jQuery('#textboxlistinput").append(dispatchId).append("').tagsinput({\n"); - //set autocompleter.source if a provider is around if (tblComponent.getProvider() != null) { - String mapperUri = tblComponent.getMapperUri(); - output.append(" source: function(request, response) {\n") - .append(" jQuery.ajax('").append(mapperUri).append("',{\n") - .append(" data: request,\n") - .append(" dataType:'json',\n") - .append(" success: function(data) {\n") - .append(" response(jQuery.map(data, function( item ) {\n") - .append(" return item;\n") - .append(" }));\n") - .append(" }\n") - .append(" });\n") - .append(" },\n"); + sb.append(" typeahead: {\n") + .append(" source: function() {") + .append(" return jQuery.getJSON('").append(tblComponent.getMapperUri()).append("');") + .append(" }") + .append(" }\n"); } - - output.append(" minLength: 2\n") - .append(" },\n") - .append(" availableTags:["); - - OWASPAntiSamyXSSFilter filter = new OWASPAntiSamyXSSFilter(); - Map<String, String> initItems = tblComponent.getCurrentItems(); - if (initItems != null) { - boolean sep = true; - for (Entry<String, String> item :initItems.entrySet()) { - if(sep) sep = false; - else output.append(","); - - String value; - if (StringHelper.containsNonWhitespace(item.getValue())) { - value = item.getValue(); - } else { - value = item.getKey(); - } - value = filter.filter(value); - value = StringHelper.escapeHtml(value); - output.append("'").append(value).append("'"); - } - } - output.append("],\n"); - - // otherwise, o_ffEvents are fired: OO-137 ( invoke o_ffEvent on UserAdd or userRemove ) but only in flexiform - String o_ffEvent = FormJSHelper.getJSFnCallFor(rootForm, dispatchId, 2); - output.append(" afterTagAdded: function(event,ui){\n") - .append(" if(!ui.duringInitialization) {") - .append(o_ffEvent).append(";\n") - .append(" }\n") - .append(" },\n") - .append(" afterTagRemoved: function(event,ui){\n") - .append(" if(!ui.duringInitialization) {") - .append(o_ffEvent).append(";\n") - .append(" }\n") - .append(" }\n") - .append(" });\n") - .append("})\n"); - output.append(FormJSHelper.getJSEnd()).append(lineBreak); + sb.append(" });\n") + .append(" jQuery('#textboxlistinput").append(dispatchId).append("').on('itemAdded itemRemoved',function(event) {\n") + .append(o_ffEvent).append(";\n") + .append(" });\n") + .append("});\n") + .append(FormJSHelper.getJSEnd()); } /** @@ -197,30 +122,4 @@ public class TextBoxListRenderer implements ComponentRenderer { FormJSHelper.appendReadOnly("-", output); } } - - /** - * @see org.olat.core.gui.components.ComponentRenderer#renderHeaderIncludes(org.olat.core.gui.render.Renderer, - * org.olat.core.gui.render.StringOutput, - * org.olat.core.gui.components.Component, - * org.olat.core.gui.render.URLBuilder, - * org.olat.core.gui.translator.Translator, - * org.olat.core.gui.render.RenderingState) - */ - @Override - public void renderHeaderIncludes(Renderer renderer, StringOutput sb, Component source, URLBuilder ubu, Translator translator, - RenderingState rstate) { - // nothing - } - - /** - * @see org.olat.core.gui.components.ComponentRenderer#renderBodyOnLoadJSFunctionCall(org.olat.core.gui.render.Renderer, - * org.olat.core.gui.render.StringOutput, - * org.olat.core.gui.components.Component, - * org.olat.core.gui.render.RenderingState) - */ - @Override - public void renderBodyOnLoadJSFunctionCall(Renderer renderer, StringOutput sb, Component source, RenderingState rstate) { - // nothing to load - } - } diff --git a/src/main/java/org/olat/core/gui/control/JSAndCSSAdder.java b/src/main/java/org/olat/core/gui/control/JSAndCSSAdder.java index abe8046d05823c4f25ff544444c0a375e5253ed6..859d3a21d930f43fc0d88ea76b2bdcd32282e802 100644 --- a/src/main/java/org/olat/core/gui/control/JSAndCSSAdder.java +++ b/src/main/java/org/olat/core/gui/control/JSAndCSSAdder.java @@ -47,98 +47,6 @@ public interface JSAndCSSAdder { public void addRequiredStaticJsFile(String jsFileName, String fileEncoding, String preAJAXAddJsCode); - /** - * adds a js file to be served in the html header to the list of required - * js-files. e.g. addRequiredJsFile(MyController.class, "js/myscript.js") - * where the file myscript.js must be under - * "location of MyController.class"/_static/js - * <p> - * In full page refresh mode, the library will be included to the page - * header using the standard script tags. - * <p> - * In AJAX mode, the library is will read the file from disk, transfer the - * content via the AJAX channel and then eval() the content in the window. - * <p> - * In case that your script needs some values to be initialized before the - * eval() happens, use the other addRequiredJsFile() for this purpose - * - * @param baseClass - * @param jsFileName - */ - //public void addRequiredJsFile(String jsFileName); - - /** - * adds a js file to be served in the html header to the list of required - * js-files. e.g. addRequiredJsFile(MyController.class, "js/myscript.js") - * where the file myscript.js must be under - * "location of MyController.class"/_static/js - * <p> - * In full page refresh mode, the library will be included to the page header - * using the standard script tags. - * <p> - * In AJAX mode, the library is will read the file from disk, transfer the - * content via the AJAX channel and then eval() the content in the window. The - * fileEncoding is used to read the file from disk. - * <p> - * In case that your script needs some values to be initialized before the - * eval() happens, use the other addRequiredJsFile() for this purpose - * - * @param baseClass - * @param jsFileName - * @param fileEncoding the encoding of the js file or NULL to use the default - * encoding (utf-8) - */ - //public void addRequiredJsFile(Class<?> baseClass, String jsFileName, String fileEncoding); - - /** - * adds a js file to be served in the html header to the list of required - * js-files. e.g. addRequiredJsFile(MyController.class, "js/myscript.js") - * where the file myscript.js must be under - * "location of MyController.class"/_static/js - * <p> - * In full page refresh mode, the library will be included to the page header - * using the standard script tags. - * <p> - * In AJAX mode, the library is will first eval() the content of the supplied - * string evalBeforeDomReplacementJsCode, then read the file from disk, - * transfere the content via the AJAX channel and then eval() the content in - * the window.The fileEncoding is used to read the file from disk. - * - * @param baseClass The class where the script is localted - * @param jsFileName The script path, e.g. js/myscript.js - * @param fileEncoding the encoding of the js file or NULL to use the default - * encoding (utf-8) - * @param preAJAXAddJsCode A string containing some values to be eval()-ed - * right before the script itself is eval()-ed - */ - //public void addRequiredJsFile(Class<?> baseClass, String jsFileName, String fileEncoding, String preAJAXAddJsCode); - - /** - * - * @param baseClass - * @param cssFileName - * @param forceRemove normally, once added css files will not be removed - * anymore. However, if your css overrides default settings (e.g. - * when you have a preview css), this css must be removed as soon as - * the validate method does not require it anymore. (e.g. when you - * leave the course edit mode) - * @param cssIndex position of the css in relation of the position of the - * theme. Use JSAndCSSAdder.CSS_INDEX_* variables to set this - */ - //public void addRequiredCSSFile(Class<?> baseClass, String cssFileName, boolean forceRemove, Integer cssLoadIndex); - - /** - * This method will add the CSS file before the theme. use the other method to change this behaviour - * @param baseClass - * @param cssFileName - * @param forceRemove normally, once added css files will not be removed - * anymore. However, if your css overrides default settings (e.g. - * when you have a preview css), this css must be removed as soon as - * the validate method does not require it anymore. (e.g. when you - * leave the course edit mode) - */ - //public void addRequiredCSSFile(Class<?> baseClass, String cssFileName, boolean forceRemove); - /** * * used rather rarely, e.g. when you have a css with content which is dynamic @@ -164,8 +72,6 @@ public interface JSAndCSSAdder { public void addStaticCSSPath(String cssPath); - - /** * * @return true if there has been a new (never been added before) (or a deleted css which has been marked as to-be-removed) required css or js file's base since the previous call to this method, false otherwise (no new js or css libs needed) @@ -173,7 +79,6 @@ public interface JSAndCSSAdder { */ public boolean finishAndCheckChange(); - /** * @param baseClass * @param rawHeader @@ -201,21 +106,4 @@ public interface JSAndCSSAdder { */ public void requireFullPageRefresh(); - /** - * Get the mapper path for this class and file name, e.g. to use in a - * preAJAXAddJsCode call when adding a JS script that needs to load other - * scripts as well. - * - * @param baseClass - * @param fileName - * the name of the file or NULL to get the base path. - * @return A string that represents the path of the JS file as it is used on - * a full page refresh. If fileName is null, the base path wihout - * trailing slash is returned. - */ - //public String getMappedPathFor(Class<?> baseClass, String fileName); - - - - } diff --git a/src/main/java/org/olat/core/gui/exception/_content/exception_page.html b/src/main/java/org/olat/core/gui/exception/_content/exception_page.html index 6f7ee80defe81dbb0fbee5977167de4e243f1454..cd525c97f4763ae0091e54192a01bfb4675a519e 100644 --- a/src/main/java/org/olat/core/gui/exception/_content/exception_page.html +++ b/src/main/java/org/olat/core/gui/exception/_content/exception_page.html @@ -77,8 +77,6 @@ var o_info = new Object(); <script type="text/javascript" src='$r.staticLink("movie/player.js")'></script> ## Always loaded -## <link type="text/css" href='$r.staticLink("js/jquery/tagit/jquery.tagit.css")' rel="stylesheet"/> -## <link type="text/css" href='$r.staticLink("js/jquery/uilayout/layout-default-latest.css")' rel="stylesheet"/> <link type="text/css" href='$r.staticLink("js/jquery/fullcalendar/fullcalendar.css")' rel="stylesheet"/> <link type="text/css" href='$r.staticLink("js/jquery/datatables/css/jquery.dataTables.css")' rel="stylesheet"/> ## FIXME:oo10 add plugin min diff --git a/src/main/webapp/static/js/JS.README b/src/main/webapp/static/js/JS.README index 3703dc94533f78c4976ec8e0d22fa18bb5f57cee..736b411fd6a3c71b9f95ddd06e2f2d91facc7a4c 100644 --- a/src/main/webapp/static/js/JS.README +++ b/src/main/webapp/static/js/JS.README @@ -23,7 +23,7 @@ it minified the 4 olat plugins for tinymce 4 quotespliter and minified css: - jquery.tagit.min.css + bootstrap-tagsinput.css layout-default-latest.min.css fullcalendar.min.css dataTables.css diff --git a/src/main/webapp/static/js/jquery/tagit/jquery.tagit.css b/src/main/webapp/static/js/jquery/tagit/jquery.tagit.css deleted file mode 100644 index 1620ba5e6c4d11b3391bf4e7c859caee760843c6..0000000000000000000000000000000000000000 --- a/src/main/webapp/static/js/jquery/tagit/jquery.tagit.css +++ /dev/null @@ -1,67 +0,0 @@ -ul.tagit { - padding: 1px 5px; - overflow: auto; - margin-left: inherit; /* usually we don't want the regular ul margins. */ - margin-right: inherit; -} -ul.tagit li { - display: block; - float: left; - margin: 2px 5px 2px 0; -} -ul.tagit li.tagit-choice { - position: relative; - line-height: inherit; -} - -ul.tagit li.tagit-choice-read-only { - padding: .2em .5em .2em .5em; -} - -ul.tagit li.tagit-choice-editable { - padding: .2em 18px .2em .5em; -} - -ul.tagit li.tagit-new { - padding: .25em 4px .25em 0; -} - -ul.tagit li.tagit-choice a.tagit-label { - cursor: pointer; - text-decoration: none; -} -ul.tagit li.tagit-choice .tagit-close { - cursor: pointer; - position: absolute; - right: .1em; - top: 50%; - margin-top: -8px; - line-height: 17px; -} - -/* used for some custom themes that don't need image icons */ -ul.tagit li.tagit-choice .tagit-close .text-icon { - display: none; -} - -ul.tagit li.tagit-choice input { - display: block; - float: left; - margin: 2px 5px 2px 0; -} -ul.tagit input[type="text"] { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - - -moz-box-shadow: none; - -webkit-box-shadow: none; - box-shadow: none; - - border: none; - margin: 0; - padding: 0; - width: inherit; - background-color: inherit; - outline: none; -} diff --git a/src/main/webapp/static/js/jquery/tagit/tag-it.js b/src/main/webapp/static/js/jquery/tagit/tag-it.js deleted file mode 100644 index 9d231dfed1b272ae19b00bb470e14bb54360a953..0000000000000000000000000000000000000000 --- a/src/main/webapp/static/js/jquery/tagit/tag-it.js +++ /dev/null @@ -1,533 +0,0 @@ -/* -* jQuery UI Tag-it! -* -* @version v2.0 (06/2011) -* -* Copyright 2011, Levy Carneiro Jr. -* Released under the MIT license. -* http://aehlke.github.com/tag-it/LICENSE -* -* Homepage: -* http://aehlke.github.com/tag-it/ -* -* Authors: -* Levy Carneiro Jr. -* Martin Rehfeld -* Tobias Schmidt -* Skylar Challand -* Alex Ehlke -* -* Maintainer: -* Alex Ehlke - Twitter: @aehlke -* -* Dependencies: -* jQuery v1.4+ -* jQuery UI v1.8+ -*/ -(function($) { - - $.widget('ui.tagit', { - options: { - allowDuplicates : false, - caseSensitive : true, - fieldName : 'tags', - placeholderText : null, // Sets `placeholder` attr on input field. - readOnly : false, // Disables editing. - removeConfirmation: false, // Require confirmation to remove tags. - tagLimit : null, // Max number of tags allowed (null for unlimited). - - // Used for autocomplete, unless you override `autocomplete.source`. - availableTags : [], - - // Use to override or add any options to the autocomplete widget. - // - // By default, autocomplete.source will map to availableTags, - // unless overridden. - autocomplete: {}, - - // Shows autocomplete before the user even types anything. - showAutocompleteOnFocus: false, - - // When enabled, quotes are unneccesary for inputting multi-word tags. - allowSpaces: false, - - // The below options are for using a single field instead of several - // for our form values. - // - // When enabled, will use a single hidden field for the form, - // rather than one per tag. It will delimit tags in the field - // with singleFieldDelimiter. - // - // The easiest way to use singleField is to just instantiate tag-it - // on an INPUT element, in which case singleField is automatically - // set to true, and singleFieldNode is set to that element. This - // way, you don't need to fiddle with these options. - singleField: false, - - // This is just used when preloading data from the field, and for - // populating the field with delimited tags as the user adds them. - singleFieldDelimiter: ',', - - // Set this to an input DOM node to use an existing form field. - // Any text in it will be erased on init. But it will be - // populated with the text of tags as they are created, - // delimited by singleFieldDelimiter. - // - // If this is not set, we create an input node for it, - // with the name given in settings.fieldName. - singleFieldNode: null, - - // Whether to animate tag removals or not. - animate: true, - - // Optionally set a tabindex attribute on the input that gets - // created for tag-it. - tabIndex: null, - - // Event callbacks. - beforeTagAdded : null, - afterTagAdded : null, - - beforeTagRemoved : null, - afterTagRemoved : null, - - onTagClicked : null, - onTagLimitExceeded : null, - - - // DEPRECATED: - // - // /!\ These event callbacks are deprecated and WILL BE REMOVED at some - // point in the future. They're here for backwards-compatibility. - // Use the above before/after event callbacks instead. - onTagAdded : null, - onTagRemoved: null, - // `autocomplete.source` is the replacement for tagSource. - tagSource: null - // Do not use the above deprecated options. - }, - - _create: function() { - // for handling static scoping inside callbacks - var that = this; - - // There are 2 kinds of DOM nodes this widget can be instantiated on: - // 1. UL, OL, or some element containing either of these. - // 2. INPUT, in which case 'singleField' is overridden to true, - // a UL is created and the INPUT is hidden. - if (this.element.is('input')) { - this.tagList = $('<ul></ul>').insertAfter(this.element); - this.options.singleField = true; - this.options.singleFieldNode = this.element; - this.element.css('display', 'none'); - } else { - this.tagList = this.element.find('ul, ol').andSelf().last(); - } - - this.tagInput = $('<input type="text" />').addClass('ui-widget-content'); - - if (this.options.readOnly) this.tagInput.attr('disabled', 'disabled'); - - if (this.options.tabIndex) { - this.tagInput.attr('tabindex', this.options.tabIndex); - } - - if (this.options.placeholderText) { - this.tagInput.attr('placeholder', this.options.placeholderText); - } - - if (!this.options.autocomplete.source) { - this.options.autocomplete.source = function(search, showChoices) { - var filter = search.term.toLowerCase(); - var choices = $.grep(this.options.availableTags, function(element) { - // Only match autocomplete options that begin with the search term. - // (Case insensitive.) - return (element.toLowerCase().indexOf(filter) === 0); - }); - showChoices(this._subtractArray(choices, this.assignedTags())); - }; - } - - if (this.options.showAutocompleteOnFocus) { - this.tagInput.focus(function(event, ui) { - that._showAutocomplete(); - }); - - if (typeof this.options.autocomplete.minLength === 'undefined') { - this.options.autocomplete.minLength = 0; - } - } - - // Bind autocomplete.source callback functions to this context. - if ($.isFunction(this.options.autocomplete.source)) { - this.options.autocomplete.source = $.proxy(this.options.autocomplete.source, this); - } - - // DEPRECATED. - if ($.isFunction(this.options.tagSource)) { - this.options.tagSource = $.proxy(this.options.tagSource, this); - } - - this.tagList - .addClass('tagit') - .addClass('ui-widget ui-widget-content ui-corner-all') - // Create the input field. - .append($('<li class="tagit-new"></li>').append(this.tagInput)) - .click(function(e) { - var target = $(e.target); - if (target.hasClass('tagit-label')) { - var tag = target.closest('.tagit-choice'); - if (!tag.hasClass('removed')) { - that._trigger('onTagClicked', e, {tag: tag, tagLabel: that.tagLabel(tag)}); - } - } else { - // Sets the focus() to the input field, if the user - // clicks anywhere inside the UL. This is needed - // because the input field needs to be of a small size. - that.tagInput.focus(); - } - }); - - // Single field support. - var addedExistingFromSingleFieldNode = false; - if (this.options.singleField) { - if (this.options.singleFieldNode) { - // Add existing tags from the input field. - var node = $(this.options.singleFieldNode); - var tags = node.val().split(this.options.singleFieldDelimiter); - node.val(''); - $.each(tags, function(index, tag) { - that.createTag(tag, null, true); - addedExistingFromSingleFieldNode = true; - }); - } else { - // Create our single field input after our list. - this.options.singleFieldNode = $('<input type="hidden" style="display:none;" value="" name="' + this.options.fieldName + '" />'); - this.tagList.after(this.options.singleFieldNode); - } - } - - // Add existing tags from the list, if any. - if (!addedExistingFromSingleFieldNode) { - this.tagList.children('li').each(function() { - if (!$(this).hasClass('tagit-new')) { - that.createTag($(this).text(), $(this).attr('class'), true); - $(this).remove(); - } - }); - } - - // Events. - this.tagInput - .keydown(function(event) { - // Backspace is not detected within a keypress, so it must use keydown. - if (event.which == $.ui.keyCode.BACKSPACE && that.tagInput.val() === '') { - var tag = that._lastTag(); - if (!that.options.removeConfirmation || tag.hasClass('remove')) { - // When backspace is pressed, the last tag is deleted. - that.removeTag(tag); - } else if (that.options.removeConfirmation) { - tag.addClass('remove ui-state-highlight'); - } - } else if (that.options.removeConfirmation) { - that._lastTag().removeClass('remove ui-state-highlight'); - } - - // Comma/Space/Enter are all valid delimiters for new tags, - // except when there is an open quote or if setting allowSpaces = true. - // Tab will also create a tag, unless the tag input is empty, - // in which case it isn't caught. - if ( - event.which === $.ui.keyCode.COMMA || - event.which === $.ui.keyCode.ENTER || - ( - event.which == $.ui.keyCode.TAB && - that.tagInput.val() !== '' - ) || - ( - event.which == $.ui.keyCode.SPACE && - that.options.allowSpaces !== true && - ( - $.trim(that.tagInput.val()).replace( /^s*/, '' ).charAt(0) != '"' || - ( - $.trim(that.tagInput.val()).charAt(0) == '"' && - $.trim(that.tagInput.val()).charAt($.trim(that.tagInput.val()).length - 1) == '"' && - $.trim(that.tagInput.val()).length - 1 !== 0 - ) - ) - ) - ) { - // Enter submits the form if there's no text in the input. - if (!(event.which === $.ui.keyCode.ENTER && that.tagInput.val() === '')) { - event.preventDefault(); - } - - that.createTag(that._cleanedInput()); - - // The autocomplete doesn't close automatically when TAB is pressed. - // So let's ensure that it closes. - that.tagInput.autocomplete('close'); - } - }).blur(function(e){ - // Create a tag when the element loses focus. - // If autocomplete is enabled and suggestion was clicked, don't add it. - if (!that.tagInput.data('autocomplete-open')) { - that.createTag(that._cleanedInput()); - } - }); - - // Autocomplete. - if (this.options.availableTags || this.options.tagSource || this.options.autocomplete.source) { - var autocompleteOptions = { - select: function(event, ui) { - that.createTag(ui.item.value); - // Preventing the tag input to be updated with the chosen value. - return false; - } - }; - $.extend(autocompleteOptions, this.options.autocomplete); - - // tagSource is deprecated, but takes precedence here since autocomplete.source is set by default, - // while tagSource is left null by default. - autocompleteOptions.source = this.options.tagSource || autocompleteOptions.source; - - this.tagInput.autocomplete(autocompleteOptions).bind('autocompleteopen', function(event, ui) { - that.tagInput.data('autocomplete-open', true); - }).bind('autocompleteclose', function(event, ui) { - that.tagInput.data('autocomplete-open', false) - }); - } - }, - - _cleanedInput: function() { - // Returns the contents of the tag input, cleaned and ready to be passed to createTag - return $.trim(this.tagInput.val().replace(/^"(.*)"$/, '$1')); - }, - - _lastTag: function() { - return this.tagList.find('.tagit-choice:last:not(.removed)'); - }, - - _tags: function() { - return this.tagList.find('.tagit-choice:not(.removed)'); - }, - - assignedTags: function() { - // Returns an array of tag string values - var that = this; - var tags = []; - if (this.options.singleField) { - tags = $(this.options.singleFieldNode).val().split(this.options.singleFieldDelimiter); - if (tags[0] === '') { - tags = []; - } - } else { - this._tags().each(function() { - tags.push(that.tagLabel(this)); - }); - } - return tags; - }, - - _updateSingleTagsField: function(tags) { - // Takes a list of tag string values, updates this.options.singleFieldNode.val to the tags delimited by this.options.singleFieldDelimiter - $(this.options.singleFieldNode).val(tags.join(this.options.singleFieldDelimiter)).trigger('change'); - }, - - _subtractArray: function(a1, a2) { - var result = []; - for (var i = 0; i < a1.length; i++) { - if ($.inArray(a1[i], a2) == -1) { - result.push(a1[i]); - } - } - return result; - }, - - tagLabel: function(tag) { - // Returns the tag's string label. - if (this.options.singleField) { - return $(tag).find('.tagit-label:first').text(); - } else { - return $(tag).find('input:first').val(); - } - }, - - _showAutocomplete: function() { - this.tagInput.autocomplete('search', ''); - }, - - _findTagByLabel: function(name) { - var that = this; - var tag = null; - this._tags().each(function(i) { - if (that._formatStr(name) == that._formatStr(that.tagLabel(this))) { - tag = $(this); - return false; - } - }); - return tag; - }, - - _isNew: function(name) { - return !this._findTagByLabel(name); - }, - - _formatStr: function(str) { - if (this.options.caseSensitive) { - return str; - } - return $.trim(str.toLowerCase()); - }, - - _effectExists: function(name) { - return Boolean($.effects && ($.effects[name] || ($.effects.effect && $.effects.effect[name]))); - }, - - createTag: function(value, additionalClass, duringInitialization) { - var that = this; - - value = $.trim(value); - - if (value === '') { - return false; - } - - if (!this.options.allowDuplicates && !this._isNew(value)) { - var existingTag = this._findTagByLabel(value); - if (this._trigger('onTagExists', null, { - existingTag: existingTag, - duringInitialization: duringInitialization - }) !== false) { - if (this._effectExists('highlight')) { - existingTag.effect('highlight'); - } - } - return false; - } - - if (this.options.tagLimit && this._tags().length >= this.options.tagLimit) { - this._trigger('onTagLimitExceeded', null, {duringInitialization: duringInitialization}); - return false; - } - - var label = $(this.options.onTagClicked ? '<a class="tagit-label"></a>' : '<span class="tagit-label"></span>').text(value); - - // Create tag. - var tag = $('<li></li>') - .addClass('tagit-choice ui-widget-content ui-state-default ui-corner-all') - .addClass(additionalClass) - .append(label); - - if (this.options.readOnly){ - tag.addClass('tagit-choice-read-only'); - } else { - tag.addClass('tagit-choice-editable'); - // Button for removing the tag. - var removeTagIcon = $('<span></span>') - .addClass('ui-icon ui-icon-close'); - var removeTag = $('<a><span class="text-icon">\xd7</span></a>') // \xd7 is an X - .addClass('tagit-close') - .append(removeTagIcon) - .click(function(e) { - // Removes a tag when the little 'x' is clicked. - that.removeTag(tag); - }); - tag.append(removeTag); - } - - // Unless options.singleField is set, each tag has a hidden input field inline. - if (!this.options.singleField) { - var escapedValue = label.html(); - tag.append('<input type="hidden" style="display:none;" value="' + escapedValue + '" name="' + this.options.fieldName + '" />'); - } - - if (this._trigger('beforeTagAdded', null, { - tag: tag, - tagLabel: this.tagLabel(tag), - duringInitialization: duringInitialization - }) === false) { - return; - } - - if (this.options.singleField) { - var tags = this.assignedTags(); - tags.push(value); - this._updateSingleTagsField(tags); - } - - // DEPRECATED. - this._trigger('onTagAdded', null, tag); - - this.tagInput.val(''); - - // Insert tag. - this.tagInput.parent().before(tag); - - this._trigger('afterTagAdded', null, { - tag: tag, - tagLabel: this.tagLabel(tag), - duringInitialization: duringInitialization - }); - - if (this.options.showAutocompleteOnFocus && !duringInitialization) { - setTimeout(function () { that._showAutocomplete(); }, 0); - } - }, - - removeTag: function(tag, animate) { - animate = typeof animate === 'undefined' ? this.options.animate : animate; - - tag = $(tag); - - // DEPRECATED. - this._trigger('onTagRemoved', null, tag); - - if (this._trigger('beforeTagRemoved', null, {tag: tag, tagLabel: this.tagLabel(tag)}) === false) { - return; - } - - if (this.options.singleField) { - var tags = this.assignedTags(); - var removedTagLabel = this.tagLabel(tag); - tags = $.grep(tags, function(el){ - return el != removedTagLabel; - }); - this._updateSingleTagsField(tags); - } - - if (animate) { - tag.addClass('removed'); // Excludes this tag from _tags. - var hide_args = this._effectExists('blind') ? ['blind', {direction: 'horizontal'}, 'fast'] : ['fast']; - - hide_args.push(function() { - tag.remove(); - }); - - tag.fadeOut('fast').hide.apply(tag, hide_args).dequeue(); - } else { - tag.remove(); - } - - this._trigger('afterTagRemoved', null, {tag: tag, tagLabel: this.tagLabel(tag)}); - }, - - removeTagByLabel: function(tagLabel, animate) { - var toRemove = this._findTagByLabel(tagLabel); - if (!toRemove) { - throw "No such tag exists with the name '" + tagLabel + "'"; - } - this.removeTag(toRemove, animate); - }, - - removeAll: function() { - // Removes all tags. - var that = this; - this._tags().each(function(index, tag) { - that.removeTag(tag, false); - }); - } - - }); -})(jQuery); - diff --git a/src/main/webapp/static/js/jquery/tagit/tag-it.min.js b/src/main/webapp/static/js/jquery/tagit/tag-it.min.js deleted file mode 100644 index 3fdf3ce05e3febeb9a707aa507d20a8a7b238e7c..0000000000000000000000000000000000000000 --- a/src/main/webapp/static/js/jquery/tagit/tag-it.min.js +++ /dev/null @@ -1,15 +0,0 @@ -(function(b){b.widget("ui.tagit",{options:{allowDuplicates:!1,caseSensitive:!0,fieldName:"tags",placeholderText:null,readOnly:!1,removeConfirmation:!1,tagLimit:null,availableTags:[],autocomplete:{},showAutocompleteOnFocus:!1,allowSpaces:!1,singleField:!1,singleFieldDelimiter:",",singleFieldNode:null,animate:!0,tabIndex:null,beforeTagAdded:null,afterTagAdded:null,beforeTagRemoved:null,afterTagRemoved:null,onTagClicked:null,onTagLimitExceeded:null,onTagAdded:null,onTagRemoved:null,tagSource:null},_create:function(){var a= -this;this.element.is("input")?(this.tagList=b("<ul></ul>").insertAfter(this.element),this.options.singleField=!0,this.options.singleFieldNode=this.element,this.element.css("display","none")):this.tagList=this.element.find("ul, ol").andSelf().last();this.tagInput=b('<input type="text" />').addClass("ui-widget-content");this.options.readOnly&&this.tagInput.attr("disabled","disabled");this.options.tabIndex&&this.tagInput.attr("tabindex",this.options.tabIndex);this.options.placeholderText&&this.tagInput.attr("placeholder", -this.options.placeholderText);this.options.autocomplete.source||(this.options.autocomplete.source=function(a,c){var d=a.term.toLowerCase(),e=b.grep(this.options.availableTags,function(a){return 0===a.toLowerCase().indexOf(d)});c(this._subtractArray(e,this.assignedTags()))});this.options.showAutocompleteOnFocus&&(this.tagInput.focus(function(){a._showAutocomplete()}),"undefined"===typeof this.options.autocomplete.minLength&&(this.options.autocomplete.minLength=0));b.isFunction(this.options.autocomplete.source)&& -(this.options.autocomplete.source=b.proxy(this.options.autocomplete.source,this));b.isFunction(this.options.tagSource)&&(this.options.tagSource=b.proxy(this.options.tagSource,this));this.tagList.addClass("tagit").addClass("ui-widget ui-widget-content ui-corner-all").append(b('<li class="tagit-new"></li>').append(this.tagInput)).click(function(c){var d=b(c.target);d.hasClass("tagit-label")?(d=d.closest(".tagit-choice"),d.hasClass("removed")||a._trigger("onTagClicked",c,{tag:d,tagLabel:a.tagLabel(d)})): -a.tagInput.focus()});var d=!1;if(this.options.singleField)if(this.options.singleFieldNode){var c=b(this.options.singleFieldNode),e=c.val().split(this.options.singleFieldDelimiter);c.val("");b.each(e,function(b,c){a.createTag(c,null,!0);d=!0})}else this.options.singleFieldNode=b('<input type="hidden" style="display:none;" value="" name="'+this.options.fieldName+'" />'),this.tagList.after(this.options.singleFieldNode);d||this.tagList.children("li").each(function(){b(this).hasClass("tagit-new")||(a.createTag(b(this).text(), -b(this).attr("class"),!0),b(this).remove())});this.tagInput.keydown(function(c){if(c.which==b.ui.keyCode.BACKSPACE&&""===a.tagInput.val()){var d=a._lastTag();!a.options.removeConfirmation||d.hasClass("remove")?a.removeTag(d):a.options.removeConfirmation&&d.addClass("remove ui-state-highlight")}else a.options.removeConfirmation&&a._lastTag().removeClass("remove ui-state-highlight");if(c.which===b.ui.keyCode.COMMA||c.which===b.ui.keyCode.ENTER||c.which==b.ui.keyCode.TAB&&""!==a.tagInput.val()||c.which== -b.ui.keyCode.SPACE&&!0!==a.options.allowSpaces&&('"'!=b.trim(a.tagInput.val()).replace(/^s*/,"").charAt(0)||'"'==b.trim(a.tagInput.val()).charAt(0)&&'"'==b.trim(a.tagInput.val()).charAt(b.trim(a.tagInput.val()).length-1)&&0!==b.trim(a.tagInput.val()).length-1))c.which===b.ui.keyCode.ENTER&&""===a.tagInput.val()||c.preventDefault(),a.createTag(a._cleanedInput()),a.tagInput.autocomplete("close")}).blur(function(){a.tagInput.data("autocomplete-open")||a.createTag(a._cleanedInput())});if(this.options.availableTags|| -this.options.tagSource||this.options.autocomplete.source)c={select:function(b,c){a.createTag(c.item.value);return!1}},b.extend(c,this.options.autocomplete),c.source=this.options.tagSource||c.source,this.tagInput.autocomplete(c).bind("autocompleteopen",function(){a.tagInput.data("autocomplete-open",!0)}).bind("autocompleteclose",function(){a.tagInput.data("autocomplete-open",!1)})},_cleanedInput:function(){return b.trim(this.tagInput.val().replace(/^"(.*)"$/,"$1"))},_lastTag:function(){return this.tagList.find(".tagit-choice:last:not(.removed)")}, -_tags:function(){return this.tagList.find(".tagit-choice:not(.removed)")},assignedTags:function(){var a=this,d=[];this.options.singleField?(d=b(this.options.singleFieldNode).val().split(this.options.singleFieldDelimiter),""===d[0]&&(d=[])):this._tags().each(function(){d.push(a.tagLabel(this))});return d},_updateSingleTagsField:function(a){b(this.options.singleFieldNode).val(a.join(this.options.singleFieldDelimiter)).trigger("change")},_subtractArray:function(a,d){for(var c=[],e=0;e<a.length;e++)-1== -b.inArray(a[e],d)&&c.push(a[e]);return c},tagLabel:function(a){return this.options.singleField?b(a).find(".tagit-label:first").text():b(a).find("input:first").val()},_showAutocomplete:function(){this.tagInput.autocomplete("search","")},_findTagByLabel:function(a){var d=this,c=null;this._tags().each(function(){if(d._formatStr(a)==d._formatStr(d.tagLabel(this)))return c=b(this),!1});return c},_isNew:function(a){return!this._findTagByLabel(a)},_formatStr:function(a){return this.options.caseSensitive? -a:b.trim(a.toLowerCase())},_effectExists:function(a){return Boolean(b.effects&&(b.effects[a]||b.effects.effect&&b.effects.effect[a]))},createTag:function(a,d,c){var e=this;a=b.trim(a);if(""===a)return!1;if(!this.options.allowDuplicates&&!this._isNew(a))return a=this._findTagByLabel(a),!1!==this._trigger("onTagExists",null,{existingTag:a,duringInitialization:c})&&this._effectExists("highlight")&&a.effect("highlight"),!1;if(this.options.tagLimit&&this._tags().length>=this.options.tagLimit)return this._trigger("onTagLimitExceeded", -null,{duringInitialization:c}),!1;var g=b(this.options.onTagClicked?'<a class="tagit-label"></a>':'<span class="tagit-label"></span>').text(a),f=b("<li></li>").addClass("tagit-choice ui-widget-content ui-state-default ui-corner-all").addClass(d).append(g);this.options.readOnly?f.addClass("tagit-choice-read-only"):(f.addClass("tagit-choice-editable"),d=b("<span></span>").addClass("ui-icon ui-icon-close"),d=b('<a><span class="text-icon">\u00d7</span></a>').addClass("tagit-close").append(d).click(function(){e.removeTag(f)}), -f.append(d));this.options.singleField||(g=g.html(),f.append('<input type="hidden" style="display:none;" value="'+g+'" name="'+this.options.fieldName+'" />'));!1!==this._trigger("beforeTagAdded",null,{tag:f,tagLabel:this.tagLabel(f),duringInitialization:c})&&(this.options.singleField&&(g=this.assignedTags(),g.push(a),this._updateSingleTagsField(g)),this._trigger("onTagAdded",null,f),this.tagInput.val(""),this.tagInput.parent().before(f),this._trigger("afterTagAdded",null,{tag:f,tagLabel:this.tagLabel(f), -duringInitialization:c}),this.options.showAutocompleteOnFocus&&!c&&setTimeout(function(){e._showAutocomplete()},0))},removeTag:function(a,d){d="undefined"===typeof d?this.options.animate:d;a=b(a);this._trigger("onTagRemoved",null,a);if(!1!==this._trigger("beforeTagRemoved",null,{tag:a,tagLabel:this.tagLabel(a)})){if(this.options.singleField){var c=this.assignedTags(),e=this.tagLabel(a),c=b.grep(c,function(a){return a!=e});this._updateSingleTagsField(c)}d?(a.addClass("removed"),c=this._effectExists("blind")? -["blind",{direction:"horizontal"},"fast"]:["fast"],c.push(function(){a.remove()}),a.fadeOut("fast").hide.apply(a,c).dequeue()):a.remove();this._trigger("afterTagRemoved",null,{tag:a,tagLabel:this.tagLabel(a)})}},removeTagByLabel:function(a,b){var c=this._findTagByLabel(a);if(!c)throw"No such tag exists with the name '"+a+"'";this.removeTag(c,b)},removeAll:function(){var a=this;this._tags().each(function(b,c){a.removeTag(c,!1)})}})})(jQuery); diff --git a/src/main/webapp/static/js/jquery/tagsinput/bootstrap-tagsinput.css b/src/main/webapp/static/js/jquery/tagsinput/bootstrap-tagsinput.css new file mode 100644 index 0000000000000000000000000000000000000000..98cfa7f3c1db344bcde8ea709c0170c16adaa6b1 --- /dev/null +++ b/src/main/webapp/static/js/jquery/tagsinput/bootstrap-tagsinput.css @@ -0,0 +1,45 @@ +.bootstrap-tagsinput { + background-color: #fff; + border: 1px solid #ccc; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + display: inline-block; + padding: 4px 6px; + margin-bottom: 10px; + color: #555; + vertical-align: middle; + border-radius: 4px; + max-width: 100%; + line-height: 22px; +} +.bootstrap-tagsinput input { + border: none; + box-shadow: none; + outline: none; + background-color: transparent; + padding: 0; + margin: 0; + width: auto !important; + max-width: inherit; +} +.bootstrap-tagsinput input:focus { + border: none; + box-shadow: none; +} +.bootstrap-tagsinput .tag { + margin-right: 2px; + color: white; +} +.bootstrap-tagsinput .tag [data-role="remove"] { + margin-left: 8px; + cursor: pointer; +} +.bootstrap-tagsinput .tag [data-role="remove"]:after { + content: "x"; + padding: 0px 2px; +} +.bootstrap-tagsinput .tag [data-role="remove"]:hover { + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} +.bootstrap-tagsinput .tag [data-role="remove"]:hover:active { + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} diff --git a/src/main/webapp/static/js/jquery/tagsinput/bootstrap-tagsinput.js b/src/main/webapp/static/js/jquery/tagsinput/bootstrap-tagsinput.js new file mode 100644 index 0000000000000000000000000000000000000000..4c97aceeae4f051241956821dc3b294207fe8504 --- /dev/null +++ b/src/main/webapp/static/js/jquery/tagsinput/bootstrap-tagsinput.js @@ -0,0 +1,503 @@ +(function ($) { + "use strict"; + + var defaultOptions = { + tagClass: function(item) { + return 'label label-info'; + }, + itemValue: function(item) { + return item ? item.toString() : item; + }, + itemText: function(item) { + return this.itemValue(item); + }, + freeInput: true, + maxTags: undefined, + confirmKeys: [13], + onTagExists: function(item, $tag) { + $tag.hide().fadeIn(); + } + }; + + /** + * Constructor function + */ + function TagsInput(element, options) { + this.itemsArray = []; + + this.$element = $(element); + this.$element.hide(); + + this.isSelect = (element.tagName === 'SELECT'); + this.multiple = (this.isSelect && element.hasAttribute('multiple')); + this.objectItems = options && options.itemValue; + this.placeholderText = element.hasAttribute('placeholder') ? this.$element.attr('placeholder') : ''; + this.inputSize = Math.max(1, this.placeholderText.length); + + this.$container = $('<div class="bootstrap-tagsinput"></div>'); + this.$input = $('<input size="' + this.inputSize + '" type="text" placeholder="' + this.placeholderText + '"/>').appendTo(this.$container); + + this.$element.after(this.$container); + + this.build(options); + } + + TagsInput.prototype = { + constructor: TagsInput, + + /** + * Adds the given item as a new tag. Pass true to dontPushVal to prevent + * updating the elements val() + */ + add: function(item, dontPushVal) { + var self = this; + + if (self.options.maxTags && self.itemsArray.length >= self.options.maxTags) + return; + + // Ignore falsey values, except false + if (item !== false && !item) + return; + + // Throw an error when trying to add an object while the itemValue option was not set + if (typeof item === "object" && !self.objectItems) + throw("Can't add objects when itemValue option is not set"); + + // Ignore strings only containg whitespace + if (item.toString().match(/^\s*$/)) + return; + + // If SELECT but not multiple, remove current tag + if (self.isSelect && !self.multiple && self.itemsArray.length > 0) + self.remove(self.itemsArray[0]); + + if (typeof item === "string" && this.$element[0].tagName === 'INPUT') { + var items = item.split(','); + if (items.length > 1) { + for (var i = 0; i < items.length; i++) { + this.add(items[i], true); + } + + if (!dontPushVal) + self.pushVal(); + return; + } + } + + var itemValue = self.options.itemValue(item), + itemText = self.options.itemText(item), + tagClass = self.options.tagClass(item); + + // Ignore items allready added + var existing = $.grep(self.itemsArray, function(item) { return self.options.itemValue(item) === itemValue; } )[0]; + if (existing) { + // Invoke onTagExists + if (self.options.onTagExists) { + var $existingTag = $(".tag", self.$container).filter(function() { return $(this).data("item") === existing; }); + self.options.onTagExists(item, $existingTag); + } + return; + } + + // register item in internal array and map + self.itemsArray.push(item); + + // add a tag element + var $tag = $('<span class="tag ' + htmlEncode(tagClass) + '">' + htmlEncode(itemText) + '<span data-role="remove"></span></span>'); + $tag.data('item', item); + self.findInputWrapper().before($tag); + $tag.after(' '); + + // add <option /> if item represents a value not present in one of the <select />'s options + if (self.isSelect && !$('option[value="' + escape(itemValue) + '"]',self.$element)[0]) { + var $option = $('<option selected>' + htmlEncode(itemText) + '</option>'); + $option.data('item', item); + $option.attr('value', itemValue); + self.$element.append($option); + } + + if (!dontPushVal) + self.pushVal(); + + // Add class when reached maxTags + if (self.options.maxTags === self.itemsArray.length) + self.$container.addClass('bootstrap-tagsinput-max'); + + self.$element.trigger($.Event('itemAdded', { item: item })); + }, + + /** + * Removes the given item. Pass true to dontPushVal to prevent updating the + * elements val() + */ + remove: function(item, dontPushVal) { + var self = this; + + if (self.objectItems) { + if (typeof item === "object") + item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == self.options.itemValue(item); } )[0]; + else + item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == item; } )[0]; + } + + if (item) { + $('.tag', self.$container).filter(function() { return $(this).data('item') === item; }).remove(); + $('option', self.$element).filter(function() { return $(this).data('item') === item; }).remove(); + self.itemsArray.splice($.inArray(item, self.itemsArray), 1); + } + + if (!dontPushVal) + self.pushVal(); + + // Remove class when reached maxTags + if (self.options.maxTags > self.itemsArray.length) + self.$container.removeClass('bootstrap-tagsinput-max'); + + self.$element.trigger($.Event('itemRemoved', { item: item })); + }, + + /** + * Removes all items + */ + removeAll: function() { + var self = this; + + $('.tag', self.$container).remove(); + $('option', self.$element).remove(); + + while(self.itemsArray.length > 0) + self.itemsArray.pop(); + + self.pushVal(); + + if (self.options.maxTags && !this.isEnabled()) + this.enable(); + }, + + /** + * Refreshes the tags so they match the text/value of their corresponding + * item. + */ + refresh: function() { + var self = this; + $('.tag', self.$container).each(function() { + var $tag = $(this), + item = $tag.data('item'), + itemValue = self.options.itemValue(item), + itemText = self.options.itemText(item), + tagClass = self.options.tagClass(item); + + // Update tag's class and inner text + $tag.attr('class', null); + $tag.addClass('tag ' + htmlEncode(tagClass)); + $tag.contents().filter(function() { + return this.nodeType == 3; + })[0].nodeValue = htmlEncode(itemText); + + if (self.isSelect) { + var option = $('option', self.$element).filter(function() { return $(this).data('item') === item; }); + option.attr('value', itemValue); + } + }); + }, + + /** + * Returns the items added as tags + */ + items: function() { + return this.itemsArray; + }, + + /** + * Assembly value by retrieving the value of each item, and set it on the + * element. + */ + pushVal: function() { + var self = this, + val = $.map(self.items(), function(item) { + return self.options.itemValue(item).toString(); + }); + + self.$element.val(val, true).trigger('change'); + }, + + /** + * Initializes the tags input behaviour on the element + */ + build: function(options) { + var self = this; + + self.options = $.extend({}, defaultOptions, options); + var typeahead = self.options.typeahead || {}; + + // When itemValue is set, freeInput should always be false + if (self.objectItems) + self.options.freeInput = false; + + makeOptionItemFunction(self.options, 'itemValue'); + makeOptionItemFunction(self.options, 'itemText'); + makeOptionItemFunction(self.options, 'tagClass'); + + // for backwards compatibility, self.options.source is deprecated + if (self.options.source) + typeahead.source = self.options.source; + + if (typeahead.source && $.fn.typeahead) { + makeOptionFunction(typeahead, 'source'); + + self.$input.typeahead({ + source: function (query, process) { + function processItems(items) { + var texts = []; + + for (var i = 0; i < items.length; i++) { + var text = self.options.itemText(items[i]); + map[text] = items[i]; + texts.push(text); + } + process(texts); + } + + this.map = {}; + var map = this.map, + data = typeahead.source(query); + + if ($.isFunction(data.success)) { + // support for Angular promises + data.success(processItems); + } else { + // support for functions and jquery promises + $.when(data) + .then(processItems); + } + }, + updater: function (text) { + self.add(this.map[text]); + }, + matcher: function (text) { + return (text.toLowerCase().indexOf(this.query.trim().toLowerCase()) !== -1); + }, + sorter: function (texts) { + return texts.sort(); + }, + highlighter: function (text) { + var regex = new RegExp( '(' + this.query + ')', 'gi' ); + return text.replace( regex, "<strong>$1</strong>" ); + } + }); + } + + self.$container.on('click', $.proxy(function(event) { + self.$input.focus(); + }, self)); + + self.$container.on('keydown', 'input', $.proxy(function(event) { + var $input = $(event.target), + $inputWrapper = self.findInputWrapper(); + + switch (event.which) { + // BACKSPACE + case 8: + if (doGetCaretPosition($input[0]) === 0) { + var prev = $inputWrapper.prev(); + if (prev) { + self.remove(prev.data('item')); + } + } + break; + + // DELETE + case 46: + if (doGetCaretPosition($input[0]) === 0) { + var next = $inputWrapper.next(); + if (next) { + self.remove(next.data('item')); + } + } + break; + + // LEFT ARROW + case 37: + // Try to move the input before the previous tag + var $prevTag = $inputWrapper.prev(); + if ($input.val().length === 0 && $prevTag[0]) { + $prevTag.before($inputWrapper); + $input.focus(); + } + break; + // RIGHT ARROW + case 39: + // Try to move the input after the next tag + var $nextTag = $inputWrapper.next(); + if ($input.val().length === 0 && $nextTag[0]) { + $nextTag.after($inputWrapper); + $input.focus(); + } + break; + default: + // When key corresponds one of the confirmKeys, add current input + // as a new tag + if (self.options.freeInput && $.inArray(event.which, self.options.confirmKeys) >= 0) { + self.add($input.val()); + $input.val(''); + event.preventDefault(); + } + } + + // Reset internal input's size + $input.attr('size', Math.max(this.inputSize, $input.val().length)); + }, self)); + + // Remove icon clicked + self.$container.on('click', '[data-role=remove]', $.proxy(function(event) { + self.remove($(event.target).closest('.tag').data('item')); + }, self)); + + // Only add existing value as tags when using strings as tags + if (self.options.itemValue === defaultOptions.itemValue) { + if (self.$element[0].tagName === 'INPUT') { + self.add(self.$element.val()); + } else { + $('option', self.$element).each(function() { + self.add($(this).attr('value'), true); + }); + } + } + }, + + /** + * Removes all tagsinput behaviour and unregsiter all event handlers + */ + destroy: function() { + var self = this; + + // Unbind events + self.$container.off('keypress', 'input'); + self.$container.off('click', '[role=remove]'); + + self.$container.remove(); + self.$element.removeData('tagsinput'); + self.$element.show(); + }, + + /** + * Sets focus on the tagsinput + */ + focus: function() { + this.$input.focus(); + }, + + /** + * Returns the internal input element + */ + input: function() { + return this.$input; + }, + + /** + * Returns the element which is wrapped around the internal input. This + * is normally the $container, but typeahead.js moves the $input element. + */ + findInputWrapper: function() { + var elt = this.$input[0], + container = this.$container[0]; + while(elt && elt.parentNode !== container) + elt = elt.parentNode; + + return $(elt); + } + }; + + /** + * Register JQuery plugin + */ + $.fn.tagsinput = function(arg1, arg2) { + var results = []; + + this.each(function() { + var tagsinput = $(this).data('tagsinput'); + + // Initialize a new tags input + if (!tagsinput) { + tagsinput = new TagsInput(this, arg1); + $(this).data('tagsinput', tagsinput); + results.push(tagsinput); + + if (this.tagName === 'SELECT') { + $('option', $(this)).attr('selected', 'selected'); + } + + // Init tags from $(this).val() + $(this).val($(this).val()); + } else { + // Invoke function on existing tags input + var retVal = tagsinput[arg1](arg2); + if (retVal !== undefined) + results.push(retVal); + } + }); + + if ( typeof arg1 == 'string') { + // Return the results from the invoked function calls + return results.length > 1 ? results : results[0]; + } else { + return results; + } + }; + + $.fn.tagsinput.Constructor = TagsInput; + + /** + * Most options support both a string or number as well as a function as + * option value. This function makes sure that the option with the given + * key in the given options is wrapped in a function + */ + function makeOptionItemFunction(options, key) { + if (typeof options[key] !== 'function') { + var propertyName = options[key]; + options[key] = function(item) { return item[propertyName]; }; + } + } + function makeOptionFunction(options, key) { + if (typeof options[key] !== 'function') { + var value = options[key]; + options[key] = function() { return value; }; + } + } + /** + * HtmlEncodes the given value + */ + var htmlEncodeContainer = $('<div />'); + function htmlEncode(value) { + if (value) { + return htmlEncodeContainer.text(value).html(); + } else { + return ''; + } + } + + /** + * Returns the position of the caret in the given input field + * http://flightschool.acylt.com/devnotes/caret-position-woes/ + */ + function doGetCaretPosition(oField) { + var iCaretPos = 0; + if (document.selection) { + oField.focus (); + var oSel = document.selection.createRange(); + oSel.moveStart ('character', -oField.value.length); + iCaretPos = oSel.text.length; + } else if (oField.selectionStart || oField.selectionStart == '0') { + iCaretPos = oField.selectionStart; + } + return (iCaretPos); + } + + /** + * Initialize tagsinput behaviour on inputs and selects which have + * data-role=tagsinput + */ + $(function() { + $("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput(); + }); +})(window.jQuery); diff --git a/src/main/webapp/static/js/jquery/tagsinput/bootstrap-tagsinput.min.js b/src/main/webapp/static/js/jquery/tagsinput/bootstrap-tagsinput.min.js new file mode 100644 index 0000000000000000000000000000000000000000..85635835537d06c7b1c79f78452a8deb8a60cb3f --- /dev/null +++ b/src/main/webapp/static/js/jquery/tagsinput/bootstrap-tagsinput.min.js @@ -0,0 +1,5 @@ +/* + * bootstrap-tagsinput v0.3.9 by Tim Schlechter + * + */ +!function(a){"use strict";function b(b,c){this.itemsArray=[],this.$element=a(b),this.$element.hide(),this.isSelect="SELECT"===b.tagName,this.multiple=this.isSelect&&b.hasAttribute("multiple"),this.objectItems=c&&c.itemValue,this.placeholderText=b.hasAttribute("placeholder")?this.$element.attr("placeholder"):"",this.inputSize=Math.max(1,this.placeholderText.length),this.$container=a('<div class="bootstrap-tagsinput"></div>'),this.$input=a('<input size="'+this.inputSize+'" type="text" placeholder="'+this.placeholderText+'"/>').appendTo(this.$container),this.$element.after(this.$container),this.build(c)}function c(a,b){if("function"!=typeof a[b]){var c=a[b];a[b]=function(a){return a[c]}}}function d(a,b){if("function"!=typeof a[b]){var c=a[b];a[b]=function(){return c}}}function e(a){return a?h.text(a).html():""}function f(a){var b=0;if(document.selection){a.focus();var c=document.selection.createRange();c.moveStart("character",-a.value.length),b=c.text.length}else(a.selectionStart||"0"==a.selectionStart)&&(b=a.selectionStart);return b}var g={tagClass:function(){return"label label-info"},itemValue:function(a){return a?a.toString():a},itemText:function(a){return this.itemValue(a)},freeInput:!0,maxTags:void 0,confirmKeys:[13],onTagExists:function(a,b){b.hide().fadeIn()}};b.prototype={constructor:b,add:function(b,c){var d=this;if(!(d.options.maxTags&&d.itemsArray.length>=d.options.maxTags||b!==!1&&!b)){if("object"==typeof b&&!d.objectItems)throw"Can't add objects when itemValue option is not set";if(!b.toString().match(/^\s*$/)){if(d.isSelect&&!d.multiple&&d.itemsArray.length>0&&d.remove(d.itemsArray[0]),"string"==typeof b&&"INPUT"===this.$element[0].tagName){var f=b.split(",");if(f.length>1){for(var g=0;g<f.length;g++)this.add(f[g],!0);return c||d.pushVal(),void 0}}var h=d.options.itemValue(b),i=d.options.itemText(b),j=d.options.tagClass(b),k=a.grep(d.itemsArray,function(a){return d.options.itemValue(a)===h})[0];if(k){if(d.options.onTagExists){var l=a(".tag",d.$container).filter(function(){return a(this).data("item")===k});d.options.onTagExists(b,l)}}else{d.itemsArray.push(b);var m=a('<span class="tag '+e(j)+'">'+e(i)+'<span data-role="remove"></span></span>');if(m.data("item",b),d.findInputWrapper().before(m),m.after(" "),d.isSelect&&!a('option[value="'+escape(h)+'"]',d.$element)[0]){var n=a("<option selected>"+e(i)+"</option>");n.data("item",b),n.attr("value",h),d.$element.append(n)}c||d.pushVal(),d.options.maxTags===d.itemsArray.length&&d.$container.addClass("bootstrap-tagsinput-max"),d.$element.trigger(a.Event("itemAdded",{item:b}))}}}},remove:function(b,c){var d=this;d.objectItems&&(b="object"==typeof b?a.grep(d.itemsArray,function(a){return d.options.itemValue(a)==d.options.itemValue(b)})[0]:a.grep(d.itemsArray,function(a){return d.options.itemValue(a)==b})[0]),b&&(a(".tag",d.$container).filter(function(){return a(this).data("item")===b}).remove(),a("option",d.$element).filter(function(){return a(this).data("item")===b}).remove(),d.itemsArray.splice(a.inArray(b,d.itemsArray),1)),c||d.pushVal(),d.options.maxTags>d.itemsArray.length&&d.$container.removeClass("bootstrap-tagsinput-max"),d.$element.trigger(a.Event("itemRemoved",{item:b}))},removeAll:function(){var b=this;for(a(".tag",b.$container).remove(),a("option",b.$element).remove();b.itemsArray.length>0;)b.itemsArray.pop();b.pushVal(),b.options.maxTags&&!this.isEnabled()&&this.enable()},refresh:function(){var b=this;a(".tag",b.$container).each(function(){var c=a(this),d=c.data("item"),f=b.options.itemValue(d),g=b.options.itemText(d),h=b.options.tagClass(d);if(c.attr("class",null),c.addClass("tag "+e(h)),c.contents().filter(function(){return 3==this.nodeType})[0].nodeValue=e(g),b.isSelect){var i=a("option",b.$element).filter(function(){return a(this).data("item")===d});i.attr("value",f)}})},items:function(){return this.itemsArray},pushVal:function(){var b=this,c=a.map(b.items(),function(a){return b.options.itemValue(a).toString()});b.$element.val(c,!0).trigger("change")},build:function(b){var e=this;e.options=a.extend({},g,b);var h=e.options.typeahead||{};e.objectItems&&(e.options.freeInput=!1),c(e.options,"itemValue"),c(e.options,"itemText"),c(e.options,"tagClass"),e.options.source&&(h.source=e.options.source),h.source&&a.fn.typeahead&&(d(h,"source"),e.$input.typeahead({source:function(b,c){function d(a){for(var b=[],d=0;d<a.length;d++){var g=e.options.itemText(a[d]);f[g]=a[d],b.push(g)}c(b)}this.map={};var f=this.map,g=h.source(b);a.isFunction(g.success)?g.success(d):a.when(g).then(d)},updater:function(a){e.add(this.map[a])},matcher:function(a){return-1!==a.toLowerCase().indexOf(this.query.trim().toLowerCase())},sorter:function(a){return a.sort()},highlighter:function(a){var b=new RegExp("("+this.query+")","gi");return a.replace(b,"<strong>$1</strong>")}})),e.$container.on("click",a.proxy(function(){e.$input.focus()},e)),e.$container.on("keydown","input",a.proxy(function(b){var c=a(b.target),d=e.findInputWrapper();switch(b.which){case 8:if(0===f(c[0])){var g=d.prev();g&&e.remove(g.data("item"))}break;case 46:if(0===f(c[0])){var h=d.next();h&&e.remove(h.data("item"))}break;case 37:var i=d.prev();0===c.val().length&&i[0]&&(i.before(d),c.focus());break;case 39:var j=d.next();0===c.val().length&&j[0]&&(j.after(d),c.focus());break;default:e.options.freeInput&&a.inArray(b.which,e.options.confirmKeys)>=0&&(e.add(c.val()),c.val(""),b.preventDefault())}c.attr("size",Math.max(this.inputSize,c.val().length))},e)),e.$container.on("click","[data-role=remove]",a.proxy(function(b){e.remove(a(b.target).closest(".tag").data("item"))},e)),e.options.itemValue===g.itemValue&&("INPUT"===e.$element[0].tagName?e.add(e.$element.val()):a("option",e.$element).each(function(){e.add(a(this).attr("value"),!0)}))},destroy:function(){var a=this;a.$container.off("keypress","input"),a.$container.off("click","[role=remove]"),a.$container.remove(),a.$element.removeData("tagsinput"),a.$element.show()},focus:function(){this.$input.focus()},input:function(){return this.$input},findInputWrapper:function(){for(var b=this.$input[0],c=this.$container[0];b&&b.parentNode!==c;)b=b.parentNode;return a(b)}},a.fn.tagsinput=function(c,d){var e=[];return this.each(function(){var f=a(this).data("tagsinput");if(f){var g=f[c](d);void 0!==g&&e.push(g)}else f=new b(this,c),a(this).data("tagsinput",f),e.push(f),"SELECT"===this.tagName&&a("option",a(this)).attr("selected","selected"),a(this).val(a(this).val())}),"string"==typeof c?e.length>1?e:e[0]:e},a.fn.tagsinput.Constructor=b;var h=a("<div />");a(function(){a("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput()})}(window.jQuery); \ No newline at end of file diff --git a/src/main/webapp/static/js/js.plugins.min.css b/src/main/webapp/static/js/js.plugins.min.css index 47ef947ebd73f2bcac58dceacb52df9eca7320f6..06ff0c1c52cac791696633aafd4ea353e6142f26 100644 --- a/src/main/webapp/static/js/js.plugins.min.css +++ b/src/main/webapp/static/js/js.plugins.min.css @@ -1,4 +1,4 @@ -ul.tagit{padding:1px 5px;overflow:auto;margin-left:inherit;margin-right:inherit}ul.tagit li{display:block;float:left;margin:2px 5px 2px 0}ul.tagit li.tagit-choice{position:relative;line-height:inherit}ul.tagit li.tagit-choice-read-only{padding:.2em .5em .2em .5em}ul.tagit li.tagit-choice-editable{padding:.2em 18px .2em .5em}ul.tagit li.tagit-new{padding:.25em 4px .25em 0}ul.tagit li.tagit-choice a.tagit-label{cursor:pointer;text-decoration:none}ul.tagit li.tagit-choice .tagit-close{cursor:pointer;position:absolute;right:.1em;top:50%;margin-top:-8px;line-height:17px}ul.tagit li.tagit-choice .tagit-close .text-icon{display:none}ul.tagit li.tagit-choice input{display:block;float:left;margin:2px 5px 2px 0}ul.tagit input[type="text"]{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none;border:0;margin:0;padding:0;width:inherit;background-color:inherit;outline:0}body{font-family:Geneva,Arial,Helvetica,sans-serif;font-size:100%;*font-size:80%}.ui-layout-pane{background:#FFF;border:1px solid #BBB;padding:10px;overflow:auto}.ui-layout-content{padding:10px;position:relative;overflow:auto}.layout-child-container,.layout-content-container{padding:0;overflow:hidden}.layout-child-container{border:0}.layout-scroll{overflow:auto}.layout-hide{display:none}.ui-layout-resizer{background:#DDD;border:1px solid #BBB;border-width:0}.ui-layout-resizer-open-hover,.ui-layout-resizer-dragging{background:#c4e1a4}.ui-layout-resizer-dragging{border:1px solid #BBB}.ui-layout-resizer-north-dragging,.ui-layout-resizer-south-dragging{border-width:1px 0}.ui-layout-resizer-west-dragging,.ui-layout-resizer-east-dragging{border-width:0 1px}.ui-layout-resizer-dragging-limit{background:#e1a4a4}.ui-layout-resizer-closed-hover{background:#ebd5aa}.ui-layout-resizer-sliding{opacity:.10;filter:alpha(opacity=10)}.ui-layout-resizer-sliding-hover{opacity:1.00;filter:alpha(opacity=100)}.ui-layout-resizer-north-sliding-hover{border-bottom-width:1px}.ui-layout-resizer-south-sliding-hover{border-top-width:1px}.ui-layout-resizer-west-sliding-hover{border-right-width:1px}.ui-layout-resizer-east-sliding-hover{border-left-width:1px}.ui-layout-toggler{border:1px solid #BBB;background-color:#BBB}.ui-layout-resizer-hover .ui-layout-toggler{opacity:.60;filter:alpha(opacity=60)}.ui-layout-toggler-hover,.ui-layout-resizer-hover .ui-layout-toggler-hover{background-color:#FC6;opacity:1.00;filter:alpha(opacity=100)}.ui-layout-toggler-north,.ui-layout-toggler-south{border-width:0 1px}.ui-layout-toggler-west,.ui-layout-toggler-east{border-width:1px 0}.ui-layout-resizer-sliding .ui-layout-toggler{display:none}.ui-layout-toggler .content{color:#666;font-size:12px;font-weight:bold;width:100%;padding-bottom:.35ex}.ui-layout-mask{border:none!important;padding:0!important;margin:0!important;overflow:hidden!important;position:absolute!important;opacity:0!important;filter:Alpha(Opacity="0")!important}.ui-layout-mask-inside-pane{top:0!important;left:0!important;width:100%!important;height:100%!important}@media print{html{height:auto!important;overflow:visible!important}body.ui-layout-container{position:static!important;top:auto!important;bottom:auto!important;left:auto!important;right:auto!important;_width:auto!important;_height:auto!important}.ui-layout-resizer,.ui-layout-toggler{display:none!important}.ui-layout-pane{border:none!important;background:transparent!important;position:relative!important;top:auto!important;bottom:auto!important;left:auto!important;right:auto!important;width:auto!important;height:auto!important;overflow:visible!important}}/*! +.bootstrap-tagsinput{background-color:#fff;border:1px solid #ccc;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);display:inline-block;padding:4px 6px;margin-bottom:10px;color:#555;vertical-align:middle;border-radius:4px;max-width:100%;line-height:22px}.bootstrap-tagsinput input{border:0;box-shadow:none;outline:0;background-color:transparent;padding:0;margin:0;width:auto!important;max-width:inherit}.bootstrap-tagsinput input:focus{border:0;box-shadow:none}.bootstrap-tagsinput .tag{margin-right:2px;color:white}.bootstrap-tagsinput .tag [data-role="remove"]{margin-left:8px;cursor:pointer}.bootstrap-tagsinput .tag [data-role="remove"]:after{content:"x";padding:0 2px}.bootstrap-tagsinput .tag [data-role="remove"]:hover{box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.bootstrap-tagsinput .tag [data-role="remove"]:hover:active{box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}body{font-family:Geneva,Arial,Helvetica,sans-serif;font-size:100%;*font-size:80%}.ui-layout-pane{background:#FFF;border:1px solid #BBB;padding:10px;overflow:auto}.ui-layout-content{padding:10px;position:relative;overflow:auto}.layout-child-container,.layout-content-container{padding:0;overflow:hidden}.layout-child-container{border:0}.layout-scroll{overflow:auto}.layout-hide{display:none}.ui-layout-resizer{background:#DDD;border:1px solid #BBB;border-width:0}.ui-layout-resizer-open-hover,.ui-layout-resizer-dragging{background:#c4e1a4}.ui-layout-resizer-dragging{border:1px solid #BBB}.ui-layout-resizer-north-dragging,.ui-layout-resizer-south-dragging{border-width:1px 0}.ui-layout-resizer-west-dragging,.ui-layout-resizer-east-dragging{border-width:0 1px}.ui-layout-resizer-dragging-limit{background:#e1a4a4}.ui-layout-resizer-closed-hover{background:#ebd5aa}.ui-layout-resizer-sliding{opacity:.10;filter:alpha(opacity=10)}.ui-layout-resizer-sliding-hover{opacity:1.00;filter:alpha(opacity=100)}.ui-layout-resizer-north-sliding-hover{border-bottom-width:1px}.ui-layout-resizer-south-sliding-hover{border-top-width:1px}.ui-layout-resizer-west-sliding-hover{border-right-width:1px}.ui-layout-resizer-east-sliding-hover{border-left-width:1px}.ui-layout-toggler{border:1px solid #BBB;background-color:#BBB}.ui-layout-resizer-hover .ui-layout-toggler{opacity:.60;filter:alpha(opacity=60)}.ui-layout-toggler-hover,.ui-layout-resizer-hover .ui-layout-toggler-hover{background-color:#FC6;opacity:1.00;filter:alpha(opacity=100)}.ui-layout-toggler-north,.ui-layout-toggler-south{border-width:0 1px}.ui-layout-toggler-west,.ui-layout-toggler-east{border-width:1px 0}.ui-layout-resizer-sliding .ui-layout-toggler{display:none}.ui-layout-toggler .content{color:#666;font-size:12px;font-weight:bold;width:100%;padding-bottom:.35ex}.ui-layout-mask{border:none!important;padding:0!important;margin:0!important;overflow:hidden!important;position:absolute!important;opacity:0!important;filter:Alpha(Opacity="0")!important}.ui-layout-mask-inside-pane{top:0!important;left:0!important;width:100%!important;height:100%!important}@media print{html{height:auto!important;overflow:visible!important}body.ui-layout-container{position:static!important;top:auto!important;bottom:auto!important;left:auto!important;right:auto!important;_width:auto!important;_height:auto!important}.ui-layout-resizer,.ui-layout-toggler{display:none!important}.ui-layout-pane{border:none!important;background:transparent!important;position:relative!important;top:auto!important;bottom:auto!important;left:auto!important;right:auto!important;width:auto!important;height:auto!important;overflow:visible!important}}/*! * FullCalendar v1.6.0 Stylesheet * Docs & License: http://arshaw.com/fullcalendar/ * (c) 2013 Adam Shaw diff --git a/src/main/webapp/static/themes/light/modules/_thirdparty.scss b/src/main/webapp/static/themes/light/modules/_thirdparty.scss index 315eeae793380636948e0b4ad373608b255673db..c9b94e400e3a8ef13eb8830d4461b48cd4a5fca2 100644 --- a/src/main/webapp/static/themes/light/modules/_thirdparty.scss +++ b/src/main/webapp/static/themes/light/modules/_thirdparty.scss @@ -137,19 +137,6 @@ border: 1px solid $basecolor; } -//overwrite tagit -ul.tagit { - li.tagit-choice.ui-widget-content.ui-state-default { - background:#DEE7F8; - border: 1px solid #CAD8F3; - } -} - -ul.tagit.ui-corner-all { - border:none; - background: none; -} - //overwrite uilayout .ui-layout-pane { border:none;