Skip to content
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

Entering value not in the source allows submission #587

Open
NikhilNanjappa opened this issue Mar 27, 2023 · 15 comments
Open

Entering value not in the source allows submission #587

NikhilNanjappa opened this issue Mar 27, 2023 · 15 comments

Comments

@NikhilNanjappa
Copy link

NikhilNanjappa commented Mar 27, 2023

Hi guys,

Good job on the module. Love it!

Just an issue I noticed and wondering if there was any workaround - Currently the user can enter any garbage value in the autocomplete input (which obviously doesnt exist in the source) and they can go ahead without any validations. I was wondering if there should be anyway to stop them from doing that ?

Real world scenario: If they search for a country "abcde", it shouldn't allow them to pass to the next page as they haven't selected any country.

PS: I'm using the accessibleAutocomplete.enhanceSelectElement version

@edwardhorsford
Copy link
Contributor

@NikhilNanjappa GOV.UK services typically only do server side validation - they don't prevent users submitting invalid answers. As such, this project has nothing built in for what you're asking.

However, you could write your own js to do something, hooking in to the onConfirm callback.

1 similar comment
@edwardhorsford
Copy link
Contributor

@NikhilNanjappa GOV.UK services typically only do server side validation - they don't prevent users submitting invalid answers. As such, this project has nothing built in for what you're asking.

However, you could write your own js to do something, hooking in to the onConfirm callback.

@NikhilNanjappa
Copy link
Author

NikhilNanjappa commented Mar 27, 2023

Thanks @edwardhorsford .

What I'm planning to do is render all the options on the server side and use the accessibleAutocomplete to filter down from the options as the user types. However, I see this on the docs

If your autocomplete is meant to select from a small list of options (a few hundred), we strongly suggest that you render a <select> menu on the server

Which is suggesting that a larger list of options should be done on the client side. I have around 1600 options and was wondering why is it bad to render a large list of options on the server side ? For larger options, isn't it actually better to do it server side rather than hit an endpoint that returns 1600 results on the client side. Is there something i'm missing ?

@edwardhorsford
Copy link
Contributor

@NikhilNanjappa I think what that's trying to say is that for smaller sets of options, it recommends rendering a select server side and delivering that in your page - and then enhance that with this component. And for larger lists of options where the list is longer than you'd be comfortable in a select or for the page weight, use ajax to request results as the user types. If you're using progressive enhancement, you'd then need some means for users to make selections if javascript isn't available.

1600 might be fine for a select - I'd probably have a look at what it does to your page weight and performance, etc.

In my service, we've got one list to query of ~40k results - for that we use ajax to request results as users type.

@NikhilNanjappa
Copy link
Author

NikhilNanjappa commented Mar 27, 2023

I see ... thanks for sharing your example @edwardhorsford . That number might increase a lot in the future so want to future proof it if possible.

I was stuck between whether to call an endpoint once to get all ~1600 results or call endpoint multiple times whenever user types. Have you by any chance made any comparison in terms of performance between these 2 approaches ?

PS: I'm leaning to the 2nd option of calling as user types as there is no need to fetch all the results for every user. I'm using ajax to call my node endpoint which in turn calls my backend java endpoint to fetch the results. I do this because we cannot hit the java endpoints directly from the browser.

@edwardhorsford
Copy link
Contributor

@NikhilNanjappa I don't see the point of calling an endpoint purely to return all results. If you're going to do that, you might as well just render the page with all the options in the select. 1600 likely isn't so big. If you were in the 10k+ I think you might want to look at continued calls.

If it helps, here's our ajax implementation. Our autocomplete is set up with a min length of 2, so we only call the server once at least two characters are returned. Our server then does the search, orders the results appropriately, truncates if there's too many results, and then returns this to the autocomplete.

@NikhilNanjappa
Copy link
Author

Thanks for the link @edwardhorsford .

Are you guys handing the validation if users submits some garbage value and it doesn’t match any results? (the scenario i raised this issue for)

@edwardhorsford
Copy link
Contributor

@NikhilNanjappa We wrote two blog posts specifically about this school search:

Part 2 covers what you're asking. For this school search, we consider this to be enhancing a free text search, rather than picking from a constrained set of options. So typing garbage isn't an error, it's just a search that will return zero results. In essence, we treat it the same as our no-javascript flow, which is to revert to a server side search and then returning the user to a page of results. In the scenario you describe, there would be zero results.

In some of our other autocompletes (the non ajax ones), we'll return the user back to the form with errors highlighted. Example:

Screenshot 2023-03-27 at 16 58 58

@NikhilNanjappa
Copy link
Author

NikhilNanjappa commented Mar 27, 2023

We are not doing the non-JS flow as of now so I can ignore that part (not recommended and progressive I know but hey-ho)

Just so I got it right for a client-side autocomplete - you make the ajax request when user types and on the same form POST, on server side, you call the lookup endpoint again & throw validation if results are zero ?

Sorry. If client-side JS was allowed, it wasnt clear how you validated invalid search values on an autocomplete.

@edwardhorsford
Copy link
Contributor

I don't think we're necessarily calling the same lookup endpoint - but the rest sounds about right - the entire form is POSTed to the server, and this is validated as normal. For the items above, I think what gets sent is a UUID. So we can validate if that's for a real item. If instead we get a string, we do check if that caselessly matches an item.

@NikhilNanjappa
Copy link
Author

NikhilNanjappa commented Mar 27, 2023

Thanks for all the help @edwardhorsford

@NikhilNanjappa
Copy link
Author

NikhilNanjappa commented Jun 12, 2023

Hi @edwardhorsford - Sorry for the sudden ping. Just had a quick question on the code you mentioned earlier.

Just wanted to understand why you had a separate text field next to the autocomplete-wrapper (which renders its own text field) and moving the autocomplete-wrapper into the form-group which already contains your text-input.

I wanted to mimic your approach so just wanted to understand it

@edwardhorsford
Copy link
Contributor

@NikhilNanjappa Afraid I don't know - I didn't directly work on this code. I guess the main thing is that when using the 'enhanceSelectElement' mode, you'll have a select submitting data (which might be wrong!) and you also want to submit the current text value of the input.

I have a vague idea / memory another input may have been needed to correctly deal with some edge cases, possibly around returning to the form with data pre-populated.

@NikhilNanjappa
Copy link
Author

Thanks @edwardhorsford . I actually wanted the field error message, highlight, field error border etc when validation fires up.

Any idea how you managed to do that ? As the default auto complete doesn’t highlight the field on error.

@edwardhorsford
Copy link
Contributor

I'm afraid I don't. But you could perhaps look at how it's done in our repo, as I know our validations work fine. Screenshot attached.

Screenshot 2023-06-13 at 12 22 55

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants