diff --git a/docs/configuration/data-validation.md b/docs/configuration/data-validation.md index 2f00814f3..f205869a9 100644 --- a/docs/configuration/data-validation.md +++ b/docs/configuration/data-validation.md @@ -56,6 +56,20 @@ FIELD_CHOICES = { } ``` +In addition to plain tuples, each choice may be defined as a dictionary, which allows specifying a description (shown as a subtitle beneath the option) alongside the value, label, and color. `value` and `label` are required; `color` and `description` are optional: + +```python +FIELD_CHOICES = { + 'dcim.Site.status': ( + {'value': 'foo', 'label': 'Foo', 'color': 'red', 'description': 'The foo status'}, + {'value': 'bar', 'label': 'Bar', 'color': 'green'}, + ) +} +``` + +!!! info "New in NetBox v4.7" + The dictionary-based format for declaring choices was introduced in NetBox v4.7. The tuple-based format remains supported, but will be deprecated in a future release and support for it will eventually be removed. + !!! info "Case-Insensitive Field Identifiers" Field identifiers are case-insensitive. Both `dcim.Site.status` and `dcim.site.status` are valid and equivalent. diff --git a/docs/plugins/development/forms.md b/docs/plugins/development/forms.md index 3af090211..d5488c3a3 100644 --- a/docs/plugins/development/forms.md +++ b/docs/plugins/development/forms.md @@ -210,6 +210,35 @@ In addition to the [form fields provided by Django](https://docs.djangoproject.c options: members: false +## Static Choice Fields + +These fields render a standard HTML `',copyClassesToDropdown:!1,placeholder:null,hidePlaceholder:null,shouldLoad:function(n){return n.length>0},render:{}};function dr(n,e){var t=Object.assign({},zo,e),i=t.dataAttr,r=t.labelField,o=t.valueField,s=t.disabledField,a=t.optgroupField,l=t.optgroupLabelField,c=t.optgroupValueField,u=n.tagName.toLowerCase(),d=n.getAttribute("placeholder")||n.getAttribute("data-placeholder");if(!d&&!t.allowEmptyOption){let g=n.querySelector('option[value=""]');g&&(d=g.textContent)}var p={placeholder:d,options:[],optgroups:[],items:[],maxItems:null},y=()=>{var g,_=p.options,C={},O=1;let w=0;var T=H=>{var I=Object.assign({},H.dataset),L=i&&I[i];return typeof L=="string"&&L.length&&(I=Object.assign(I,JSON.parse(L))),I},$=(H,I)=>{var L=Fe(H.value);if(L!=null&&!(!L&&!t.allowEmptyOption)){if(C.hasOwnProperty(L)){if(I){var W=C[L][a];W?Array.isArray(W)?W.push(I):C[L][a]=[W,I]:C[L][a]=I}}else{var G=T(H);G[r]=G[r]||H.textContent,G[o]=G[o]||L,G[s]=G[s]||H.disabled,G[a]=G[a]||I,G.$option=H,G.$order=G.$order||++w,C[L]=G,_.push(G)}H.selected&&p.items.push(L)}},j=H=>{var I,L;L=T(H),L[l]=L[l]||H.getAttribute("label")||"",L[c]=L[c]||O++,L[s]=L[s]||H.disabled,L.$order=L.$order||++w,p.optgroups.push(L),I=L[c],ve(H.children,W=>{$(W,I)})};p.maxItems=n.hasAttribute("multiple")?null:1,ve(n.children,H=>{g=H.tagName.toLowerCase(),g==="optgroup"?j(H):g==="option"&&$(H)})},m=()=>{var g,_;let C=n.getAttribute(i);if(C)p.options=JSON.parse(C),ve(p.options,w=>{p.items.push(w[o])});else{var O=(_=(g=n==null?void 0:n.value)===null||g===void 0?void 0:g.trim())!==null&&_!==void 0?_:"";if(!t.allowEmptyOption&&!O.length)return;let w=O.split(t.delimiter);ve(w,T=>{let $={};$[r]=T,$[o]=T,p.options.push($)}),p.items=w}};return u==="select"?y():m(),Object.assign({},zo,p,e)}var nl=0,we=class extends No(ni){constructor(e,t){super(),this.order=0,this.isOpen=!1,this.isDisabled=!1,this.isReadOnly=!1,this.isInvalid=!1,this.isValid=!0,this.isLocked=!1,this.isFocused=!1,this.isInputHidden=!1,this.isSetup=!1,this.isDropdownContentStale=!0,this.ignoreFocus=!1,this.ignoreHover=!1,this.hasOptions=!1,this.lastValue="",this.caretPos=0,this.loading=0,this.loadedSearches={},this.activeOption=null,this.activeItems=[],this.optgroups={},this.options={},this.userOptions={},this.items=[],this.refreshTimeout=null,nl++;var i,r=nt(e);if(r.tomselect)throw new Error("Tom Select already initialized on this element");r.tomselect=this;var o=window.getComputedStyle&&window.getComputedStyle(r,null);i=o.getPropertyValue("direction");let s=dr(r,t);this.settings=s,this.input=r,this.tabIndex=r.tabIndex||0,this.is_select_tag=r.tagName.toLowerCase()==="select",this.rtl=/rtl/i.test(i),this.inputId=lr(r,"tomselect-"+nl),this.isRequired=r.required,this.sifter=new sr(this.options,{diacritics:s.diacritics}),s.mode=s.mode||(s.maxItems===1?"single":"multi"),typeof s.hideSelected!="boolean"&&(s.hideSelected=s.mode==="multi"),typeof s.hidePlaceholder!="boolean"&&(s.hidePlaceholder=s.mode!=="multi");var a=s.createFilter;typeof a!="function"&&(typeof a=="string"&&(a=new RegExp(a)),a instanceof RegExp?s.createFilter=_=>a.test(_):s.createFilter=_=>this.settings.duplicates||!this.options[_]),this.initializePlugins(s.plugins),this.setupCallbacks(),this.setupTemplates();let l=nt("
"),c=nt("
"),u=this._render("dropdown"),d=nt('
'),p=this.input.getAttribute("class")||"",y=s.mode;var m;if($e(l,s.wrapperClass,p,y),$e(c,s.controlClass),Nt(l,c),$e(u,s.dropdownClass,y),s.copyClassesToDropdown&&$e(u,p),$e(d,s.dropdownContentClass),Nt(u,d),nt(s.dropdownParent||l).appendChild(u),$o(s.controlInput)){m=nt(s.controlInput);var g=["autocorrect","autocapitalize","autocomplete","spellcheck","aria-label"];ve(g,_=>{r.getAttribute(_)&&le(m,{[_]:r.getAttribute(_)})}),m.tabIndex=-1,c.appendChild(m),this.focus_node=m}else s.controlInput?(m=nt(s.controlInput),this.focus_node=m):(m=nt(""),this.focus_node=c);this.wrapper=l,this.dropdown=u,this.dropdown_content=d,this.control=c,this.control_input=m,this.setup()}setup(){let e=this,t=e.settings,i=e.control_input,r=e.dropdown,o=e.dropdown_content,s=e.wrapper,a=e.control,l=e.input,c=e.focus_node,u={passive:!0},d=e.inputId+"-ts-dropdown";le(o,{id:d}),le(c,{role:"combobox","aria-haspopup":"listbox","aria-expanded":"false","aria-controls":d});let p=lr(c,e.inputId+"-ts-control"),y="label[for='"+Ga(e.inputId)+"']",m=document.querySelector(y),g=e.focus.bind(e);if(m){De(m,"click",g),le(m,{for:p});let w=lr(m,e.inputId+"-ts-label");le(c,{"aria-labelledby":w}),le(o,{"aria-labelledby":w})}if(s.style.width=l.style.width,s.style.minWidth=l.style.minWidth,s.style.maxWidth=l.style.maxWidth,e.plugins.names.length){let w="plugin-"+e.plugins.names.join(" plugin-");$e([s,r],w)}(t.maxItems===null||t.maxItems>1)&&e.is_select_tag&&le(l,{multiple:"multiple"}),t.placeholder&&le(i,{placeholder:t.placeholder}),!t.splitOn&&t.delimiter&&(t.splitOn=new RegExp("\\s*"+Lt(t.delimiter)+"+\\s*")),t.load&&t.loadThrottle&&(t.load=Ua(t.load,t.loadThrottle)),De(r,"mousemove",()=>{e.ignoreHover=!1}),De(r,"mouseenter",w=>{var T=ur(w.target,"[data-selectable]",r);T&&e.onOptionHover(w,T)},{capture:!0}),De(r,"click",w=>{let T=ur(w.target,"[data-selectable]");T&&(e.onOptionSelect(w,T),fe(w,!0))}),De(a,"click",w=>{var T=ur(w.target,"[data-ts-item]",a);if(T&&e.onItemSelect(w,T)){fe(w,!0);return}i.value==""&&(e.onClick(),fe(w,!0))}),De(c,"keydown",w=>e.onKeyDown(w)),De(i,"keypress",w=>e.onKeyPress(w)),De(i,"input",w=>e.onInput(w)),De(c,"blur",w=>e.onBlur(w)),De(c,"focus",w=>e.onFocus(w)),De(i,"paste",w=>e.onPaste(w));let _=w=>{let T=w.composedPath()[0];if(!s.contains(T)&&!r.contains(T)){e.isFocused&&e.blur(),e.inputState();return}T==i&&e.isOpen?w.stopPropagation():fe(w,!0)},C=()=>{e.isOpen&&e.positionDropdown()},O=()=>{e.isValid&&(e.isValid=!1,e.isInvalid=!0,e.refreshState())};De(l,"invalid",O),De(document,"mousedown",_),De(window,"scroll",C,u),De(window,"resize",C,u),this._destroy=()=>{l.removeEventListener("invalid",O),document.removeEventListener("mousedown",_),window.removeEventListener("scroll",C),window.removeEventListener("resize",C),m&&m.removeEventListener("click",g)},this.revertSettings={innerHTML:l.innerHTML,tabIndex:l.tabIndex},l.tabIndex=-1,l.insertAdjacentElement("afterend",e.wrapper),e.sync(!1),t.items=[],delete t.optgroups,delete t.options,e.refreshItems(),e.close(!1),e.inputState(),e.isSetup=!0,e.on("change",this.onChange),$e(l,"tomselected","ts-hidden-accessible"),e.trigger("initialize"),t.preload===!0&&e.preload()}setupOptions(e=[],t=[]){this.addOptions(e),ve(t,i=>{this.registerOptionGroup(i)})}setupTemplates(){var e=this,t=e.settings.labelField,i=e.settings.optgroupLabelField,r={optgroup:o=>{let s=document.createElement("div");return s.className="optgroup",s.appendChild(o.options),s},optgroup_header:(o,s)=>'
'+s(o[i])+"
",option:(o,s)=>"
"+s(o[t])+"
",item:(o,s)=>"
"+s(o[t])+"
",option_create:(o,s)=>'
Add '+s(o.input)+"
",no_results:()=>'
No results found
',loading:()=>'
',not_loading:()=>{},dropdown:()=>"
"};e.settings.render=Object.assign({},r,e.settings.render)}setupCallbacks(){var e,t,i={initialize:"onInitialize",change:"onChange",item_add:"onItemAdd",item_remove:"onItemRemove",item_select:"onItemSelect",clear:"onClear",option_add:"onOptionAdd",option_remove:"onOptionRemove",option_clear:"onOptionClear",optgroup_add:"onOptionGroupAdd",optgroup_remove:"onOptionGroupRemove",optgroup_clear:"onOptionGroupClear",dropdown_open:"onDropdownOpen",dropdown_close:"onDropdownClose",type:"onType",load:"onLoad",focus:"onFocus",blur:"onBlur"};for(e in i)t=this.settings[i[e]],t&&this.on(e,t)}sync(e=!0){let t=this,i=e?dr(t.input,{delimiter:t.settings.delimiter,allowEmptyOption:t.settings.allowEmptyOption}):t.settings;t.setupOptions(i.options,i.optgroups),t.setValue(i.items||[],!0),t.input.disabled?t.disable():t.input.readOnly?t.setReadOnly(!0):t.enable(),t.lastQuery=null}onClick(){var e=this;if(e.activeItems.length>0){e.clearActiveItems(),e.focus();return}e.isFocused&&e.isOpen?e.blur():e.focus()}onMouseDown(){}onChange(){cr(this.input,"input"),cr(this.input,"change")}onPaste(e){var t=this;if(t.isInputHidden||t.isLocked){fe(e);return}t.settings.splitOn&&setTimeout(()=>{var i=t.inputValue();if(i.match(t.settings.splitOn)){var r=i.trim().split(t.settings.splitOn);ve(r,o=>{Fe(o)&&(this.options[o]?t.addItem(o):t.createItem(o))})}},0)}onKeyPress(e){var t=this;if(t.isLocked){fe(e);return}var i=String.fromCharCode(e.keyCode||e.which);if(t.settings.create&&t.settings.mode==="multi"&&i===t.settings.delimiter){t.createItem(),fe(e);return}}onKeyDown(e){var t=this;if(t.ignoreHover=!0,t.isLocked){e.keyCode!==9&&fe(e);return}switch(e.keyCode){case 65:if(Mt(ci,e)&&t.control_input.value==""){fe(e),t.selectAll();return}break;case 27:t.isOpen&&(fe(e,!0),t.close()),t.clearActiveItems();return;case 40:if(!t.isOpen&&t.hasOptions)t.open();else if(t.activeOption){let i=t.getAdjacent(t.activeOption,1);i&&t.setActiveOption(i)}fe(e);return;case 38:if(t.activeOption){let i=t.getAdjacent(t.activeOption,-1);i&&t.setActiveOption(i)}fe(e);return;case 13:t.canSelect(t.activeOption)?(t.onOptionSelect(e,t.activeOption),fe(e)):t.settings.create&&t.createItem()?fe(e):document.activeElement==t.control_input&&t.isOpen&&fe(e);return;case 37:t.advanceSelection(-1,e);return;case 39:t.advanceSelection(1,e);return;case 9:t.settings.selectOnTab&&(t.canSelect(t.activeOption)?(t.onOptionSelect(e,t.activeOption),fe(e)):t.settings.create&&t.createItem()&&fe(e));return;case 8:case 46:t.deleteSelection(e);return}t.isInputHidden&&!Mt(ci,e)&&fe(e)}onInput(e){if(this.isLocked)return;let t=this.inputValue();if(this.lastValue!==t){if(this.lastValue=t,t==""){this._onInput();return}this.refreshTimeout&&window.clearTimeout(this.refreshTimeout),this.refreshTimeout=qa(()=>{this.refreshTimeout=null,this._onInput()},this.settings.refreshThrottle)}}_onInput(){let e=this.lastValue;this.settings.shouldLoad.call(this,e)&&this.load(e),this.refreshOptions(),this.trigger("type",e)}onOptionHover(e,t){this.ignoreHover||this.setActiveOption(t,!1)}onFocus(e){var t=this,i=t.isFocused;if(t.isDisabled||t.isReadOnly){t.blur(),fe(e);return}t.ignoreFocus||(t.isFocused=!0,t.settings.preload==="focus"&&t.preload(),i||t.trigger("focus"),t.activeItems.length||(t.inputState(),t.refreshOptions(!!t.settings.openOnFocus)),t.refreshState())}onBlur(e){if(document.hasFocus()!==!1){var t=this;if(t.isFocused){t.isFocused=!1,t.ignoreFocus=!1;var i=()=>{t.close(),t.setActiveItem(),t.setCaret(t.items.length),t.trigger("blur")};t.settings.create&&t.settings.createOnBlur?t.createItem(null,i):i()}}}onOptionSelect(e,t){var i,r=this;t.parentElement&&t.parentElement.matches("[data-disabled]")||(t.classList.contains("create")?r.createItem(null,()=>{r.settings.closeAfterSelect?r.close():r.settings.clearAfterSelect&&r.setTextboxValue()}):(i=t.dataset.value,typeof i!="undefined"&&(r.isDropdownContentStale=r.settings.hideSelected,r.addItem(i),r.settings.closeAfterSelect?r.close():r.settings.clearAfterSelect&&r.setTextboxValue(),!r.settings.hideSelected&&e.type&&/click/.test(e.type)&&r.setActiveOption(t))))}canSelect(e){return!!(this.isOpen&&e&&this.dropdown_content.contains(e))}onItemSelect(e,t){var i=this;return!i.isLocked&&i.settings.mode==="multi"?(fe(e),i.setActiveItem(t,e),!0):!1}canLoad(e){return!(!this.settings.load||this.loadedSearches.hasOwnProperty(e))}load(e){let t=this;if(!t.canLoad(e))return;$e(t.wrapper,t.settings.loadingClass),t.loading++;let i=t.loadCallback.bind(t);t.settings.load.call(t,e,i)}loadCallback(e,t){let i=this;i.loading=Math.max(i.loading-1,0),i.isDropdownContentStale=!0,i.clearActiveOption(),i.setupOptions(e,t),i.refreshOptions(i.isFocused&&!i.isInputHidden),i.loading||gt(i.wrapper,i.settings.loadingClass),i.trigger("load",e,t)}preload(){var e=this.wrapper.classList;e.contains("preloaded")||(e.add("preloaded"),this.load(""))}setTextboxValue(e=""){var t=this.control_input,i=t.value!==e;i&&(t.value=e,cr(t,"update"),this.lastValue=e)}getValue(){return this.is_select_tag&&this.input.hasAttribute("multiple")?this.items:this.items.join(this.settings.delimiter)}setValue(e,t){var i=t?[]:["change"];Po(this,i,()=>{this.clear(t),this.addItems(e,t)})}setMaxItems(e){e===0&&(e=null),this.settings.maxItems=e,this.refreshState()}setActiveItem(e,t){var i=this,r,o,s,a,l,c;if(i.settings.mode!=="single"){if(!e){i.clearActiveItems(),i.isFocused&&i.inputState();return}if(r=t&&t.type.toLowerCase(),r==="click"&&Mt("shiftKey",t)&&i.activeItems.length){for(c=i.getLastActive(),s=Array.prototype.indexOf.call(i.control.children,c),a=Array.prototype.indexOf.call(i.control.children,e),s>a&&(l=s,s=a,a=l),o=s;o<=a;o++)e=i.control.children[o],i.activeItems.indexOf(e)===-1&&i.setActiveItemClass(e);fe(t)}else r==="click"&&Mt(ci,t)||r==="keydown"&&Mt("shiftKey",t)?e.classList.contains("active")?i.removeActiveItem(e):i.setActiveItemClass(e):(i.clearActiveItems(),i.setActiveItemClass(e));i.inputState(),i.isFocused||i.focus()}}setActiveItemClass(e){let t=this,i=t.control.querySelector(".last-active");i&>(i,"last-active"),$e(e,"active last-active"),t.trigger("item_select",e),t.activeItems.indexOf(e)==-1&&t.activeItems.push(e)}removeActiveItem(e){var t=this.activeItems.indexOf(e);this.activeItems.splice(t,1),gt(e,"active")}clearActiveItems(){gt(this.activeItems,"active"),this.activeItems=[]}setActiveOption(e,t=!0){e!==this.activeOption&&(this.clearActiveOption(),e&&(this.activeOption=e,le(this.focus_node,{"aria-activedescendant":e.getAttribute("id")}),le(e,{"aria-selected":"true"}),$e(e,"active"),t&&this.scrollToOption(e)))}scrollToOption(e,t){if(!e)return;let i=this.dropdown_content,r=i.clientHeight,o=i.scrollTop||0,s=e.offsetHeight,a=e.getBoundingClientRect().top-i.getBoundingClientRect().top+o;a+s>r+o?this.scroll(a-r+s,t):a{e.setActiveItemClass(i)}))}inputState(){var e=this;e.control.contains(e.control_input)&&(le(e.control_input,{placeholder:e.settings.placeholder}),e.activeItems.length>0||!e.isFocused&&e.settings.hidePlaceholder&&e.items.length>0?(e.setTextboxValue(),e.isInputHidden=!0):(e.settings.hidePlaceholder&&e.items.length>0&&le(e.control_input,{placeholder:""}),e.isInputHidden=!1),e.wrapper.classList.toggle("input-hidden",e.isInputHidden))}inputValue(){return this.control_input.value.trim()}focus(){var e=this;if(e.isDisabled||e.isReadOnly)return;e.ignoreFocus=!0;let t=this.control_input.offsetWidth?this.control_input:this.focus_node;t.focus(),setTimeout(()=>{e.ignoreFocus=!1,t.getRootNode().activeElement===t&&this.onFocus()},0)}blur(){this.focus_node.blur(),this.onBlur()}getScoreFunction(e){return this.sifter.getScoreFunction(e,this.getSearchOptions())}getSearchOptions(){var e=this.settings,t=e.sortField;return typeof e.sortField=="string"&&(t=[{field:e.sortField}]),{fields:e.searchField,conjunction:e.searchConjunction,sort:t,nesting:e.nesting}}search(e){var t,i,r=this,o=this.getSearchOptions();if(r.settings.score&&(i=r.settings.score.call(r,e),typeof i!="function"))throw new Error('Tom Select "score" setting must be a function that returns a function');return r.isDropdownContentStale||e!==r.lastQuery?(r.lastQuery=e,/(.)\1{15,}/.test(e)&&(e=""),t=r.sifter.search(e,Object.assign(o,{score:i})),r.currentResults=t):t=Object.assign({},r.currentResults),r.settings.hideSelected&&(t.items=t.items.filter(s=>{let a=Fe(s.id);return!(a!==null&&r.items.indexOf(a)!==-1)})),t}refreshOptions(e=!0){var t,i,r,o,s,a,l,c,u,d;let p={},y=[];var m=this,g=m.inputValue();let _=g===m.lastQuery||g==""&&m.lastQuery==null;var C=m.search(g),O=null,w=m.settings.shouldOpen||!1,T=m.dropdown_content;_&&(O=m.activeOption,O&&(u=O.closest("[data-group]"))),o=C.items.length,typeof m.settings.maxOptions=="number"&&(o=Math.min(o,m.settings.maxOptions)),o>0&&(w=!0);let $=(I,L)=>{let W=p[I];if(W!==void 0){let Q=y[W];if(Q!==void 0)return[W,Q.fragment]}let G=document.createDocumentFragment();return W=y.length,y.push({fragment:G,order:L,optgroup:I}),[W,G]};for(t=0;t0&&(Q=Q.cloneNode(!0),le(Q,{id:W.$id+"-clone-"+i,"aria-selected":null}),Q.classList.add("ts-cloned"),gt(Q,"active"),m.activeOption&&m.activeOption.dataset.value==L&&u&&u.dataset.group===s.toString()&&(O=Q)),ie.appendChild(Q),s!=""&&(p[s]=Ce)}}m.settings.lockOptgroupOrder&&y.sort((I,L)=>I.order-L.order),l=document.createDocumentFragment(),ve(y,I=>{let L=I.fragment,W=I.optgroup;if(!L||!L.children.length)return;let G=m.optgroups[W];if(G!==void 0){let Q=document.createDocumentFragment(),Z=m.render("optgroup_header",G);Nt(Q,Z),Nt(Q,L);let he=m.render("optgroup",{group:G,options:Q});Nt(l,he)}else Nt(l,L)}),T.innerHTML="",Nt(T,l),m.isDropdownContentStale=!1,m.settings.highlight&&(Za(T),C.query.length&&C.tokens.length&&ve(C.tokens,I=>{Ja(T,I.regex)}));var H=I=>{let L=m.render(I,{input:g});return L&&(w=!0,T.insertBefore(L,T.firstChild)),L};if(m.loading?H("loading"):m.settings.shouldLoad.call(m,g)?C.items.length===0&&H("no_results"):H("not_loading"),c=m.canCreate(g),c&&(d=H("option_create")),m.hasOptions=C.items.length>0||c,w){if(C.items.length>0){if(!O&&m.settings.mode==="single"&&m.items[0]!=null&&(O=m.getOption(m.items[0])),!T.contains(O)){let I=0;d&&!m.settings.addPrecedence&&(I=1),O=m.selectable()[I]}}else d&&(O=d);e&&!m.isOpen&&(m.open(),m.scrollToOption(O,"auto")),m.setActiveOption(O)}else m.clearActiveOption(),e&&m.isOpen&&m.close(!1)}selectable(){return this.dropdown_content.querySelectorAll("[data-selectable]")}addOption(e,t=!1){let i=this;if(Array.isArray(e))return i.addOptions(e,t),!1;let r=Fe(e[i.settings.valueField]);return r===null||i.options.hasOwnProperty(r)?(i.updateOption(e[i.settings.valueField],e),!1):(e.$order=e.$order||++i.order,e.$id=i.inputId+"-opt-"+e.$order,i.options[r]=e,i.isDropdownContentStale=!0,t&&(i.userOptions[r]=t,i.trigger("option_add",r,e)),r)}addOptions(e,t=!1){ve(e,i=>{this.addOption(i,t)})}registerOption(e){return this.addOption(e)}registerOptionGroup(e){var t=Fe(e[this.settings.optgroupValueField]);return t===null?!1:(e.$order=e.$order||++this.order,this.optgroups[t]=e,t)}addOptionGroup(e,t){var i;t[this.settings.optgroupValueField]=e,(i=this.registerOptionGroup(t))&&this.trigger("optgroup_add",i,t)}removeOptionGroup(e){this.optgroups.hasOwnProperty(e)&&(delete this.optgroups[e],this.clearCache(),this.trigger("optgroup_remove",e))}clearOptionGroups(){this.optgroups={},this.clearCache(),this.trigger("optgroup_clear")}updateOption(e,t){let i=this;var r,o;let s=Fe(e),a=Fe(t[i.settings.valueField]);if(s===null)return;let l=i.options[s];if(l==null)return;if(typeof a!="string")throw new Error("Value must be set in option data");let c=i.getOption(s),u=i.getItem(s);if(t.$order=t.$order||l.$order,delete i.options[s],i.uncacheValue(a),i.options[a]=t,c){if(i.dropdown_content.contains(c)){let d=i._render("option",t);li(c,d),i.activeOption===c&&i.setActiveOption(d)}c.remove()}u&&(o=i.items.indexOf(s),o!==-1&&i.items.splice(o,1,a),r=i._render("item",t),u.classList.contains("active")&&$e(r,"active"),li(u,r)),i.isDropdownContentStale=!0}removeOption(e,t){let i=this;e=si(e),i.uncacheValue(e),delete i.userOptions[e],delete i.options[e],i.isDropdownContentStale=!0,i.trigger("option_remove",e),i.removeItem(e,t)}clearOptions(e){let t=(e||this.clearFilter).bind(this);this.loadedSearches={},this.userOptions={},this.clearCache();let i={};ve(this.options,(r,o)=>{t(r,o)&&(i[o]=r)}),this.options=this.sifter.items=i,this.isDropdownContentStale=!0,this.trigger("option_clear")}clearFilter(e,t){return this.items.indexOf(t)>=0}getOption(e,t=!1){let i=Fe(e);if(i===null)return null;let r=this.options[i];if(r!=null){if(r.$div)return r.$div;if(t)return this._render("option",r)}return null}getAdjacent(e,t,i="option"){var r=this,o;if(!e)return null;i=="item"?o=r.controlChildren():o=r.dropdown_content.querySelectorAll("[data-selectable]");for(let s=0;s0?o[s+1]:o[s-1];return null}getItem(e){if(typeof e=="object")return e;var t=Fe(e);return t!==null?this.control.querySelector(`[data-value="${Fo(t)}"]`):null}addItems(e,t){var i=this,r=Array.isArray(e)?e:[e];r=r.filter(s=>i.items.indexOf(s)===-1);let o=r[r.length-1];r.forEach(s=>{i.isPending=s!==o,i.addItem(s,t)})}addItem(e,t){var i=t?[]:["change","dropdown_close"];Po(this,i,()=>{var r,o;let s=this,a=s.settings.mode,l=Fe(e);if(!(l&&s.items.indexOf(l)!==-1&&(a==="single"&&s.close(),a==="single"||!s.settings.duplicates))&&!(l===null||!s.options.hasOwnProperty(l))&&(a==="single"&&s.clear(t),!(a==="multi"&&s.isFull()))){if(r=s._render("item",s.options[l]),s.control.contains(r)&&(r=r.cloneNode(!0)),o=s.isFull(),s.items.splice(s.caretPos,0,l),s.insertAtCaret(r),s.isSetup){if(!s.isPending&&s.settings.hideSelected){let c=s.getOption(l),u=s.getAdjacent(c,1);u&&s.setActiveOption(u)}s.settings.clearAfterSelect&&s.setTextboxValue(),!s.isPending&&!s.settings.closeAfterSelect&&s.refreshOptions(s.isFocused&&a!=="single"),s.settings.closeAfterSelect!=!1&&s.isFull()?s.close():s.isPending||s.positionDropdown(),s.trigger("item_add",l,r),s.isPending||s.updateOriginalInput({silent:t})}(!s.isPending||!o&&s.isFull())&&(s.inputState(),s.refreshState())}})}removeItem(e=null,t){let i=this;if(e=i.getItem(e),!e)return;var r,o;let s=e.dataset.value;r=Vo(e),e.remove(),e.classList.contains("active")&&(o=i.activeItems.indexOf(e),i.activeItems.splice(o,1),gt(e,"active")),i.items.splice(r,1),i.isDropdownContentStale=!0,!i.settings.persist&&i.userOptions.hasOwnProperty(s)&&i.removeOption(s,t),r{}){arguments.length===3&&(t=arguments[2]),typeof t!="function"&&(t=()=>{});var i=this,r=i.caretPos,o;if(e=e||i.inputValue(),!i.canCreate(e))return Fe(e)&&this.options[e]&&i.addItem(e),t(),!1;i.lock();var s=!1,a=l=>{if(i.unlock(),!l||typeof l!="object")return t();var c=Fe(l[i.settings.valueField]);if(typeof c!="string")return t();i.setTextboxValue(),i.addOption(l,!0),i.setCaret(r),i.addItem(c),t(l),s=!0};return typeof i.settings.create=="function"?o=i.settings.create.call(this,e,a):o={[i.settings.labelField]:e,[i.settings.valueField]:e},s||a(o),!0}refreshItems(){var e=this;e.isDropdownContentStale=!0,e.isSetup&&e.addItems(e.items),e.updateOriginalInput(),e.refreshState()}refreshState(){let e=this;e.refreshValidityState();let t=e.isFull(),i=e.isLocked;e.wrapper.classList.toggle("rtl",e.rtl);let r=e.wrapper.classList;r.toggle("focus",e.isFocused),r.toggle("disabled",e.isDisabled),r.toggle("readonly",e.isReadOnly),r.toggle("required",e.isRequired),r.toggle("invalid",!e.isValid),r.toggle("locked",i),r.toggle("full",t),r.toggle("input-active",e.isFocused&&!e.isInputHidden),r.toggle("dropdown-active",e.isOpen),r.toggle("has-options",Qa(e.options)),r.toggle("has-items",e.items.length>0)}refreshValidityState(){var e=this;e.input.validity&&(e.isValid=e.input.validity.valid,e.isInvalid=!e.isValid)}isFull(){return this.settings.maxItems!==null&&this.items.length>=this.settings.maxItems}updateOriginalInput(e={}){let t=this;var i,r;let o=t.input.querySelector('option[value=""]');if(t.is_select_tag){let l=function(c,u,d){return c||(c=nt('")),c!=o&&t.input.append(c),s.push(c),(c!=o||a>0)&&(c.selected=!0),c},s=[],a=t.input.querySelectorAll("option:checked").length;t.input.querySelectorAll("option:checked").forEach(c=>{c.selected=!1}),t.items.length==0&&t.settings.mode=="single"?l(o,"",""):t.items.forEach(c=>{if(i=t.options[c],r=i[t.settings.labelField]||"",s.includes(i.$option)){let u=t.input.querySelector(`option[value="${Fo(c)}"]:not(:checked)`);l(u,c,r)}else i.$option=l(i.$option,c,r)})}else t.input.value=t.getValue();t.isSetup&&(e.silent||t.trigger("change",t.getValue()))}open(){var e=this;e.isLocked||e.isOpen||e.settings.mode==="multi"&&e.isFull()||(e.isOpen=!0,le(e.focus_node,{"aria-expanded":"true"}),e.refreshState(),ai(e.dropdown,{visibility:"hidden",display:"block"}),e.positionDropdown(),ai(e.dropdown,{visibility:"visible",display:"block"}),e.focus(),e.trigger("dropdown_open",e.dropdown))}close(e=!0){var t=this,i=t.isOpen;e&&(t.setTextboxValue(),t.settings.mode==="single"&&t.items.length&&t.inputState()),t.isOpen=!1,le(t.focus_node,{"aria-expanded":"false"}),ai(t.dropdown,{display:"none"}),t.settings.hideSelected&&t.clearActiveOption(),t.refreshState(),i&&t.trigger("dropdown_close",t.dropdown)}positionDropdown(){if(this.settings.dropdownParent==="body"){var e=this.control,t=e.getBoundingClientRect(),i=e.offsetHeight+t.top+window.scrollY,r=t.left+window.scrollX;ai(this.dropdown,{width:t.width+"px",top:i+"px",left:r+"px"})}}clear(e){var t=this;if(t.items.length){var i=t.controlChildren();ve(i,r=>{t.removeItem(r,!0)}),t.inputState(),e||t.updateOriginalInput(),t.trigger("clear")}}insertAtCaret(e){let t=this,i=t.caretPos,r=t.control;r.insertBefore(e,r.children[i]||null),t.setCaret(i+1)}deleteSelection(e){var t,i,r,o,s=this;t=e&&e.keyCode===8?-1:1,i=Ya(s.control_input);let a=[];if(s.activeItems.length)o=Bo(s.activeItems,t),r=Vo(o),t>0&&r++,ve(s.activeItems,l=>a.push(l));else if((s.isFocused||s.settings.mode==="single")&&s.items.length){let l=s.controlChildren(),c;t<0&&i.start===0&&i.length===0?c=l[s.caretPos-1]:t>0&&i.start===s.inputValue().length&&(c=l[s.caretPos]),c!==void 0&&a.push(c)}if(!s.shouldDelete(a,e))return!1;for(fe(e,!0),typeof r!="undefined"&&s.setCaret(r);a.length;)s.removeItem(a.pop());return s.inputState(),s.positionDropdown(),s.refreshOptions(!1),!0}shouldDelete(e,t){let i=e.map(r=>r.dataset.value);return!(!i.length||typeof this.settings.onDelete=="function"&&this.settings.onDelete.call(this,i,t)===!1)}advanceSelection(e,t){var i,r,o=this;o.rtl&&(e*=-1),!o.inputValue().length&&(Mt(ci,t)||Mt("shiftKey",t)?(i=o.getLastActive(e),i?i.classList.contains("active")?r=o.getAdjacent(i,e,"item"):r=i:e>0?r=o.control_input.nextElementSibling:r=o.control_input.previousElementSibling,r&&(r.classList.contains("active")&&o.removeActiveItem(i),o.setActiveItemClass(r))):o.moveCaret(e))}moveCaret(e){}getLastActive(e){let t=this.control.querySelector(".last-active");if(t)return t;var i=this.control.querySelectorAll(".active");if(i)return Bo(i,e)}setCaret(e){this.caretPos=this.items.length}controlChildren(){return Array.from(this.control.querySelectorAll("[data-ts-item]"))}lock(){this.setLocked(!0)}unlock(){this.setLocked(!1)}setLocked(e=this.isReadOnly||this.isDisabled){this.isLocked=e,this.refreshState()}disable(){this.setDisabled(!0),this.close()}enable(){this.setDisabled(!1)}setDisabled(e){this.focus_node.tabIndex=e?-1:this.tabIndex,this.isDisabled=e,this.input.disabled=e,this.control_input.disabled=e,this.setLocked()}setReadOnly(e){this.isReadOnly=e,this.input.readOnly=e,this.control_input.readOnly=e,this.setLocked()}destroy(){var e=this,t=e.revertSettings;e.trigger("destroy"),e.off(),e.wrapper.remove(),e.dropdown.remove(),e.input.innerHTML=t.innerHTML,e.input.tabIndex=t.tabIndex,gt(e.input,"tomselected","ts-hidden-accessible"),e._destroy(),delete e.input.tomselect}render(e,t){var i,r;let o=this;if(typeof this.settings.render[e]!="function"||(r=o.settings.render[e].call(this,t,ar),!r))return null;if(r=nt(r),e==="option"||e==="option_create"?t[o.settings.disabledField]?le(r,{"aria-disabled":"true"}):le(r,{"data-selectable":""}):e==="optgroup"&&(i=t.group[o.settings.optgroupValueField],le(r,{"data-group":i}),t.group[o.settings.disabledField]&&le(r,{"data-disabled":""})),e==="option"||e==="item"){let s=si(t[o.settings.valueField]);le(r,{"data-value":s}),e==="item"?($e(r,o.settings.itemClass),le(r,{"data-ts-item":""})):($e(r,o.settings.optionClass),le(r,{role:"option",id:t.$id}),t.$div=r,o.options[s]=t)}return r}_render(e,t){let i=this.render(e,t);if(i==null)throw"HTMLElement expected";return i}clearCache(){ve(this.options,e=>{e.$div&&(e.$div.remove(),delete e.$div)})}uncacheValue(e){let t=this.getOption(e);t&&t.remove()}canCreate(e){return this.settings.create&&e.length>0&&this.settings.createFilter.call(this,e)}hook(e,t,i){var r=this,o=r[t];r[t]=function(){var s,a;return e==="after"&&(s=o.apply(r,arguments)),a=i.apply(r,arguments),e==="instead"?a:(e==="before"&&(s=o.apply(r,arguments)),s)}}};var xm=(n,e,t,i)=>{n.addEventListener(e,t,i)};function il(){xm(this.input,"change",()=>{this.sync()})}var Tm=n=>typeof n=="undefined"||n===null?null:Cm(n),Cm=n=>typeof n=="boolean"?n?"1":"0":n+"",rl=(n,e=!1)=>{n&&(n.preventDefault(),e&&n.stopPropagation())},Sm=n=>{if(n.jquery)return n[0];if(n instanceof HTMLElement)return n;if(Am(n)){var e=document.createElement("template");return e.innerHTML=n.trim(),e.content.firstChild}return document.querySelector(n)},Am=n=>typeof n=="string"&&n.indexOf("<")>-1;function ol(n){var e=this,t=e.onOptionSelect;e.settings.hideSelected=!1;let i=Object.assign({className:"tomselect-checkbox",checkedClassNames:void 0,uncheckedClassNames:void 0},n);var r=function(a,l){l?(a.checked=!0,i.uncheckedClassNames&&a.classList.remove(...i.uncheckedClassNames),i.checkedClassNames&&a.classList.add(...i.checkedClassNames)):(a.checked=!1,i.checkedClassNames&&a.classList.remove(...i.checkedClassNames),i.uncheckedClassNames&&a.classList.add(...i.uncheckedClassNames))},o=function(a){setTimeout(()=>{var l=a.querySelector("input."+i.className);l instanceof HTMLInputElement&&r(l,a.classList.contains("selected"))},1)};e.hook("after","setupTemplates",()=>{var s=e.settings.render.option;e.settings.render.option=(a,l)=>{var c=Sm(s.call(e,a,l)),u=document.createElement("input");i.className&&u.classList.add(i.className),u.addEventListener("click",function(p){rl(p)}),u.type="checkbox";let d=Tm(a[e.settings.valueField]);return r(u,!!(d&&e.items.indexOf(d)>-1)),c.prepend(u),c}}),e.on("item_remove",s=>{var a=e.getOption(s);a&&(a.classList.remove("selected"),o(a))}),e.on("item_add",s=>{var a=e.getOption(s);a&&o(a)}),e.hook("instead","onOptionSelect",(s,a)=>{if(a.classList.contains("selected")){a.classList.remove("selected"),e.removeItem(a.dataset.value),e.refreshOptions(),rl(s,!0);return}t.call(e,s,a),o(a)})}var Dm=n=>{if(n.jquery)return n[0];if(n instanceof HTMLElement)return n;if(Om(n)){var e=document.createElement("template");return e.innerHTML=n.trim(),e.content.firstChild}return document.querySelector(n)},Om=n=>typeof n=="string"&&n.indexOf("<")>-1;function sl(n){let e=this,t=Object.assign({className:"clear-button",title:"Clear All",role:"button",tabindex:0,html:i=>`
×
`},n);e.on("initialize",()=>{var i=Dm(t.html(t));i.addEventListener("click",r=>{e.isLocked||(e.clear(),e.settings.mode==="single"&&e.settings.allowEmptyOption&&e.addItem(""),e.refreshOptions(!1),r.preventDefault(),r.stopPropagation())}),e.control.appendChild(i)})}var Lm=(n,e=!1)=>{n&&(n.preventDefault(),e&&n.stopPropagation())},An=(n,e,t,i)=>{n.addEventListener(e,t,i)},Mm=(n,e)=>{if(Array.isArray(n))n.forEach(e);else for(var t in n)n.hasOwnProperty(t)&&e(n[t],t)},Nm=n=>{if(n.jquery)return n[0];if(n instanceof HTMLElement)return n;if(km(n)){var e=document.createElement("template");return e.innerHTML=n.trim(),e.content.firstChild}return document.querySelector(n)},km=n=>typeof n=="string"&&n.indexOf("<")>-1,Hm=(n,e)=>{Mm(e,(t,i)=>{t==null?n.removeAttribute(i):n.setAttribute(i,""+t)})},Im=(n,e)=>{var t;(t=n.parentNode)==null||t.insertBefore(e,n.nextSibling)},Rm=(n,e)=>{var t;(t=n.parentNode)==null||t.insertBefore(e,n)},Pm=(n,e)=>{do{var t;if(e=(t=e)==null?void 0:t.previousElementSibling,n==e)return!0}while(e&&e.previousElementSibling);return!1};function al(){var n=this;if(n.settings.mode!=="multi")return;var e=n.lock,t=n.unlock;let i=!0,r;n.hook("after","setupTemplates",()=>{var o=n.settings.render.item;n.settings.render.item=(s,a)=>{let l=Nm(o.call(n,s,a));Hm(l,{draggable:"true"});let c=g=>{i||Lm(g),g.stopPropagation()},u=g=>{r=l,setTimeout(()=>{l.classList.add("ts-dragging")},0)},d=g=>{g.preventDefault(),l.classList.add("ts-drag-over"),y(l,r)},p=()=>{l.classList.remove("ts-drag-over")},y=(g,_)=>{_!==void 0&&(Pm(_,l)?Im(g,_):Rm(g,_))},m=()=>{var g;document.querySelectorAll(".ts-drag-over").forEach(C=>C.classList.remove("ts-drag-over")),(g=r)==null||g.classList.remove("ts-dragging"),r=void 0;var _=[];n.control.querySelectorAll("[data-value]").forEach(C=>{if(C.dataset.value){let O=C.dataset.value;O&&_.push(O)}}),n.setValue(_)};return An(l,"mousedown",c),An(l,"dragstart",u),An(l,"dragenter",d),An(l,"dragover",d),An(l,"dragleave",p),An(l,"dragend",m),l}}),n.hook("instead","lock",()=>(i=!1,e.call(n))),n.hook("instead","unlock",()=>(i=!0,t.call(n)))}var Fm=(n,e=!1)=>{n&&(n.preventDefault(),e&&n.stopPropagation())},$m=n=>{if(n.jquery)return n[0];if(n instanceof HTMLElement)return n;if(Bm(n)){var e=document.createElement("template");return e.innerHTML=n.trim(),e.content.firstChild}return document.querySelector(n)},Bm=n=>typeof n=="string"&&n.indexOf("<")>-1;function ll(n){let e=this,t=Object.assign({title:"Untitled",headerClass:"dropdown-header",titleRowClass:"dropdown-header-title",labelClass:"dropdown-header-label",closeClass:"dropdown-header-close",html:i=>'
'+i.title+'×
'},n);e.on("initialize",()=>{var i=$m(t.html(t)),r=i.querySelector("."+t.closeClass);r&&r.addEventListener("click",o=>{Fm(o,!0),e.close()}),e.dropdown.insertBefore(i,e.dropdown.firstChild)})}var Vm=(n,e)=>{if(Array.isArray(n))n.forEach(e);else for(var t in n)n.hasOwnProperty(t)&&e(n[t],t)},zm=(n,...e)=>{var t=jm(e);n=Wm(n),n.map(i=>{t.map(r=>{i.classList.remove(r)})})},jm=n=>{var e=[];return Vm(n,t=>{typeof t=="string"&&(t=t.trim().split(/[\t\n\f\r\s]/)),Array.isArray(t)&&(e=e.concat(t))}),e.filter(Boolean)},Wm=n=>(Array.isArray(n)||(n=[n]),n),qm=(n,e)=>{if(!n)return-1;e=e||n.nodeName;for(var t=0;n=n.previousElementSibling;)n.matches(e)&&t++;return t};function cl(){var n=this;n.hook("instead","setCaret",e=>{n.settings.mode==="single"||!n.control.contains(n.control_input)?e=n.items.length:(e=Math.max(0,Math.min(n.items.length,e)),e!=n.caretPos&&!n.isPending&&n.controlChildren().forEach((t,i)=>{i{if(!n.isFocused)return;let t=n.getLastActive(e);if(t){let i=qm(t);n.setCaret(e>0?i+1:i),n.setActiveItem(),zm(t,"last-active")}else n.setCaret(n.caretPos+e)})}var Um=(n,e=!1)=>{n&&(n.preventDefault(),e&&n.stopPropagation())},Ym=(n,e,t,i)=>{n.addEventListener(e,t,i)},Gm=(n,e)=>{if(Array.isArray(n))n.forEach(e);else for(var t in n)n.hasOwnProperty(t)&&e(n[t],t)},ul=n=>{if(n.jquery)return n[0];if(n instanceof HTMLElement)return n;if(Km(n)){var e=document.createElement("template");return e.innerHTML=n.trim(),e.content.firstChild}return document.querySelector(n)},Km=n=>typeof n=="string"&&n.indexOf("<")>-1,Xm=(n,...e)=>{var t=Qm(e);n=Jm(n),n.map(i=>{t.map(r=>{i.classList.add(r)})})},Qm=n=>{var e=[];return Gm(n,t=>{typeof t=="string"&&(t=t.trim().split(/[\t\n\f\r\s]/)),Array.isArray(t)&&(e=e.concat(t))}),e.filter(Boolean)},Jm=n=>(Array.isArray(n)||(n=[n]),n);function dl(){let n=this;n.settings.shouldOpen=!0,n.hook("before","setup",()=>{var e;n.focus_node=n.control,Xm(n.control_input,"dropdown-input");let t=ul('