14

I want to call the function whenever the input is changed.

I have created the following in my home.html file

<ion-input type="text" class="scoreboardus" [(ngModel)]='text' 
      (input)='onInputTime($event.target.value)' (change)='onChangeTime($event.target.value)'>
   </ion-input>

and in home.ts file

onChangeTime() {
  alert('onChangeTime called');
}

onInputTime() {
  alert('onInputTime called');
}

the above code works fine if manually give values in the input field.

My problem:

I am changing input value from one of external javascript file.

$('.scoreboardus input').val(200).trigger('onchange');

The above code change the input field value… But function is not called

resultant code should work after creating an app.

Krsna Kishore
  • 8,233
  • 4
  • 32
  • 48
Sugumar Venkatesan
  • 4,019
  • 8
  • 46
  • 77
  • Duplicate of https://stackoverflow.com/questions/34827334/triggering-angular2-change-detection-manually – Greg Dan Sep 16 '17 at 16:05

6 Answers6

26

The Ionic's input events start with ion:

  • (ionChange) instead of (change)
  • (ionInput) instead of (input)
<ion-input type="text" class="scoreboardus" [(ngModel)]='text'
  (ionInput)='onInputTime($event.target.value)'
  (ionChange)='onChangeTime($event.target.value)'>
hc_dev
  • 8,389
  • 1
  • 26
  • 38
Fabio Campinho
  • 982
  • 8
  • 13
  • @vSugumar since you're commenting the same for all answers and not replying to any comments, I will vote to close the question once the bounty period is over – Sagar V Sep 20 '17 at 07:29
  • @– i-- I tried all the posted answers before posting my question here... – Sugumar Venkatesan Sep 20 '17 at 08:28
  • You could try: this.elementRef.nativeElement.querySelector('.scoreboardus') .addEventListener('change', this.onChangeTime.bind(this)); – Fabio Campinho Sep 21 '17 at 11:36
6

Have you installed the Jquery in your ionic-2 as follows

Installing Jquery

 npm install jquery --save

After that, install JQuery global derectory to typings ( you can import it):

typings install dt~jquery --global --save

Then, you can import JQuery in your "home.ts"

import * as $ from 'jquery'

Now try your Jquery function as follows:

$('.scoreboardus input').val(200).trigger('change');

Update: You could assign a template reference variable to the , like #ionInput1, get a hold of its native element (via @ViewChild) inside the component class and then use jQuery itself to listen to the change event.

   import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';

    @Component({
      selector: 'my-app',
      template: `
      <h1>Firing Jquery</h1>
      <hr>
     <ion-input type="text" class="scoreboardus" [(ngModel)]='text' 
      (input)='onInputTime($event.target.value)' (change)='onChangeTime($event.target.value)' #ionInput1>
   </ion-input>
      })
    export class AppComponent implements AfterViewInit  {

      @ViewChild('ionInput1') ionInput1:ElementRef;

      ngAfterViewInit() {
        $(this.ionInput1.nativeElement).on('change', (e) => {
          console.log('Change made -- ngAfterViewInit');
          this.onChangeTime(e);
        });
      }

      onChangeTime(): void{
        console.log('Change made -- onChangeTime');
      }

    }

For More info Refer this SO SOlution

Krsna Kishore
  • 8,233
  • 4
  • 32
  • 48
2

You are very close to what you're looking for.

Your code has a small issue

$('.scoreboardus input').val(200).trigger('onchange');
                                           ^^^^^^^^^

Instead of onchange, you should use change to trigger the action. on should not be added as prefix. The event name should be the same we are using in on() function in jQuery or addEventListener in JavaScript.

$('.scoreboardus input').val(200).trigger('change');

onchange won't work

$(document).ready(function(){
  $('#ip').on('change',function(){
    alert(this.value);
  });
  $('#btn').click(function(){
    $('#ip').val('test').trigger('onchange');
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="ip" />
<button id="btn">Change</button>

you have to use change instead

$(document).ready(function(){
  $('#ip').on('change',function(){
    alert(this.value);
  });
  $('#btn').click(function(){
    $('#ip').val('test').trigger('change');
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="ip" />
<button id="btn">Change</button>

Your code works only when editing manually is because the changes made by the scripts won't trigger the event listener. You have to trigger it manually.

Also note that you have to use arrow function ()=>{} inside Angular and add the jQuery code inside ngAfterViewInit then only dynamic elements will be supported in angular

Sagar V
  • 12,158
  • 7
  • 41
  • 68
  • can you add the angular code you tried? not working means is it set the value and not trigger the event or not setting the value at all? – Sagar V Sep 13 '17 at 06:01
2

There are two dark points in your way, what we can not control. They are:
1. (change)='onChangeTime($event.target.value)'. I'm not sure how Ionic bind change function. Maybe it is not the same with change function of input. So we can not control it.
2. $(...).trigger('onchange') we can not control how Jquery triggle it.

So, just do the way that we know and we can control. It is pure javascript.

<ion-input type="text" class="scoreboardus" [(ngModel)]='text'> </ion-input>

You should add onChange listener by javascript:

ionViewDidEnter() { 
    let input = <HTMLInputElement>document.querySelector('.scoreboardus input');
    input.addEventListener('change', (event) => {
      console.log("onChange function fired");
      //Your onChange function here. Do what you want
      this.text = event.target["value"];
    })

    //Now we try to change your input value by javascript
    setTimeout(() => {
      input.value = "Hey. Im changing";

      //Trigger onChange function manually
      var evt = document.createEvent("HTMLEvents");
      evt.initEvent("change", false, true);
      input.dispatchEvent(evt);
      console.log("I'm done");
    }, 3000)
  }
Duannx
  • 7,501
  • 1
  • 26
  • 59
  • Don't do this. If you're using "addEventListener" in angular you're doing something wrong. – Lenny Mar 12 '18 at 03:32
  • @Lenny : :"If you're using "addEventListener" in angular you're doing something wrong". Can you please explain that? – Duannx Mar 12 '18 at 03:55
  • The whole point of a framework like angular is so you don't have to manually manipulate the DOM. In fact, manually bypassing angular can cause very unpredictable bugs. Plus, is usually way more work than just doing it "The Angular Way" – Lenny Mar 17 '18 at 05:54
  • @Lenny I agree that angular help us don't have to manually manipulate the DOM. But Angular can not support us in all cases. This case is an example. We need to manipulate DOM by pure JS to achive what we want. I often do that and did not find any downside of it – Duannx Mar 17 '18 at 06:26
  • Angular has built in change detection so this isn't needed, HOWEVER in a scenario where you do need to manually bind to the DOM you still shouldn't use vanilla JS as angular has decorators for this. See: `@HostListener()` and `@HostBinding()` in the angular docs – Lenny Jul 24 '18 at 23:24
0

Use keyup event this fires event handlers automatically and works for me

-2

try this :

 <ion-item>
    <ion-input [(ngModel)]="nickname" (keypress)="onChange($event)" ></ion-input>
  </ion-item>