1

I fear I am missing something really simple, but I have tried multiple attempts with various errors. On to the code:

<script>
        document.getElementById("optStats").on("change", function(e) {
    alert("Switch changed!");
  });
    </script>
<ons-switch modifier="list-item" id="optStats"></ons-switch>

So the above does not work. It generates an error of Uncaught TypeError: Cannot read property of on of null. So I assumed that I needed to add the function to the onload init function but it still failed with the same error.

I have tried all the options listed here: https://onsen.io/guide/overview.html#EventHandling without success. This would include using var instead of id and just about anything else listed that I thought would work.

Edit: Full code that is not working, but works in codepen without template tag.

<ons-template id="options.html" >
        <ons-page>
            <ons-toolbar>
                <div class="center">Options</div>
            </ons-toolbar>         
            <ons-list modifier="inset" style="margin-top:10px;">
                <ons-list-item>
                  Detailed Stats
                  <ons-switch modifier="list-item" id="optStats"></ons-switch>
                </ons-list-item>
            </ons-list>            
        </ons-page>
    </ons-template>

I am using this in ons.ready() and have tried it outside which results in the same error, cannot read property of addEventListener, as listed above for both.

document.getElementById('optStats').addEventListener('change', function(e) {
      console.log('click', e.target.checked);
    });

Last Update I swear: FINALLY!!!! Thank you @Fran-dios!

After working with this, init is not the event you want to use, you definitely want to use show for what I was trying to do.

document.addEventListener("show", function(event){
    if (event.target.id == "pgOptions") { 
        document.getElementById('optStats').addEventListener('change', function(e) {
            localStorage.setItem('useDetailedStats', e.target.checked); 
            useDetailedStats = e.target.checked;
        });
        document.getElementById('optStats').setChecked(useDetailedStats);
      } 
},false);

For whatever reason, when using init on a <ons-tabbar>, whenever you would press the tab, it would cause the switch to change states. By using show, it does not. Additionally, when I logged the init action, the page, even though it was not being shown on app startup, was still being logged as being init twice. Show does not cause this. Either way, the code that @fran-dios provided is the correct basis to get what I needed and his answer is still correct, I just needed to use a different event.

Munsterlander
  • 1,356
  • 1
  • 16
  • 29

1 Answers1

4

I fear you are right. Perhaps what you want to use is JS' addEventListener rather than jQuery's on. The rest should be correct.

Update:

Super simple example: http://codepen.io/frankdiox/pen/WrKjew

<ons-page>
  <ons-switch id="mySwitch"></ons-switch>
</ons-page>
-----
document.getElementById('my-switch').addEventListener('change', function(e) {
  console.log('click', e);
});

Update 2:

The real problem is about initializing pages in Onsen UI 2. The best way is using page life cycle events, specifically init event.

document.addEventListener("init", function(event) {
  if (event.target.id == "my-page") {
    document.getElementById("my-switch").addEventListener('change', function(e) {
      console.log('click', e);
    });
  }
}, false);
Augusto
  • 2,125
  • 18
  • 27
Fran Dios
  • 3,482
  • 2
  • 15
  • 26
  • I placed `document.getElementById("optStats").addEventListener("change", function(){ alert('t'); });` in an ons.ready() function to make sure the DOM was loaded and it results in a similar error except for `cannot read property of addEventListener`. So, if this doesn't work, what would you say is the best way to save setting switches then, onload / exit (push/pop) of screen? – Munsterlander Feb 01 '16 at 19:16
  • @Munsterlander I added an example. Make sure that you are finding something with `getElementById`. Is perhaps your switch not attached to the DOM? – Fran Dios Feb 02 '16 at 02:43
  • I checked it and confirmed. What is weird, is I copied my code to your example and it works, but not when in my app. I get the same error in my app as listed above. I am stumped. – Munsterlander Feb 02 '16 at 03:19
  • Would it not function being in a template? – Munsterlander Feb 02 '16 at 03:31
  • Not if you didn't push the content of that template before. Templates are like different html files, their content is not attached to the DOM so you cannot find it with `getElementById`. – Fran Dios Feb 02 '16 at 04:01
  • I just tested that and was coming back to say this. Sorry for wasting everyone's time on this. I know this is a completely different question, but how can you push the content of the template before hand? I am using the tabbar and have an options tab. Would I need to invoke the loadPage()? If so, when exactly would you do this, in the ons.ready() then add the listener? – Munsterlander Feb 02 '16 at 04:06
  • I tried: `document.getElementById('myTabBar').loadPage('options.html'); document.getElementById('mySwitch').addEventListener('change', function(e) { alert('yay'); });` The page is loaded but the error still persists saying that the DOM object does not exist. Is there a way to do a callback on pageLoad()? – Munsterlander Feb 02 '16 at 04:40
  • The content of the template are attached to the DOM whenever you use them. For example in the tabbar, if you click on a tab it internally calls loadPage and attaches the linked page to the DOM. I believe what you want to do is to "initialize" a page with custom data/behavior, so please read this: https://onsen.io/guide/overview.html#Pagelifecycle – Fran Dios Feb 02 '16 at 05:05
  • `init` event is fired when the page is ready and attached, so simply listen for `init` events (you can add a listener to your tabbar element or directly to the document) and then set up your stuff in that page. – Fran Dios Feb 02 '16 at 05:07
  • Thank you! I will work with this. I was just a bit higher in the docs and didn't make it down that far. I think this will get what I need done. All else fails, use a button to save! HA! Sorry, spent all day on this and the chart thing that are all related to this issue. What a time suck for not reading the docs a bit far enough. – Munsterlander Feb 02 '16 at 05:09
  • The init function caused a very unique error. By switching it to show, it resolves this issue. I have updated the question to show the new code. – Munsterlander Feb 08 '16 at 02:09
  • 100% working document.getElementById('myswitch').addEventListener('change', function(e) { console.log('click', e); }); – GUGAN RAJ Feb 14 '22 at 06:09