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

Allow autoComplete to use a select as source of suggestions #709

Merged
merged 1 commit into from
Nov 28, 2016

Conversation

adamliptrot-oc
Copy link
Contributor

No description provided.

Copy link
Contributor

@feedmypixel feedmypixel left a 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(){
Copy link
Contributor

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

Copy link
Contributor Author

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?

Copy link
Contributor

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") + '"]');
}
Copy link
Contributor

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.

Copy link
Contributor Author

@adamliptrot-oc adamliptrot-oc Nov 17, 2016

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.

Copy link
Contributor

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;
Copy link
Contributor

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){
Copy link
Contributor

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

Copy link
Contributor Author

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(){
Copy link
Contributor

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}}"
Copy link
Contributor

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)

@adamliptrot-oc
Copy link
Contributor Author

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.

@feedmypixel
Copy link
Contributor

@adamliptrot-oc Your PR has gone slightly off in an unexpected direction.

So we now have two ways of instantiating an autoComplete:
• There is the current way of instantiating an autoComplete and passing in the variables as shown for the country example.
• Your way of sending in countries and $countryCodeInput via data- attributes.

I like the way of sending in these details via data- attributes rather than specifying them in autoCompleteFactory.js. So to be backwardly compatible your PR needs to instantiate an autoComplete that picks these arguments via data-attributes but also caters for the current way of passing these data attributes in.
The countryCode instantiation in autoCompleteFactory.js can be left untouched.

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")];
Copy link
Contributor

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;
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

@feedmypixel feedmypixel Nov 24, 2016

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done:
#716

}
}
return target;
};
Copy link
Contributor

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"
Copy link
Contributor

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 () {
Copy link
Contributor

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

Copy link
Contributor Author

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.

Copy link
Contributor

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") + '"]');
Copy link
Contributor

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 () {
Copy link
Contributor

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done #721

@feedmypixel
Copy link
Contributor

feedmypixel commented Nov 28, 2016

LGTM 👍 - before merge please squash your commits into sensible commits, there feels like a lot of W.I.P commits here

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

Successfully merging this pull request may close these issues.

2 participants