The problem is that you initialize $("#testing") before the DOM is ready, so this jQuery object is empty.
A simple solution is to put all your code in a ready-made callback.
Another option is to replace
settings: { testButton: $("#testing") }, init: function() { s = this.settings; this.bindUIActions(); },
with
settings: { }, init: function() { s = this.settings; s.testButton = $("#testing"); this.bindUIActions(); },
But itβs hard to understand why you are using such code for such a simple thing. Perhaps you are abusing the template and not very clean, since you have two global variables s and TestWidget , when there will already be a lot of them.
Here is a small variation of your code, which, in my opinion, would be cleaner, although it still used modules ( IIFE option ):
TestWidget = (function(){ var settings = {}; return { init: function() { settings.testButton = $("#testing"); this.bindUIActions(); }, bindUIActions: function() { console.log(settings.testButton); settings.testButton.click(function() { alert('testButton clicked'); }); } } })(); $(document).ready(function() { TestWidget.init(); });
settings is stored in closure and does not leak in the global namespace. Please note that even this version does not make sense if you are not doing more with the module.
source share