Zend Framework dijit.FilteringSelect Configure

To configure a FilteringSelect dijit, including client and server-side validation, with a Zend Framework .ini file, use the following syntax:

; status element
; These MUST match the definitions in the user table
elements.status.type = "FilteringSelect"
elements.status.options.label = "Status"
elements.status.options.dijitParams.searchAttr = "name"
elements.status.options.autoComplete = true
elements.status.options.required = "true"
elements.status.options.validators.inarray.validator = "InArray"
elements.status.options.validators.inarray.options.haystack[] = "pending"
elements.status.options.validators.inarray.options.haystack[] = "activated"
elements.status.options.validators.inarray.options.haystack[] = "disabled"
elements.status.options.validators.inarray.options.haystack[] = "locked"
elements.status.options.validators.inarray.options.messages.notInArray = "Invalid status"
elements.status.options.multioptions.pending = "pending"
elements.status.options.multioptions.activated = "activated"
elements.status.options.multioptions.disabled = "disabled"
elements.status.options.multioptions.locked = "locked"

Sourcing dojo from AOL's CDN under Zend Framework

This implementation uses a default layout. To set the path and name of the layout (default.phtml), the application.ini file was configured like so:

configs/application.ini

resources.layout[] =
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
resources.layout.layout = "default"

Bootstrap.php adds dojo to thel helper path for the view in _initView. The locale is set up as well as the translation.

Bootstrap.php

protected function _initView()
    {
        Zend_Session::start();
        $session=new Zend_Session_Namespace('global');
        $options=$this->getOptions();

        $locale = new Zend_Locale(Zend_Locale::BROWSER,TRUE);
        $session->strLocale=$locale->toString();
        Zend_Registry::set('Zend_Locale', $locale);

        $language_path=$options['resources']['locale']['translation']['path'];
        $translate = new Zend_Translate(array('adapter'=>'gettext',
                'content'=>$language_path,
                'scan' => Zend_Translate::LOCALE_DIRECTORY,
                'locale'=>$locale->toString()));
        Zend_Registry::set('Zend_Translate', $translate);

        $view = new Zend_View();
        $view->doctype('XHTML1_STRICT');
        $view->headLink()->appendStylesheet('/css/base.css')
            ->appendStylesheet('/css/color.css');

        $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
        $viewRenderer->setView($view);

        $view->addHelperPath('Zend/Dojo/View/Helper/', 'Zend_Dojo_View_Helper');
        Zend_Dojo_View_Helper_Dojo::setUseDeclarative();

        $view->strLocale=$session->strLocale;

        return $view;
    }

In the controller for the form, dojo is enabled. This way, the layout only includes dojo if the form or page requires it.

        $this->view->form = $form;
        $this->view->dojo()->enable();
        if ($this->getRequest()->isPost())

In the layout, the final dojo configuration is done, if dojo is enabled.

application/layouts/scripts/default.phtml


<?php 
// application/layouts/scripts/default.phtml

echo $this->doctype() ?>
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head>  
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    <?php echo $this->headTitle() ?>
    <?php echo $this->headMeta() ?>
    <?php echo $this->headLink() ?>
    <?php echo $this->headStyle() ?>
<?php if ($this->dojo()->isEnabled()){
        $this->dojo()
            ->setCdnBase(Zend_Dojo::CDN_BASE_AOL)
            ->setCdnVersion('1.5')
            ->setCdnDojoPath(Zend_Dojo::CDN_DOJO_PATH_AOL);
        $this->dojo()
            ->setDjConfigOption('parseOnLoad', true)
            ->setDjConfigOption('locale',$this->strLocale)
            ->setDjConfigOption('cdnbase',Zend_Dojo::CDN_BASE_AOL)
            ->setDjConfigOption('cdnversion','1.5')
            ->setDjConfigOption('cdndojopath',Zend_Dojo::CDN_DOJO_PATH_AOL)
            ->addStyleSheetModule('dijit.themes.tundra')
            ->requireModule('dijit.form.Form')
            ->requireModule('dijit.form.ValidationTextBox')
            ->requireModule('dijit.form.TextBox');
            echo $this->dojo();
   }
?>

PHP Base Class Implementation with Iterator

This is a class definition for a base class which can be extended.

Features

  • Attributes are defined dynamically
  • Iteration is implemented, to allow the use of foreach
  • Attribute validation is included
  • Uses array_fill_keys if it is available, otherwise gracefully degrades to use a foreach loop
  • Allows attribute assignment with an associative array

Base Class Definition


