Wednesday, 17 April 2013

Passing data between navigation views in Sencha Touch 2

I've grossly neglected this blog so I though I'd best put something up. I've been using Sencha Touch recently and here is a way for passing data between navigation views.

The Views:

Ext.define('DataTest.view.Main', {
    extend: 'Ext.Container',
    xtype: 'main',
    requires: [
        'Ext.TitleBar',
        'Ext.navigation.View',
        'DataTest.view.FormPage1'
    ],
    config: {
        tabBarPosition: 'bottom',
        layout: 'fit',
        items: [
            {
                xtype: 'navigationview',
                itemId: 'mainNavView',
                navigationBar: {
                    docked: 'top'
                },
                items: [{
                        xtype: 'formpage1'
                    }]
            }
        ]
    }
});

Some Forms

Ext.define('DataTest.view.FormPage1', {
    extend: 'Ext.form.Panel',
    xtype: 'formpage1',
    config: {
        nextpage: 'formpage2',
        items: [{
                html: 'Form Page 1'
            }, {
                xtype: 'textfield',
                name: 'text1',
                label: 'Text 1'
            }, {
                xtype: "button",
                itemId: "nextButton",
                text: 'Next'
            }]
    }
});
Ext.define('DataTest.view.FormPage2', {
    extend: 'Ext.form.Panel',
    xtype: 'formpage2',
    config: {
        nextpage: 'formpage3',
        items: [{
                html: 'Form Page 2'
            }, {
                xtype: 'textfield',
                name: 'text2',
                label: 'Text 2'
            }, {
                xtype: "button",
                itemId: "nextButton",
                text: 'Next'
            }]
    }
});
Ext.define('DataTest.view.FormPage3', {
    extend: 'Ext.form.Panel',
    xtype: 'formpage3',
    config: {
        nextpage: '',
        items: [{
                html: 'Form Page 3'
            }, {
                xtype: 'textfield',
                name: 'text3',
                label: 'Text 3'
            }, {
                xtype: "button",
                itemId: "nextButton",
                text: 'Fin'
            }]
    }
});

And finally the controller

Ext.define('DataTest.controller.Main', {
    extend: 'Ext.app.Controller',
    requires: ['Ext.Anim'],
    config: {
        refs: {
            mainNavView: "main #mainNavView",
            nextButton1: "formpage1 #nextButton",
            nextButton2: "formpage2 #nextButton",
            nextButton3: "formpage3 #nextButton"
        },
        control: {
            mainNavView: {
                activate: "onMainNavViewActivate",
                push: "onMainNavViewPush",
                pop: "onMainNavViewPop",
            },
            nextButton1: {tap: "onNextButtonTap"},
            nextButton2: {tap: "onNextButtonTap"},
            nextButton3: {tap: "onNextButtonTap"}
        }
    },
    onMainNavViewActivate: function() {
        this.dataObj = {};
    },
    onMainNavViewPush: function(self, view) {
        view.setValues(this.dataObj);
        console.log("push: ", this.dataObj);
    },
    onMainNavViewPop: function(self, view) {
        this.dataObj = Ext.Object.merge(this.dataObj, view.getValues());    
        console.log("pop: ", this.dataObj);
    },
    onNextButtonTap: function(self) {
        var form = self.up('formpanel'),
                nextPage = form.getNextpage();
        this.dataObj = Ext.Object.merge(this.dataObj, form.getValues());
        if (nextPage != '') {
            this.getMainNavView().push({xtype: self.up('formpanel').getNextpage()});
        } else {
            this.getMainNavView().reset();
        }
    }
});

Tuesday, 21 February 2012

jQuery image mouseover / mouseout replacement

This plugin takes a standard mouseover / mouseout source replacement on an image and swaps it for a nice jQuery image fade between the two images
(function ($) {
    "use strict";
    $.fn.hoverFade = function () {

        return this.each(function () {

            var $this = $(this), $parent, mOver = $this.attr("onmouseover"), mOut = $this.attr("onmouseout");

            if ((mOver !== undefined) && (mOut !== undefined)) {

                mOver = mOver.replace("this.src=", "").replace(";", "").replace("'", "");
                mOut = mOut.replace("this.src=", "").replace(";", "").replace("'", "");

                $this.removeAttr("onmouseover")
                    .removeAttr("onmouseout")
                    .wrap("<div style='position:relative; display:inline-block; width:" + $this.width() + "px; height:" + $this.height() + "px' />")
                    .attr("style", "position:absolute; left:0; top:0;");

                $parent = $this.parent("div");

                $parent.append("<img class='hoverFadeOver' src='" + mOver + "' />");

                $(".hoverFadeOver", $parent).css({
                    "position": "absolute",
                    "left": "0",
                    "top": "0",
                    "opacity": 0
                });

                $parent.hover(function () {
                    $(".hoverFadeOver", $(this)).animate({
                        "opacity": 1
                    });
                }, function () {
                    $(".hoverFadeOver", $(this)).animate({
                        "opacity": 0
                    });
                });
            }

        });
    };
}(jQuery));

Usage:
<script>
$(function () {
 $('img').hoverFade();
});
</script>

<img src="/myimage.jpg" onmouseover="this.src='/myimage-over.jpg';" onmouseout="this.src='/myimage-over.jpg';" />

Notes: it does currently require that the format of the src in the onmouseover / onmouseout handlers is as above but hey, you get the idea right?

jQuery UI widget with setInterval (in context)

This is a basic jQuery UI widget using setInterval in context thanks to Javascript is Awesome
(function ($) {
    "use strict";
    $.widget('test.pauser', {

        options: {
        },

        _create: function () {
            var $this = this;
            $this.index = 0;
            $this.max = 5;
            $this._start();
            $("#msg").append("timer");
        },

        _setIntervalWithContext: function (code, delay, context) {
            return setInterval(function () {
                code.call(context);
            }, delay);
        },

        _doTimer: function () {
            var $this = this, i;
            $("#msg").append("timer");
            ++$this.index;
            if ($this.index >= $this.max) {
                $this.index = 0;
            }
            for (i = 0; i < $this.index; i++) {
                $("#msg").append(".");
            }
        },

        _start: function () {
            var $this = this;
            $this.interval = $this._setIntervalWithContext(function () {
                $this._doTimer();
            }, 1000, $this);
        },

        pause: function () {
            var $this = this;
            $("#msg").append("pause!");
            $("#pause").hide();
            $("#resume").show();
            clearInterval($this.interval);

        },

        resume: function () {
            var $this = this;
            $("#msg").append("resume!");
            $("#pause").show();
            $("#resume").hide();
            $this._start();
        }

    });

}(jQuery));
And here is how to use it...
$(function () {
    $("#resume").hide();
            
    $("#msg").pauser();
                
    $("#pause").click(function() {
        $("#msg").pauser("pause");
    });
                
    $("#resume").click(function() {
        $("#msg").pauser("resume");                    
    });
});
...in here!
pauseresume