Robert Basic's blog

Posts tagged 'dojo'

A quick note on Dojo's data grids and dojox.data.HtmlStore

by Robert Basic on December 23, 2011.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

I’m spending this day trying to create an “universal” administration dashboard with which I’ll finally be happy with. I’m using Dojo to spice up the UI, because I think it’s awesome and it has a lot of stuff in it and plays well with Zend Framework. This post is dedicated to the future stupid me.

Anyway, when using dojox.data.HtmlStore as a store for a dojox.data.DataGrid (or any other grid, really), pay attention to the definition of the columns structure which is passed to the grid. I was doing a really stupid thing which cost me a bunch of hours until I finally figured out what was going on.

Let’s take for example this is the given HTML table:

<table id="datastore">
<thead>
    <tr>
    <th>ID</th>
    <th>Name</th>
    </tr>
</thead>
<tbody>
    <!-- body comes here -->
</tbody>
</table>

I was defining the structure for the columns as:

var struct = [[
   { field: 'id', name: 'ID', width: 'auto' },
   { field: 'name', name: 'Name', width: 'auto'}
]];

which was wrong. This is the correct one:

var struct = [[
   { field: 'ID', name: 'ID', width: 'auto' },
   { field: 'Name', name: 'Name', width: 'auto'}
]];

Use what’s in the TH tags for the field properties! I was trying to be clever and use the name of the fields in the database. The worst part is that there will be no errors, the grid will render correctly the header row and a correct number of rows for the data, but! it will show “…” in each column, instead of the actual data.

Happy hackin’!

Tags: data grid, dojo, dojo store, htmlstore.
Categories: Development, Programming.

Need help on your PHP projects? Let's talk!

Multiple Dojo tooltips on page load

by Robert Basic on March 15, 2011.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

As I said a few days (weeks?) ago, I’ve decided to learn dojo and not by just doing random examples, but by changing the whole administration panel for phpplaneta.net to use dojo and the ZendDojo* components. Maybe it’ll become a bit more usable and prettier :)

Fast forward a few hours into this journey of dojos and dijits and I found myself hacking and extending it just to make it work and behave like I want it to. I knew that this time would come sooner and later, but somehow this was way to soon. All I wanted is to have multiple tooltips pop up soon as the page loads; it couldn’t be so hard, right? Right? Well, it wasn’t hard, but it sure wasn’t easy either.

Note: when first started this post there was a section generally on dojo, which started out as a few words, thoughts, on it, but in the end turned out to be big enough for a separate post. The plan is to finish that once when I get to the end of this “dojo journey”.

OK, back to topic. What I wanted to achieve, and to some extent I did, is to show a few dijit tooltips when a page loads, for example after a user has submitted an invalid Zend_Dojo_Form, show the error messages in the tooltips. Bonus points for marking the invalid form elements as invalid a la dijit.form.validationtextbox.

First thing I learnt is that by default there can be only one dijit.Tooltip shown on the page at a time. A dijit.Tooltip will be shown when the element it is connected to gets focus and will be hidden when the element loses focus. By the logic that there can not be more than one element in focus at a time, dijit.Tooltip works perfectly.

To achieve what I wanted to, I had to make it possible to have several tooltips shown at the same time, all connected to different elements, plus they should be “activated” programmatically on page load, instead of waiting for the user to bring those elements in focus.

Making it possible to have multiple tooltips: the “offending” code that was stopping me from showing multiple tooltips is in dijit/Tooltip.js, around lines 83-93. Be warned, dojo code is a bit cryptic in places and figuring it out takes time. A whole lot of it. That piece of code there is responsible for creating a new tooltip instance each and every time. Luckily, that part can be easily overwritten in our dojo.addOnLoad function:

var ttids = Array();
dijit.showTooltip=function(_a,_b,_c,_d){
    if(!ttids[_b.id]){
        ttids[_b.id]=new dijit._MasterTooltip();
    }
    return ttids[_b.id].show(_a,_b,_c,_d);
};
dijit.hideTooltip=function(_e){
    if(!ttids[_e.id]){
        ttids[_e.id]=new dijit._MasterTooltip();
    }
    return ttids[_e.id].hide(_e);
};

Showing those tooltips programatically is a bit harder. I hoped that there’s some built-in method which when called will just happily show the tooltip, but I was foolish for having such hopes. Anyway, by looking at how dijit.Tooltip was created/declared, I’ve wrote my own tooltip which extends dijit.Tooltip and adds the “missing method”:

dojo.declare("app.errorTooltip", dijit.Tooltip, {
    show: function() {
        var elem = dojo.byId(this.connectId[0]);
        if(dojo.isIE) {
            elem.fireEvent('onfocus');
        } else {
            var e = document.createEvent("HTMLEvents");
            e.initEvent('focus', false, true);
            elem.dispatchEvent(e);
        }
    }
});

Now, when creating a tooltip, instead of dijit.Tooltip I need to use app.errorTooltip (error, as I’m currently using it for showing errors). The contents of the show() method are a different story and they belong to that rant post about dojo I promised earlier :D All that code is actually doing there is firing the “onfocus” event on the element to which our tooltip is connected to.