require_once 'include/common.php';

class Base Implements Iterator
{
        /**      Location for overloaded data.  */
        protected $data = array();

        public function __construct($attribute_names=null,$attribute_values=null)
        {
                if ($attribute_names!==null)
                {
                        if (function_exists(array_fill_keys))
                                $this->data=array_fill_keys($attribute_names,'');
                        else
                                foreach ($attribute_names as $v)
                                        $this->data[$v]='';
                        if ($attribute_values!==null)
                                foreach ($attribute_values as $k => $v)
                                        $this->$k=$v;
                }
                else
                        if (get_class($this)!=='Base')
                                halt(FAIL_CLASS_HAS_NO_ATTRIBUTES,get_class($this).' class has no attributes');
        }

        public function __set($name,$value)
        {
                if (array_key_exists($name,$this->data))
                        $this->data[$name]=$value;
                else
                        halt(FAIL_INVALID_ATTRIBUTE,get_class($this).' invalid attribute '.$name);
        }

        public function __get($name)
        {
                if (array_key_exists($name,$this->data))
                        return($this->data[$name]);
                else
                        return null;
        }

        public function __isset($name)
        {
                return isset($this->data[$name]);
        }
        public function rewind()
        {
                return reset($this->data);
        }

        public function current()
        {
                return current($this->data);
        }

        public function key()
        {
                return key($this->data);
        }

        public function next()
        {
                return next($this->data);
        }

        public function valid()
        {
                return current($this->data)!==false;
        }


        public function __destruct()
        {
        }
}

Extension Class

class User extends Base
{
        public function __construct($aArgs=null)
        {
                bsBase::__construct(array(
                        'userID','roleName','userName',
                        'firstName','middleName','lastName','loginName',
                        'password','email','contactPhone'),$aArgs);
        }

        function __destruct()
        {
        }
}

Object Instantiation


/* Create a new user, with the userID set to 1 */
$oUser=new User(array('userID'=>1));
$oUser->firstName='John';
foreach ($oUser as $k => $v)
  echo $k.' -> '.$v.PHP_EOL;

This post courtesy of Lyrix, Inc. / Mobiso

dijit ValidationTextBox Custom Validator

The dijit ValidationTextBox widget is an excellent way to help users enter valid data. Recently, I had a very long and complex regular expression that caused performance issues when the data was typed into the input. To improve performance, I used a custom validator (http://docs.dojocampus.org/dijit/form/ValidationTextBox-tricks).


var dijits=Array('sInboundFormat','sOutboundFormat');
var regexps=Array(/^sip:[\w]+@[\w\.]$/,/^sip:[\w]+@[\w\.]$/);

dojo.addOnLoad(function()
{
        var i,ld=dijits.length;
        for (i=0;i<ld;i++)
        {
                /* Store the regular expression for the input */
                dijit.byId(dijits[i]).cRegExp=regexps[i];
                /* The bValid flag stores the current state of the input */
                dijit.byId(dijits[i]).bValid=true;
                dijit.byId(dijits[i]).validator=function (value,constraints) {
                        /* Determine where the focus is */
                        var d=dijit.getFocus();
                        /* If the focus is on the save button */
                        if ((d!=null) && (d.node!=null) && (d.node.id=='btnSave'))
                        {
                            if (dojo.trim(this.value)!='')
                            {
                                /* Set the bValid flag */
                                this.bValid=this.cRegExp.test(this.value);
                                /* Update the error icon on the input */
                                if (!this.bValid)
                                        dojo.addClass(this.domNode,'dijitError');
                                else
                                        dojo.removeClass(this.domNode,'dijitError');
                            }
                            else
                                this.bValid=!this.required;
                        }
                        /* Return the input state (valid or not) */
                        return this.bValid;
                };
        }
});

This code adds an attribute to the widget, bValid. bValid is initialized to true, and updated after the input is validated. The performance gain is realized by testing the focus and only running the test if the user has just clicked ‘Save’.

Since the validation is not performed as the data is entered, it’s not a real-time validation, however, the input does include the warning icon after the validation cycle, to help the user quickly find errors.

This post courtesy of Lyrix, Inc. / Mobiso

An Excellent Dialup ISP - US

As noted in the previous post, a free Juno account grants you access to juno.com, including their webmail.

Juno requires that even people that subscribe to their service use their software to connect to the Internet.

Unfortunately, their software isn’t available for Linux.

An excellent alternative is http://dialup4less.com. The rates are fair, the service is great, and the connection is fast. They have access numbers in most states, if not all.