Search code examples
javascripttitaniumtitanium-alloytitanium-widgets

Modifying widgets in an alloy project


I have a widget which is a photo gallery. It's basic functionality means that it only allows the user to click on a thumbnail and then enlarge/de enlarge upon an onclick event.

I need to expand the widget so that there is a button which allows the user to change their profile pictures accordingly (if they select that picture).

Here is how the code looks by default in widget.js:

var topView = Ti.UI.createView({
    width:Ti.UI.FILL,
    height: Ti.UI.FILL,
    zIndex:1200,
    visible:false
});

// this gets image , adds it to top view
var imgView = Ti.UI.createImageView({
    image: url,
    width:Ti.UI.SIZE,
    height: Ti.UI.SIZE
});

//add it
topView.add(imgView);

Now to add a button, I can add the following into widget.js:

var button = Titanium.UI.createButton({
    title : 'Use Picture',
    top : 10,
    width : 100,
    height : 50
}); 

button.addEventListener('click', function(e) {
    Alloy.Global.Image = url;
});

topView.add(button);

This will close the pop up and return the url of that image by putting it inside a global variable. I can then use this and change my the picture to the new one by calling that in the relevant controller.

The question is, what is the best way expand the widget.js code and is using a global variable this way the best way to do this?


Solution

  • What I often do with custom widgets is adding a callback, so you can return values directly.

    widget.xml

    <Alloy>
        <Button title="Click me!" onTouchend="buttonClicked" />
    </Alloy>
    

    widget.js

    // This will hold our callback
    var onClickCallback;
    
    // The button has been clicked, call callback
    function buttonClicked(e) {
        if(typeof(onClickCallback) === 'function') {
            onClickCallback({ type:'clicked!' }); }
       }
    }
    
    // Assign our callback
    function onClick(callback) {
        onClickCallback = callback;
    }
    
    // Make the onClick function public
    exports.onClick = onClick;
    

    index.xml

    <Alloy>
        <Window>
            <Widget id="myWidget" src="myWidget" />
        </Window>
    </Alloy>
    

    index.js

    // Now we can intercept the click within the widget
    // and use the values passed
    $.myWidget.onClick(function(e) {
        alert(e.type);
    });