Making md-inputfield work for all Input fields
Posted: 30 Nov 2017, 05:50
If you're like me you purchased the Ultima theme with the expectation that all Input controls would conform to the Material Design guidelines for Components as documented here:
https://material.io/guidelines/componen ... ields.html
The guidelines clearly outline how to display all types of text inputs including textareas, dropdowns etc. but sadly if you had tried to to used the md-inputfield to display all the text inputs in PrimeNG you would be familiar with the ugly mess in the following image:
As you can see placeholders don't work for any control (even for InputText) and any input that has internal labels gets completely messed up (i.e. Dropdown and MultiSelect). It's not shown in the image but changing the label colour when the control is invalid is also only possible for InputText and Password inputs.
Despite a large number of people requesting this to be fixed in this forum and a number of feature requests on GitHub this issue still exists. Wouldn't it be great if our forms could all look like the following image?
Fortunately this is not that difficult to achieve. All that you need to do is make a few small changes to the md-inputfield class in the _forms.scss file as follows:
Unfortunately the label must always be floated for Dropdown, MultiSelect and Chips as the classes required to float it on focus or when filled don't currently exists in these components. Usually this isn't a problem as it is common for there to be a default label or placeholder for these controls.
I did try and get this working for the new TextBox but the expanding nature InputTextarea and Chips made this too difficult to get working properly and given that I'm unlikely to ever use this I thought I'd spend my time on something more productive.
https://material.io/guidelines/componen ... ields.html
The guidelines clearly outline how to display all types of text inputs including textareas, dropdowns etc. but sadly if you had tried to to used the md-inputfield to display all the text inputs in PrimeNG you would be familiar with the ugly mess in the following image:
As you can see placeholders don't work for any control (even for InputText) and any input that has internal labels gets completely messed up (i.e. Dropdown and MultiSelect). It's not shown in the image but changing the label colour when the control is invalid is also only possible for InputText and Password inputs.
Despite a large number of people requesting this to be fixed in this forum and a number of feature requests on GitHub this issue still exists. Wouldn't it be great if our forms could all look like the following image?
Fortunately this is not that difficult to achieve. All that you need to do is make a few small changes to the md-inputfield class in the _forms.scss file as follows:
Code: Select all
.md-inputfield {
display: block;
position:relative;
// Added > to the label selector to prevent labels inside input components from being selected.
>label {
color:#999;
font-weight:normal;
position:absolute;
pointer-events:none;
left:5px;
top:1px;
transition: 0.3s ease all;
-moz-transition: 0.3s ease all;
-webkit-transition: 0.3s ease all;
}
input[placeholder] ~ label,
textarea[placeholder] ~ label,
p-autoComplete[placeholder] ~ label,
p-calendar[placeholder] ~ label,
p-inputMask[placeholder] ~ label,
p-spinner[placeholder] ~ label,
p-dropdown ~ label,
p-multiSelect ~ label,
p-chips ~ label,
textarea:focus ~ label,
textarea.ui-state-filled ~ label,
input:focus ~ label,
input.ui-state-filled ~ label,
.ui-inputwrapper-focus ~ label,
.ui-inputwrapper-filled ~ label {
top:-20px;
font-size:12px;
color:$primaryColor;
}
.textarea:-webkit-autofill ~ label,
.input:-webkit-autofill ~ label {
top:-20px;
font-size:12px;
color:$primaryColor;
}
p-autoComplete.ng-dirty.ng-invalid ~ label,
p-dropdown.ng-dirty.ng-invalid ~ label,
p-multiSelect.ng-dirty.ng-invalid ~ label,
p-calendar.ng-dirty.ng-invalid ~ label,
p-inputMask.ng-dirty.ng-invalid ~ label,
p-spinner.ng-dirty.ng-invalid ~ label,
p-chips.ng-dirty.ng-invalid ~ label,
textarea.ng-dirty.ng-invalid ~ label,
input.ng-dirty.ng-invalid ~ label {
color: $invalidInputLabelColor;
}
.ui-message {
&.ui-messages-error {
background-color: transparent;
border: 0 none;
margin: 0px;
color: $inputErrorTextColor;
font-size: .75em;
}
}
&.md-inputfield-fill {
.ui-chips,
.ui-multiselect,
.ui-dropdown,
textarea,
input {
background-color: $textboxBgColor;
padding-left: 4px;
padding-right: 4px;
padding-top: 4px;
}
// Added > to the label selector to prevent labels inside input components from being selected.
>label {
top: 2px;
}
input[placeholder] ~ label,
textarea[placeholder] ~ label,
p-autoComplete[placeholder] ~ label,
p-calendar[placeholder] ~ label,
p-inputMask[placeholder] ~ label,
p-spinner[placeholder] ~ label,
p-dropdown ~ label,
p-multiSelect ~ label,
p-chips ~ label,
textarea:focus ~ label,
textarea.ui-state-filled ~ label,
input:focus ~ label,
input.ui-state-filled ~ label,
.ui-inputwrapper-focus ~ label,
.ui-inputwrapper-filled ~ label {
top:-20px;
font-size:12px;
color:$primaryColor;
}
}
&.md-inputfield-box {
background-color: #f7f7f7;
height: 44px;
>*:not(label) {
bottom: 0px;
position: absolute;
background-color: $textboxBgColor;
padding-left: 4px;
padding-right: 4px;
padding-top: 24px;
}
>label {
top: 23px;
}
input:focus ~ label,
input.ui-state-filled ~ label,
.ui-inputwrapper-focus ~ label,
.ui-inputwrapper-filled ~ label {
top:1px;
}
.input:-webkit-autofill ~ label {
top:1px;
}
}
}
I did try and get this working for the new TextBox but the expanding nature InputTextarea and Chips made this too difficult to get working properly and given that I'm unlikely to ever use this I thought I'd spend my time on something more productive.