-
Notifications
You must be signed in to change notification settings - Fork 64
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
Allow autoComplete to use a select as source of suggestions #709
Conversation
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.
@adamliptrot-oc Good work and some nice backward compatibility guarding. Overall you have work in the factory which can be moved inside the autoComplete.js
file. Also please update documentation here and here
var suggestionDisplayTemplate = function (title, value) { | ||
return title + ' (+' + value + ')'; | ||
}; | ||
$('.js-choose-country-auto-complete').each(function(){ |
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.
Is this to allow multiple AutoCompletes
? or just a different way of running the code if the element exists? I would be wary of enabling multiples
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.
It was yes, so we enforce one instance per page?
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.
how are you going to handle multiple autoCompletes with different data? Not sure how wonderful a page with 2 autoCompletes would look! ;) I would call YAGNI on this
$countryCodeInput = $('#countryCode'); | ||
} else { | ||
$countryCodeInput = $('[id="' + $(this).attr("data-suggestions") + '"]'); | ||
} |
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.
so data-suggestions
is used for validation here and the $countryCodeInput
is used as the $targetInputElem
described here
So with those explanations (data-suggestions
validation needs documenting) I think you would agree it feels a bit mixed up whats going on here.
What you are wanting to say is target your select. This "target" element should be sent in via a new data-
.
For backwards compatibility you need to keep the $countryCodeInput
work (as you have done) but I would move this check inside the autoComplete.js
file here Then you can check to see if it is an element or a string and do the appropriate.
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.
I wanted to allow $countryCodeInput to be definable from the view as it is currently hard-coded in the factory. If the ID is already defined in the view (or the list is not one of countries) we need to allow this (using a defined ID also restricts instance use).
Agree that if data-suggestions is used elsewhere for validation I need to separate out my added functionality to make it clearer - didn't realise that integration was there. I had done this originally but decided to re-use the data-suggestions attribute as it seemed un-used. Will update.
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.
I wanted to allow $countryCodeInput to be definable from the view as it is currently hard-coded in the factory. If the ID is already defined in the view (or the list is not one of countries) we need to allow this (using a defined ID also restricts instance use).
Agreed. So I think we are saying the same thing here. Send in the $countryCodeInput
via a data attribute. The #countryCode
just needs to be kept for backwards compatibility.
I see a future bit of work to remove the #countryCode
selector from the Js
and move it into the data-
attribute in the view for services who have not refactored to the data-
way.
As said above for this check it doesn't feel right to have it in the factory, this can also go into the autoComplete.js
return title + ' (+' + value + ')'; | ||
}; | ||
|
||
var suggestions; |
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.
Please place vars at the top of a function due to hoisting
}; | ||
|
||
var suggestions; | ||
if($('select[id="' + $(this).attr("data-suggestions") + '"]').length > 0){ |
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.
so you are building suggestions from the target element. This also feels like it shouldn't be in the factory it should be internal in the autoComplete.js
file.
So I would make the second argument suggestions
accept either a string or an object. If a string get that element, if an object do what you currently do. I would also abstract the work of greating suggestion into a high level function for self documentation createSuggestionsFromSelect
for instance
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.
Sounds good
var suggestions; | ||
if($('select[id="' + $(this).attr("data-suggestions") + '"]').length > 0){ | ||
suggestions = []; | ||
$('[id="' + $(this).attr("data-suggestions") + '"]').find('option').each(function(){ |
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.
you can cache a few selector calls here into variables
@@ -18,7 +18,7 @@ Auto complete html markup: | |||
autocomplete="off" | |||
spellcheck="false" | |||
required | |||
data-suggestions="countries" | |||
data-suggestions="{{OPTIONAL: id of select input to use as suggestions source}}" |
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.
this data-suggestions
attribute is used for validation purposes here (needs documenting)
Just updated the autoComplete, moving most of the config into the main file as it can deduce most of it from the element's attributes. |
@adamliptrot-oc Your PR has gone slightly off in an unexpected direction. So we now have two ways of instantiating an autoComplete: I like the way of sending in these details via Have a read through the comments I have added on the original PR and lets have a hangout to confirm the direction. |
suggestions = countries; | ||
} else { | ||
// allow custom variable | ||
suggestions = window[el.attr("data-suggestions")]; |
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.
I would avoid muddying the waters here, data-suggestions
is for validation only if you wish to have a way of sending in a global then create a new data-
attribute and make this backwardly compatible with the suggestionsData
argument
// need to populate the data-suggestions attribute from this for validation | ||
// generate a global variable to hold the data and insert into data-suggestions attribute | ||
var r = randomVariableName(); | ||
window[r] = suggestions; |
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.
I'm not sure why this needs to be exposed as a global?
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.
As the validator expects a global. Agreed this could be changed but it is outside the scope of this PR and can be picked up in a separate one.
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.
agreed, please capture this by raising an issue around this work
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.
Done:
#716
} | ||
} | ||
return target; | ||
}; |
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.
I think my comment has been misunderstood. Keep the original instantiation and in the autoCompleteFactory.js
and inside of autoComplete.js
check if the argument is an element, if not then check the data-linked
attribute
Then you can check to see if it is an element or a string and do the appropriate.
data-suggestions="countries" | ||
// or specify a select input ID to act as source of data: | ||
data-linked="mySelectID" |
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.
data-linked
doesn't means anything to me? data-select-elem
?
/** | ||
* Generate random variable name to ensure no conflicts | ||
*/ | ||
var randomVariableName = function () { |
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.
we don't need this randomVariableName
functionality right? just place it on window.suggestions
and at the moment we don't support 2x autoCompletes on the same page. As discussed the placing this on window
will be removed in future work
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.
I'd prefer not to use anything which could possibly be a conflict in the global space, so I think this should stay until the additional future work to remove the global object is completed.
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.
IMO guarding against a conflict with creating a random global variable is hiding the issue away from the developer. If the global is being overridden due to a variable of the same name already existing the code shouldn't abstract that away and guard for it, the developer should change the name of the global to fix the problem at the source.
var getTargetInput = function (el) { | ||
var target; | ||
// input to post back a selection from the autocomplete | ||
var dataPostTo = $('[id="' + el.attr("data-post-to") + '"]'); |
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.
data-target-elem
feels a little bit more descriptive when looking at it in the html. data-post-to
feels a bit POST
form'y ... thoughts?
@@ -2,18 +2,28 @@ require('jquery'); | |||
var autoComplete = require('./autoComplete.js'); | |||
|
|||
var createAutoCompleteCountries = function () { |
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.
want to also add an issue around removing this deprecated work? and playing any html updates in service frontends?
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.
Done #721
LGTM 👍 - before merge please squash your commits into sensible commits, there feels like a lot of W.I.P commits here |
generated from commit 329c37b
No description provided.