Wednesday, April 9, 2014

Zend Framework 2.x Learn ZF2 by Example : Unable to render template

Getting to the MVC portion of the book and ran into an error. On page 59 it shows you how to manually include a template to aid debugging. I ran into this error when trying to see my changes.


Fatal error: Uncaught exception 'Zend\View\Exception\RuntimeException' with message 'Zend\View\Renderer\PhpRenderer::render: Unable to render template "debug/layout/sidebar"; resolver could not resolve to a file' in /Volumes/zend_framework/learnzf2/vendor/zendframework/zendframework/library/Zend/View/Renderer/PhpRenderer.php:498 Stack trace: #0 /Volumes/zend_framework/learnzf2/vendor/zendframework/zendframework/library/Zend/View/View.php(205): Zend\View\Renderer\PhpRenderer->render(Object(Zend\View\Model\ViewModel)) #1 /Volumes/zend_framework/learnzf2/vendor/zendframework/zendframework/library/Zend/Mvc/View/Http/DefaultRenderingStrategy.php(102): Zend\View\View->render(Object(Zend\View\Model\ViewModel)) #2 [internal function]: Zend\Mvc\View\Http\DefaultRenderingStrategy->render(Object(Zend\Mvc\MvcEvent)) #3 /Volumes/zend_framework/learnzf2/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent)) #4 /Volumes/zend_framework/learnzf2/vendor/zendframe in /Volumes/zend_framework/learnzf2/vendor/zendframework/zendframework/library/Zend/View/Renderer/PhpRenderer.php on line 498

Page 58 talks about the way templates are included. The middle of the page shows a config option called 'template_path_stack'. This is the path the PhpRender uses to find manually included templates. There is a similar line in the Application module.config.php. I thought this would be imported into the master config but that didn't happen. You have to add this.

Tuesday, April 8, 2014

Zend Framework 2.x Learn ZF2 by Example : Error creating Debug module

I'm rewriting part of my website with Zend Framework 2 because I want to use something more mature and flexible than something I wrote years ago. I picked up the book Learn ZF2 by Example because it was rated well. The intro gets your feet wet and eases you in. I got stuck when trying to reproduce the steps to create a new module using ZFTool.

On page 28 under Automatic Module Creation they want you to download a tool that will help with creating new modules. I'm not sure if the instructions are old but it not work. Running the command will give you the following error

Fatal error: Uncaught exception 'Zend\ModuleManager\Exception\RuntimeException' with message 'Module (ZFTool) could not be initialized.' in /Volumes/zend_framework/learnzf2/vendor/zendframework/zendframework/library/Zend/ModuleManager/ModuleManager.php:189
Stack trace:
#0 /Volumes/zend_framework/learnzf2/vendor/zendframework/zendframework/library/Zend/ModuleManager/ModuleManager.php(163): Zend\ModuleManager\ModuleManager->loadModuleByName(Object(Zend\ModuleManager\ModuleEvent))
#1 /Volumes/zend_framework/learnzf2/vendor/zendframework/zendframework/library/Zend/ModuleManager/ModuleManager.php(90): Zend\ModuleManager\ModuleManager->loadModule('ZFTool')
#2 [internal function]: Zend\ModuleManager\ModuleManager->onLoadModules(Object(Zend\ModuleManager\ModuleEvent))
#3 /Volumes/zend_framework/learnzf2/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\ModuleManager\ModuleEvent))
#4 /Volumes/zend_framework/learnzf2/vendor/zendframework/zendframework/library/Zend/ in /Volumes/zend_framework/learnzf2/vendor/zendframework/zendframework/library/Zend/ModuleManager/ModuleManager.php on line 189

Your path will vary, but the error is the same. Searching google didn't give me a good answer. The ZFTool page has instructions on how to install the it using composer. When the install finished I ran the command php vendor/bin/zf.php create module Debug and the new module was created.

I hope this saves you some time.

Monday, February 24, 2014

Sencha Touch: Reorder a list with drag and drop handles using SortableList

Part of a project I'm working on requires the ability to reorder a list. I was pretty sure sencha touch could handle this, but couldn't figure out how to do it. I searched google for a solid week. I had one lead that turned bad after digging into it further. I basically gave up and moved onto the next issue when I ran across the solution buried in their documentation: SortableList

The second problem arose from the poor documentation on this feature. Outside of the class docs there is nothing explaining how to use it. The upside is at least it's easy to view the source.

I ran across this forum post that talked about a bug in the code. This was the only code I found that gave an example of how the code works.

There are a few things required to use this plugin.

Step 1: Include the plugin

// Make sure the plugin in include when the app builds
requires: ['Ext.plugin.SortableList'],

config:{
        // Include the plugin in your config. Don't forget the period on the class name
        plugins: [{xclass: 'Ext.plugin.SortableList', handleSelector: '.gripper'}],

        
        // These are required to fix a bug that exists in the plugin
        infinite: true,
        variableHeights: true,
        ...
}

Step 2: Configure the drag handle

config: {
        // Set the class to the name you passed in for the handleSelector
        itemTpl: '<span class="gripper"></span>[html goes here]'
        ...
        }

The tag used for the list-sortablehandle is the object that will start the reorder process. This can be styled using whatever you like.

Step 3: Listen for the finishing event

config: {
        listeners:[
            event: 'dragsort',
            // to is the new position in the list
            // from is where the item used to be
            fn: function(listObject, row, to, from)
        ]
        ...
}

It was smooth sailing after this point.

Thursday, January 23, 2014

Javascript: Problems, trouble, issues parsing JSON data / Unexpected token

I ran into an issue trying to parse a JSON string that made very little sense. Normally when you have a token in the JSON response that doesn't work the error will include that character. This time it gave me nothing.

// This is all you have to do
JSON.parse(jsonObject);

After 4 hours and much googling I had no answer. I though for some reason the server response had the wrong type of quotes on it, but turned out to be something very left field.

I used JSON.stringify() on the server response and saw something really weird on the end of the string that wasn't showing up by looking at the response.

// What is this?!
'"timeCreated\":1390518047098}\u0000\u0000\'

The \u0000 character was choking the parser and wasn't showing up as a bad token. This is the unicode character for null. Not sure why it was on the response but it was causing the problem. Running this cleaned up the problem.

// Take out the garbage
[server response] = [server response].replace(/\u0000/g, "")

As a safety measure it's good to have a method you can use to clean your JSON strings before trying to parse them.

Friday, January 10, 2014

Javascript: Quick Date timestamp

I wanted to find a quick way to compare two dates. The easiest way is to use their unix timestamp. If the date exists as an object you can use .getTime() to retrieve the number of milliseconds that have passed since epoch time.

You can retrieve that number even faster with the following bit of code

+new Date

I found the tip here and wanted to surface it.

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.