mirror of
https://github.com/ONLYOFFICE/onlyoffice.github.io.git
synced 2026-04-07 14:04:30 +08:00
multiselect component
This commit is contained in:
@ -71,8 +71,7 @@
|
||||
<div id="mainCont" class="flexCol">
|
||||
<div id="configState" class="hidden">
|
||||
<p>
|
||||
<span class="i18n">This plugin help you search references by author, title or year in your own
|
||||
library.</span>
|
||||
<span class="i18n">This plugin help you search references by author, title or year in your own library.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="i18n">To use Zotero you should get an API key.</span>
|
||||
@ -112,17 +111,15 @@
|
||||
<div id="selectedThumb" class="scrollThumb hidden"></div>
|
||||
</div>
|
||||
<div id="searchWrapper">
|
||||
<label for="library" class="i18n">Search in:</label>
|
||||
<div class="selectHolder">
|
||||
<input id="library" readonly class="form-control control select form-control" type="text">
|
||||
<div id="searchLibrary" class="selectList hidden">
|
||||
</div>
|
||||
</div>
|
||||
<label id="searchLabel">
|
||||
<input id="searchField" autocomplete="off" class="form-control i18n" type="text"
|
||||
placeholder="Search references by author, title or year" style="width: 100%;" />
|
||||
<span id="searchClear" class="hidden">×</span>
|
||||
</label>
|
||||
<label for="searchField" class="i18n">Search the references you want to cite in this document.</label>
|
||||
<input id="searchField" autocomplete="off" class="form-control i18n" type="text"
|
||||
placeholder="Search references by author, title" />
|
||||
<button>
|
||||
<svg width="12" height="11" viewBox="0 0 12 11" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5 9L7 11V5L12 0H0L5 5V9Z" fill="black" fill-opacity="0.8"/>
|
||||
</svg>
|
||||
</button>
|
||||
<div id="librarySelectList"></div>
|
||||
</div>
|
||||
|
||||
<div id="docsWrapper" class="flexSize">
|
||||
@ -140,12 +137,10 @@
|
||||
<button id="insertLinkBtn" class="button control i18n btn-text-default"
|
||||
style="flex: 1; margin-left: 8px; margin-right: 0;" disabled>Insert Citation</button>
|
||||
</div>
|
||||
<button id="cancelBtn" class="button control i18n btn-text-default" disabled>Cancel
|
||||
select</button>
|
||||
<button id="cancelBtn" class="button control i18n btn-text-default" disabled>Cancel select</button>
|
||||
</div>
|
||||
<div id="insertBibDiv" class="flex">
|
||||
<button id="insertBibBtn" class="button control i18n btn-text-default">Insert
|
||||
Bibliography</button>
|
||||
<button id="insertBibBtn" class="button control i18n btn-text-default">Insert Bibliography</button>
|
||||
<button id="refreshBtn" class="button control btn-text-default i18n">Refresh</button>
|
||||
</div>
|
||||
<div id="omitAuthorDiv">
|
||||
|
||||
@ -344,6 +344,9 @@ body.theme-dark .custom-button-container {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
}
|
||||
.input-field-clearable {
|
||||
padding-right: 22px;
|
||||
}
|
||||
|
||||
.input-field-disabled .input-field-element {
|
||||
pointer-events: none;
|
||||
@ -512,6 +515,7 @@ body.theme-dark {
|
||||
}
|
||||
|
||||
.selectbox-header {
|
||||
overflow: hidden;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: 1px;
|
||||
@ -598,6 +602,12 @@ body.theme-dark {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
.selectbox-option-divider {
|
||||
margin: 4px 0;
|
||||
border: none;
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
|
||||
.selectbox-checkbox {
|
||||
margin: 0;
|
||||
@ -653,10 +663,8 @@ body.theme-light .selectbox-container {
|
||||
}
|
||||
}
|
||||
|
||||
.selectbox-option {
|
||||
&:hover {
|
||||
background-color: var(--select-option-hover);
|
||||
}
|
||||
.selectbox-option:hover {
|
||||
background-color: var(--select-option-hover);
|
||||
}
|
||||
|
||||
.selectbox-option-selected {
|
||||
@ -665,6 +673,9 @@ body.theme-light .selectbox-container {
|
||||
background-color: var(--select-option-selected);
|
||||
}
|
||||
}
|
||||
.selectbox-option-divider {
|
||||
border-color: var(--input-border);
|
||||
}
|
||||
}
|
||||
|
||||
body.theme-dark .selectbox-container {
|
||||
@ -705,10 +716,8 @@ body.theme-dark .selectbox-container {
|
||||
}
|
||||
}
|
||||
|
||||
.selectbox-option {
|
||||
&:hover {
|
||||
background-color: var(--select-option-hover-dark);
|
||||
}
|
||||
.selectbox-option:hover {
|
||||
background-color: var(--select-option-hover-dark);
|
||||
}
|
||||
|
||||
.selectbox-option-selected {
|
||||
@ -717,6 +726,9 @@ body.theme-dark .selectbox-container {
|
||||
background-color: var(--select-option-selected-dark);
|
||||
}
|
||||
}
|
||||
.selectbox-option-divider {
|
||||
border-color: var(--input-border-dark);
|
||||
}
|
||||
}
|
||||
/** Message ************ */
|
||||
.message-container {
|
||||
|
||||
@ -106,22 +106,7 @@ input[type="text"] {
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
overflow-y: hidden;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
#searchLabel {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#searchClear {
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
right: 4px;
|
||||
font-family: Arial;
|
||||
font-size: 22px;
|
||||
line-height: 0;
|
||||
color: #BDBDBD;
|
||||
cursor: pointer;
|
||||
padding: 14px 12px 10px 12px;
|
||||
}
|
||||
|
||||
#mainCont {
|
||||
@ -163,18 +148,16 @@ input[type="text"] {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
#searchWrapper input {
|
||||
width: 100%;
|
||||
height: 22px;
|
||||
padding-right: 18px;
|
||||
margin-bottom: 15px;
|
||||
font-size: 11px;
|
||||
#searchWrapper .input-field-container-searchField {
|
||||
width: 207px;
|
||||
}
|
||||
|
||||
#searchWrapper .selectList {
|
||||
top: 22px;
|
||||
z-index: 1;
|
||||
}
|
||||
#searchField {
|
||||
width: 207px;
|
||||
}
|
||||
|
||||
#controlsHolder {
|
||||
border-top: 1px solid #cfcfcf;
|
||||
|
||||
@ -100,6 +100,9 @@
|
||||
groups: [],
|
||||
};
|
||||
|
||||
/** @type {Object.<string, Button | InputField | SelectBox>} */
|
||||
var customElements = {};
|
||||
|
||||
/** @type {Object.<string, HTMLElement | HTMLInputElement>} */
|
||||
var elements = {};
|
||||
function initElements() {
|
||||
@ -159,26 +162,6 @@
|
||||
if (!locatorLabelsList) {
|
||||
throw new Error("locatorLabelsList not found");
|
||||
}
|
||||
const library = document.getElementById("library");
|
||||
if (!library) {
|
||||
throw new Error("library not found");
|
||||
}
|
||||
const searchLibrary = document.getElementById("searchLibrary");
|
||||
if (!searchLibrary) {
|
||||
throw new Error("searchLibrary not found");
|
||||
}
|
||||
const searchLabel = document.getElementById("searchLabel");
|
||||
if (!searchLabel) {
|
||||
throw new Error("searchLabel not found");
|
||||
}
|
||||
const searchClear = document.getElementById("searchClear");
|
||||
if (!searchClear) {
|
||||
throw new Error("searchClear not found");
|
||||
}
|
||||
const searchField = document.getElementById("searchField");
|
||||
if (!searchField) {
|
||||
throw new Error("searchField not found");
|
||||
}
|
||||
const styleWrapper = document.getElementById("styleWrapper");
|
||||
if (!styleWrapper) {
|
||||
throw new Error("styleWrapper not found");
|
||||
@ -242,6 +225,18 @@
|
||||
if (!cslFileInput) {
|
||||
throw new Error("cslFileInput not found");
|
||||
}
|
||||
customElements = {
|
||||
searchField: new InputField("searchField", {
|
||||
type: "text",
|
||||
autofocus: true,
|
||||
showClear: true,
|
||||
}),
|
||||
librarySelectList: new SelectBox("librarySelectList", {
|
||||
placeholder: "Loading...",
|
||||
multiple: true,
|
||||
}),
|
||||
saveAsTextBtn: new Button("saveAsTextBtn"),
|
||||
};
|
||||
elements = {
|
||||
loader: loader,
|
||||
libLoader: libLoader,
|
||||
@ -263,12 +258,6 @@
|
||||
locatorLabel: locatorLabel,
|
||||
locatorLabelsList: locatorLabelsList,
|
||||
|
||||
library: library,
|
||||
searchLibrary: searchLibrary,
|
||||
searchLabel: searchLabel,
|
||||
searchClear: searchClear,
|
||||
searchField: searchField,
|
||||
|
||||
styleWrapper: styleWrapper,
|
||||
styleSelectList: styleSelectList,
|
||||
styleSelectListOther: styleSelectListOther,
|
||||
@ -283,7 +272,6 @@
|
||||
insertLinkBtn: insertLinkBtn,
|
||||
cancelBtn: cancelBtn,
|
||||
refreshBtn: refreshBtn,
|
||||
saveAsTextBtn: new Button("saveAsTextBtn"),
|
||||
|
||||
checkOmitAuthor: checkOmitAuthor,
|
||||
cslFileInput: cslFileInput,
|
||||
@ -298,9 +286,6 @@
|
||||
window.Asc.plugin.init = function () {
|
||||
initElements();
|
||||
showLoader(true);
|
||||
setTimeout(function () {
|
||||
if (elements.searchField) elements.searchField.focus();
|
||||
}, 100);
|
||||
|
||||
router = new Router();
|
||||
sdk = new ZoteroSdk();
|
||||
@ -447,22 +432,35 @@
|
||||
return sdk
|
||||
.getUserGroups()
|
||||
.then(function (/** @type {Array<UserGroupInfo>} */ groups) {
|
||||
let selectedItem = localStorage.getItem("selectedGroup");
|
||||
let hasSelected = false;
|
||||
groups.forEach(function (group) {
|
||||
group.id = String(group.id);
|
||||
});
|
||||
|
||||
const customGroups = [
|
||||
{ id: "all", name: translate("Everywhere") },
|
||||
{ id: "my_library", name: translate("My Library") },
|
||||
{
|
||||
id: "group_libraries",
|
||||
name: translate("Group Libraries"),
|
||||
},
|
||||
];
|
||||
if (elements.library instanceof HTMLInputElement) {
|
||||
elements.library.value = customGroups[0].name;
|
||||
!hasSelected &&
|
||||
customGroups.forEach(function (group) {
|
||||
if (group.id === selectedItem) {
|
||||
hasSelected = true;
|
||||
}
|
||||
});
|
||||
!hasSelected &&
|
||||
groups.forEach(function (group) {
|
||||
if (group.id.toString() === selectedItem) {
|
||||
hasSelected = true;
|
||||
}
|
||||
});
|
||||
if (!hasSelected) {
|
||||
selectedItem = "my_library";
|
||||
hasSelected = true;
|
||||
}
|
||||
elements.library.setAttribute("data-value", customGroups[0].id);
|
||||
elements.library.setAttribute("title", customGroups[0].name);
|
||||
|
||||
const selectedItem =
|
||||
localStorage.getItem("selectedGroup") || "all";
|
||||
|
||||
/**
|
||||
* @param {string|number} id
|
||||
@ -472,95 +470,92 @@
|
||||
if (typeof id === "number") {
|
||||
id = id.toString();
|
||||
}
|
||||
const el = document.createElement("span");
|
||||
el.setAttribute("data-value", id);
|
||||
el.textContent = name;
|
||||
elements.searchLibrary.appendChild(el);
|
||||
if (
|
||||
id === selectedItem &&
|
||||
elements.library instanceof HTMLInputElement
|
||||
) {
|
||||
el.setAttribute("selected", "");
|
||||
elements.library.value = name;
|
||||
elements.library.setAttribute("data-value", id);
|
||||
elements.library.setAttribute("title", name);
|
||||
}
|
||||
if (customElements.librarySelectList instanceof SelectBox)
|
||||
customElements.librarySelectList.addItem(
|
||||
id,
|
||||
name,
|
||||
id === selectedItem
|
||||
);
|
||||
};
|
||||
|
||||
const addSeparator = function () {
|
||||
const el = document.createElement("hr");
|
||||
elements.searchLibrary.appendChild(el);
|
||||
};
|
||||
|
||||
elements.searchLibrary.addEventListener("click", function (e) {
|
||||
const target = e.target;
|
||||
let option;
|
||||
if (target && target instanceof HTMLSpanElement) {
|
||||
option = target;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
const selected =
|
||||
elements.searchLibrary.querySelector("span[selected]");
|
||||
selected && selected.attributes.removeNamedItem("selected");
|
||||
option.setAttribute("selected", "");
|
||||
const id = option.getAttribute("data-value");
|
||||
const name = option.textContent;
|
||||
if (
|
||||
!(elements.library instanceof HTMLInputElement) ||
|
||||
!(elements.searchField instanceof HTMLInputElement) ||
|
||||
typeof id !== "string"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
elements.library.value = option.textContent;
|
||||
elements.library.setAttribute("data-value", id);
|
||||
elements.library.setAttribute("title", name);
|
||||
|
||||
localStorage.setItem("selectedGroup", id);
|
||||
|
||||
switchClass(elements.searchClear, displayNoneClass, true);
|
||||
elements.searchField.value = "";
|
||||
lastSearch.text = "";
|
||||
clearLibrary();
|
||||
});
|
||||
|
||||
if (groups.length === 0) {
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < customGroups.length; i++) {
|
||||
const id = customGroups[i].id;
|
||||
const name = customGroups[i].name;
|
||||
addGroupToSelectBox(id, name);
|
||||
}
|
||||
addSeparator();
|
||||
|
||||
if (groups.length === 0) {
|
||||
return;
|
||||
}
|
||||
customElements.librarySelectList.addSeparator();
|
||||
for (var i = 0; i < groups.length; i++) {
|
||||
const id = groups[i].id;
|
||||
const name = groups[i].name;
|
||||
addGroupToSelectBox(id, name);
|
||||
}
|
||||
selectedGroupsWatcher(customGroups, groups);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {number|"all"|"my_library"|"group_libraries"}
|
||||
* @param {Array<{id: string, name: string}>} customGroups
|
||||
* @param {Array<UserGroupInfo>} groups
|
||||
* @returns
|
||||
*/
|
||||
function selectedGroupsWatcher(customGroups, groups) {
|
||||
if (customElements.librarySelectList instanceof SelectBox === false) {
|
||||
return;
|
||||
}
|
||||
customElements.librarySelectList.subscribe(function (event) {
|
||||
if (event.type !== "selectbox:change") {
|
||||
return;
|
||||
}
|
||||
const values = event.detail.values;
|
||||
const current = event.detail.current;
|
||||
const bEnabled = event.detail.enabled;
|
||||
const customIds = customGroups.map(function (group) {
|
||||
return group.id;
|
||||
});
|
||||
let ids = groups.map(function (group) {
|
||||
return group.id;
|
||||
});
|
||||
|
||||
let bWasCustom = customIds.indexOf(String(current)) !== -1;
|
||||
|
||||
if (bWasCustom && current === "group_libraries") {
|
||||
if (bEnabled) {
|
||||
customElements.librarySelectList.selectItems(ids, true);
|
||||
} else {
|
||||
customElements.librarySelectList.unselectItems(ids, true);
|
||||
}
|
||||
} else if (!bWasCustom) {
|
||||
let bAllGroupsSelected = ids.every(function (id) {
|
||||
return values.indexOf(id) !== -1;
|
||||
});
|
||||
if (bAllGroupsSelected) {
|
||||
customElements.librarySelectList.selectItems(
|
||||
"group_libraries",
|
||||
true
|
||||
);
|
||||
} else {
|
||||
customElements.librarySelectList.unselectItems(
|
||||
"group_libraries",
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {number|"my_library"|"group_libraries"}
|
||||
*/
|
||||
function getSelectedGroup() {
|
||||
for (var i = 0; i < elements.searchLibrary.children.length; i++) {
|
||||
const option = elements.searchLibrary.children[i];
|
||||
if (option.hasAttribute("selected")) {
|
||||
const id = option.getAttribute("data-value");
|
||||
if (
|
||||
id === "my_library" ||
|
||||
id === "group_libraries" ||
|
||||
id === "all"
|
||||
) {
|
||||
return id;
|
||||
}
|
||||
return Number(id);
|
||||
}
|
||||
const id = customElements.librarySelectList.getValue();
|
||||
if (id === "my_library" || id === "group_libraries") {
|
||||
return id;
|
||||
}
|
||||
return "all";
|
||||
return Number(id);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -706,7 +701,6 @@
|
||||
case "my_library":
|
||||
groups = [];
|
||||
break;
|
||||
case "all":
|
||||
case "group_libraries":
|
||||
groups = userGroups.map(function (group) {
|
||||
return group.id;
|
||||
@ -722,10 +716,7 @@
|
||||
let hideLoader = !groups.length;
|
||||
const bCount = true;
|
||||
|
||||
if (
|
||||
selectedGroup === "my_library" ||
|
||||
selectedGroup === "all"
|
||||
) {
|
||||
if (selectedGroup === "my_library") {
|
||||
promises.push(
|
||||
loadLibrary(
|
||||
sdk.getItems(text),
|
||||
@ -757,37 +748,16 @@
|
||||
return Promise.all(promises);
|
||||
});
|
||||
}
|
||||
elements.searchField.onkeypress = function (e) {
|
||||
if (!(e.target instanceof HTMLInputElement)) return;
|
||||
if (e.keyCode == 13) searchFor(e.target.value);
|
||||
};
|
||||
elements.searchField.onblur = function (e) {
|
||||
setTimeout(function () {
|
||||
if (!(e.target instanceof HTMLInputElement)) return;
|
||||
searchFor(e.target.value);
|
||||
}, 500);
|
||||
};
|
||||
elements.searchField.onkeyup = function (e) {
|
||||
if (!(e.target instanceof HTMLInputElement)) return;
|
||||
switchClass(
|
||||
elements.searchClear,
|
||||
displayNoneClass,
|
||||
!e.target.value
|
||||
);
|
||||
};
|
||||
elements.searchClear.onclick = function (e) {
|
||||
if (
|
||||
!(e.target instanceof HTMLElement) ||
|
||||
!(elements.searchField instanceof HTMLInputElement)
|
||||
)
|
||||
return;
|
||||
if (e.target.classList.contains(displayNoneClass)) return true;
|
||||
switchClass(elements.searchClear, displayNoneClass, true);
|
||||
elements.searchField.value = "";
|
||||
lastSearch.text = "";
|
||||
clearLibrary();
|
||||
return true;
|
||||
};
|
||||
if (customElements.searchField instanceof HTMLInputElement) {
|
||||
customElements.searchField.subscribe(function (e) {
|
||||
if (
|
||||
e.type === "inputfield:blur" ||
|
||||
e.type === "inputfield:submit"
|
||||
) {
|
||||
searchFor(e.detail.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
elements.cancelBtn.onclick = function (e) {
|
||||
var ids = [];
|
||||
@ -898,8 +868,8 @@
|
||||
});
|
||||
};
|
||||
|
||||
if (elements.saveAsTextBtn instanceof Button) {
|
||||
elements.saveAsTextBtn.subscribe(function (event) {
|
||||
if (customElements.saveAsTextBtn instanceof Button) {
|
||||
customElements.saveAsTextBtn.subscribe(function (event) {
|
||||
if (event.type !== "button:click") {
|
||||
return;
|
||||
}
|
||||
@ -998,7 +968,6 @@
|
||||
elements.styleLang.onselectchange = function (inp, val, isClick) {
|
||||
showLoader(true);
|
||||
localesManager.saveLastUsedLanguage(val);
|
||||
console.warn("load locale", val);
|
||||
localesManager
|
||||
.loadLocale(val)
|
||||
.then(function () {
|
||||
@ -1262,7 +1231,6 @@
|
||||
*/
|
||||
function onClickListElement(list, input) {
|
||||
return function (/** @type {MouseEvent} */ ev) {
|
||||
console.warn("onClickListElement", input);
|
||||
if (!ev.target || !(ev.target instanceof HTMLElement)) {
|
||||
console.error("onClickListElement: no target");
|
||||
return;
|
||||
|
||||
@ -48,6 +48,7 @@ function InputField(input, options) {
|
||||
}
|
||||
}
|
||||
|
||||
this._id = input.id || "input_" + Math.random().toString(36).slice(2, 9);
|
||||
this.isFocused = false;
|
||||
this.isValid = true;
|
||||
this._validationMessage = "";
|
||||
@ -55,11 +56,11 @@ function InputField(input, options) {
|
||||
this._subscribers = [];
|
||||
/** @type {InputBoundHandlesType} */
|
||||
this._boundHandles = {
|
||||
focus: function () {
|
||||
self._handleFocus();
|
||||
focus: function (e) {
|
||||
self._handleFocus(e);
|
||||
},
|
||||
blur: function () {
|
||||
self._handleBlur();
|
||||
blur: function (e) {
|
||||
self._handleBlur(e);
|
||||
},
|
||||
input: function (e) {
|
||||
self._handleInput(e);
|
||||
@ -106,7 +107,7 @@ InputField.prototype._createDOM = function () {
|
||||
|
||||
var fragment = document.createDocumentFragment();
|
||||
fragment.appendChild(this._container);
|
||||
this._container.className += " input-field-container";
|
||||
this._container.className += " input-field-container input-field-container-" + this._id;
|
||||
|
||||
var inputField = document.createElement("div");
|
||||
this._container.appendChild(inputField);
|
||||
@ -165,6 +166,7 @@ InputField.prototype._createDOM = function () {
|
||||
this._validationElement.style.display = "none";
|
||||
|
||||
if (this._options.showClear) {
|
||||
this.input.className += " input-field-clearable";
|
||||
this._clearButton = document.createElement("button");
|
||||
inputField.appendChild(this._clearButton);
|
||||
this._clearButton.className += " input-field-clear";
|
||||
@ -191,13 +193,20 @@ InputField.prototype._bindEvents = function () {
|
||||
this.input.addEventListener("change", this._boundHandles.validate);
|
||||
};
|
||||
|
||||
InputField.prototype._handleFocus = function () {
|
||||
/**
|
||||
* @param {Event} e
|
||||
*/
|
||||
InputField.prototype._handleFocus = function (e) {
|
||||
this.isFocused = true;
|
||||
this._container.className += " input-field-focused";
|
||||
this._updateClearButton();
|
||||
this._triggerFocusEvent(e);
|
||||
};
|
||||
|
||||
InputField.prototype._handleBlur = function () {
|
||||
/**
|
||||
* @param {Event} e
|
||||
*/
|
||||
InputField.prototype._handleBlur = function (e) {
|
||||
this.isFocused = false;
|
||||
|
||||
var classes = this._container.className.split(" ");
|
||||
@ -210,6 +219,7 @@ InputField.prototype._handleBlur = function () {
|
||||
this._container.className = newClasses.join(" ");
|
||||
|
||||
this.validate();
|
||||
this._triggerBlurEvent(e);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -480,6 +490,40 @@ InputField.prototype._triggerInputEvent = function (e) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Event} e
|
||||
*/
|
||||
InputField.prototype._triggerFocusEvent = function (e) {
|
||||
var detail = {
|
||||
value: this.input.value,
|
||||
originalEvent: e,
|
||||
};
|
||||
|
||||
this._subscribers.forEach(function (cb) {
|
||||
cb({
|
||||
type: "inputfield:focus",
|
||||
detail: detail,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Event} e
|
||||
*/
|
||||
InputField.prototype._triggerBlurEvent = function (e) {
|
||||
var detail = {
|
||||
value: this.input.value,
|
||||
originalEvent: e,
|
||||
};
|
||||
|
||||
this._subscribers.forEach(function (cb) {
|
||||
cb({
|
||||
type: "inputfield:blur",
|
||||
detail: detail,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
InputField.prototype._triggerChange = function () {
|
||||
var detail = {
|
||||
value: this.input.value,
|
||||
|
||||
@ -39,7 +39,7 @@ function SelectBox(container, options) {
|
||||
|
||||
this._selectedValues = new Set();
|
||||
this._isOpen = false;
|
||||
/** @type {Array<{ value: string | number, text: string, selected: boolean }>} */
|
||||
/** @type {Array<{ value: string, text: string, selected: boolean } | null>} */
|
||||
this._items = [];
|
||||
/** @type {Function[]} */
|
||||
this._subscribers = [];
|
||||
@ -54,7 +54,8 @@ function SelectBox(container, options) {
|
||||
close: function (e) {
|
||||
if (
|
||||
e.target instanceof HTMLElement &&
|
||||
!self._container.contains(e.target)
|
||||
!self._container.contains(e.target) &&
|
||||
!e.target.classList.contains("selectbox-option")
|
||||
) {
|
||||
self._closeDropdown();
|
||||
}
|
||||
@ -222,6 +223,10 @@ SelectBox.prototype._handleSearch = function (e) {
|
||||
*/
|
||||
SelectBox.prototype._handleKeydown = function (e) {
|
||||
var key = e.key || e.keyCode;
|
||||
const items = this._items.filter(function (item) {
|
||||
return item !== null;
|
||||
});
|
||||
let newItem;
|
||||
|
||||
switch (key) {
|
||||
case " ":
|
||||
@ -238,50 +243,51 @@ SelectBox.prototype._handleKeydown = function (e) {
|
||||
case "ArrowDown":
|
||||
case 40:
|
||||
e.preventDefault();
|
||||
if (this._selectedValues.size === 0 && this._items.length > 0) {
|
||||
var firstItem = this._items[0];
|
||||
this._selectedValues.add(firstItem.value);
|
||||
if (this._selectedValues.size === 0 && items.length > 0) {
|
||||
newItem = items[0];
|
||||
this._selectedValues.add(newItem.value);
|
||||
} else {
|
||||
var selectedArray = Array.from(this._selectedValues);
|
||||
var currentIndex = -1;
|
||||
for (var i = 0; i < this._items.length; i++) {
|
||||
if (this._items[i].value === selectedArray[0]) {
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
if (items[i].value === selectedArray[0]) {
|
||||
currentIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var nextIndex = (currentIndex + 1) % this._items.length;
|
||||
var nextIndex = (currentIndex + 1) % items.length;
|
||||
this._selectedValues.clear();
|
||||
this._selectedValues.add(this._items[nextIndex].value);
|
||||
newItem = items[nextIndex];
|
||||
this._selectedValues.add(newItem.value);
|
||||
}
|
||||
this._updateSelectedText();
|
||||
this._renderOptions(this.searchInput ? this.searchInput.value : "");
|
||||
this._triggerChange();
|
||||
this._triggerChange(newItem.value, true);
|
||||
break;
|
||||
case "ArrowUp":
|
||||
case 38:
|
||||
e.preventDefault();
|
||||
if (this._selectedValues.size === 0 && this._items.length > 0) {
|
||||
var lastItem = this._items[this._items.length - 1];
|
||||
this._selectedValues.add(lastItem.value);
|
||||
if (this._selectedValues.size === 0 && items.length > 0) {
|
||||
newItem = items[items.length - 1];
|
||||
this._selectedValues.add(newItem.value);
|
||||
} else {
|
||||
var selectedArray = Array.from(this._selectedValues);
|
||||
var currentIndex = -1;
|
||||
for (var i = 0; i < this._items.length; i++) {
|
||||
if (this._items[i].value === selectedArray[0]) {
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
if (items[i].value === selectedArray[0]) {
|
||||
currentIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var prevIndex =
|
||||
(currentIndex - 1 + this._items.length) %
|
||||
this._items.length;
|
||||
(currentIndex - 1 + items.length) % items.length;
|
||||
this._selectedValues.clear();
|
||||
this._selectedValues.add(this._items[prevIndex].value);
|
||||
newItem = items[prevIndex];
|
||||
this._selectedValues.add(newItem.value);
|
||||
}
|
||||
this._updateSelectedText();
|
||||
this._renderOptions(this.searchInput ? this.searchInput.value : "");
|
||||
this._triggerChange();
|
||||
this._triggerChange(newItem.value, true);
|
||||
break;
|
||||
case "Tab":
|
||||
case 9:
|
||||
@ -299,28 +305,32 @@ SelectBox.prototype._renderOptions = function (searchTerm) {
|
||||
/** @type {HTMLDivElement | null} */
|
||||
var selectedOption = null;
|
||||
|
||||
var filteredItems = [];
|
||||
var filteredItems = this._items;
|
||||
if (searchTerm) {
|
||||
for (var i = 0; i < this._items.length; i++) {
|
||||
var item = this._items[i];
|
||||
if (item.text.toLowerCase().indexOf(searchTerm) !== -1) {
|
||||
filteredItems.push(item);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
filteredItems = this._items.slice();
|
||||
filteredItems = filteredItems.filter(function (item) {
|
||||
return (
|
||||
item !== null &&
|
||||
item.text.toLowerCase().indexOf(searchTerm) !== -1
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
var fragment = document.createDocumentFragment();
|
||||
for (var i = 0; i < filteredItems.length; i++) {
|
||||
var item = filteredItems[i];
|
||||
if (!item) {
|
||||
const hr = document.createElement("hr");
|
||||
hr.className += " selectbox-option-divider";
|
||||
fragment.appendChild(hr);
|
||||
continue;
|
||||
}
|
||||
var option = document.createElement("div");
|
||||
option.className += " selectbox-option";
|
||||
if (this._selectedValues.has(item.value)) {
|
||||
option.className += " selectbox-option-selected";
|
||||
selectedOption = option;
|
||||
}
|
||||
option.setAttribute("data-value", String(item.value));
|
||||
option.setAttribute("data-value", item.value);
|
||||
|
||||
if (this._options.multiple) {
|
||||
var input = document.createElement("input");
|
||||
@ -398,23 +408,24 @@ SelectBox.prototype._handleDropdownClick = function (e) {
|
||||
}
|
||||
|
||||
var value = option.getAttribute("data-value");
|
||||
if (value === null) return;
|
||||
let enabled = true;
|
||||
|
||||
if (this._options.multiple) {
|
||||
if (this._selectedValues.has(value)) {
|
||||
this._selectedValues.delete(value);
|
||||
this.unselectItems(value, true);
|
||||
enabled = false;
|
||||
} else {
|
||||
this._selectedValues.add(value);
|
||||
this.selectItems(value, true);
|
||||
}
|
||||
} else {
|
||||
this._selectedValues.clear();
|
||||
this._selectedValues.add(value);
|
||||
this.selectItems(value, true);
|
||||
this._closeDropdown();
|
||||
}
|
||||
|
||||
this._updateSelectedText();
|
||||
this._renderOptions(this.searchInput ? this.searchInput.value : "");
|
||||
|
||||
this._triggerChange();
|
||||
this._triggerChange(value, enabled);
|
||||
};
|
||||
|
||||
SelectBox.prototype._updateSelectedText = function () {
|
||||
@ -427,7 +438,7 @@ SelectBox.prototype._updateSelectedText = function () {
|
||||
var selectedItems = [];
|
||||
for (var i = 0; i < this._items.length; i++) {
|
||||
var item = this._items[i];
|
||||
if (this._selectedValues.has(item.value)) {
|
||||
if (item && this._selectedValues.has(item.value)) {
|
||||
selectedItems.push(item);
|
||||
}
|
||||
}
|
||||
@ -444,7 +455,7 @@ SelectBox.prototype._updateSelectedText = function () {
|
||||
var selectedItem = null;
|
||||
for (var i = 0; i < this._items.length; i++) {
|
||||
var item = this._items[i];
|
||||
if (this._selectedValues.has(item.value)) {
|
||||
if (item && this._selectedValues.has(item.value)) {
|
||||
selectedItem = item;
|
||||
break;
|
||||
}
|
||||
@ -456,19 +467,26 @@ SelectBox.prototype._updateSelectedText = function () {
|
||||
}
|
||||
};
|
||||
|
||||
SelectBox.prototype._triggerChange = function () {
|
||||
/**
|
||||
* @param {string} currentValue
|
||||
* @param {boolean} enabled
|
||||
*/
|
||||
SelectBox.prototype._triggerChange = function (currentValue, enabled) {
|
||||
var values = Array.from(this._selectedValues);
|
||||
var items = [];
|
||||
for (var i = 0; i < this._items.length; i++) {
|
||||
var item = this._items[i];
|
||||
if (this._selectedValues.has(item.value)) {
|
||||
if (item && this._selectedValues.has(item.value)) {
|
||||
items.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {SelectboxEventDetail} */
|
||||
var detail = {
|
||||
values: values,
|
||||
items: items,
|
||||
current: currentValue,
|
||||
enabled: enabled,
|
||||
};
|
||||
|
||||
this._subscribers.forEach(function (cb) {
|
||||
@ -480,7 +498,7 @@ SelectBox.prototype._triggerChange = function () {
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Function} callback
|
||||
* @param {function(SelectboxEventType): void} callback
|
||||
* @returns {Object}
|
||||
*/
|
||||
SelectBox.prototype.subscribe = function (callback) {
|
||||
@ -497,7 +515,7 @@ SelectBox.prototype.subscribe = function (callback) {
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string | number} value
|
||||
* @param {string} value
|
||||
* @param {string} text
|
||||
* @param {boolean} selected
|
||||
*/
|
||||
@ -517,17 +535,20 @@ SelectBox.prototype.addItem = function (value, text, selected) {
|
||||
this._updateSelectedText();
|
||||
};
|
||||
|
||||
SelectBox.prototype.addSeparator = function () {
|
||||
this._items.push(null);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
*/
|
||||
SelectBox.prototype.removeItem = function (value) {
|
||||
var newItems = [];
|
||||
for (var i = 0; i < this._items.length; i++) {
|
||||
if (this._items[i].value !== value) {
|
||||
newItems.push(this._items[i]);
|
||||
this._items = this._items.filter(function (item) {
|
||||
if (item === null || item.value !== value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
this._items = newItems;
|
||||
return false;
|
||||
});
|
||||
this._selectedValues.delete(value);
|
||||
this._updateSelectedText();
|
||||
};
|
||||
@ -554,6 +575,148 @@ SelectBox.prototype.setValue = function (value) {
|
||||
this._renderOptions();
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string | Array<string>} values
|
||||
* @param {boolean} [bSilent]
|
||||
*/
|
||||
SelectBox.prototype.selectItems = function (values, bSilent) {
|
||||
const self = this;
|
||||
if (!this._options.multiple && Array.isArray(values)) {
|
||||
console.error(
|
||||
"Method selectItem is only available for multi-select boxes."
|
||||
);
|
||||
return;
|
||||
}
|
||||
/** @type {string} */
|
||||
let value = "";
|
||||
|
||||
if (this._options.multiple) {
|
||||
/**
|
||||
* @param {string} value
|
||||
*/
|
||||
let checkMultiOption = function (value) {
|
||||
if (self._optionsContainer) {
|
||||
let option = self._optionsContainer.querySelector(
|
||||
'[data-value="' + value + '"]'
|
||||
);
|
||||
|
||||
if (option) {
|
||||
let checkbox = option.querySelector(
|
||||
'input[type="checkbox"]'
|
||||
);
|
||||
if (checkbox && checkbox instanceof HTMLInputElement) {
|
||||
checkbox.checked = true;
|
||||
}
|
||||
option.classList.add("selectbox-option-selected");
|
||||
}
|
||||
}
|
||||
};
|
||||
if (Array.isArray(values)) {
|
||||
for (var i = 0; i < values.length; i++) {
|
||||
value = values[i];
|
||||
if (!this._selectedValues.has(value)) {
|
||||
this._selectedValues.add(value);
|
||||
checkMultiOption(value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
value = values;
|
||||
if (!this._selectedValues.has(value)) {
|
||||
this._selectedValues.add(value);
|
||||
checkMultiOption(value);
|
||||
}
|
||||
}
|
||||
} else if (!Array.isArray(values)) {
|
||||
value = values;
|
||||
this._selectedValues.clear();
|
||||
this._selectedValues.add(value);
|
||||
|
||||
if (this._optionsContainer) {
|
||||
let selectedOptions = this._optionsContainer.querySelectorAll(
|
||||
'.selectbox-option-selected[data-value="' + value + '"]'
|
||||
);
|
||||
selectedOptions.forEach(function (option) {
|
||||
option.classList.remove("selectbox-option-selected");
|
||||
});
|
||||
let option = this._optionsContainer.querySelector(
|
||||
'[data-value="' + value + '"]'
|
||||
);
|
||||
|
||||
if (option) {
|
||||
option.classList.add("selectbox-option-selected");
|
||||
}
|
||||
}
|
||||
this._closeDropdown();
|
||||
}
|
||||
|
||||
this._updateSelectedText();
|
||||
|
||||
if (bSilent) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._triggerChange(value, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string | Array<string>} values
|
||||
* @param {boolean} [bSilent]
|
||||
*/
|
||||
SelectBox.prototype.unselectItems = function (values, bSilent) {
|
||||
const self = this;
|
||||
if (!this._options.multiple) {
|
||||
console.error(
|
||||
"Method unselectItem is only available for multi-select boxes."
|
||||
);
|
||||
return;
|
||||
}
|
||||
/** @type {string} */
|
||||
let value = "";
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
*/
|
||||
let uncheckMultiOption = function (value) {
|
||||
if (self._optionsContainer) {
|
||||
let option = self._optionsContainer.querySelector(
|
||||
'[data-value="' + value + '"]'
|
||||
);
|
||||
|
||||
if (option) {
|
||||
let checkbox = option.querySelector('input[type="checkbox"]');
|
||||
if (checkbox && checkbox instanceof HTMLInputElement) {
|
||||
checkbox.checked = false;
|
||||
}
|
||||
option.classList.remove("selectbox-option-selected");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (Array.isArray(values)) {
|
||||
for (var i = 0; i < values.length; i++) {
|
||||
value = values[i];
|
||||
if (this._selectedValues.has(value)) {
|
||||
this._selectedValues.delete(value);
|
||||
uncheckMultiOption(value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
value = values;
|
||||
if (this._selectedValues.has(value)) {
|
||||
this._selectedValues.delete(value);
|
||||
uncheckMultiOption(value);
|
||||
}
|
||||
}
|
||||
|
||||
this._updateSelectedText();
|
||||
|
||||
if (bSilent) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._triggerChange(value, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} bSelectFirst
|
||||
*/
|
||||
@ -562,7 +725,9 @@ SelectBox.prototype.clear = function (bSelectFirst) {
|
||||
this._selectedValues.clear();
|
||||
if (bSelectFirst && this._items.length > 0) {
|
||||
var firstItem = this._items[0];
|
||||
this._selectedValues.add(firstItem.value);
|
||||
if (firstItem) {
|
||||
this._selectedValues.add(firstItem.value);
|
||||
}
|
||||
}
|
||||
this._updateSelectedText();
|
||||
this._renderOptions();
|
||||
|
||||
@ -26,8 +26,8 @@
|
||||
|
||||
/**
|
||||
* @typedef {Object} InputBoundHandlesType
|
||||
* @property {() => void} focus
|
||||
* @property {() => void} blur
|
||||
* @property {(ev: Event) => void} focus
|
||||
* @property {(ev: Event) => void} blur
|
||||
* @property {(ev: Event) => void} input
|
||||
* @property {(ev: KeyboardEvent) => void} keydown
|
||||
* @property {() => void} clear
|
||||
@ -68,6 +68,20 @@
|
||||
* @property {boolean} [multiple]
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} SelectboxEventType
|
||||
* @property {string} type
|
||||
* @property {SelectboxEventDetail} detail
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} SelectboxEventDetail
|
||||
* @property {Array<string|number>} values
|
||||
* @property {string|number} current
|
||||
* @property {boolean} enabled
|
||||
* @property {Array<SelectboxItem>} [items]
|
||||
*/
|
||||
|
||||
/** ********************** */
|
||||
|
||||
/**
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
|
||||
/**
|
||||
* @typedef {Object} UserGroupInfo
|
||||
* @property {number} id
|
||||
* @property {number|string} id
|
||||
* @property {string} name
|
||||
*/
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
"Failed to insert citation": "Nepodarilo se vložit citaci",
|
||||
"Failed to insert bibliography": "Nepodarilo se vložit bibliografii",
|
||||
"Failed to refresh": "Nepodarilo se aktualizovat",
|
||||
"Search in:": "Vyhledat v:",
|
||||
"Search the references you want to cite in this document.": "Vyhledejte odkazy, které chcete citovat v tomto dokumentu.",
|
||||
"Everywhere": "Vезде",
|
||||
"My Library": "Moje knihovna",
|
||||
"Group Libraries": "Skupinové knihovny",
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
"Failed to insert citation": "Fehler beim Einfügen des Zitats",
|
||||
"Failed to insert bibliography": "Fehler beim Einfügen der Bibliographie",
|
||||
"Failed to refresh": "Fehler beim Aktualisieren",
|
||||
"Search in:": "Suche in:",
|
||||
"Search the references you want to cite in this document.": "Suchen Sie die Referenzen, die Sie in diesem Dokument zitieren wollen.",
|
||||
"Everywhere": "Alle",
|
||||
"My Library": "Meine Bibliothek",
|
||||
"Group Libraries": "Gruppenbibliotheken",
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
"Failed to insert citation": "Fallo al insertar la cita",
|
||||
"Failed to insert bibliography": "Fallo al insertar la bibliografía",
|
||||
"Failed to refresh": "Fallo al actualizar",
|
||||
"Search in:": "Buscar en:",
|
||||
"Search the references you want to cite in this document.": "Busque las referencias que desea citar en este documento.",
|
||||
"Everywhere": "Todo",
|
||||
"My Library": "Mi biblioteca",
|
||||
"Group Libraries": "Bibliotecas de grupos",
|
||||
|
||||
@ -26,7 +26,6 @@
|
||||
"Refresh": "Rafraîchir",
|
||||
"Unlink citations": "Dissocier les citations",
|
||||
"Please insert some citation into the document.": "Veuillez insérer une citation dans le document.",
|
||||
|
||||
"Omit Author": "Omettre l'auteur",
|
||||
"Connection to Zotero failed": "La connexion à Zotero a échoué",
|
||||
"Connection to Zotero failed. Make sure Zotero is running": "La connexion à Zotero a échoué. Vérifiez que Zotero est actif",
|
||||
@ -38,7 +37,7 @@
|
||||
"Failed to insert citation": "Échec de l'insertion de la citation",
|
||||
"Failed to insert bibliography": "Échec de l'insertion de la bibliographie",
|
||||
"Failed to refresh": "Échec de la mise à jour",
|
||||
"Search in:": "Rechercher dans:",
|
||||
"Search the references you want to cite in this document.": "Rechercher les citations que vous souhaitez citer dans ce document.",
|
||||
"Everywhere": "Partout",
|
||||
"My Library": "Ma bibliothèque",
|
||||
"Group Libraries": "Bibliothèques de groupes",
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
"Open Zotero website": "Apri il sito web Zotero",
|
||||
"Invalid API key": "Chiave API non valida",
|
||||
"API Key": "Chiave API",
|
||||
"Search in all literature:": "Cerca in tutta la letteratura",
|
||||
"Nothing found": "Niente trovato",
|
||||
"Style is not selected": "Lo stile non ? selezionato",
|
||||
"Language is not selected": "Il linguaggio non ? selezionato",
|
||||
"Search references by author, title or year": "Cerca riferimenti per autore, titolo o anno",
|
||||
@ -37,7 +37,7 @@
|
||||
"Failed to insert citation": "Impossibile inserire la citazione",
|
||||
"Failed to insert bibliography": "Impossibile inserire la bibliografia",
|
||||
"Failed to refresh": "Impossibile aggiornare",
|
||||
"Search in:": "Cerca in:",
|
||||
"Search the references you want to cite in this document.": "Cerca i riferimenti che desideri citare nel documento corrente.",
|
||||
"Everywhere": "Tutto",
|
||||
"My Library": "La mia biblioteca",
|
||||
"Group Libraries": "Biblioteca dei gruppi",
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
"Failed to insert citation": "引用の挿入に失敗しました",
|
||||
"Failed to insert bibliography": "文献引用の挿入に失敗しました",
|
||||
"Failed to refresh": "リフレッシュに失敗しました",
|
||||
"Search in:": "検索対象:",
|
||||
"Search the references you want to cite in this document.": "この文書内で引用したい文献を検索します。",
|
||||
"Everywhere": "全て",
|
||||
"My Library": "私のライブラリ",
|
||||
"Group Libraries": "グループライブラリ",
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
"Failed to insert citation": "Het invoegen van de citaat is mislukt",
|
||||
"Failed to insert bibliography": "Het invoegen van de bibliografie is mislukt",
|
||||
"Failed to refresh": "Het vernieuwen is mislukt",
|
||||
"Search in:": "Zoeken in:",
|
||||
"Search the references you want to cite in this document.": "Zoek de referenties die u wilt citaat in dit document.",
|
||||
"Everywhere": "Elke plaats",
|
||||
"My Library": "Mijn bibliotheek",
|
||||
"Group Libraries": "Groepsbibliotheek",
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
"Failed to insert citation": "Falha ao inserir citação",
|
||||
"Failed to insert bibliography": "Falha ao inserir bibliografia",
|
||||
"Failed to refresh": "Falha ao atualizar",
|
||||
"Search in:": "Procurar em:",
|
||||
"Search the references you want to cite in this document.": "Procure as referências que deseja citar neste documento.",
|
||||
"Everywhere": "Todos os lugares",
|
||||
"My Library": "A minha biblioteca",
|
||||
"Group Libraries": "Grupos de bibliotecas",
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
"Failed to insert citation": "Falha ao inserir citação",
|
||||
"Failed to insert bibliography": "Falha ao inserir bibliografia",
|
||||
"Failed to refresh": "Falha ao actualizar",
|
||||
"Search in:": "Procurar em:",
|
||||
"Search the references you want to cite in this document.": "Procura as referências que queres citar neste documento.",
|
||||
"Everywhere": "Todos os lugares",
|
||||
"My Library": "A minha biblioteca",
|
||||
"Group Libraries": "Grupos de bibliotecas",
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
"Failed to insert citation": "Не удалось вставить цитату",
|
||||
"Failed to insert bibliography": "Не удалось вставить библиографию",
|
||||
"Failed to refresh": "Не удалось обновить",
|
||||
"Search in:": "Поиск в:",
|
||||
"Search the references you want to cite in this document.": "Поиск ссылок, которые вы хотите цитировать в этом документе.",
|
||||
"Everywhere": "Везде",
|
||||
"My Library": "Моя библиотека",
|
||||
"Group Libraries": "Группы библиотек",
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
"Failed to insert citation": "Zbatimi i citimit dështoi",
|
||||
"Failed to insert bibliography": "Zbatimi i bibliografise dështoi",
|
||||
"Failed to refresh": "Rifreskimi dështoi",
|
||||
"Search in:": "Kerkoni sipas:",
|
||||
"Search the references you want to cite in this document.": "Kerkoni referenca sipas autorit, titullit ose vitit",
|
||||
"Everywhere": "Gjithashtu",
|
||||
"My Library": "Kutia mija",
|
||||
"Group Libraries": "Kutia e grupave",
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
"Failed to insert citation": "Убациње цитата није успело",
|
||||
"Failed to insert bibliography": "Убациње библиографије није успело",
|
||||
"Failed to refresh": "Освежавање није успело",
|
||||
"Search in:": "Претражите у:",
|
||||
"Search the references you want to cite in this document.": "Претражите референце које желите да цитирате у овом документу.",
|
||||
"Everywhere": "Све",
|
||||
"My Library": "Моја библиотека",
|
||||
"Group Libraries": "Групе библиотека",
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
"Failed to insert citation": "Neuspelo ubacivanje citata",
|
||||
"Failed to insert bibliography": "Neuspelo ubacivanje bibliografije",
|
||||
"Failed to refresh": "Neuspelo osvežavanje",
|
||||
"Search in:": "Pretražite u:",
|
||||
"Search the references you want to cite in this document.": "Pretražite referencu koje zelite da citirate u ovom dokumentu.",
|
||||
"Everywhere": "Sve",
|
||||
"My Library": "Moja biblioteka",
|
||||
"Group Libraries": "Grupe biblioteka",
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
"Failed to insert citation": "插入引用失敗",
|
||||
"Failed to insert bibliography": "插入參考文献失敗",
|
||||
"Failed to refresh": "刷新失敗",
|
||||
"Search in:": "搜索:",
|
||||
"Search the references you want to cite in this document.": "在此文件中搜索引用。",
|
||||
"Everywhere": "全部",
|
||||
"My Library": "我的圖書館",
|
||||
"Group Libraries": "群組圖書館",
|
||||
|
||||
Reference in New Issue
Block a user