I am engineering a custom autocomplete
type for the afQuickfield
in my Meteor project. The issue I am having is that when I set the type="autocomplete"
on the afQuickfield
, the class="form-control"
attribute is missing. For all other field types, it is included.
I grepped form-control
across the entire codebases for meteor-autoform
as well as the scss
and js
directories of the bootstrap
library. I only see occurances in the changelog and class definitions in scss/css.
I could just include class="form-control"
in the afQuickfield
definition, but that's a monkey patch and I'm not a fan of cutting corners.
Can anyone help me understand how form-control
gets assigned in autoForm
fields?
Here's my custom autocomplete
code (it's a WIP, so no judging!). I'm just hoping to start with a text element with the proper atts
so I can build from there.
// autocomplete.js
AutoForm.addInputType('autocomplete', {
template: 'afAutocomplete',
valueOut: function () {
return this.val()
},
valueConverters: {
stringArray: AutoForm.valueConverters.stringToStringArray,
number: AutoForm.valueConverters.stringToNumber,
numberArray: AutoForm.valueConverters.stringToNumberArray,
boolean: AutoForm.valueConverters.stringToBoolean,
booleanArray: AutoForm.valueConverters.stringToBooleanArray,
date: AutoForm.valueConverters.stringToDate,
dateArray: AutoForm.valueConverters.stringToDateArray
},
contextAdjust: function (context) {
context.atts.autocomplete = 'off'
return context
}
})
// autocomplete.html
<template name="afAutocomplete">
<input type="text" value="{{this.value}}" {{this.atts}} />
</template>
Here's the code from the type="text"
field for comparison.
// text.js
AutoForm.addInputType('text', {
template: 'afInputText',
valueOut: function () {
return this.val()
},
valueConverters: {
stringArray: AutoForm.valueConverters.stringToStringArray,
number: AutoForm.valueConverters.stringToNumber,
numberArray: AutoForm.valueConverters.stringToNumberArray,
boolean: AutoForm.valueConverters.stringToBoolean,
booleanArray: AutoForm.valueConverters.stringToBooleanArray,
date: AutoForm.valueConverters.stringToDate,
dateArray: AutoForm.valueConverters.stringToDateArray
},
contextAdjust: function (context) {
if (typeof context.atts.maxlength === 'undefined' && typeof context.max === 'number') {
context.atts.maxlength = context.max
}
return context
}
})
// text.html
<template name="afInputText">
<input type="text" value="{{this.value}}" {{this.atts}}/>
</template>
As you can see the two are practically identical, yet the autocomplete version is without the form-control
class in the actual HTML output.
Any ideas?
Actually this seems to be a follow-up bug from AutoForm
, because it should already throw the following error, when including afInputText
:
There are multiple templates named 'afInputText'. Each template needs a unique name
form-control
?This is correct in itself, because there is no class
attribute on the input
within the afAutoComplete
template.
AutoForm built-in input types have no class attributes, because they will be overridden by the themes.
For example the text
input in the Bootstrap 4 theme looks currently like this:
<template name="afInputText_bootstrap4">
<input type="text" value="{{this.value}}" {{attsPlusFormControlClass}}/>
</template>
which itself is defined as helper.
Since there may be one day, where you will move from Bootstrap 4 to Bootstrap 5 you can actually create your component + logic as defined above:
// autocomplete.js
AutoForm.addInputType('autocomplete', {
template: 'afAutocomplete',
valueOut: function () {
return this.val()
},
valueConverters: {
stringArray: AutoForm.valueConverters.stringToStringArray,
number: AutoForm.valueConverters.stringToNumber,
numberArray: AutoForm.valueConverters.stringToNumberArray,
boolean: AutoForm.valueConverters.stringToBoolean,
booleanArray: AutoForm.valueConverters.stringToBooleanArray,
date: AutoForm.valueConverters.stringToDate,
dateArray: AutoForm.valueConverters.stringToDateArray
},
contextAdjust: function (context) {
context.atts.autocomplete = 'off'
return context
}
})
// autocomplete.html
<template name="afAutocomplete">
<input type="text" value="{{this.value}}" {{this.atts}} />
</template>
and additionally create a separate template, that overrides the styling:
<template name="afAutocomplete_bootstrap4">
<input type="text" class="form-control" value="{{this.value}}" {{attsPlusFormControlClass}} />
</template>
Important here is the combination of afAutocomplete
and _bootstrap4
which is used by AutoForm to determine the current template, as long as either the default template is set to bootstrap4
or the current form uses bootstrap4
as theme.