1

I'm using mdl-select component. It's a drop-down list. When you press it there are focusin event fired. But it doesn't when you press an arrow-dropdown icon, so I needed to change a template a bit to have a desired behavior. But it's a library component. Is there a way to override it's template?

The thing I need to change just to add tabindex=\"-1\" to element. I can do it with js, but I use component a lot in app, and I don't want to use document.getElement... every time I use MdlSelectComponent in the views of my own components.

I tried to use @Component decorator function on MdlSelectComponent type, however it requires to declare this class once again and anyway have done nothing.

Update

main.browser.ts

/*
 * Angular bootstraping
 */
import { Component } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { decorateModuleRef } from './app/environment';
import { bootloader } from '@angularclass/hmr';

import {MdlSelectComponent} from '@angular2-mdl-ext/select';
/*
 * App Module
 * our top level module that holds all of our components
 */
import { AppModule } from './app';

/*
 * Bootstrap our Angular app with a top level NgModule
 */
export function main(): Promise<any> {
  console.log(MdlSelectComponent)
  MdlSelectComponent.decorator.template = "<div class=\"mdl-textfield is-upgraded\" [class.is-focused]=\"this.popoverComponent.isVisible || this.focused\" [class.is-disabled]=\"this.disabled\" [class.is-dirty]=\"isDirty()\"> <span [attr.tabindex]=\"!this.disabled ? 0 : null\" (focus)=\"open($event);addFocus();\" (blur)=\"removeFocus()\"> <!-- don't want click to also trigger focus --> </span> <input #selectInput tabindex=\"-1\" [readonly]=\"!autocomplete\" class=\"mdl-textfield__input\" (click)=\"toggle($event)\" (keyup)=\"onInputChange($event)\" (blur)=\"onInputBlur()\" [placeholder]=\"placeholder ? placeholder : ''\" [attr.id]=\"textfieldId\" [value]=\"text\"> <span class=\"mdl-select__toggle material-icons\" (click)=\"toggle($event)\"> keyboard_arrow_down </span> <label class=\"mdl-textfield__label\" [attr.for]=\"textfieldId\">{{ label }}</label> <span class=\"mdl-textfield__error\"></span> <mdl-popover [class.mdl-popover--above]=\"autocomplete\" hide-on-click=\"!multiple\" [style.width.%]=\"100\"> <div class=\"mdl-list mdl-shadow--6dp\"> <ng-content></ng-content> </div> </mdl-popover> </div> ";

  return platformBrowserDynamic()
    .bootstrapModule(AppModule)
    .then(decorateModuleRef)
    .catch((err) => console.error(err));
}

// needed for hmr
// in prod this is replace for document ready
bootloader(main);

APP.COMPONENT.TS

import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { Router } from '@angular/router';
require('../../../styles/styles.scss');
import {MdlSelectComponent} from '@angular2-mdl-ext/select';
//
declare let Reflect: any;
Reflect.getOwnMetadata('annotations', MdlSelectComponent)[0].template = 'Hooray';
@Component({
    selector: 'app',
    encapsulation: ViewEncapsulation.None,
    styleUrls: [],
    template: `
        <div>
            <mdl-select [(ngModel)]="personId">
                <mdl-option *ngFor="let p of people" [value]="p.id">{{p.name}}</mdl-option>
            </mdl-select>
            <router-outlet></router-outlet>
        </div>`
})
export class AppComponent implements OnInit {
    constructor(
        router: Router,
    ) {
        router.events.subscribe(data => {
            scrollTo(0, 0);
        });
    }

    public ngOnInit() {
    }
}
4
  • You can copy paste the component with your own name and add the functionality you desire. SInce you are using angular2-mdl it should be very easy Commented Jul 5, 2017 at 11:24
  • @Skeptor Peatifully, it's not an option. Component uses a lot of inner library dependences, and it's not a single component from the library I use. As a case I can override that file with a help of webpack, but I wanted to know if I can just redecorate it with a new template for example in app.component.ts/ Commented Jul 5, 2017 at 12:02
  • Try if you can do something like MdlSelectComponent.decorator.template ='' inside main.ts. Since its all mdl , you can write your own html with appropriate classes just for that component and build your own component Commented Jul 5, 2017 at 12:33
  • @Skeptor Have done this (see update) but is says there'is no decorator property on this type. Am I doing something wrong? Commented Jul 5, 2017 at 13:06

1 Answer 1

2

As @angular2-mdl-ext/select uses Reflect to define decorators then you do the following

declare let Reflect: any;
Reflect.getOwnMetadata('annotations', MdlSelectComponent)[0].template = 'Hooray';

Plunker Example

Sign up to request clarification or add additional context in comments.

7 Comments

Hi, thanks you very mush for replay. I've inserted the following lines in my app.module.ts file as you did in planker, however still can't get it to work - template doesn't change( Have tried with main.ts and app.component.ts as well. You can see app.component.ts in updates. What have I done wrong?
@K.Rice How do you build your project? Maybe you can put up a github repo with minimal reproduction?
Thanks for repo. You are overriding another component with the same name import { MdlSelectComponent } from '@angular2-mdl-ext/select';
But you use component from import { MdlSelectModule, MdlSelectComponent } from '@angular-mdl/select';
So remove import { MdlSelectComponent } from '@angular2-mdl-ext/select'; and import MdlSelectComponent from @angular-mdl/select
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.