Skip to content

Commit

Permalink
Use standard dropdowns for autocomplete
Browse files Browse the repository at this point in the history
  • Loading branch information
zbynek committed Jul 11, 2024
1 parent 4761c15 commit 6b14251
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 46 deletions.
2 changes: 2 additions & 0 deletions war/src/main/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Tooltips from "@/components/tooltips";
import StopButtonLink from "@/components/stop-button-link";
import ConfirmationLink from "@/components/confirmation-link";
import Dialogs from "@/components/dialogs";
import Autocomplete from "@/components/autocomplete";

Dropdowns.init();
Notifications.init();
Expand All @@ -13,3 +14,4 @@ Tooltips.init();
StopButtonLink.init();
ConfirmationLink.init();
Dialogs.init();
Autocomplete.init();
90 changes: 90 additions & 0 deletions war/src/main/js/components/autocomplete/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import behaviorShim from "@/util/behavior-shim";
import Utils from "@/components/dropdowns/utils";

function init() {
function addValue(value, item, delimiter) {
const prev = value.includes(delimiter)
? value.substring(0, value.lastIndexOf(delimiter) + 1) + " "
: "";
return prev + item + delimiter + " ";
}

function validate(e) {
if (e.targetUrl) {
var method = e.getAttribute("checkMethod") || "post";
try {
FormChecker.delayedCheck(e.targetUrl(), method, e.targetElement);
} catch (x) {
console.warn(x);
return;
}
}
}

function convertSuggestionToItem(suggestion, e) {
const delimiter = e.getAttribute("autoCompleteDelimChar");
return {
label: suggestion.name,
onClick: () => {
e.value = delimiter
? addValue(e.value, suggestion.name, delimiter)
: suggestion.name;
validate(e);
e.focus();
},
};
}

function createAndShowDropdown(e, div, suggestions) {
const items = suggestions.map((s) =>
convertSuggestionToItem(s, e),
);
if (!e.dropdown) {
Utils.generateDropdown(
div,
(instance) => {
e.dropdown = instance;
},
true,
);
}
e.dropdown.setContent(Utils.generateDropdownItems(items, true));
e.dropdown.show();
}

function updateSuggestions(e, div) {
const text = e.value.trim();
const delimiter = e.getAttribute("autoCompleteDelimChar");
const word = delimiter ? text.split(delimiter).reverse()[0].trim() : text;
if (!word) {
if (e.dropdown) {
e.dropdown.hide();
}
return;
}
const url =
e.getAttribute("autoCompleteUrl") + "?value=" + encodeURIComponent(word);
fetch(url)
.then((rsp) => (rsp.ok ? rsp.json().suggestions : {}))
.then((response) => createAndShowDropdown(e, div, response));
}

behaviorShim.specify(
"INPUT.auto-complete",
"input-auto-complete",
0,
function (e) {
// form field with auto-completion support
// insert the auto-completion container
var div = document.createElement("DIV");
e.parentNode.insertBefore(div, e.nextElementSibling);
e.style.position = "relative";

e.addEventListener("input", (evt) => {
updateSuggestions(e, div);
});
},
);
}

export default { init };
11 changes: 8 additions & 3 deletions war/src/main/js/components/dropdowns/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ const SELECTED_ITEM_CLASS = "jenkins-dropdown__item--selected";
* @param element - the element to generate the dropdown for
* @param callback - called to retrieve the list of dropdown items
*/
function generateDropdown(element, callback) {
function generateDropdown(element, callback, immediate) {
tippy(
element,
Object.assign({}, Templates.dropdown(), {
onCreate(instance) {
instance.reference.addEventListener("mouseenter", () => {
const onload = () => {
if (instance.loaded) {
return;
}
Expand All @@ -26,7 +26,12 @@ function generateDropdown(element, callback) {
});

callback(instance);
});
};
if (immediate) {
onload();
} else {
instance.reference.addEventListener("mouseenter", onload);
}
},
}),
);
Expand Down
43 changes: 0 additions & 43 deletions war/src/main/webapp/scripts/hudson-behavior.js
Original file line number Diff line number Diff line change
Expand Up @@ -1310,49 +1310,6 @@ function rowvgStartEachRow(recursive, f) {
},
);

Behaviour.specify(
"INPUT.auto-complete",
"input-auto-complete",
++p,
function (e) {
// form field with auto-completion support
// insert the auto-completion container
var div = document.createElement("DIV");
e.parentNode.insertBefore(div, e.nextElementSibling);
e.style.position = "relative"; // or else by default it's absolutely positioned, making "width:100%" break

var ds = new YAHOO.util.XHRDataSource(e.getAttribute("autoCompleteUrl"));
ds.responseType = YAHOO.util.XHRDataSource.TYPE_JSON;
ds.responseSchema = {
resultsList: "suggestions",
fields: ["name"],
};

// Instantiate the AutoComplete
var ac = new YAHOO.widget.AutoComplete(e, div, ds);
ac.generateRequest = function (query) {
return "?value=" + query;
};
ac.autoHighlight = false;
ac.prehighlightClassName = "yui-ac-prehighlight";
ac.animSpeed = 0;
ac.formatResult = ac.formatEscapedResult;
ac.useShadow = true;
ac.autoSnapContainer = true;
ac.delimChar = e.getAttribute("autoCompleteDelimChar");
ac.doBeforeExpandContainer = function (textbox, container) {
// adjust the width every time we show it
container.style.width = textbox.clientWidth + "px";
var Dom = YAHOO.util.Dom;
Dom.setXY(container, [
Dom.getX(textbox),
Dom.getY(textbox) + textbox.offsetHeight,
]);
return true;
};
},
);

Behaviour.specify(
"A.jenkins-help-button",
"a-jenkins-help-button",
Expand Down

0 comments on commit 6b14251

Please sign in to comment.