InfomediaLtd / angular2-materialize

Angular 2 support for Materialize CSS framework.
https://infomedialtd.github.io/angular2-materialize/
MIT License
407 stars 140 forks source link

Labels overlapping prefilled content in forms #131

Open calabo-Act21 opened 7 years ago

calabo-Act21 commented 7 years ago

I'm having issues in form : when i'm binding my inputs to an asynchron loaded data, the label are overlapping the values. It seems to be a known issue. At first, I fixed it by adding 'active' class to the form labels.

It worked well until I add a select directive to the form.

Calling Materialize.updateTextFields(); could help, but I don't really know how to get the Materialize object in my component (need some webpack configuration ?).

My project is generated with the latest angular-cli, using webpack under the hood.

Thanks a lot for your help !

rubyboy commented 7 years ago

Not sure if Materialize.updateTextFields() is the best option, but Materialize is a global object so you should be able to just call it. I'm not a webpack user but I know you could use the "export" or other plugins to inject global objects into your components.

If you post example code maybe someone could pick that up and try to fix the problem. If you find a solution please post it here and we can incorporate that into the library.

Thanks.

calabo-Act21 commented 7 years ago

Thanks for your answer.

To reproduce the issue, you only have to bind your form example to a string value on your component.

I think it's a known issue since on the materialize website we can read :

If you are having trouble with the labels overlapping prefilled content, Try adding class="active" to the label. You can also call the function Materialize.updateTextFields(); to reinitialize all the Materialize labels on the page if you are dynamically adding inputs.

calabo-Act21 commented 7 years ago

In fact, on your quick sample, you can see it on the first field : http://angular2-materialize.surge.sh/#/ModelBindings

ghost commented 7 years ago

Link 404

wceolin commented 7 years ago

@dh-fallen have you found a solution for this issue? I used to set the label class to active, but I realize it doesn't work when importing the MaterializeModule.

rvaliev commented 7 years ago

I have just the same issue. Adding class="active" to the label doesn't work.

mikeacameron commented 7 years ago

What I did at work was create a directive, which I put on my FormGroup. When the any form values change, I do Materialize.updateTextFields().

rvaliev commented 7 years ago

@lengtche could you please show some real code that worked for you? Thanks

mikeacameron commented 7 years ago

You can do something like this:

import { Directive } from '@angular/core';
import { NgModel, FormControl } from '@angular/forms';

@Directive({
    selector: '[updateTextFields]',
    providers: [NgModel]
})
export class UpdateTextFieldsDirective {
    constructor(private model: NgModel) {
    }

    ngOnInit() {
        // haven't really looked into how to handle form groups or binds using ngModel
        let m = this.model.formDirective ?
            this.model.formDirective :
            this.model;

        m.valueChanges.subscribe(value => {
            Materialize.updateTextFields();
        });
    }
}

With that you should be able to add directive updateTextFields to your form fields.

rvaliev commented 7 years ago

@lengtche Thanks, but I get an error that Materialize couldn't be found. Actually I'm not able to use Materialize.updateTextFields(), while other materialize features are working well in template. I've imported and enabled Materialize accordingly to this doc: https://www.npmjs.com/package/angular2-materialize

JCarran0 commented 7 years ago

Calling Materialize.updateTextFields() upon form update doesn't seem to fix this issue for me.

lucassch commented 7 years ago

Put class = "active" in label works for me but it looks a little ugly.

RadouaneRoufid commented 7 years ago

Did any one found a good solution for this problem ?

I'm actually using the following workaround :

declare var Materialize:any;

export class MyComponent implements OnInit, AfterViewChecked {
...
  ngAfterViewChecked() {
    Materialize.updateTextFields();
  }
}

The idea is to call Materialize.updateTextFields(); after the dom initialization.

rvgarimrj commented 7 years ago

same here. tried both methods but cant make it work. any workaround ?

Uncaught (in promise): Error: Error in :0:0 caused by: Cannot read property 'updateTextFields' of undefined

rubyboy commented 7 years ago

@rvaliev this sounds like a problem importing MaterializeCSS. The Materialize object should be available globally. Try checking in the browser console if it exists ( console.log(Materialize) ). If it doesn't, then you should review how you're importing the MaterializeCSS library to your project.

rvgarimrj commented 7 years ago

It's possible. Can you help ? I followed these steps:

npm install materialize-css --save
npm install angular2-materialize --save

At angular-cli.json :

Go to section apps and find styles array inside it (with only styles.css value by default), add the following line inside array before any styles:

"../node_modules/materialize-css/dist/css/materialize.css"

Go to section apps and find scripts array inside it, and add the following lines inside array

"../node_modules/jquery/dist/jquery.js", "../node_modules/hammerjs/hammer.js", "../node_modules/materialize-css/dist/js/materialize.js"

Add to the top of app.module.ts

import { MaterializeModule } from 'angular2-materialize';

Add MaterializeModule inside imports array of @NgModule decorator in app.module.ts

Add this line to header of index.html

<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

But when tried console.log(Materialize) I got an error":

ERROR in /jolet_angular/src/app/app.component.ts (27,21): Cannot find name 'Materialize'

rubyboy commented 7 years ago

@rvgarimrj the steps look fine. You can double-check and confirm with the sample JSON in the repo (https://github.com/InfomediaLtd/angular2-materialize/blob/master/sample/.angular-cli.json).

Would you like to share your project? Will be easier to provide help with a reproducible use case.

rvgarimrj commented 7 years ago

@rubyboy thank you. Now I could solve the problem. I am using docker and when migrating from angular2 to angular4 npm was broken. I then used docker-compose run web site npm rebuild node-sass --force and it seams to be solved. Thank you for your support.

rubyboy commented 7 years ago

@rvgarimrj I'm glad you've solved it. Thanks for letting us know.

rubyboy commented 7 years ago

Duplicate: https://github.com/InfomediaLtd/angular2-materialize/issues/106

ghost commented 7 years ago

No clean solution available ?

(Other than https://github.com/InfomediaLtd/angular2-materialize/issues/106#issuecomment-280598020)

art-codes commented 7 years ago

Try setting a timeout function after the ajax call and before calling the Materialize.updateTextFields() method:

$timeout(function () { Materialize.updateTextFields(); }, 10);

Keshava11 commented 7 years ago

For those who use the files from CDN.

I got it fixed by changing the way of inclusion of js and css files.

<head>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.min.css">
</head>
<body>
------------------------
---------------------------
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/js/materialize.min.js"></script>
</body>

Just that change and it worked.

821jieun commented 6 years ago

thanks for the suggestions! @Keshava11 and @anacarol91 i tried both ways, but i am still having the overlap issues has anyone found anything else that works for them?

juliosilvacwb commented 6 years ago

put a ngClass in your label like this

<label for="name" [ngClass]="{'active': user.name }">Name

LutfiLokman commented 5 years ago

Other than setting the label as class=active, put an empty placeholder in input, for example where I want the date template to pre-fill the form and force the label to be active:

<input placeholder="" type="date" id="dateofBirth">

amo42 commented 5 years ago

Same issue here. Since I'm using the CSS Framework for a Chrome extension with vanilla JS, loading some data from the Chrome storage triggered the issue. using the empty placeholder workaround (thank @narxiss24 ) works just fine, while the Materialize.updateTextFields(); won't work. Btw. Adding timeouts to is not a very smart solution from my pov.

Femi1 commented 4 years ago

Add style to material-icons .material-icons {z-index:1}