9

I am trying to put an image inside a Select component in Ionic 2 : I have put the image source files inside the www/img folder in my Ionic 2 project. However, using a simple img-tag does not display any image using this code:

<ion-list>
  <ion-item>
    <ion-label>Gaming</ion-label>
    <ion-select [(ngModel)]="gaming">
      <ion-option value="nes">
        NES
        <img src="img/myImage.png">
      </ion-option>
    </ion-select>
  </ion-item>
</ion-list>

Does anyone have any idea?

John
  • 10,165
  • 5
  • 55
  • 71

4 Answers4

3

The ion-select component doesn't allow direct customization to itself and anything that you add to ion-select and ion-option which is not as per the ionic documentation, will be ignore in the generated output.

You cannot add class or style to the component.

One way to do this is to put the ion-select in a parent element like div or ion-row etc. with class and apply the CSS rules using .parentclass childElement selector.

To show the images in option check the function below:

    prepareImageSelector() {
    setTimeout(() => {
        let buttonElements = document.querySelectorAll('div.alert-radio-group button');
        if (!buttonElements.length) {
            this.prepareImageSelector();
        } else {
            for (let index = 0; index < buttonElements.length; index++) {
                let buttonElement = buttonElements[index];
                let optionLabelElement = buttonElement.querySelector('.alert-radio-label');
                let image = optionLabelElement.innerHTML.trim();
                buttonElement.classList.add('imageselect', 'image_' + image);
                if (image == this.image) {
                    buttonElement.classList.add('imageselected');
                }
            }
        }
    }, 100);
}

I have implemented color and image selector using ion-select. Please refer https://github.com/ketanyekale/ionic-color-and-image-selector

You can also check the answer at Ionic select input of colours

Ketan Yekale
  • 2,108
  • 3
  • 26
  • 33
  • Thank you for your answer. I am no longer able to test nor validate this method, but if someone else can confirm that the solution works, I will accept this answer. – John May 24 '18 at 07:12
  • That’s fine. Let’s wait until someone else confirms this. I’ve used the solution to one of live projects. If you can check https://github.com/ketanyekale/ionic-color-and-image-selector/blob/master/README.md , I’ve already added the screenshot to the readme file. – Ketan Yekale May 24 '18 at 18:07
  • Also, This is tested and live for browser, android and iOS platforms. – Ketan Yekale May 24 '18 at 18:14
  • Is it possible to use an image and a label together? As the example in my question, I wanted to display a small image next to a lable. – John May 25 '18 at 10:35
  • Yes, small image next to label is also possible with some CSS tweak. I’ll do it and add it to my git repo with a screenshot. – Ketan Yekale May 26 '18 at 16:34
  • Done. Check the recent commits to the git hub repository for https://github.com/ketanyekale/ionic-color-and-image-selector/wiki/images/ion_select_for_image_with_label.PNG – Ketan Yekale May 28 '18 at 10:16
2

I achieved it like this.

<ion-select (click)="loadFlags()" formControlName="pays"  value="select-country">           
    <ion-select-option  value="select-country" >select your country </ion-select-option>
    <ion-select-option *ngFor="let country of countries" value="{{country.name}}">{{country.name}}</ion-select-option>
</ion-select>

And this is my .ts file

loadFlags() {
    setTimeout(function(){ 
     let radios=document.getElementsByClassName('alert-radio-label');
     for (let index = 1; index < radios.length; index++) {
        let element = radios[index];
        element.innerHTML=element.innerHTML.concat('<img class="country-image" 
       style="width: 30px;height:16px;" src="'+countries[index-1].flag+'" />');
      }
  }, 1000);
}

Timeout is to let the system create alert componens. My Json is an array with elements like {name:"Cameroon",flag:"https://restcountries.eu/data/cmr.svg"}

this is my result

Paulius Nyoumi
  • 191
  • 1
  • 12
0

On your basis, I have worked out a more concise solution!

The method 'prepareImageSelector' is used as the Click event of the control。

Thank you!

   image: string = 'English';
 
   prepareImageSelector() {
    setTimeout(() => {
      let buttonElements = document.querySelectorAll('div.alert-radio-group button');
      if (!buttonElements.length) {
        this.prepareImageSelector();
      } else {
        for (let index = 0; index < buttonElements.length; index++) {
          let buttonElement = buttonElements[index];
          let optionLabelElement = buttonElement.querySelector('.alert-radio-label');
          let image = optionLabelElement.innerHTML.trim();
          if (image == this.image) {
            optionLabelElement.innerHTML += '<img  src="assets/img/English.png" style="width:20px;height:20px;float:right;"/>';
          }
        }
      }
    }, 100);
  }
Gavin L
  • 1
  • 1
  • When I run your code snippet I get _"Uncaught SyntaxError: Unexpected token {"_. – skomisa Mar 01 '19 at 08:29
  • No, you shouldn't. You should add it to your JS / TS code and try it! In the process of trying, we should pay attention to these problems: 1.The cartridge frame must be ‘AlertController’ 2.Path Problem of Pictures – Gavin L Mar 04 '19 at 01:46
  • 1
    OK, but in that case what is the point of providing a **Run code snippet** button at all? Why not just provide your code and explain how it should be implemented? Providing your solution as runnable code that doesn't work seems counterproductive. Am I missing something here? – skomisa Mar 04 '19 at 02:44
0

There are already some great answers, and I honestly think Select with some images should have been part of the core Ionic library, but here we are.

I made the following adaptations for my answer:

  • Implemented with Ionic Vue (Ionic 6, so it's still an issue)
  • Flags for the countries are nested in a country JSON obtained from an API call.
  • Implemented for Action Sheet instead of Alert as the other answers
  • Flags appear on the left instead of the right

First, the HTML:

<IonSelect @click="loadFlags()" placeholder="Country" :interface-options="customAlertOptions" interface="action-sheet" cancelText="Cancel" style="width: 100%" v-model="selected_country">
  <template v-for="(country, index) in countries" :key="index">
    <div class="ion-text-center">
      <IonSelectOption :value="country.code">
        <IonLabel>{{ country.name }}</IonLabel>
      </IonSelectOption>
    </div>
  </template>
</IonSelect>

And then the Javascript:

loadFlags() {
  let that = this;
  setTimeout(function() {
    let radios = document.getElementsByClassName('action-sheet-button-inner');
    for (let i = 0; i < that.countries.length; i++) {
      let element = radios[i];
      element.innerHTML = `<div style="display: flex; position: relative; width: 100%"><img style="width: 40px;height:40px;" src="${that.countries[i].flag}"/>`
          + `<span style="font-size:16px; position: absolute; top:10px; left: 70px;">${element.innerHTML}</span></div>`
     }
  }, 10)
}

Even though it's a little crude, the innerHTML in the loadFlags function, with some HTML and CSS, can be used to achieve almost anything.

jaletechs
  • 501
  • 1
  • 7
  • 19