Google analytics code

Saturday, December 14, 2013

Sencha Touch: Problems with Date Time Picker

Part of a project I'm working on requires an form element that allows the user to select a date and time for the same field. Sencha Touch has a built in form field for selecting a date and it works really well. They don't have one that allows you to pick both the date and the time.

I found a plugin on Sencha's site that seemed to be just what I was looking for. There were a few issues with it.

#1 No install instructions.
This is the first plugin I've used and I couldn't find anything on Sencha's site that was helpful. After some digging I found instructions for another plugin that pointed me in the right direction.

  1. Copy the ux folder to your app directory.
  2. Open your app.js file and locate the Ext.Loader line. If there isn't a setPath method chained to setConfig add one. Add these key/value pairs to the object. They correspond to the Ext.define namespaces for DateTime.js and DateTimePicker.js located in the ux folder.
    1. 'Ext.ux.field' : './ux'
    2. 'Ext.ux.picker': './ux'
#2 Bugs
The first problem I had was the cancel button destroyed the picker. One feature of the plugin allows you to destroy the picker to save memory. It's missing a check for the destroy option and nukes it on cancel.

The second problem is if you press OK to the default date it doesn't actually read it properly. Deep in DateTime.js the getValue method looks through the items on the picker and grabs the slots. It calls getValue on each slot but returns nothing. You need to pass true for it to read the proper value.

I was able to find the original source on github. I forked the repo and fixed all the bugs I found. I submitted a pull request so hopefully I'll hear back from the guy soon so future users will have fewer problems.

UPDATE
The github version of the plugin has integrated my pull request that fixes the issues I ran into.

Thursday, November 14, 2013

Sencha Touch: Submit the form with Go/Enter

I'm in the process of refactoring some code from my first Sencha Touch project. I followed a really great tutorial from Miami Coder used to build a login page. There are a few things I wish it did better in terms of separating view and controller code, but you learn that stuff on the road.

One thing I really wish it covered was submitting the form using the Go key on iPhone, or Enter key. It's reliant on pressing the Log In button and then letting the code grab the values and move on. I want to make two changes. I want to listen for the Go key and submit the form, and I want the code to exist in the Controller, not the View.

First let's set up the View.

                xtype: 'fieldset',
                itemId: 'login-form',
                name: 'login-form',
                items: [
                    {
                        xtype: 'textfield',
                        placeHolder: 'Username',
                        itemId: 'user-name-text-field',
                        required: true,
                        autoComplete: false,
                        autoCorrect: false
                    },
                    {
                        xtype: 'passwordfield',
                        placeHolder: 'Password',
                        itemId: 'password-text-field',
                        required: true
                    }
                ]
            },
            {
                xtype: 'button',
                itemId: 'login-button',
                action: 'login',
                // This is just a color style
                ui: 'action',
                text: 'Log in',
                cls: 'login-button'
            }
Now let's set up the Controller.
config: {
        control:{
            // Listen for the login button
            'button[action=login]':{
                tap: 'tryLogin'
            },
            // Listen for a field form submit
            'fieldset[name=login-form]':{
                action: 'tryLogin'
            }
        }
    }
I listen for events in the Controller instead of launching events through the Application from the View and listening for them elsewhere. The View is kept nice and clean and all the logic is in the Controller where it belongs. The Controller can grab a reference to the View and update whatever it needs.

'control' is my new favorite property. It's great for event listening. Once I found out I could tie a function to a button without listening for a command I never looked back.

Monday, November 11, 2013

Git : Tower on sale 50% off

A while ago I wrote an article about my search for a good git client. There are a lot out for OSX which is good because you have a choice, but not all of them are good.


After playing with a few clients I've settled on Tower. It's a really streamlined client that isn't cluttered with buttons. The one downside is that it wasn't cheap. It's normally $59. It's on sale today for $29.50. I highly recommend picking it up. Falls under getting what you pay for.

Monday, August 26, 2013

PHP: Zend Studio 10 Sale