Finally, querying the DOM for all elements which contain the actual error messages I was first interested in, creating a app.errorTooltip for each of those error message and showing those tooltips with the method I created.

var errors = dojo.query("form ul.errors").forEach(function(node, idx, nodes){
    var id = node.parentNode.firstChild.getAttribute('for');
    var label = "<ul class='errors'>" + node.innerHTML + "</ul>";
    var tooltip = app.errorTooltip({
        label: label,
        connectId: [id]
    });
    document.body.appendChild(tooltip.domNode);
    tooltip.show();
    // these next 2 lines are for marking the connected fields as invalid
    // as they are also an instance of dijit.form.ValidationTextBox
    dijit.byId(id).state = "Error";
    dijit.byId(id)._setStateClass();
}).style({"display":"none"});

There. Multiple dojo tooltips shown on page load. Mission accomplished. As I said, it’s not easy, but it’s not hard either.

Happy hackin’! :)

Tags: custom tooltips, dijit.tooltip, dojo, tooltips.
Categories: Development.

Need help on your PHP projects? Let's talk!

Playing with Zend Framework and Dojo

by Robert Basic on March 02, 2011.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

Yesterday there was some talk on Twitter including Zend Framework and Dojo. I didn’t quite follow it through, something about why Dojo and not jQuery, it’s not that popular blablabla. Anyway, who cares? We have Zend_Dojo, we have ZendX_Jquery. I’m using ZendX_Jquery, but only as far as setting it up and loading jquery and jqueryui via the view helpers. Tried to use it on forms, to use tabs and whatnot, but in the end it was easier to write up a separate javascript file and do the jquery stuff there. But, I’ve never used Zend_Dojo before. Guess I was a bit scared away with all that dojo, dijit, dojox stuff… So, last night, being bored and all, I’ve decided to try and use it. Oh boy. How wrong was I for not diving into it before. OK, so far I’ve created only one form with dojo, but damn it’s good.

In short: set up the Zend_Dojo view helpers, pick a theme, make the forms extend Zend_Dojo_Form, change the elements from Zend_FormElement* to Zend_Dojo_FormElement*, if needed add/tweak some attributes and bang! the form is all sexy with nice colors & rounded borders & (error) messages in a nice little tooltip. And I haven’t wrote a single line of javascript. Not.a.single.line. Magic, I like it.

Setting it up

All I did was to set up dojo is:

<?php

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap {

    public function _initViewHelpers()
    {
        $this->bootstrap('layout');
        $this->_layout = $this->getResource('layout');
        $this->_view = $this->_layout->getView();

        $this->_view->addHelperPath('Zend/Dojo/View/Helper','Zend_Dojo_View_Helper');

        $this->_view->dojo()
                        ->enable()
                        ->setCdnBase(Zend_Dojo::CDN_BASE_GOOGLE)
                        ->setCdnVersion('1.5.0')
                        ->setCdnDojoPath(Zend_Dojo::CDN_DOJO_PATH_GOOGLE)
                        ->addStyleSheetModule('dijit.themes.claro')
                        ->useCdn();
    }

and then just called echo $this->dojo(); in the layout and added class=“cairo” to the body element. I think this body thing can also be done via the helpers. The biggest struggle I had with the theme. Where do I download it? There’s no “download theme x” on the dojo website. How do I set it up? What is this madness? Then I realized it can pull not just the javascript files from the CDN, but also the CSS and images! Very cool.

A simple form

Next step: spice up the forms with Zend_Dojo_Form:

<?php
class My_Form extends Zend_Dojo_Form
{
    public function init()
    {
        $this->addElement(
            'ValidationTextBox',
            'title',
            array(
                'label' => 'Title:',
                'missingMessage' => 'You have to enter something', // overriding the default "This value is required."
                'promptMessage' => 'Enter a title', // on focus
                'invalidMessage' => 'Type some random characters, 3 min, 100 max', // error message for the failed regExp
                'regExp' => '.{3,100}', // regexp for validation
                'required' => true,
                'validators' => array(
                    array(
                        'validator' => 'StringLength', 'options' => array(3, 100)
                    )
                ),
                'filters' => array(
                    array(
                        'filter' => 'StringTrim',
                        'filter' => 'StripTags'
                    )
                )
            )
        );

With these ~20 lines I’ve got some basic client side validation with a pretty nice look and feel to it while still having all of the Zend_Form power to do the validation and filtering on the server side. Still need to figure out what those “constraints” are and how and for what to use them (they’re in the ZF manual, so they gotta be good for something), how to add for example a dojox.validate.isEmailAddress validator to the element, but for starters, this is quite impressive.

Besides this, I’ve also played with Zend_Dojo_Form_Element_Editor which is a WYSIWYG editor, extended Zend_Dojo_Form_Element_Button to create my own ResetButton (for some odd reason there is no reset button in Zend_Dojo), played around with the decorators… But that’s for some future rambling, gotta go to work now.

In the end, I feel stupid for not using Zend_Dojo before, well, Zend_Dojo_Form at least, but I definitely will be from now on. Here’s to hoping that it will be included in Zend Framework 2, too :)

Happy hackin’!

Tags: dojo, form, zend framework, zend_dojo, zf.
Categories: Programming.

Need help on your PHP projects? Let's talk!