angular / components

Component infrastructure and Material Design components for Angular
https://material.angular.io
MIT License
24.32k stars 6.72k forks source link

Support template content for selected value in md-select #2275

Closed wouterbeukers closed 7 years ago

wouterbeukers commented 7 years ago

Bug, feature request, or proposal:

bug

What is the expected behavior?

Selected option of a md-select supports html-tags

What is the current behavior?

Selected option of a md-select doesn't supports html-tags

What are the steps to reproduce?

See http://plnkr.co/edit/QJUCobw9yFcu1l1WtpOR?p=preview Open the md-select. In the dropdown the option supports html tags Select the option All html tags are stripped of the shown value in the md-select.

dougmbarcellos commented 7 years ago

Use this to display the formatted html: <div [innerHtml]="selectedValue"></div>

wouterbeukers commented 7 years ago

That isn't the issue. It is about the value what the md-selects shows after you select an option. This value is stripped of al it's html-tags.

negberts commented 7 years ago

The html is stripped here:

get viewValue(): string { // TODO(kara): Add input property alternative for node envs. return this._getHostElement().textContent.trim(); }

I would love to change it, but I don't know what the impact will be. There's probably a reason why textContent is taken and not just value

fxck commented 7 years ago

@kara do you have something in mind regarding this? I would probably like to take a look at it.. also @crisbeto do you expect any problems with this because of multiselect?

crisbeto commented 7 years ago

I don't expect any issues with multi select since it'll use the same property to get the text. I was actually considering giving this a shot in the next few days.

andreasrueedlinger commented 7 years ago

@crisbeto thanks for your PR. So I guess you intended that with this change you can add the "plain HTML" option as label as follows: <md-select-label [innerHtml]="select.selected?._getHostElement().innerHTML"></md-select-label>

crisbeto commented 7 years ago

This is the intended usage @andreasrueedlinger:

<md-select #select="mdSelect">
  <md-select-label>
    {{ select.selected?.viewValue }}
  </md-select-label>
  <!-- options go here -->
</md-select>
andreasrueedlinger commented 7 years ago

@crisbeto but that does not fix the problem adressed in this issue, namely that the label does not support Html!

crisbeto commented 7 years ago

You can put any HTML you want inside the md-select-label element.

fxck commented 7 years ago

That's not what he meant I think.

When you have..

<md-option>
  <img src="whatever.jpg" /> Whatever
</md-option>

..and you select it, the selected content won't be <img src="whatever.jpg" /> Whatever, it will be stripped down to Whatever. He wants the original unstripped HTML to be there instead. I'm not sure if {{ select.selected?.viewValue }} does that?

andreasrueedlinger commented 7 years ago

But in your example you use normal binding and viewValue which returns the trimmed textContent, so no Html anymore. My example:

<md-select placeholder="Feedback" [formControl]="control" #select="mdSelect">
  <md-select-label [innerHtml]="select.selected?._getHostElement().innerHTML"></md-select-label>
  <md-option value="good">
    <md-icon>thumb_up</md-icon> Nice!
  </md-option>
  <md-option value="bad">
    <md-icon>thumb_down</md-icon> Bad!
  </md-option>
</md-select>
crisbeto commented 7 years ago

That's true, but if we just dumped the innerHTML instead, we'd be opening the user up to XSS, in addition to the potential performance implications.

fxck commented 7 years ago

There should be a straightforward way to do it nevertheless. It's pretty limiting when you know the values are safe.

fxck commented 7 years ago

Also the way it works currently is that if I have..

<md-option>
  <span class="in-a-circle-with-background-and-uppercase">un</span>User Name
</md-option>

..the selected value will be unUser Name, which is pretty annoying..

crisbeto commented 7 years ago

You can still use _getHostElement().innerHTML as @andreasrueedlinger mentioned, but there are better ways to do the same (e.g. you could map images or icons to values in your component).

andreasrueedlinger commented 7 years ago

XSS should not be a problem since Angular sanitizes the input to innerHtml unless you explicitely allow (https://angular.io/docs/ts/latest/api/platform-browser/index/DomSanitizer-class.html)

ermarkar commented 7 years ago

support for multiple selection ?

fxck commented 7 years ago

Good thing is that I think this could be used for https://github.com/angular/material2/pull/2722#issuecomment-277622084

Toub commented 7 years ago

Is there any workaround with 2.0.0-beta.3 ?

fxck commented 7 years ago

@Toub still waiting for https://github.com/angular/material2/pull/3341

matte00 commented 7 years ago

Any news about this?

negberts commented 7 years ago

An updated plunker for the problem can be found here: http://plnkr.co/edit/vuF3Pz7UHDXERXZbtiIK?p=preview

mladilav commented 7 years ago

Any news about this?

sdargaud commented 7 years ago

As a dirty workaround I am currently using somehting along those lines :

<md-select placeholder="Feedback" [formControl]="control" #select="mdSelect">
  <md-option value="good">
    <md-icon *ngIf="select.panelOpen">thumb_up</md-icon> Nice!</md-icon>
    <div *ngIf="!select.panelOpen">Nice!</div>
  </md-option>
</md-select>

At least I don't have "thumb_up Nice!" displayed and can work with it until it's fixed (be aware, it does seem to take some time to evaluate the template when opening the select, and the raw html is shown for a short period of time).

LayZeeDK commented 5 years ago

For future reference, you can use the <mat-select-trigger> to change the display of the selected value.

It was added by @crisbeto in Angular Material version 2 beta 10.

angular-automatic-lock-bot[bot] commented 5 years ago

This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.