-2

I'm using stencil.js to create a web component that is framework agnostic and contains some ionic4 web components including <ion-input>

The docs for ion-input show a method getInputElement() => Promise<HTMLInputElement> to access the native <input> but I'm not finding the correct way to use it to expose the inner element in my component.

How does getInputElement it get used?

@Component({
  tag: 'my-component',
  styleUrl: 'my-component.css',
  shadow: true
})

export class MyComponent {    
  @Element() el: HTMLElement;
  @Prop .... ///some props
  @State ... // some state

  componentDidLoad(){}

  render() (
      <div className="foo">
        <ion-item>
          <ion-label> {this.someProp}</ion-label>
          <ion-input          
            value={this.someProp}
            clear-input={this.someProp}            
            onInput={this.handleInput} /> 
        </ion-item>
       <div>...more</div>
      </div>
    )
}
Maik Lowrey
  • 15,957
  • 6
  • 40
  • 79
charlietfl
  • 170,828
  • 13
  • 121
  • 150

2 Answers2

3

I'd assume you could do something like this using the ref feature (you should probably type this):

ionInputElement;

@Element() el: HTMLElement;
@Prop .... ///some props
@State ... // some state

componentDidLoad(){
  this.ionInputElement.getInputElement().then((el) => this.el = el);
}

render() {
  return (
    <div className="foo">
      <ion-item>
        <ion-label> {this.someProp}</ion-label>
        <ion-input ref={(el) => this.ionInputElement = el}         
          value={this.someProp}
          clear-input={this.someProp}            
          onInput={this.handleInput} /> 
      </ion-item>
      <div>...more</div>
    </div>
  );
}
G. Tranter
  • 16,766
  • 1
  • 48
  • 68
  • I probably tried something like that before. Finally worked in `componentDidLoad()` as per your approach by wrapping in a `setTimeout()` which seems like ugly hack. Thanks...didn't expect this one to take so long to get an answer! – charlietfl Apr 30 '19 at 22:02
  • I wouldn't expect to have to use `setTimeout()` since that's really the purpose of the Promise returned by `getInputElement()`. But I never tried it. `componentDidLoad()` is expected however, because `ref` only works once the component is loaded. – G. Tranter May 01 '19 at 14:20
2

You can get a reference to a JSX element by using the ref prop. e.g.:

<ion-input ref={input => this.ionInput = input}

Then in one of your component's methods you can access it as this.ionInput.getInputElement()

See more at https://stenciljs.com/docs/templating-jsx#getting-a-reference-to-a-dom-element

matthewsteele
  • 1,797
  • 1
  • 15
  • 31