switched es6 structurally to generate a wrapping .mdb-form-group instead of altering anything with the BS .form-group in an attempt to avoid any side effects to margin/padding/spacing since we only need it to be a marker div.

This commit is contained in:
Kevin Ross 2015-12-05 18:55:29 -06:00
parent 108da48a0b
commit f7f064dff4
6 changed files with 94 additions and 31 deletions

View File

@ -107,12 +107,23 @@ class Application {
.tooltip('_fixTitle') .tooltip('_fixTitle')
}) })
} }
fixMissingFormGroups() {
//let selectors = [
// '#search-input',
// `input.form-control[placeholder='Readonly input here…']`
//]
//for( let selector of selectors){
// $(selector).parent().wrapInner(`<div class='form-group'></div>`)
//}
}
} }
$(() => { $(() => {
let app = new Application() let app = new Application()
app.displayTypographyProperties() app.displayTypographyProperties()
app.initializeClipboard() app.initializeClipboard()
app.fixMissingFormGroups()
// $.bootstrapMaterialDesign() // $.bootstrapMaterialDesign()
$('body').bootstrapMaterialDesign() $('body').bootstrapMaterialDesign()
}) })

View File

@ -4,7 +4,10 @@ const BaseInput = (($) => {
const Default = { const Default = {
formGroup: { formGroup: {
template: `<div class='form-group'></div>`, required: true
},
mdbFormGroup: {
template: `<div class='mdb-form-group'></div>`,
required: true, required: true,
autoCreate: true autoCreate: true
}, },
@ -15,12 +18,15 @@ const BaseInput = (($) => {
const ClassName = { const ClassName = {
FORM_GROUP: 'form-group', FORM_GROUP: 'form-group',
MDB_FORM_GROUP: 'mdb-form-group',
HAS_ERROR: 'has-error', HAS_ERROR: 'has-error',
IS_EMPTY: 'is-empty' IS_EMPTY: 'is-empty',
IS_FOCUSED: 'is-focused'
} }
const Selector = { const Selector = {
FORM_GROUP: `.${ClassName.FORM_GROUP}` //, FORM_GROUP: `.${ClassName.FORM_GROUP}`,
MDB_FORM_GROUP: `.${ClassName.MDB_FORM_GROUP}`
} }
const FormControlSizeConversions = { const FormControlSizeConversions = {
@ -48,12 +54,13 @@ const BaseInput = (($) => {
// Enforce required classes for a consistent rendering // Enforce required classes for a consistent rendering
this._rejectWithoutRequiredClasses() this._rejectWithoutRequiredClasses()
if (this.config.formGroup.autoCreate) { if (this.config.mdbFormGroup.autoCreate) {
// Will create form-group if necessary // Will create form-group if necessary
this.autoCreateFormGroup() this.autoCreateMdbFormGroup()
} }
// different components have different rules, always run this separately // different components have different rules, always run this separately
this.$mdbFormGroup = this.findMdbFormGroup(this.config.mdbFormGroup.required)
this.$formGroup = this.findFormGroup(this.config.formGroup.required) this.$formGroup = this.findFormGroup(this.config.formGroup.required)
this._convertFormControlSizeVariations() this._convertFormControlSizeVariations()
@ -65,7 +72,7 @@ const BaseInput = (($) => {
dispose(dataKey) { dispose(dataKey) {
$.removeData(this.$element, dataKey) $.removeData(this.$element, dataKey)
this.$element = null this.$element = null
this.$formGroup = null this.$mdbFormGroup = null
this.config = null this.config = null
} }
@ -119,38 +126,38 @@ const BaseInput = (($) => {
} }
addFormGroupFocus() { addFormGroupFocus() {
this.$formGroup.addClass(ClassName.IS_FOCUSED) this.$mdbFormGroup.addClass(ClassName.IS_FOCUSED)
} }
removeFormGroupFocus() { removeFormGroupFocus() {
this.$formGroup.removeClass(ClassName.IS_FOCUSED) this.$mdbFormGroup.removeClass(ClassName.IS_FOCUSED)
} }
addHasError() { addHasError() {
this.$formGroup.addClass(ClassName.HAS_ERROR) this.$mdbFormGroup.addClass(ClassName.HAS_ERROR)
} }
removeHasError() { removeHasError() {
this.$formGroup.removeClass(ClassName.HAS_ERROR) this.$mdbFormGroup.removeClass(ClassName.HAS_ERROR)
} }
addIsEmpty() { addIsEmpty() {
this.$formGroup.addClass(ClassName.IS_EMPTY) this.$mdbFormGroup.addClass(ClassName.IS_EMPTY)
} }
removeIsEmpty() { removeIsEmpty() {
this.$formGroup.removeClass(ClassName.IS_EMPTY) this.$mdbFormGroup.removeClass(ClassName.IS_EMPTY)
} }
isEmpty() { isEmpty() {
return (this.$element.val() === null || this.$element.val() === undefined || this.$element.val() === '') return (this.$element.val() === null || this.$element.val() === undefined || this.$element.val() === '')
} }
// Find or create a form-group if necessary // Find or create a mdb-form-group if necessary
autoCreateFormGroup() { autoCreateMdbFormGroup() {
let fg = this.findFormGroup(false) let fg = this.findMdbFormGroup(false)
if (fg === null || fg.length === 0) { if (fg === undefined || fg.length === 0) {
this.outerElement().wrap(this.config.formGroup.template) this.outerElement().wrap(this.config.mdbFormGroup.template)
} }
} }
@ -160,11 +167,20 @@ const BaseInput = (($) => {
return this.$element return this.$element
} }
// Find expected form-group // Find mdb-form-group
findMdbFormGroup(raiseError = true) {
let mfg = this.$element.closest(Selector.MDB_FORM_GROUP)
if (mfg.length === 0 && raiseError) {
$.error(`Failed to find ${Selector.MDB_FORM_GROUP} for ${Util.describe(this.$element)}`)
}
return mfg
}
// Find mdb-form-group
findFormGroup(raiseError = true) { findFormGroup(raiseError = true) {
let fg = this.$element.closest(Selector.FORM_GROUP) // note that form-group may be grandparent in the case of an input-group let fg = this.$element.closest(Selector.FORM_GROUP)
if (fg.length === 0 && raiseError) { if (fg.length === 0 && raiseError) {
$.error(`Failed to find form-group for ${Util.describe(this.$element)}`) $.error(`Failed to find ${Selector.FORM_GROUP} for ${Util.describe(this.$element)}`)
} }
return fg return fg
} }
@ -210,7 +226,7 @@ const BaseInput = (($) => {
for (let inputSize in FormControlSizeConversions) { for (let inputSize in FormControlSizeConversions) {
if (this.$element.hasClass(inputSize)) { if (this.$element.hasClass(inputSize)) {
this.$element.removeClass(inputSize) this.$element.removeClass(inputSize)
this.$formGroup.addClass(FormControlSizeConversions[inputSize]) this.$mdbFormGroup.addClass(FormControlSizeConversions[inputSize])
} }
} }
} }

View File

@ -9,6 +9,9 @@ const BaseToggle = (($) => {
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
*/ */
const Default = { const Default = {
formGroup: {
required: false
}
} }
const Selector = { const Selector = {
@ -48,12 +51,9 @@ const BaseToggle = (($) => {
Util.assert(this.outerElement().hasClass(this.outerClass), `${this.constructor.name}'s ${this.$element} grandparent element should have class .${this.outerClass}.`) Util.assert(this.outerElement().hasClass(this.outerClass), `${this.constructor.name}'s ${this.$element} grandparent element should have class .${this.outerClass}.`)
} }
// ------------------------------------------------------------------------
// protected
addFocusListener() { addFocusListener() {
// checkboxes didn't appear to bubble to the document, so we'll bind these directly // checkboxes didn't appear to bubble to the document, so we'll bind these directly
this.$formGroup.find(Selector.LABEL).hover(() => { this.$mdbFormGroup.find(Selector.LABEL).hover(() => {
this.addFormGroupFocus() this.addFormGroupFocus()
}, () => { }, () => {
this.removeFormGroupFocus() this.removeFormGroupFocus()

View File

@ -47,6 +47,9 @@ const BootstrapMaterialDesign = (($) => {
checkbox: { checkbox: {
selector: '.checkbox > label > input[type=checkbox]' selector: '.checkbox > label > input[type=checkbox]'
}, },
//checkboxInline: {
// selector: 'label.checkbox-inline > input[type=checkbox]'
//},
switch: { switch: {
selector: '.switch > label > input[type=checkbox]' selector: '.switch > label > input[type=checkbox]'
}, },

View File

@ -18,7 +18,14 @@ const File = (($) => {
const DATA_KEY = `mdb.${NAME}` const DATA_KEY = `mdb.${NAME}`
const JQUERY_NO_CONFLICT = $.fn[NAME] const JQUERY_NO_CONFLICT = $.fn[NAME]
const Default = {
formGroup: {
required: false
}
}
const ClassName = { const ClassName = {
FILE: NAME,
IS_FILE: 'is-file' IS_FILE: 'is-file'
} }
@ -34,9 +41,9 @@ const File = (($) => {
class File extends BaseInput { class File extends BaseInput {
constructor(element, config) { constructor(element, config) {
super(element, $.extend({invalidComponentMatches: [Checkbox, Radio, Text, Textarea, Select, Switch]}, config)) super(element, $.extend({invalidComponentMatches: [Checkbox, Radio, Text, Textarea, Select, Switch]}, Default, config))
this.$formGroup.addClass(ClassName.IS_FILE) this.$mdbFormGroup.addClass(ClassName.IS_FILE)
} }
dispose() { dispose() {
@ -57,12 +64,20 @@ const File = (($) => {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// protected // protected
// Demarcation element (e.g. first child of a form-group)
outerElement() {
// label.file > input[type=file]
return this.$element
}
rejectWithoutRequiredStructure() { rejectWithoutRequiredStructure() {
// FIXME: implement this once we determine how we want to implement files since BS4 has tried to take a shot at this // label.file > input[type=file]
Util.assert(this.outerElement().prop('tagName') === 'label', `${this.constructor.name}'s ${Util.describe(this.$element)} parent element ${Util.describe(this.outerElement())} should be <label>.`)
Util.assert(this.outerElement().hasClass(ClassName.FILE), `${this.constructor.name}'s ${Util.describe(this.$element)} parent element ${Util.describe(this.outerElement())} should have class .${ClassName.FILE}.`)
} }
addFocusListener() { addFocusListener() {
this.$formGroup this.$mdbFormGroup
.on('focus', () => { .on('focus', () => {
this.addFormGroupFocus() this.addFormGroupFocus()
}) })
@ -84,7 +99,7 @@ const File = (($) => {
} else { } else {
this.addIsEmpty() this.addIsEmpty()
} }
this.$formGroup.find(Selector.FILENAMES).val(value) this.$mdbFormGroup.find(Selector.FILENAMES).val(value)
}) })
} }

View File

@ -19,6 +19,9 @@ const Text = (($) => {
const JQUERY_NO_CONFLICT = $.fn[NAME] const JQUERY_NO_CONFLICT = $.fn[NAME]
const Default = { const Default = {
formGroup: {
required: false
},
template: `<span class='text-input-decorator'></span>`, template: `<span class='text-input-decorator'></span>`,
requiredClasses: ['form-control'] requiredClasses: ['form-control']
} }
@ -39,7 +42,7 @@ const Text = (($) => {
} }
// Add marker div the end of the form-group // Add marker div the end of the form-group
this.$formGroup.append(this.config.template) this.$mdbFormGroup.append(this.config.template)
} }
dispose(dataKey = DATA_KEY) { dispose(dataKey = DATA_KEY) {
@ -59,6 +62,21 @@ const Text = (($) => {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// protected // protected
// Find or create a mdb-form-group if necessary
autoCreateMdbFormGroup() {
let mfg = this.findMdbFormGroup(false)
if (mfg === null || mfg.length === 0) {
let fg = this.$formGroup
if (fg === undefined || fg.length === 0) {
// if a form-group doesn't exist (not recommended), just wrap the element.
this.outerElement().wrap(this.config.mdbFormGroup.template)
} else {
// a form-group does exist, so add an mdb-form-group wrapping it's internal contents
fg.wrapInner(this.config.mdbFormGroup.template)
}
}
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// private // private