Major rework of the text field component.
Should now be easier to use, and less fragile.master
parent
68da2c4186
commit
2dae4da264
|
@ -1,214 +1,172 @@
|
|||
@import "../colors";
|
||||
@import "../animation/animation";
|
||||
@import "../ripple/ripple";
|
||||
|
||||
$input-text-font-size: 16px;
|
||||
$input-text-width: 100%;
|
||||
$input-text-padding: 4px;
|
||||
$input-text-ripple-size: 32px;
|
||||
|
||||
$input-text-button-size: 32px;
|
||||
$input-text-floating-label-fontsize: 12px;
|
||||
$input-text-expandable-icon-dim: 24px;
|
||||
$input-text-expandable-search-icon-color: rgba(0, 0, 0, 0.45);
|
||||
$input-text-expandable-search-icon-highlight-color: $input-text-highlight-color;
|
||||
$input-text-expandable-icon-top: 16px;
|
||||
|
||||
.wsk-input {
|
||||
margin : 20px 0;
|
||||
// The container for the whole component.
|
||||
.wsk-textfield {
|
||||
position: relative;
|
||||
width : 300px;
|
||||
|
||||
font-size: 16px;
|
||||
|
||||
display: inline-block;
|
||||
|
||||
box-sizing: border-box;
|
||||
width: 300px;
|
||||
margin: 0;
|
||||
|
||||
// Align buttons, if used.
|
||||
& .wsk-button {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.wsk-input--right {
|
||||
// Optional class to align right.
|
||||
.wsk-textfield--align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.wsk-input--large {
|
||||
// Optional class to display at full width.
|
||||
.wsk-textfield--full-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wsk-textfield {
|
||||
border : none;
|
||||
// Optional class to make the text field expandable.
|
||||
.wsk-textfield--expandable {
|
||||
min-width: $input-text-button-size;
|
||||
min-height: $input-text-button-size;
|
||||
}
|
||||
|
||||
// Styling for the input element.
|
||||
.wsk-textfield__input {
|
||||
border: none;
|
||||
border-bottom: 1px solid $input-text-bottom-border-color;
|
||||
display : block;
|
||||
font-size : $input-text-font-size;
|
||||
margin : 0;
|
||||
padding : $input-text-padding 0;
|
||||
width : $input-text-width;
|
||||
background : $input-text-font-size;
|
||||
text-align : left;
|
||||
display: block;
|
||||
font-size: $input-text-font-size;
|
||||
margin: 0;
|
||||
padding: $input-text-padding 0;
|
||||
width: $input-text-width;
|
||||
background: $input-text-font-size;
|
||||
text-align: left;
|
||||
|
||||
.wsk-textfield.is-focused & {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.wsk-textfield.is-invalid & {
|
||||
border-color: $input-text-error-color;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.wsk-textfield.is-disabled & {
|
||||
background-color: transparent;
|
||||
border-bottom: 1px dotted $input-text-disabled-color;
|
||||
}
|
||||
}
|
||||
|
||||
.wsk-textfield ~ .wsk-label {
|
||||
bottom : 0;
|
||||
color : $input-text-label-color;
|
||||
font-size : $input-text-font-size;
|
||||
left : 0;
|
||||
right : 0;
|
||||
// Styling for the label / floating label.
|
||||
.wsk-textfield__label {
|
||||
bottom: 0;
|
||||
color: $input-text-label-color;
|
||||
font-size: $input-text-font-size;
|
||||
left: 0;
|
||||
right: 0;
|
||||
pointer-events: none;
|
||||
position : absolute;
|
||||
top : $input-text-padding;
|
||||
width : 100%;
|
||||
overflow : hidden;
|
||||
white-space : nowrap;
|
||||
text-align : left;
|
||||
position: absolute;
|
||||
top: $input-text-padding;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
|
||||
.wsk-textfield.is-dirty & {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
// Floating Label
|
||||
.wsk-textfield--floating-label & {
|
||||
@include material-animation-default();
|
||||
}
|
||||
|
||||
.wsk-textfield--floating-label.is-focused &,
|
||||
.wsk-textfield--floating-label.is-dirty & {
|
||||
color: $input-text-highlight-color;
|
||||
font-size : $input-text-floating-label-fontsize;
|
||||
top: -($input-text-floating-label-fontsize + $input-text-padding);
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.wsk-textfield--floating-label.is-invalid & {
|
||||
color: $input-text-error-color;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
// The after label is the colored underline for the TextField.
|
||||
&:after {
|
||||
background-color: $input-text-highlight-color;
|
||||
bottom: 0;
|
||||
content: '';
|
||||
height: 2px;
|
||||
left: 45%;
|
||||
position: absolute;
|
||||
@include material-animation-default();
|
||||
visibility: hidden;
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.wsk-textfield.is-focused &:after {
|
||||
left: 0;
|
||||
visibility: visible;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wsk-textfield.is-invalid &:after {
|
||||
background-color: $input-text-error-color;
|
||||
}
|
||||
}
|
||||
|
||||
/** The after label is the colored underline for the TextField **/
|
||||
.wsk-textfield ~ .wsk-label:after {
|
||||
background-color : $input-text-highlight-color;
|
||||
bottom : 0;
|
||||
content : '';
|
||||
height : 2px;
|
||||
left : 45%;
|
||||
position : absolute;
|
||||
@include material-animation-default();
|
||||
visibility : hidden;
|
||||
width : 10px;
|
||||
}
|
||||
|
||||
/** TextField Focus Styles **/
|
||||
.wsk-textfield:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.wsk-textfield:focus ~ .wsk-label:after {
|
||||
left : 0;
|
||||
visibility: visible;
|
||||
width : 100%;
|
||||
}
|
||||
|
||||
/** TextField Invalid Styles **/
|
||||
.wsk-textfield:invalid {
|
||||
border-color: $input-text-error-color;
|
||||
box-shadow : none;
|
||||
}
|
||||
|
||||
.wsk-textfield:invalid ~ .wsk-label:after {
|
||||
background-color: $input-text-error-color;
|
||||
}
|
||||
|
||||
/** TextField Error **/
|
||||
.wsk-textfield ~ .wsk-input__error {
|
||||
color : $input-text-error-color;
|
||||
position : absolute;
|
||||
font-size : 12px;
|
||||
// TextField Error.
|
||||
.wsk-textfield__error {
|
||||
color: $input-text-error-color;
|
||||
position: absolute;
|
||||
font-size: 12px;
|
||||
margin-top: 3px;
|
||||
visibility: hidden;
|
||||
|
||||
.wsk-textfield.is-invalid & {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.wsk-textfield:invalid ~ .wsk-input__error {
|
||||
visibility: visible;
|
||||
}
|
||||
// Expandable Holder.
|
||||
.wsk-textfield__expandable-holder {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
margin-left: $input-text-button-size;
|
||||
|
||||
.wsk-textfield.is-dirty ~ .wsk-label {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/** Floating Label */
|
||||
.wsk-textfield--floating-label ~ .wsk-label {
|
||||
@include material-animation-default();
|
||||
}
|
||||
|
||||
.wsk-textfield--floating-label:focus ~ .wsk-label,
|
||||
.wsk-textfield--floating-label.is-dirty ~ .wsk-label {
|
||||
color : $input-text-highlight-color;
|
||||
font-size : $input-text-floating-label-fontsize;
|
||||
top : -($input-text-floating-label-fontsize+$input-text-padding);
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.wsk-textfield--floating-label:invalid ~ .wsk-label {
|
||||
color : $input-text-error-color;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/** Expandable Icon/Holder */
|
||||
.wsk-input__expandable-holder{
|
||||
display : inline-block;
|
||||
position : relative;
|
||||
}
|
||||
|
||||
.wsk-input__expandable-holder .wsk-textfield {
|
||||
@include material-animation-default();
|
||||
display : inline-block;
|
||||
display: inline-block;
|
||||
|
||||
// Safari (possibly others) need to be convinced that this field is actually
|
||||
// visible, otherwise it cannot be tabbed to nor focused via a <label>.
|
||||
// TODO: In some cases (Retina displays), this is big enough to render the
|
||||
// inner element :(
|
||||
max-width: 0.1px;
|
||||
}
|
||||
|
||||
.wsk-input__expandable-holder .wsk-textfield:focus,
|
||||
.wsk-input__expandable-holder .wsk-textfield .is-dirty {
|
||||
// This is an unforunate hack. Animating between widths in percent (%)
|
||||
// in many browsers (Chrome, Firefox) only animates the inner visual style
|
||||
// of the input - the outer bounding box still 'jumps'.
|
||||
// Thus assume a sensible maximum, and animate to/from that value.
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.wsk-textfield-expandable-icon {
|
||||
display : inline-block;
|
||||
width : $input-text-expandable-icon-dim;
|
||||
height : $input-text-expandable-icon-dim;
|
||||
text-align : center;
|
||||
border-color: $input-text-expandable-search-icon-color; // inherits to .wsk-textfield-expandable-icon-search
|
||||
position : relative;
|
||||
}
|
||||
|
||||
.wsk-textfield-expandable-icon:hover {
|
||||
border-color: $input-text-expandable-search-icon-highlight-color;
|
||||
cursor : pointer;
|
||||
}
|
||||
|
||||
.wsk-textfield-expandable-icon .wsk-textfield-expandable-icon-search {
|
||||
border : 2px solid #000;
|
||||
border-color : inherit;
|
||||
border-radius : 100px;
|
||||
position : relative;
|
||||
box-sizing : border-box;
|
||||
width : 10px;
|
||||
height : 10px;
|
||||
display : inline-block;
|
||||
margin : 1px 4px 4px 1px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.wsk-textfield-expandable-icon .wsk-textfield-expandable-icon-search::after {
|
||||
content : '';
|
||||
transform : rotate(-45deg);
|
||||
width : 0;
|
||||
border-left : 2px solid #000;
|
||||
border-color: inherit;
|
||||
height : 5px;
|
||||
position : absolute;
|
||||
display : inline-block;
|
||||
bottom : -5px;
|
||||
right : -3px;
|
||||
}
|
||||
|
||||
.wsk-textfield-expandable-icon__ripple__container {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: -((($input-text-ripple-size - $input-text-expandable-icon-dim) / 2) - 0px);
|
||||
left: -(($input-text-ripple-size - $input-text-expandable-icon-dim) / 2);
|
||||
|
||||
box-sizing: border-box;
|
||||
width: $input-text-ripple-size;
|
||||
height: $input-text-ripple-size;
|
||||
border-radius: 50%;
|
||||
|
||||
overflow: hidden;
|
||||
-webkit-mask-image: -webkit-radial-gradient(circle, white, black);
|
||||
}
|
||||
|
||||
.wsk-textfield-expandable-icon__ripple__container .wsk-ripple {
|
||||
background: $input-text-expandable-search-icon-highlight-color;
|
||||
}
|
||||
|
||||
/** Disabled Styling **/
|
||||
.wsk-textfield[disabled] {
|
||||
background-color: transparent;
|
||||
border-bottom : 1px dashed $input-text-disabled-color;
|
||||
|
||||
.wsk-textfield.is-focused &, .wsk-textfield.is-dirty & {
|
||||
// This is an unfortunate hack. Animating between widths in percent (%)
|
||||
// in many browsers (Chrome, Firefox) only animates the inner visual style
|
||||
// of the input - the outer bounding box still 'jumps'.
|
||||
// Thus assume a sensible maximum, and animate to/from that value.
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,80 +16,80 @@
|
|||
|
||||
<div class="PreviewBlock">
|
||||
<form action="#">
|
||||
<div class="wsk-input">
|
||||
<input class="wsk-textfield wsk-js-textfield" type="text" name="sample" />
|
||||
<label class="wsk-label" for="sample">Type Something...</label>
|
||||
<div class="wsk-textfield wsk-js-textfield">
|
||||
<input class="wsk-textfield__input" type="text" id="sample1" />
|
||||
<label class="wsk-textfield__label" for="sample1">Type Something...</label>
|
||||
</div>
|
||||
|
||||
<div class="wsk-input">
|
||||
<input class="wsk-textfield wsk-js-textfield" type="text" pattern="[0-9]*" name="sample" />
|
||||
<label class="wsk-label" for="sample">Numbers Only</label>
|
||||
<span class="wsk-input__error">Input is not a number!</span>
|
||||
<div class="wsk-textfield wsk-js-textfield">
|
||||
<input class="wsk-textfield__input" type="text" pattern="[0-9]*" id="sample2" />
|
||||
<label class="wsk-textfield__label" for="sample2">Numbers Only</label>
|
||||
<span class="wsk-textfield__error">Input is not a number!</span>
|
||||
</div>
|
||||
|
||||
<div class="wsk-input">
|
||||
<input class="wsk-textfield wsk-js-textfield" type="text" disabled name="sample" />
|
||||
<label class="wsk-label" class="wsk-label" for="sample">I'm Disabled</label>
|
||||
<div class="wsk-textfield wsk-js-textfield">
|
||||
<input class="wsk-textfield__input" type="text" disabled id="sample3" />
|
||||
<label class="wsk-textfield__label" for="sample3">I'm Disabled</label>
|
||||
</div>
|
||||
|
||||
<div class="wsk-input">
|
||||
<input class="wsk-textfield wsk-js-textfield wsk-textfield--floating-label" type="text" name="sample" />
|
||||
<label class="wsk-label" for="sample">Text Input</label>
|
||||
<div class="wsk-textfield wsk-js-textfield wsk-textfield--floating-label">
|
||||
<input class="wsk-textfield__input" type="text" id="sample4" />
|
||||
<label class="wsk-textfield__label" for="sample4">Text Input</label>
|
||||
</div>
|
||||
|
||||
<div class="wsk-input">
|
||||
<input class="wsk-textfield wsk-js-textfield wsk-textfield--floating-label" type="text" pattern="[0-9]*" name="sample" />
|
||||
<label class="wsk-label" for="sample">Numbers Only</label>
|
||||
<span class="wsk-input__error">Input is not a number!</span>
|
||||
<div class="wsk-textfield wsk-js-textfield wsk-textfield--floating-label">
|
||||
<input class="wsk-textfield__input" type="text" pattern="[0-9]*" id="sample5" />
|
||||
<label class="wsk-textfield__label" for="sample5">Numbers Only</label>
|
||||
<span class="wsk-textfield__error">Input is not a number!</span>
|
||||
</div>
|
||||
|
||||
<div class="wsk-input">
|
||||
<textarea class="wsk-textfield wsk-js-textfield" type="text" rows= "1" name="sample" ></textarea>
|
||||
<label class="wsk-label" for="sample">Type multiple lines here...</label>
|
||||
<div class="wsk-textfield wsk-js-textfield">
|
||||
<textarea class="wsk-textfield__input" type="text" rows= "1" id="sample6" ></textarea>
|
||||
<label class="wsk-textfield__label" for="sample6">Type multiple lines here...</label>
|
||||
</div>
|
||||
|
||||
<div class="wsk-input">
|
||||
<textarea class="wsk-textfield wsk-js-textfield" type="text" rows="3" name="sample" ></textarea>
|
||||
<label class="wsk-label" for="sample">This input is 3 rows high</label>
|
||||
<div class="wsk-textfield wsk-js-textfield">
|
||||
<textarea class="wsk-textfield__input" type="text" rows="3" id="sample7" ></textarea>
|
||||
<label class="wsk-textfield__label" for="sample7">This input is 3 rows high</label>
|
||||
</div>
|
||||
|
||||
<div class="wsk-input">
|
||||
<textarea class="wsk-textfield wsk-js-textfield" type="text" maxrows="3" rows="1" name="sample" ></textarea>
|
||||
<label class="wsk-label" for="sample">This input is at most 3 rows high</label>
|
||||
<div class="wsk-textfield wsk-js-textfield">
|
||||
<textarea class="wsk-textfield__input" type="text" maxrows="3" rows="1" id="sample8" ></textarea>
|
||||
<label class="wsk-textfield__label" for="sample8">This input is at most 3 rows high</label>
|
||||
</div>
|
||||
|
||||
<div class="wsk-input">
|
||||
<textarea class="wsk-textfield wsk-js-textfield wsk-textfield--floating-label" type="text" rows= "1" name="sample" ></textarea>
|
||||
<label class="wsk-label" for="sample">Multiple lines and a floating label</label>
|
||||
<div class="wsk-textfield wsk-js-textfield wsk-textfield--floating-label">
|
||||
<textarea class="wsk-textfield__input" type="text" rows="1" id="sample9" ></textarea>
|
||||
<label class="wsk-textfield__label" for="sample9">Multiple lines and a floating label</label>
|
||||
</div>
|
||||
|
||||
<div class="wsk-input">
|
||||
<label class="wsk-textfield-expandable-icon wsk-label" for="sample-expandable">
|
||||
<span class="wsk-textfield-expandable-icon-search"></span>
|
||||
<div class="wsk-textfield wsk-js-textfield wsk-textfield--expandable">
|
||||
<label class="wsk-button wsk-js-button wsk-button--icon" for="sample-expandable">
|
||||
<span class="wsk-icon wsk-icon--search"/>
|
||||
</label>
|
||||
<div class="wsk-input__expandable-holder">
|
||||
<input class="wsk-textfield wsk-js-textfield wsk-textfield--expandable" type="text" name="sample" id="sample-expandable" />
|
||||
<label class="wsk-label" for="sample">Expandable Input</label>
|
||||
<div class="wsk-textfield__expandable-holder">
|
||||
<input class="wsk-textfield__input" type="text" id="sample-expandable" />
|
||||
<label class="wsk-textfield__label" for="sample-expandable">Expandable Input</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wsk-input">
|
||||
<label class="wsk-textfield-expandable-icon wsk-label" for="sample-expandable-floating">
|
||||
<span class="wsk-textfield-expandable-icon-search"></span>
|
||||
<div class="wsk-textfield wsk-js-textfield wsk-textfield--expandable wsk-textfield--floating-label">
|
||||
<label class="wsk-button wsk-js-button wsk-button--icon" for="sample-expandable-floating">
|
||||
<span class="wsk-icon wsk-icon--search"/>
|
||||
</label>
|
||||
<div class="wsk-input__expandable-holder">
|
||||
<input class="wsk-textfield wsk-js-textfield wsk-textfield--expandable wsk-textfield--floating-label" type="text" name="sample" id="sample-expandable-floating" />
|
||||
<label class="wsk-label" for="sample">Expandable & Floating Input</label>
|
||||
<div class="wsk-textfield__expandable-holder">
|
||||
<input class="wsk-textfield__input" type="text" id="sample-expandable-floating" />
|
||||
<label class="wsk-textfield__label" for="sample-expandable-floating">Expandable & Floating Input</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wsk-input wsk-input--right wsk-input--large">
|
||||
<div class="wsk-textfield wsk-js-textfield wsk-textfield--expandable wsk-textfield--floating-label wsk-textfield--align-right wsk-textfield--full-width">
|
||||
Right/No Label:
|
||||
<label class="wsk-textfield-expandable-icon wsk-label" for="sample-expclean">
|
||||
<span class="wsk-textfield-expandable-icon-search"></span>
|
||||
<label class="wsk-button wsk-js-button wsk-button--icon" for="sample-expclean">
|
||||
<span class="wsk-icon wsk-icon--search"/>
|
||||
</label>
|
||||
<div class="wsk-input__expandable-holder">
|
||||
<input class="wsk-textfield wsk-js-textfield wsk-textfield--expandable" type="text" name="sample" id="sample-expclean" />
|
||||
<div class="wsk-textfield__expandable-holder">
|
||||
<input class="wsk-textfield__input" type="text" name="sample" id="sample-expclean" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -98,6 +98,7 @@
|
|||
<!-- build:js(app/styleguide/textfield/) ../../scripts/main.min.js -->
|
||||
<script src="../wskComponentHandler.js"></script>
|
||||
<script src="textfield.js"></script>
|
||||
<script src="../button/button.js"></script>
|
||||
<script src="../third_party/rAF.js"></script>
|
||||
<script src="../ripple/ripple.js"></script>
|
||||
<!-- endbuild -->
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
@import "../styleguide_demo_bp";
|
||||
@import "../button/button";
|
||||
@import "../icons/icons";
|
||||
@import "_textfield";
|
||||
|
||||
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
resize : none;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.wsk-textfield {
|
||||
display: block;
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
|
|
@ -31,59 +31,15 @@ MaterialTextfield.prototype.Constant_ = {
|
|||
* @private
|
||||
*/
|
||||
MaterialTextfield.prototype.CssClasses_ = {
|
||||
WSK_TEXT_EXP_ICO_RIP_CONTAINER: 'wsk-textfield-expandable-icon__ripple__' +
|
||||
'container',
|
||||
|
||||
WSK_JS_RIPPLE_EFFECT: 'wsk-js-ripple-effect',
|
||||
|
||||
WSK_RIPPLE_CENTER: 'wsk-ripple--center',
|
||||
|
||||
WSK_RIPPLE: 'wsk-ripple',
|
||||
|
||||
IS_DIRTY: 'is-dirty'
|
||||
LABEL: 'wsk-textfield__label',
|
||||
INPUT: 'wsk-textfield__input',
|
||||
IS_DIRTY: 'is-dirty',
|
||||
IS_FOCUSED: 'is-focused',
|
||||
IS_DISABLED: 'is-disabled',
|
||||
IS_INVALID: 'is-invalid',
|
||||
IS_UPGRADED: 'is-upgraded'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle upgrade of icon element.
|
||||
* @param {HTMLElement} iconElement HTML element to contain icon.
|
||||
* @private
|
||||
*/
|
||||
MaterialTextfield.prototype.expandableIcon_ = function(iconElement) {
|
||||
'use strict';
|
||||
|
||||
if (!iconElement.getAttribute('data-upgraded')) {
|
||||
var container = document.createElement('span');
|
||||
container.classList.add(this.CssClasses_.WSK_TEXT_EXP_ICO_RIP_CONTAINER);
|
||||
container.classList.add(this.CssClasses_.WSK_JS_RIPPLE_EFFECT);
|
||||
container.classList.add(this.CssClasses_.WSK_RIPPLE_CENTER);
|
||||
|
||||
var ripple = document.createElement('span');
|
||||
ripple.classList.add(this.CssClasses_.WSK_RIPPLE);
|
||||
container.appendChild(ripple);
|
||||
|
||||
iconElement.appendChild(container);
|
||||
iconElement.setAttribute('data-upgraded', '');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle input being entered.
|
||||
* @param {Event} event The event that fired.
|
||||
* @private
|
||||
*/
|
||||
MaterialTextfield.prototype.onInputChange_ = function(event) {
|
||||
'use strict';
|
||||
|
||||
if (event.target.value && event.target.value.length > 0) {
|
||||
event.target.classList.add(this.CssClasses_.IS_DIRTY);
|
||||
} else {
|
||||
event.target.classList.remove(this.CssClasses_.IS_DIRTY);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle input being entered.
|
||||
* @param {Event} event The event that fired.
|
||||
|
@ -100,6 +56,55 @@ MaterialTextfield.prototype.onKeyDown_ = function(event) {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle focus.
|
||||
* @param {Event} event The event that fired.
|
||||
* @private
|
||||
*/
|
||||
MaterialTextfield.prototype.onFocus_ = function(event) {
|
||||
'use strict';
|
||||
|
||||
this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle lost focus.
|
||||
* @param {Event} event The event that fired.
|
||||
* @private
|
||||
*/
|
||||
MaterialTextfield.prototype.onBlur_ = function(event) {
|
||||
'use strict';
|
||||
|
||||
this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle class updates.
|
||||
* @param {HTMLElement} button The button whose classes we should update.
|
||||
* @param {HTMLElement} label The label whose classes we should update.
|
||||
* @private
|
||||
*/
|
||||
MaterialTextfield.prototype.updateClasses_ = function() {
|
||||
'use strict';
|
||||
|
||||
if (this.input_.disabled) {
|
||||
this.element_.classList.add(this.CssClasses_.IS_DISABLED);
|
||||
} else {
|
||||
this.element_.classList.remove(this.CssClasses_.IS_DISABLED);
|
||||
}
|
||||
|
||||
if (this.input_.validity.valid) {
|
||||
this.element_.classList.remove(this.CssClasses_.IS_INVALID);
|
||||
} else {
|
||||
this.element_.classList.add(this.CssClasses_.IS_INVALID);
|
||||
}
|
||||
|
||||
if (this.input_.value && this.input_.value.length > 0) {
|
||||
this.element_.classList.add(this.CssClasses_.IS_DIRTY);
|
||||
} else {
|
||||
this.element_.classList.remove(this.CssClasses_.IS_DIRTY);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize element.
|
||||
|
@ -108,33 +113,34 @@ MaterialTextfield.prototype.init = function() {
|
|||
'use strict';
|
||||
|
||||
if (this.element_) {
|
||||
var expandableIcons =
|
||||
document.querySelectorAll('.wsk-textfield-expandable-icon');
|
||||
for (var i = 0; i < expandableIcons.length; ++i) {
|
||||
this.expandableIcon_(expandableIcons[i]);
|
||||
}
|
||||
this.label_ = this.element_.querySelector('.' + this.CssClasses_.LABEL);
|
||||
this.input_ = this.element_.querySelector('.' + this.CssClasses_.INPUT);
|
||||
|
||||
if (this.element_.hasAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE)) {
|
||||
this.maxRows = parseInt(this.element_.getAttribute(
|
||||
this.Constant_.MAX_ROWS_ATTRIBUTE), 10);
|
||||
if (isNaN(this.maxRows)) {
|
||||
console.log(
|
||||
'maxrows attribute provided, but wasn\'t a number: ' +
|
||||
this.maxRows);
|
||||
this.maxRows = this.Constant_.NO_MAX_ROWS;
|
||||
if (this.input_) {
|
||||
if (this.input_.hasAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE)) {
|
||||
this.maxRows = parseInt(this.input_.getAttribute(
|
||||
this.Constant_.MAX_ROWS_ATTRIBUTE), 10);
|
||||
if (isNaN(this.maxRows)) {
|
||||
this.maxRows = this.Constant_.NO_MAX_ROWS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.element_.addEventListener('input', this.onInputChange_.bind(this));
|
||||
if (this.maxRows !== this.Constant_.NO_MAX_ROWS) {
|
||||
// TODO: This should handle pasting multi line text.
|
||||
// Currently doesn't.
|
||||
this.element_.addEventListener('keydown', this.onKeyDown_.bind(this));
|
||||
this.input_.addEventListener('input', this.updateClasses_.bind(this));
|
||||
this.input_.addEventListener('focus', this.onFocus_.bind(this));
|
||||
this.input_.addEventListener('blur', this.onBlur_.bind(this));
|
||||
|
||||
if (this.maxRows !== this.Constant_.NO_MAX_ROWS) {
|
||||
// TODO: This should handle pasting multi line text.
|
||||
// Currently doesn't.
|
||||
this.input_.addEventListener('keydown', this.onKeyDown_.bind(this));
|
||||
}
|
||||
|
||||
this.updateClasses_();
|
||||
this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// The component registers itself. It can assume componentHandler is available
|
||||
// in the global scope.
|
||||
componentHandler.register({
|
||||
|
|
Loading…
Reference in New Issue