Zend Studio is a fantastic PHP dev tool. I've used it for years and they keep making it better. It's built on top of Eclipse so it can be used as a plugin. I have it set up this way so I can work on my PHP API and Android client in the same tool.

It's on sale now for a limited time. Not sure when the sale ends, but it's totally worth picking up.

Friday, August 2, 2013

Javascript / IE8 : file fields created by javascript allows text entry

I ran into an issue in IE8 while creating file fields in javascript for a form. The newly created file field allowed text entry. It didn't matter if I used jQuery or created the field with createElement.


$
var fileField = $('',{
            'id': 'picker-2',
            'type': 'file'});

            $('#fields').append(fileField);

When the field was placed on the screen it allowed users to enter text. This isn't a huge issue, but this shouldn't happen. It doesn't happen when you create the file field through HTML. You can see an example here.

The solution to this problem is cloning the newly created field before appending it to the DOM.


var fileField = $('',{
            'id': 'picker-2',
            'type': 'file'});

$('#fields').append(fileField.clone());
            
            

This will make it behave like a normal file field. You can see an example here.

Thursday, July 18, 2013

Sencha Touch: Using the Action property of the Button element

I've been trying to wire up the buttons in my UI to handlers inside the view so I could have them fire an event to the controller and complete an action, but it required me to put a function in the config section and it looks messy and isn't portable.

After much googling I found a hidden property of Button called action. I can't find very good documentation on it and wanted to show an example of it because it will make your life so much easier.


// Building a button inside of an items array
{
    xtype: 'button',
    action: 'warnOnLeave',
    align: 'left',
    iconCls: 'home',
    ui: 'back',
}

// Handle the button click inside a controller
control: {
    // Listen for the new button press
    'button[action=warnOnLeave]':{
        tap: 'onCreateNewContent'
    }
}

This saved me quite a few steps because all my button actions triggered something in the controller. This way I can skip using fireEvent and just tie the event to a handler method in the controller.

Sencha Touch: Center elements in a tab panel

By default elements in Ext.tab.Panel are aligned left. I wanted to center them so it's not so close to the back button in the Title Bar.


I found the answer while digging around in the comments section of the Sencha Touch documentation and wanted to surface the answer so others could easily find it.

