-
Notifications
You must be signed in to change notification settings - Fork 395
11/UI/add async autocomplete to tag input #9516
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
11/UI/add async autocomplete to tag input #9516
Conversation
|
Hi @kergomard We are currently a bit understaffed. However, we are looking into this asap all coordinators are available again. Thx for your patience! |
56bb33f to
01b0a61
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @kergomard
Thank you a lot for contributing to ILIAS. This will be a great added value for the tags.
The interaction of sorting is smartly solved, thanks for that.
Please answer the following questions:
- Example 6 «With autocomplete endpoint»: I can’t reproduce the «Expected Output». I am not able to see a tag «Interesting» at the beginning. I also can’t select any by typing A, B, I or R. If I add a new one, it disappears directly after it was shown. Can you have a look on this, if the expected output need another description or is there something in the code?
-
C\Field\Tag::withAsyncAutocomplete()I: does this feature take the existing::withUserCreatedTagsAllowed()andwithSuggestionsStartAfter()into account as well? Is this handled by the library we use?
Please consider the following suggestions. You do not need to follow those, but please indicate shortly why you prefer to do otherwise:
- It’s not part of your PR, but if we are doing something here for the Tag-Input, there are some other places, where a little change on the text would be welcome:
- Example 5: In «Expected Output» the label of the input is called «Basic TagInput», but in the form it is called «Basic Tag». Please adjust the label or the description.
- KS-Description «Purpose»: Is the information at the end about «[...](@see Tag::withUserCreatedTagsAllowed)» necessary to document? I can’t relate this information to somewhere in the description or Example. Is this an information that developers need and if so is it the right place in «Purpose»?
-
C\Field\Tag::withAsyncAutocomplete()II: you mention in the method documentation that consumers MUST use the query parameterterm. Is it at all possible to change this? We encountered some problems in the past with e.g.C\Modal\Interruptive, where we used a hardcoded value like this.
Please implement the following changes:
- Example 3 «Expected Output»: The following sentence has a missing part: «Tags can be sorted by dragging and dropping them in the ». Please add an ending to the sentence.
- Example 6: The label of the input in «Expected Output» is called «Basic TagInput», but in the form it is called «Tag Input with Autocomplete».
- There are 6 errors from HTML Validator (1 per example): «Element tags not allowed as child of element div in this context. (Suppressing further errors from this subtree.)». Thanks for taking a look.
-
C\Field\Tag::withSortable(): please rename this method towithIsSortable(). This way it's' clear we are talking about a boolean state. (adjust getter as well) -
C\Field\Tagsetters: please useselforstaticfor their return types. -
C\Field\Taggetters: please remove them from the public interface.
Since these changes do not affect the public interface greatly, we already label this for presentation at next JF.
If you have any questions about something in this review, please contact us.
|
Jour Fixe, 21 JUL 2025: We highly appreciate the suggested extension of the tag input and accept it for trunk. |
|
Thank you very much for your review. I went through the different points and fixed things with . Here are a few remarks:
Yeah, sorry, forgot to change the beginning of the text. Fixed
Yes, this actually uses an interface offered by the library (See), but it did not respect
I do not really have an much of an opinion on this. I think there is some information there, as it points you to the place were you can enable/disable it. I think the place in "purpose" is neither completely wrong nor completely correct, but I think it can be explained why the information is there. I can remove it (then I would suggest to remove the whole sentence "Besides the tags to choose..."), if you want me to.
I would personally suggest to stick with this approach. I can imagine that we would add a second parameter to
The
I removed all getters, I personally always thought they were wrong, but with this we are actually breaking the rules: "Put getters for all properties on your interface." see. I assume you are now going to take a deeper look at the implementation, right? As soon as we agree on the implementation details, I will take care of tests, rebasing, and so on. Thanks again and best, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @kergomard,
As you mentioned in #9941, you will take over @nhaagen's PR and incorporate the relevant changes to address the Mantis issue, adopt the PHPUnit tests and implement a JavaScript unit tests to cover this issue inside your new structure yourself. According todo's will be added in this review.
During the technical review of this PR, we have noticed that most of our remarks regard the ordering-feature, not the autocomplete one. We therefore suggest to move the ordering-feature into a separate PR, where we can discuss these remarks separately. An according todo will be added to the review as well.
About the concrete changes, please answer the following questions:
- Custom HTML tags: you mentioned that the custom HTML elements, which are invalid, require an upstream fix. We are confused, because the
<tag>and<x>elements are added in your JavaScript code as a template forTagify. Could you explain what you meant with upstream fix, and why we cannot simply change these elements to e.g.<div>?
Please consider the following suggestions. You do not need to follow them, but please indicate shortly why you prefer to do otherwise:
-
@yaireo/tagifymodule: you can importTagifyfrom the node-module. However, we are currently missing the Dependency to include such imports properly into ourrollupbundles. If #10059 is merged before this, you may incorporate this change, if not, we will do it afterwards. -
UI\URLBuilder: convention, regarding the query parameter, is fine for the time being. However, we would like to utilise theUI\URLBuildermore strongly. If this change is too much, feel free to add this to our roadmap instead. The idea was to change the method signature of/toField\Tag::withAsyncAutocomplete(URLBuilder $url_builder, URLBuilderToken $term_parameter): selfand incorporate the URL-builder (PHP and JS) for building the target URL of the autocomplete endpoint. You can take a look at how the data table utilises this mechanism for its actions.
Please implement the following changes:
-
tagAutocompleteTriggerTimeout(tag.js:19): please include this value inside theI\Field\Tag::getConfiguration()for now. I can imagine that this value may vary depending on the use-case of the tag input, or even on server response time. This will allow for easy modification/configuration later on. Please also incorporate some information about the unit of this value into the name of the constant (i.e. ms). -
retrieveAutocomplete()(tag.js:92): why do you wrap things inside thiscontextobject? Please pass these things as dedicated parameters, or declare them e.g. as an outer-scope variable inside your module - if this is shared. - Probable bug: the
context.timeout.signalshould probably becontext.controller.signal, the other value is an integer. -
il.UI.Input.tagInput(input.factory.js:40): the previous functionality was exposed in this namespace. To make sure we don't cause any breaking changes somewhere, please stick to the old property name. -
il.UI.Input.tagInput.getTagifyInstance()(input.factory.js): this method was removed. Please make sure you expose this function and hereby access to theTagifyinstances. - Mantis issue I: please pick the relevant changes of @nhaagen's PR to address the issue mentioned above. Make sure to pick the PHPUnit test as well.
- Mantis issue II: please implement a JavaScript unit test which covers the issue mentioned above, so it fits your new structure.
- Ordering-feature: please move these changes to a separate PR. We can skip to the technical review immediately, once you opened it.
- Unit tests: please implement some PHP (see our new-ish guidelines) and JavaScript unit tests.
Kind regards,
5b8c993 to
3b5f9bf
Compare
|
Thank you very much for the review @thibsy, @thibsy and @yvseiler
You are right, I didn't even think about that. We now override all custom tags with
If I'm being honest with you, I think this is really wrong as we are now back to an unnecessary book-keeping and handing out instances of Tagify directly which really ties us closely to this implementation. I implemented this, but I would kindly ask you to reconsider. I didn't find anywhere where this was used in core right now.
I hope I changed this as you expected it. I needed to move creating the
I tried to implement something but failed miserably as Best, |
e1fa444 to
dab5dfc
Compare
|
Hi @thibsy Thank you very much for the hint on the tests! I first had the same idea to mock "Tagify", but then gave up on it, when I thought it all too complicated. I now added a few js-tests, and moved to importing the node module. Sorry for the force push, there was no way around it. Looking forward to the review, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @kergomard,
Thx for splitting up the PR and implementing the requested changes, especially the UI\URLBuilder part :).
The PR became much easier to review now, so I might have found some nitpicks after all. I added them to this iteration of the review.
About the concrete changes, please answer the following questions:
-
UI\URLBuilder: It looks like I imagined. However, I am not quite sure what you mean by "I needed to move creating the URLBuilder and the URLBuilderToken out of the JSON". Which JSON? Could you elaborate? (And JF should be notified about the interface change, yes, but since it's minimal we can do this after merge.) -
@yaireo/tagifymodule: #10059 has been merged. It would be great if you could give this a try. The procedure should be documented.
Please consider the following suggestions. You do not need to follow them, but please indicate shortly why you prefer to do otherwise:
-
il.UI.Input.tagInput.getTagifyInstance()(input.factory.js): I am actually with you on this; I could not find usages of this function in core, so I am fine with removing it. I'll leave it up to you, since you implemented it already.
Please implement the following changes:
-
typeofchecks: please replace these 3 checks either by positiveinstanceofchecks or by strict-comparisons against their actual possible values. - JSDoc: there are some JSDoc annotations:
-
tag.js:26should also beundefined -
tag.js:30should also beundefined -
tag.js:35should bestring, and a*is missing on34 -
tag.js:102returns for void should be omitted -
tag.js:156should beHTMLInputElement -
tag.js:156should beArray(capital A) -
tag.js:159andtag.js:160should also beundefined
-
-
tag.js:20: please make this aMapinstead. - JS tests: I gave you some directions in kergomard#5, hope this helps.
|
P.S. the examples are not working because of the problems you outlined in #10043. Applying the PR makes the examples usable again. I'll try to look into this soon. |
|
Thank you very much for the review @thibsy !
Sorry for not being clear on this: The problem is, that up to this point the URL was handed in as part of the parameter config that was a JSON encoded in PHP. This does not work with the Endpoint and the Token, so I had to move them out of the config even if they could be seen as part of the configuration. I think the current solution is correct, though.
I had separated this in one commit to make things easier, if you agreed with me. It is reverted.
I was able to replace the AbortController. I think that works, but I didn't find a solution for the other two tests.
This was removed when the commit was reverted. Thanks again and best, |
thibsy
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thx a lot @kergomard for implementing the changes. !== undefined is fine. Everything should be in order now. I will merge after JF this afternoon.
|
Jour Fixe, 13 OCT 2025: We accept the additional change of the PR as described above for trunk. |
Hi all
This PR contains a proposal to add the options to the tag-input to
I added bot option in one PR as this allowed me to keep it functional while working on it without having to move changes to the basic js-code forth and back. The two parts an in separate commits. We can split this up again, if needed.
The changes to the interface are rather small adding only four functions (
withAsyncAutocomplete,getAsyncAutocomplete,withOrderable,getOrderable- see)The implementation for the async autocomplete is also rather straight forward. Compared to the current implementation for the autocomplete text fields it does NOT allow to add a "more" option, so all possible entries need to be loaded at once. This is due to limitations in
Tagify.The implementation for sortable is more interesting as it contains many decisions that can also be taken very differently. The main point that need discussion from my point of view (there are surely more):
draggableto the framework. Draggable aims to be as generic as possible, while implementing as much logic as it can.draggableis right now implemented as a single function containing the whole logic. This could also be done as a class, but as most of what happens in there is bound to event-handlers we would always need to bindthisto a variable to be able to access it inside the handler-functions. This is also a possibility and I can rewrite this rather easily, if you want me to. In a first step I decided against it, as we would also need to assign the class to a variable (most probably an array) and we never need it again.draggableis rather complex, as it needs to handle three scenarios: We might be on a client that supports the draggable facility (i.e. we have a mouse), we might be on a touch client, or we might be operating the operation by keyboard. I tried to implement a solution for all of those. I also tried to implement a solution for people depending on a screen reader.There are no tests contained, I will take care of those once we are clear if this is what we want and what the implementation is really going to look like.
What the async autocomplete looks like:
Bildschirmaufzeichnung vom 2025-05-06 14-36-23.webm
What sorting looks like:
Bildschirmaufzeichnung vom 2025-05-06 14-36-58.webm
Thank you very much and best,
@kergomard