2016-01-26 21:12:48 +03:00
/ * *
* $ . bootstrapMaterialDesign ( config ) is a macro class to configure the components generally
2017-03-22 16:10:37 +03:00
* used in Material Design for Bootstrap . You may pass overrides to the configurations
2016-01-26 21:12:48 +03:00
* which will be passed into each component , or you may omit use of this class and
* configure each component separately .
* /
2017-08-11 17:59:31 +03:00
const BootstrapMaterialDesign = ( $ => {
2016-01-26 21:12:48 +03:00
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* Constants
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
2017-08-11 17:59:31 +03:00
const NAME = "bootstrapMaterialDesign" ;
const DATA _KEY = ` bmd. ${ NAME } ` ;
const JQUERY _NAME = NAME ; // retain this full name since it is long enough not to conflict
const JQUERY _NO _CONFLICT = $ . fn [ JQUERY _NAME ] ;
2016-01-26 21:12:48 +03:00
/ * *
* Global configuration :
* The global configuration hash will be mixed in to each components ' config .
* e . g . calling $ . bootstrapMaterialDesign ( { global : { validate : true } } ) would pass ` validate:true ` to every component
*
*
* Component configuration :
* - selector : may be a string or an array . Any array will be joined with a comma to generate the selector
* - disable any component by defining it as false with an override . e . g . $ . bootstrapMaterialDesign ( { autofill : false } )
*
* @ see each individual component for more configuration settings .
* /
const Default = {
global : {
validate : false ,
label : {
2017-08-11 17:59:31 +03:00
className : "bmd-label-static" // default style of label to be used if not specified in the html markup
2016-01-26 21:12:48 +03:00
}
} ,
autofill : {
2017-08-11 17:59:31 +03:00
selector : "body"
2016-01-26 21:12:48 +03:00
} ,
checkbox : {
2017-08-11 17:59:31 +03:00
selector : ".checkbox > label > input[type=checkbox]"
2016-01-26 21:12:48 +03:00
} ,
checkboxInline : {
2017-08-11 17:59:31 +03:00
selector : "label.checkbox-inline > input[type=checkbox]"
2016-01-26 21:12:48 +03:00
} ,
collapseInline : {
2016-03-21 17:56:51 +03:00
selector : '.bmd-collapse-inline [data-toggle="collapse"]'
2016-01-26 21:12:48 +03:00
} ,
drawer : {
2017-08-11 17:59:31 +03:00
selector : ".bmd-layout-drawer"
2016-01-26 21:12:48 +03:00
} ,
file : {
2017-08-11 17:59:31 +03:00
selector : "input[type=file]"
2016-01-26 21:12:48 +03:00
} ,
radio : {
2017-08-11 17:59:31 +03:00
selector : ".radio > label > input[type=radio]"
2016-01-26 21:12:48 +03:00
} ,
radioInline : {
2017-08-11 17:59:31 +03:00
selector : "label.radio-inline > input[type=radio]"
2016-01-26 21:12:48 +03:00
} ,
ripples : {
//selector: ['.btn:not(.btn-link):not(.ripple-none)'] // testing only
selector : [
2017-08-11 17:59:31 +03:00
".btn:not(.btn-link):not(.ripple-none)" ,
".card-image:not(.ripple-none)" ,
".navbar a:not(.ripple-none)" ,
".dropdown-menu a:not(.ripple-none)" ,
".nav-tabs a:not(.ripple-none)" ,
".pagination li:not(.active):not(.disabled) a:not(.ripple-none)" ,
".ripple" // generic marker class to add ripple to elements
2016-01-26 21:12:48 +03:00
]
} ,
select : {
2017-08-11 17:59:31 +03:00
selector : [ "select" ]
2016-01-26 21:12:48 +03:00
} ,
switch : {
2017-08-11 17:59:31 +03:00
selector : ".switch > label > input[type=checkbox]"
2016-01-26 21:12:48 +03:00
} ,
text : {
// omit inputs we have specialized components to handle - we need to match text, email, etc. The easiest way to do this appears to be just omit the ones we don't want to match and let the rest fall through to this.
2017-08-11 17:59:31 +03:00
selector : [
` input:not([type=hidden]):not([type=checkbox]):not([type=radio]):not([type=file]):not([type=button]):not([type=submit]):not([type=reset]) `
]
2016-01-26 21:12:48 +03:00
} ,
textarea : {
2017-08-11 17:59:31 +03:00
selector : [ "textarea" ]
2016-01-26 21:12:48 +03:00
} ,
arrive : true ,
// create an ordered component list for instantiation
instantiation : [
2017-08-11 17:59:31 +03:00
"ripples" ,
"checkbox" ,
"checkboxInline" ,
"collapseInline" ,
"drawer" ,
2016-01-29 20:42:19 +03:00
//'file',
2017-08-11 17:59:31 +03:00
"radio" ,
"radioInline" ,
"switch" ,
"text" ,
"textarea" ,
"select" ,
"autofill"
2016-01-26 21:12:48 +03:00
]
2017-08-11 17:59:31 +03:00
} ;
2016-01-26 21:12:48 +03:00
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* Class Definition
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
class BootstrapMaterialDesign {
constructor ( $element , config ) {
2017-08-11 17:59:31 +03:00
this . $element = $element ;
this . config = $ . extend ( true , { } , Default , config ) ;
let $document = $ ( document ) ;
2016-01-26 21:12:48 +03:00
for ( let component of this . config . instantiation ) {
// the component's config fragment is passed in directly, allowing users to override
2017-08-11 17:59:31 +03:00
let componentConfig = this . config [ component ] ;
2016-01-26 21:12:48 +03:00
// check to make sure component config is enabled (not `false`)
if ( componentConfig ) {
// assemble the selector as it may be an array
2017-08-11 17:59:31 +03:00
let selector = this . _resolveSelector ( componentConfig ) ;
2016-01-26 21:12:48 +03:00
// mix in global options
2017-08-11 17:59:31 +03:00
componentConfig = $ . extend (
true ,
{ } ,
this . config . global ,
componentConfig
) ;
2016-01-26 21:12:48 +03:00
2016-03-28 23:18:19 +03:00
// create the jquery fn name e.g. 'bmdText' for 'text'
2017-08-11 17:59:31 +03:00
let componentName = ` ${ component . charAt ( 0 ) . toUpperCase ( ) +
component . slice ( 1 ) } ` ;
let jqueryFn = ` bmd ${ componentName } ` ;
2016-01-26 21:12:48 +03:00
try {
// safely instantiate component on selector elements with config, report errors and move on.
// console.debug(`instantiating: $('${selector}')[${jqueryFn}](${componentConfig})`) // eslint-disable-line no-console
2017-08-11 17:59:31 +03:00
$ ( selector ) [ jqueryFn ] ( componentConfig ) ;
2016-01-26 21:12:48 +03:00
// add to arrive if present and enabled
if ( document . arrive && this . config . arrive ) {
2017-08-11 17:59:31 +03:00
$document . arrive ( selector , function ( ) {
// eslint-disable-line no-loop-func
$ ( this ) [ jqueryFn ] ( componentConfig ) ;
} ) ;
2016-01-26 21:12:48 +03:00
}
} catch ( e ) {
2017-08-11 17:59:31 +03:00
let message = ` Failed to instantiate component: $ (' ${ selector } ')[ ${ jqueryFn } ]( ${ componentConfig } ) ` ;
console . error ( message , e , ` \n Selected elements: ` , $ ( selector ) ) ; // eslint-disable-line no-console
throw e ;
2016-01-26 21:12:48 +03:00
}
}
}
}
dispose ( ) {
2017-08-11 17:59:31 +03:00
this . $element . data ( DATA _KEY , null ) ;
this . $element = null ;
this . config = null ;
2016-01-26 21:12:48 +03:00
}
// ------------------------------------------------------------------------
// private
_resolveSelector ( componentConfig ) {
2017-08-11 17:59:31 +03:00
let selector = componentConfig . selector ;
2016-01-26 21:12:48 +03:00
if ( Array . isArray ( selector ) ) {
2017-08-11 17:59:31 +03:00
selector = selector . join ( ", " ) ;
2016-01-26 21:12:48 +03:00
}
2017-08-11 17:59:31 +03:00
return selector ;
2016-01-26 21:12:48 +03:00
}
// ------------------------------------------------------------------------
// static
static _jQueryInterface ( config ) {
2017-08-11 17:59:31 +03:00
return this . each ( function ( ) {
let $element = $ ( this ) ;
let data = $element . data ( DATA _KEY ) ;
2016-01-26 21:12:48 +03:00
if ( ! data ) {
2017-08-11 17:59:31 +03:00
data = new BootstrapMaterialDesign ( $element , config ) ;
$element . data ( DATA _KEY , data ) ;
2016-01-26 21:12:48 +03:00
}
2017-08-11 17:59:31 +03:00
} ) ;
2016-01-26 21:12:48 +03:00
}
}
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* jQuery
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
2017-08-11 17:59:31 +03:00
$ . fn [ JQUERY _NAME ] = BootstrapMaterialDesign . _jQueryInterface ;
$ . fn [ JQUERY _NAME ] . Constructor = BootstrapMaterialDesign ;
2016-01-26 21:12:48 +03:00
$ . fn [ JQUERY _NAME ] . noConflict = ( ) => {
2017-08-11 17:59:31 +03:00
$ . fn [ JQUERY _NAME ] = JQUERY _NO _CONFLICT ;
return BootstrapMaterialDesign . _jQueryInterface ;
} ;
2016-01-26 21:12:48 +03:00
2017-08-11 17:59:31 +03:00
return BootstrapMaterialDesign ;
} ) ( jQuery ) ;
2016-01-26 21:12:48 +03:00
2017-08-11 17:59:31 +03:00
export default BootstrapMaterialDesign ;