Ext.define("Sample.view.ContentEditorContainer",{
    extend: 'Ext.tab.Panel',
    alias: 'widget.contenteditorcontainer',
    
    config: {
        // How to center tabs in a panel floating at the top
        tabBar: {
            layout: {
                type: 'hbox',
                align: 'center',
                pack: 'center'
            }
        },

This will center the elements.


Here is the documentation for centering elements on a panel.

Wednesday, July 17, 2013

Tep Wireless Sale: 50% off

I used a tep internet hotspot on my last vacation and the it worked really well. I highly recommend it to anyone going on an overseas trip.

They're having a 50% off sale right now. The coupon code is “FireSale”.

Friday, July 12, 2013

Javascript / jQuery : Scroll to the top of a document

Quick way to scroll to the top of a page via jQuery

jQuery(window).scrollTop(0);

Objective C : Learning the syntax

I'm in the process of trying to learn Objective-C. In the beginning this can be really rough. There are so many brackets. So many brackets...

This site has been pretty helpful in trying to make some sense out of the chaos:
http://cocoadevcentral.com/d/learn_objectivec/

This is the video course I'm learning from: Coding Together: Developing Apps for iPhone and iPad (Winter 2013). It's really good, better than most books I've read and it's free.

Programming iOS 6 however has been a fantastic book and explains obj-c in great depth. You'll need at least a basic understanding of either C or C++. Other books have you blindly follow code examples without explaining anything. This book tells you exactly what's going on. I wish more books were written in this fashion.

There's lot of other stuff obj-c does that seem auto-magical. Like the variables that are created from that are prefixed with an _. It's all about comments you guys.

Sencha Touch: Ext version of jQuery methods

I'm trying to use as many native parts of Ext as I can without leaning on other libraries. It's not so much that I wouldn't use the other libraries anyway, but it's better to embrace change. There's a lot of useful stuff that Underscore handles really well.

jQuery Underscore Ext (Sencha Touch)
jQuery.noop Ext.emptyFn
jQuery.proxy Ext.bind
jQuery('selector') Ext.query('selector') 
jQuery.trim Ext.String.trim
[jQuery wrapped elem] = jQuery('selector') [Ext wrapped elem] = Ext.get([from Ext.query])
_.isEmpty, _.isNull Ext.isEmpty

Monday, July 8, 2013

Sencha Touch: Disable script caching

While working on a Sencha Touch project I needed to look in one of the core sencha files. The problem is there is a _dc property attached to every script it brings in. It's great for making sure your code isn't cached, but terrible for debugging.

After a big of digging I found the code needed to turn off caching. Open up the app.js file and look at the very top. You should see a Ext.Loader.setPath method. Update it to look like this and caching should now be disabled.

Ext.Loader.setPath({
    'Ext': 'touch/src',
    'Sample': 'app'
}).setConfig({
    disableCaching: false
});

Monday, April 8, 2013

Opensource version of maxgif.com

Once google made searching for gifs possible I lost almost an entire day just looking for corgi gifs. This led to making a site that showed blown up versions of the gifs. It's the same thing as maxgif.com (nsfw). I wanted to set this up so anyone could do the same thing. I put the code up on github.com so others can check it out.

Have fun. Put a link in the comments if you used it somewhere.

Monday, April 1, 2013

Sunday, February 24, 2013

Books : Apress sale

Apress is having a big sale on Apple/iOS/Mac books to celebrate Steve Jobs 55 birthday. Use the order code JOBS55 to get a 55% discount. I've had my eye on a few books that I picked up at a really good price. Hard to pass up a good book sale.

Wednesday, February 13, 2013

Gaming: The Room, Little Inferno and Node.Hack

Most of my gaming now a days happens on a tablet because it's easy to hop in and out. Every once in awhile I'll run into something that really grabs me and I keep playing for hours on end. Here are some recent examples.

The Room


The concept reminds me a lot of The 7th Guest in the fact that it's puzzle based and sometimes not very obvious what you need to do next, but it still keeps you hooked. The game consists of a room with a box on a table. The box has multiple boxes inside it and the goal is to solve the puzzles on the current box to get to the next nested box. The concept is simple but the puzzles aren't. If you get stuck there is a hint system in the top left of the screen. I'm on box three and it's probably going to take an hour or so to figure it out.

This is currently on sale for $0.99. The normal price is $1.99

Little Inferno


This is a simple game on the outside, but has a few layers to it. On the outside it's a game about burning things. The more things you burn the more money it gives you to buy new things to burn. There is a combo system that rewards you for burning combinations of things. For example placing the pirate and bike in the fireplace and burning them both gives you the Bike Pirate combo. There are 99 combos and not all of them are easy to figure out. There is actually a story to the game that you can ignore for the most part but the ending is far more rewarding if you don't. It's told through letters you get in the mail that you can burn for money.

It's list price is $4.99. The PC and Wii U version is $15.

Node.Hack



This puzzle game plays very heavily on a risk/reward mechanic. The player navigates a maze that's populated with enemies. The goal is to dodge the enemies and collect points detonated as different colored nodes. Once green bar at the bottom is full the level starts falling apart. You can still collect points before leaving and this is where the risk/reward mechanic comes into play. There is a leader board system for each level and achievements for killing enemies with specific weapons under certain situations.



It's tough but rewarding once you reach the end with a higher score than your buddy. Every time I think my score is pretty good the wife has done far better.  It's on sale for $0.99.

Friday, January 25, 2013

jQuery / Javascript: Detecting orientation and updating for it

I'm getting started on a new mobile project at work. The first step is playing with the orientation of the device and updating the layout so it takes advantage of the available space.

The javascript event you're looking for is orientationchange. You can watch for this with the jQuery on method.

$(window).on('orientationchange',updateDisplay);

The handler method will look at the window.orientation to figure out if it's portrait or landscape.


if(Math.abs(window.orientation) === 90){
// landscape: do stuff
}
else{
// portrait: do stuff
}

You can see an example here.