converted inputs to es6 classes

This commit is contained in:
Kevin Ross 2015-12-01 18:28:36 -06:00
parent b034b426bc
commit 68391413ab
8 changed files with 537 additions and 171 deletions

View File

@ -103,11 +103,11 @@ module.exports = function (grunt) {
'js/dist/util.js' : 'js/src/util.js', 'js/dist/util.js' : 'js/src/util.js',
'js/dist/ripples.js' : 'js/src/ripples.js', 'js/dist/ripples.js' : 'js/src/ripples.js',
'js/dist/autofill.js' : 'js/src/autofill.js', 'js/dist/autofill.js' : 'js/src/autofill.js',
'js/dist/input.js' : 'js/src/input.js',
'js/dist/checkbox.js' : 'js/src/checkbox.js', 'js/dist/checkbox.js' : 'js/src/checkbox.js',
'js/dist/togglebutton.js' : 'js/src/togglebutton.js', 'js/dist/togglebutton.js' : 'js/src/togglebutton.js',
'js/dist/radio.js' : 'js/src/radio.js', 'js/dist/radio.js' : 'js/src/radio.js',
//'js/dist/dropdown.js' : 'js/src/dropdown.js', 'js/dist/fileinput.js' : 'js/src/fileinput.js',
//'js/dist/modal.js' : 'js/src/modal.js',
//'js/dist/scrollspy.js' : 'js/src/scrollspy.js', //'js/dist/scrollspy.js' : 'js/src/scrollspy.js',
//'js/dist/tab.js' : 'js/src/tab.js', //'js/dist/tab.js' : 'js/src/tab.js',
//'js/dist/tooltip.js' : 'js/src/tooltip.js', //'js/dist/tooltip.js' : 'js/src/tooltip.js',
@ -130,11 +130,11 @@ module.exports = function (grunt) {
'dist/js/umd/util.js' : 'js/src/util.js', 'dist/js/umd/util.js' : 'js/src/util.js',
'dist/js/umd/ripples.js' : 'js/src/ripples.js', 'dist/js/umd/ripples.js' : 'js/src/ripples.js',
'dist/js/umd/autofill.js' : 'js/src/autofill.js', 'dist/js/umd/autofill.js' : 'js/src/autofill.js',
'dist/js/umd/input.js' : 'js/src/input.js',
'dist/js/umd/checkbox.js' : 'js/src/checkbox.js', 'dist/js/umd/checkbox.js' : 'js/src/checkbox.js',
'dist/js/umd/togglebutton.js' : 'js/src/togglebutton.js', 'dist/js/umd/togglebutton.js' : 'js/src/togglebutton.js',
'dist/js/umd/radio.js' : 'js/src/radio.js', 'dist/js/umd/radio.js' : 'js/src/radio.js',
//'dist/js/umd/collapse.js' : 'js/src/collapse.js', 'dist/js/umd/fileinput.js' : 'js/src/fileinput.js',
//'dist/js/umd/dropdown.js' : 'js/src/dropdown.js',
//'dist/js/umd/modal.js' : 'js/src/modal.js', //'dist/js/umd/modal.js' : 'js/src/modal.js',
//'dist/js/umd/scrollspy.js' : 'js/src/scrollspy.js', //'dist/js/umd/scrollspy.js' : 'js/src/scrollspy.js',
//'dist/js/umd/tab.js' : 'js/src/tab.js', //'dist/js/umd/tab.js' : 'js/src/tab.js',
@ -193,11 +193,11 @@ module.exports = function (grunt) {
'js/src/util.js', 'js/src/util.js',
'js/src/ripples.js', 'js/src/ripples.js',
'js/src/autofill.js', 'js/src/autofill.js',
'js/src/input.js',
'js/src/checkbox.js', 'js/src/checkbox.js',
'js/src/togglebutton.js', 'js/src/togglebutton.js',
'js/src/radio.js', 'js/src/radio.js',
//'js/src/dropdown.js', 'js/src/fileinput.js',
//'js/src/modal.js',
//'js/src/scrollspy.js', //'js/src/scrollspy.js',
//'js/src/tab.js', //'js/src/tab.js',
//'js/src/tooltip.js', //'js/src/tooltip.js',

View File

@ -1,5 +1,6 @@
//import Util from './util' import Util from './util'
// Checkbox decorator, to be called after Input
const Checkbox = (($) => { const Checkbox = (($) => {
/** /**
@ -27,17 +28,32 @@ const Checkbox = (($) => {
this.config = $.extend({}, Default, config) this.config = $.extend({}, Default, config)
this.element.after(this.config.template) this.element.after(this.config.template)
this.formGroup = Util.findFormGroup(this.element)
this._bindEventListeners()
} }
dispose() { dispose() {
$.removeData(this.element, DATA_KEY) $.removeData(this.element, DATA_KEY)
this.element = null this.element = null
this.formGroup = null
this.config = null this.config = null
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// private // private
_bindEventListeners() {
// checkboxes didn't appear to bubble to the document, so we'll bind these directly
this.formGroup.find('.checkbox label').hover(() => {
Util.addFormGroupFocus(this.formGroup)
}, () => {
Util.removeFormGroupFocus(this.formGroup)
})
this.element.change(() => {
this.element.blur()
})
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// static // static

112
js/src/fileinput.js Normal file
View File

@ -0,0 +1,112 @@
import Util from './util'
// FileInput decorator, to be called after Input
const FileInput = (($) => {
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
const NAME = 'fileInput'
const DATA_KEY = `mdb.${NAME}`
const JQUERY_NO_CONFLICT = $.fn[NAME]
const Default = {}
const ClassName = {
IS_FILEINPUT: 'is-fileinput',
IS_EMPTY: 'is-empty'
}
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
class FileInput {
constructor(element, config) {
this.element = element
this.config = $.extend({}, Default, config)
this.formGroup = Util.findFormGroup(this.element)
this.formGroup.addClass(ClassName.IS_FILEINPUT)
this._bindEventListeners()
}
dispose() {
$.removeData(this.element, DATA_KEY)
this.element = null
this.formGroup = null
this.config = null
}
// ------------------------------------------------------------------------
// private
_bindEventListeners() {
this.formGroup.on('focus', () => {
Util.addFormGroupFocus(this.formGroup)
})
.on('blur', () => {
Util.removeFormGroupFocus(this.formGroup)
})
// set the fileinput readonly field with the name of the file
this.element.on('change', () => {
let value = ''
$.each(this.element.files, (i, file) => {
value += `${file.name} , `
})
value = value.substring(0, value.length - 2)
if (value) {
this._removeIsEmpty()
} else {
this._addIsEmpty()
}
this.formGroup.find('input.form-control[readonly]').val(value)
})
}
_addIsEmpty() {
this.formGroup.addClass(ClassName.IS_EMPTY)
}
_removeIsEmpty() {
this.formGroup.removeClass(ClassName.IS_EMPTY)
}
// ------------------------------------------------------------------------
// static
static _jQueryInterface(config) {
return this.each(function () {
let $element = $(this)
let data = $element.data(DATA_KEY)
if (!data) {
data = new FileInput(this, config)
$element.data(DATA_KEY, data)
}
})
}
}
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$.fn[NAME] = FileInput._jQueryInterface
$.fn[NAME].Constructor = FileInput
$.fn[NAME].noConflict = () => {
$.fn[NAME] = JQUERY_NO_CONFLICT
return FileInput._jQueryInterface
}
return FileInput
})(jQuery)
export default FileInput

199
js/src/input.js Normal file
View File

@ -0,0 +1,199 @@
import Util from './util'
const Input = (($) => {
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
const NAME = 'input'
const DATA_KEY = `mdb.${NAME}`
const JQUERY_NO_CONFLICT = $.fn[NAME]
const Default = {
convertInputSizeVariations: true,
template: `<span class='material-input'></span>`,
formGroup: {
template: `"<div class='form-group'></div>`
}
}
const InputSizeConversions = {
"input-lg": "form-group-lg",
"input-sm": "form-group-sm"
}
const ClassName = {
IS_EMPTY: 'is-empty',
FORM_GROUP: 'form-group',
HAS_ERROR: 'has-error'
}
const Selector = {
FORM_GROUP: `.${ClassName.FORM_GROUP}` //,
}
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
class Input {
constructor(element, config) {
this.element = element
this.config = $.extend({}, Default, config)
// Requires form-group standard markup (will add it if necessary)
this.formGroup = this._findOrCreateFormGroup()
this._convertInputSizeVariations()
// Initially mark as empty
if (this._isEmpty()) {
this.formGroup.addClass(ClassName.IS_EMPTY)
}
// Add marker div the end of the form-group
this.formGroup.append(this.config.template)
this._bindEventListeners()
}
dispose() {
$.removeData(this.element, DATA_KEY)
this.element = null
this.formGroup = null
this.config = null
}
// ------------------------------------------------------------------------
// private
_bindEventListeners() {
this.element
.on('keydown paste', (event) => {
if (Util.isChar(event)) {
this._removeIsEmpty()
}
})
.on('keyup change', (event) => {
let isValid = (typeof this.element[0].checkValidity === "undefined" || this.element[0].checkValidity())
if (this.element.val() === "" && isValid) {
this._addIsEmpty()
} else {
this._removeIsEmpty()
}
// Validation events do not bubble, so they must be attached directly to the input: http://jsfiddle.net/PEpRM/1/
// Further, even the bind method is being caught, but since we are already calling #checkValidity here, just alter
// the form-group on change.
//
// NOTE: I'm not sure we should be intervening regarding validation, this seems better as a README and snippet of code.
// BUT, I've left it here for backwards compatibility.
if (isValid) {
this._removeHasError()
} else {
this._addHasError()
}
})
.on('focus', () => {
Util.addFormGroupFocus(this.formGroup)
})
.on('blur', () => {
Util.removeFormGroupFocus(this.formGroup)
})
// make sure empty is added back when there is a programmatic value change.
// NOTE: programmatic changing of value using $.val() must trigger the change event i.e. $.val('x').trigger('change')
.on('change', () => {
if (this.element.attr('type') === 'file') {
return
}
let value = this.element.val()
if (value) {
this._removeIsEmpty()
} else {
this._addIsEmpty()
}
})
}
_addHasError() {
this.formGroup.addClass(ClassName.HAS_ERROR)
}
_removeHasError() {
this.formGroup.removeClass(ClassName.HAS_ERROR)
}
_addIsEmpty() {
this.formGroup.addClass(ClassName.IS_EMPTY)
}
_removeIsEmpty() {
this.formGroup.removeClass(ClassName.IS_EMPTY)
}
_isEmpty() {
return (this.element.val() === null || this.element.val() === undefined || this.element.val() === "")
}
_convertInputSizeVariations() {
if (!this.config.convertInputSizeVariations) {
return
}
// Modification - Change input-sm/lg to form-group-sm/lg instead (preferred standard and simpler css/less variants)
for (let inputSize in InputSizeConversions) {
if (this.element.hasClass(inputSize)) {
this.element.removeClass(inputSize)
this.formGroup.addClass(InputSizeConversions[inputSize])
}
}
}
_findOrCreateFormGroup() {
let fg = this.element.closest(Selector.FORM_GROUP) // note that form-group may be grandparent in the case of an input-group
if (fg.length === 0) {
this.element.wrap(this.config.formGroup.template)
fg = this.element.closest(Selector.FORM_GROUP) // find node after attached (otherwise additional attachments don't work)
}
return fg
}
// ------------------------------------------------------------------------
// static
static _jQueryInterface(config) {
return this.each(function () {
let $element = $(this)
let data = $element.data(DATA_KEY)
if (!data) {
data = new Input(this, config)
$element.data(DATA_KEY, data)
}
})
}
}
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$.fn[NAME] = Input._jQueryInterface
$.fn[NAME].Constructor = Input
$.fn[NAME].noConflict = () => {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Input._jQueryInterface
}
return Input
})(jQuery)
export default Input

View File

@ -2,15 +2,15 @@
(function($) { (function($) {
// Selector to select only not already processed elements // Selector to select only not already processed elements
$.expr[":"].notmdproc = function(obj){ //$.expr[":"].notmdproc = function(obj){
if ($(obj).data("mdproc")) { // if ($(obj).data("mdproc")) {
return false; // return false;
} else { // } else {
return true; // return true;
} // }
}; //};
//
//function _isChar(evt) { //function isChar(evt) {
// if (typeof evt.which == "undefined") { // if (typeof evt.which == "undefined") {
// return true; // return true;
// } else if (typeof evt.which == "number" && evt.which > 0) { // } else if (typeof evt.which == "number" && evt.which > 0) {
@ -18,14 +18,14 @@
// } // }
// return false; // return false;
//} //}
//
function _addFormGroupFocus(element){ //function addFormGroupFocus(formGroup){
$(element).closest(".form-group").addClass("is-focused"); // formGroup.addClass("is-focused");
} //}
//
function _removeFormGroupFocus(element){ //function removeFormGroupFocus(formGroup){
$(element).closest(".form-group").removeClass("is-focused"); // remove class from form-group // formGroup.removeClass("is-focused"); // remove class from form-group
} //}
$.material = { $.material = {
"options": { "options": {
@ -50,7 +50,8 @@
"inputElements": "input.form-control, textarea.form-control, select.form-control", "inputElements": "input.form-control, textarea.form-control, select.form-control",
"checkboxElements": ".checkbox > label > input[type=checkbox]", "checkboxElements": ".checkbox > label > input[type=checkbox]",
"togglebuttonElements": ".togglebutton > label > input[type=checkbox]", "togglebuttonElements": ".togglebutton > label > input[type=checkbox]",
"radioElements": ".radio > label > input[type=radio]" "radioElements": ".radio > label > input[type=radio]" ,
"fileInputElements": 'input[type=file]'
}, },
//"checkbox": function(selector) { //"checkbox": function(selector) {
// // Add fake-checkbox to material checkboxes // // Add fake-checkbox to material checkboxes
@ -72,133 +73,133 @@
// .data("mdproc", true) // .data("mdproc", true)
// .after("<span class='circle'></span><span class='check'></span>"); // .after("<span class='circle'></span><span class='check'></span>");
//}, //},
"input": function(selector) { //"input": function(selector) {
$((selector) ? selector : this.options.inputElements) // $((selector) ? selector : this.options.inputElements)
.filter(":notmdproc") // .filter(":notmdproc")
.data("mdproc", true) // .data("mdproc", true)
.each( function() { // .each( () => {
var $input = $(this); // var $input = $(this);
//
// Requires form-group standard markup (will add it if necessary) // // Requires form-group standard markup (will add it if necessary)
var $formGroup = $input.closest(".form-group"); // note that form-group may be grandparent in the case of an input-group // var $formGroup = $input.closest(".form-group"); // note that form-group may be grandparent in the case of an input-group
if($formGroup.length === 0){ // if($formGroup.length === 0){
$input.wrap("<div class='form-group'></div>"); // $input.wrap("<div class='form-group'></div>");
$formGroup = $input.closest(".form-group"); // find node after attached (otherwise additional attachments don't work) // $formGroup = $input.closest(".form-group"); // find node after attached (otherwise additional attachments don't work)
} // }
//
// Modification - Change input-sm/lg to form-group-sm/lg instead (preferred standard and simpler css/less variants) // // Modification - Change input-sm/lg to form-group-sm/lg instead (preferred standard and simpler css/less variants)
var legacySizes = { // var legacySizes = {
"input-lg": "form-group-lg", // "input-lg": "form-group-lg",
"input-sm": "form-group-sm" // "input-sm": "form-group-sm"
}; // };
$.each( legacySizes, function( legacySize, standardSize ) { // $.each( legacySizes, function( legacySize, standardSize ) {
if ($input.hasClass(legacySize)) { // if ($input.hasClass(legacySize)) {
$input.removeClass(legacySize); // $input.removeClass(legacySize);
$formGroup.addClass(standardSize); // $formGroup.addClass(standardSize);
} // }
}); // TODO: determine if we want to keep meddling this much. // }); // TODO: determine if we want to keep meddling this much.
//
// Set as empty if is empty (damn I must improve this...) // // Set as empty if is empty (damn I must improve this...)
if ($input.val() === null || $input.val() == "undefined" || $input.val() === "") { // if ($input.val() === null || $input.val() == "undefined" || $input.val() === "") {
$formGroup.addClass("is-empty"); // $formGroup.addClass("is-empty");
} // }
//
// Add at the end of the form-group // // Add at the end of the form-group
$formGroup.append("<span class='material-input'></span>"); // $formGroup.append("<span class='material-input'></span>");
//
// Support for file input // // Support for file input
if ($formGroup.find("input[type=file]").length > 0) { // if ($formGroup.find("input[type=file]").length > 0) {
$formGroup.addClass("is-fileinput"); // $formGroup.addClass("is-fileinput");
} // }
}); // });
}, //},
"attachInputEventHandlers": function() { //"attachInputEventHandlers": () => {
//
// 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
$(".form-group .checkbox label").hover(function() { //$(".form-group .checkbox label").hover(() => {
_addFormGroupFocus(this); // Util.addFormGroupFocus(this);
}, function() { //}, () => {
_removeFormGroupFocus(this); // Util.removeFormGroupFocus(this);
}); //});
//
$(document) //$(document)
.on("change", ".checkbox input[type=checkbox]", function() { $(this).blur(); }) //.on("change", ".checkbox input[type=checkbox]", () => { $(this).blur(); })
.on("keydown paste", ".form-control", function(e) { //.on("keydown paste", ".form-control", function(e) {
if(_isChar(e)) { // if(Util.isChar(e)) {
$(this).closest(".form-group").removeClass("is-empty"); // $(this).closest(".form-group").removeClass("is-empty");
} // }
}) //})
.on("keyup change", ".form-control", function() { //.on("keyup change", ".form-control", () => {
var $input = $(this); // var $input = $(this);
var $formGroup = $input.closest(".form-group"); // var $formGroup = $input.closest(".form-group");
var isValid = (typeof $input[0].checkValidity === "undefined" || $input[0].checkValidity()); // var isValid = (typeof $input[0].checkValidity === "undefined" || $input[0].checkValidity());
//
if ($input.val() === "" && isValid) { // if ($input.val() === "" && isValid) {
$formGroup.addClass("is-empty"); // $formGroup.addClass("is-empty");
} // }
else { // else {
$formGroup.removeClass("is-empty"); // $formGroup.removeClass("is-empty");
} // }
//
// Validation events do not bubble, so they must be attached directly to the input: http://jsfiddle.net/PEpRM/1/ // // Validation events do not bubble, so they must be attached directly to the input: http://jsfiddle.net/PEpRM/1/
// Further, even the bind method is being caught, but since we are already calling #checkValidity here, just alter // // Further, even the bind method is being caught, but since we are already calling #checkValidity here, just alter
// the form-group on change. // // the form-group on change.
// // //
// NOTE: I'm not sure we should be intervening regarding validation, this seems better as a README and snippet of code. // // NOTE: I'm not sure we should be intervening regarding validation, this seems better as a README and snippet of code.
// BUT, I've left it here for backwards compatibility. // // BUT, I've left it here for backwards compatibility.
if(isValid){ // if(isValid){
$formGroup.removeClass("has-error"); // $formGroup.removeClass("has-error");
} // }
else{ // else{
$formGroup.addClass("has-error"); // $formGroup.addClass("has-error");
} // }
}) //})
.on("focus", ".form-control, .form-group.is-fileinput", function() { //.on("focus", ".form-control, .form-group.is-fileinput", () => {
_addFormGroupFocus(this); // Util.addFormGroupFocus(this.formGroup);
}) //})
.on("blur", ".form-control, .form-group.is-fileinput", function() { //.on("blur", ".form-control, .form-group.is-fileinput", () => {
_removeFormGroupFocus(this); // Util.removeFormGroupFocus(this.formGroup);
}) //})
// make sure empty is added back when there is a programmatic value change. //// make sure empty is added back when there is a programmatic value change.
// NOTE: programmatic changing of value using $.val() must trigger the change event i.e. $.val('x').trigger('change') //// NOTE: programmatic changing of value using $.val() must trigger the change event i.e. $.val('x').trigger('change')
.on("change", ".form-group input", function() { //.on("change", ".form-group input", () => {
var $input = $(this); // var $input = $(this);
if($input.attr("type") == "file") { // if($input.attr("type") == "file") {
return; // return;
} // }
//
var $formGroup = $input.closest(".form-group"); // var $formGroup = $input.closest(".form-group");
var value = $input.val(); // var value = $input.val();
if (value) { // if (value) {
$formGroup.removeClass("is-empty"); // $formGroup.removeClass("is-empty");
} else { // } else {
$formGroup.addClass("is-empty"); // $formGroup.addClass("is-empty");
} // }
}) //})
// set the fileinput readonly field with the name of the file //// set the fileinput readonly field with the name of the file
.on("change", ".form-group.is-fileinput input[type='file']", function() { //.on("change", ".form-group.is-fileinput input[type='file']", () => {
var $input = $(this); // var $input = $(this);
var $formGroup = $input.closest(".form-group"); // var $formGroup = $input.closest(".form-group");
var value = ""; // var value = "";
$.each(this.files, function(i, file) { // $.each(this.files, function(i, file) {
value += file.name + ", "; // value += file.name + ", ";
}); // });
value = value.substring(0, value.length - 2); // value = value.substring(0, value.length - 2);
if (value) { // if (value) {
$formGroup.removeClass("is-empty"); // $formGroup.removeClass("is-empty");
} else { // } else {
$formGroup.addClass("is-empty"); // $formGroup.addClass("is-empty");
} // }
$formGroup.find("input.form-control[readonly]").val(value); // $formGroup.find("input.form-control[readonly]").val(value);
}); //});
}, //},
"ripples": function(selector) { //"ripples": function(selector) {
$((selector) ? selector : this.options.withRipples).ripples(); // $((selector) ? selector : this.options.withRipples).ripples();
}, //},
//"autofill": function() { //"autofill": () => {
// // This part of code will detect autofill when the page is loading (username and password inputs for example) // // This part of code will detect autofill when the page is loading (username and password inputs for example)
// var loading = setInterval(function() { // var loading = setInterval(() => {
// $("input[type!=checkbox]").each(function() { // $("input[type!=checkbox]").each(() => {
// var $this = $(this); // var $this = $(this);
// if ($this.val() && $this.val() !== $this.attr("value")) { // if ($this.val() && $this.val() !== $this.attr("value")) {
// $this.triggerStart("change"); // $this.triggerStart("change");
@ -207,18 +208,18 @@
// }, 100); // }, 100);
// //
// // After 10 seconds we are quite sure all the needed inputs are autofilled then we can stop checking them // // After 10 seconds we are quite sure all the needed inputs are autofilled then we can stop checking them
// setTimeout(function() { // setTimeout(() => {
// clearInterval(loading); // clearInterval(loading);
// }, 10000); // }, 10000);
//}, //},
//"attachAutofillEventHandlers": function() { //"attachAutofillEventHandlers": () => {
// // Listen on inputs of the focused form (because user can select from the autofill dropdown only when the input has focus) // // Listen on inputs of the focused form (because user can select from the autofill dropdown only when the input has focus)
// var focused; // var focused;
// $(document) // $(document)
// .on("focus", "input", function() { // .on("focus", "input", () => {
// var $inputs = $(this).parents("form").find("input").not("[type=file]"); // var $inputs = $(this).parents("form").find("input").not("[type=file]");
// focused = setInterval(function() { // focused = setInterval(() => {
// $inputs.each(function() { // $inputs.each(() => {
// var $this = $(this); // var $this = $(this);
// if ($this.val() !== $this.attr("value")) { // if ($this.val() !== $this.attr("value")) {
// $this.triggerStart("change"); // $this.triggerStart("change");
@ -226,19 +227,22 @@
// }); // });
// }, 100); // }, 100);
// }) // })
// .on("blur", ".form-group input", function() { // .on("blur", ".form-group input", () => {
// clearInterval(focused); // clearInterval(focused);
// }); // });
//}, //},
"init": function() { "init": () => {
var $document = $(document); var $document = $(document);
if ($.fn.ripples && this.options.ripples) { if ($.fn.ripples && this.options.ripples) {
this.ripples(); //this.ripples();
$(this.options.withRipples).ripples()
} }
if (this.options.input) { if (this.options.input) {
this.input(); this.input();
this.attachInputEventHandlers(); this.attachInputEventHandlers();
$(this.options.inputElements).input()
} }
if (this.options.checkbox) { if (this.options.checkbox) {
//this.checkbox(); //this.checkbox();
@ -255,36 +259,41 @@
if (this.options.autofill) { if (this.options.autofill) {
//this.autofill(); //this.autofill();
//this.attachAutofillEventHandlers(); //this.attachAutofillEventHandlers();
new Autofill() new Autofill() // FIXME: if this is the best way to invoke, perhaps it shouldn't be a jquery fn as well?
} }
$(this.options.fileInputElements).fileInput()
if (document.arrive && this.options.arrive) { if (document.arrive && this.options.arrive) {
if ($.fn.ripples && this.options.ripples) { if ($.fn.ripples && this.options.ripples) {
$document.arrive(this.options.withRipples, function() { $document.arrive(this.options.withRipples, () => {
$.material.ripples($(this)); $(this).ripples()
}); });
} }
if (this.options.input) { if (this.options.input) {
$document.arrive(this.options.inputElements, function() { $document.arrive(this.options.inputElements, () => {
$.material.input($(this)); $(this).input()
}); });
} }
if (this.options.checkbox) { if (this.options.checkbox) {
$document.arrive(this.options.checkboxElements, function() { $document.arrive(this.options.checkboxElements, () => {
$(this).checkbox(); $(this).checkbox();
}); });
} }
if (this.options.radio) { if (this.options.radio) {
$document.arrive(this.options.radioElements, function() { $document.arrive(this.options.radioElements, () => {
$(this).radio(); $(this).radio();
}); });
} }
if (this.options.togglebutton) { if (this.options.togglebutton) {
$document.arrive(this.options.togglebuttonElements, function() { $document.arrive(this.options.togglebuttonElements, () => {
$(this).togglebutton(); $(this).togglebutton();
}); });
} }
$document.arrive(this.options.fileInputElements, () => {
$(this).fileInput();
});
} }
} }
}; };

View File

@ -1,5 +1,6 @@
//import Util from './util' //import Util from './util'
// Radio decorator, to be called after Input
const Radio = (($) => { const Radio = (($) => {
/** /**

View File

@ -1,5 +1,6 @@
//import Util from './util' //import Util from './util'
// Togglebutton decorator, to be called after Input
const Togglebutton = (($) => { const Togglebutton = (($) => {
/** /**

View File

@ -16,6 +16,15 @@ const Util = (($) => {
transition: 'transitionend' transition: 'transitionend'
} }
const ClassName = {
IS_FOCUSED: 'is-focused',
FORM_GROUP: 'form-group'
}
const Selector = {
FORM_GROUP: `.${ClassName.FORM_GROUP}` //,
}
function transitionEndTest() { function transitionEndTest() {
if (window.QUnit) { if (window.QUnit) {
return false return false
@ -57,13 +66,32 @@ const Util = (($) => {
return transitionEndSelector return transitionEndSelector
}, },
isChar(evt) { isChar(event) {
if (typeof evt.which === "undefined") { if (typeof event.which === "undefined") {
return true return true
} else if (typeof evt.which === "number" && evt.which > 0) { } else if (typeof event.which === "number" && event.which > 0) {
return !evt.ctrlKey && !evt.metaKey && !evt.altKey && evt.which !== 8 && evt.which !== 9 return !event.ctrlKey && !event.metaKey && !event.altKey && event.which !== 8 && event.which !== 9
} }
return false return false
},
addFormGroupFocus(formGroup) {
formGroup.addClass(ClassName.IS_FOCUSED)
},
removeFormGroupFocus(formGroup) {
formGroup.removeClass(ClassName.IS_FOCUSED)
},
/**
Find expected form-group
*/
findFormGroup(element) {
let fg = element.closest(Selector.FORM_GROUP) // note that form-group may be grandparent in the case of an input-group
if (fg.length === 0) {
$.error(`Failed to find form-group for ${element}`)
}
return fg
} }
} }