I'm really stumped with this one, it flat out doesn't work in anything like
the way you'd expect / want it to, and I can't find a single piece of
documentation on this anywhere. I'm not even talking about dependent
dropdowns here, all I am trying to do is get $form->populate to correctly
work in my Edit action when I'm using a FilteringSelect that uses a store
instead of setMultiOptions. Note, this exact same form works just fine (and
submits the ID value correctly) from the New action, the ONLY thing that
fails is the populate method, everything else works perfectly.

Let's get in to the code. I've trimmed the unimportant parts.

EDIT ACTION IN THE CONTROLLER:

    public function editAction() {
        $form = $this->getForm();
        $id = (int)$this->_request->getParam('id', 0);
        $form->setAction("/$this->_class/edit/id/$id")
             ->setMethod('post')
             ->setName('editform')
             ->setElementsBelongTo('editform');

        if ($this->_request->isPost()) {
            //SAVE RECORD
            $formData = $this->_request->getPost();
            $formData['id'] = (int) $id;
            $model = $this->getModel();
            if (true === $model->update($formData)) {
                //SAVE SUCCESS
                $this->_redirect("/$this->_class/display/id/$id");
            } else {
                //SAVE FAILURE, RETURN AND EDIT AGAIN
                $form->populate($formData);
            }
        } else {
             //INITIAL LOAD, GET VALUES AND POPULATE
             $model = $this->getModel();
             $job = $model->get($id);
             $form->populate($job);
        }
        $this->view->form = $form;

    }

ADDELEMENT METHOD FROM THE FORM CLASS

        $this->addElement('FilteringSelect', 'fk_client_id', array(
            'label'        => 'Client:',
            'store'          => 'clientStore',
            'autoComplete'   => 'false',
            'hasDownArrow'   => 'true',
            'id' => 'fk_client_id',
        ));

JAVASCRIPT THAT CREATES THE STORE

dojo.declare("ClientReadStore", dojox.data.QueryReadStore, {
    fetch:function (request) {
        request.serverQuery = { autocomplete:1, str:request.query.name };
        return this.inherited("fetch", arguments);
    }
});

JSON FORMAT THE STORE RETURNS
(this is a long story, I had to rewrite
Zend_Controller_Action_Helper_AutoCompleteDojo because it doesn't work, as
has been noted by others, but the end result is that it now outputs this
JSON, and it works)

({"identifier":"key","items":[

{"label":"aaaaaaaa","name":"aaaaaaaa","key":1},
{"label":"bbbbbbb","name":"bbbbbbb","key":2},
{"label":"vvvvvvvvv","name":"vvvvvvvvv","key":3},
{"label":"ffffffff","name":"ffffffff","key":4},
{"label":"ddddddd","name":"ddddddd","key":5}
{"label":"sssssssss","name":"sssssssss","key":7},
{"label":"rrrrrrrrrr","name":"rrrrrrrrrr","key":8},
{"label":"jjjjjjjjjjjj","name":"jjjjjjjjjjjj","key":9}

]})

EDIT ACTION VIEW SCRIPT

<? Zend_Dojo_View_Helper_Dojo::setUseDeclarative();?>

<div dojoType="ClientReadStore" jsId="clientStore"
    url="/clients/autocomplete/format/ajax?autocomplete=1&str=*"
    requestMethod="get"></div>

<? echo $this->form; ?>


As you can see, this is all pretty basic stuff, and follows (as far as I can
piece together) the best practices for doing this sort of thing. Now. Here's
the debugging information I've managed to coax out so far.

If you call print_r($this->form-getValues()) in the View script, it returns
this:

Array ( [editform] => Array ( [fk_client_id] => 484 [fk_client_contact_id]
=> 459 [position] => CIVIL ENGINEER [quantity] => 1 [start] => ASAP?
[duration] => 3 - 4 MTHS INIT [rate] => NEG [charge] => [experience] => MPD
JV. DESIGN EARTHWORKS, DRAINAGE, ROADS. STOCK YARD. [notes] => [comment] =>
COMMENT COMMENT COMMENT [contractor] => UNKNOWN [filled] => 2002-04-10
00:00:00 [fk_agency_id] => 0 ) )

So as you can see, the variable we're working on here (fk_client_id) is
being correctly populated in the view. However, when we do the same thing on
the form from the Dojo side, we get an entirely different result.

If you call alert(dojo.toJson(dijit.byId("editform").getValues())); in order
to dump out the contents of the form, we get...

{"editform[fk_client_id]":"","editform[fk_client_contact_id]":"","editform[position]":"CIVIL
ENGINEER","editform[quantity]":"1","editform[start]":"ASAP?","editform[duration]":"3
- 4 MTHS
INIT","editform[rate]":"NEG","editform[charge]":"","editform[experience]":"MPD
JV.  DESIGN EARTHWORKS, DRAINAGE, ROADS.  STOCK
YARD.","editform[notes]":"","editform[comment]":"COMMENT COMMENT
COMMENT","editform[contractor]":"UNKNOWN","editform[filled]":undefined,"editform[fk_agency_id]":"","editform[save]":"Save"}

As you can see, the fk_client_id field is empty. SO. Is this a bug? Or am I
doing something horribly wrong? <rant> Or am I supposed to be building some
JS to... I'm not even sure any more, the closest I can get to making the
form do anything at all has been
dijit.byId("fk_client_id").setValue('<?=$this->form-getValue('fk_client_id'))?>');,
but all that does is put the ID in the drop down, which certainly isn't what
we want. Am I meant to use the ID, write an ajax call to go grab the name
value associated with that ID, then set THAT as the value? Even that isn't
going to work correctly because the dijit form setValue doesn't support a
key=>value pair, so it'll just submit the text version, which I suppose I
could convert back to the id in my controller, but goddamn it if that is the
ONLY way to make this work then I'm packing up and going home, because
that's an impossibly ugly hack, and having to write that would make my skin
crawl.</rant>


If anyone has any ideas at all on how to make this work, or can point me to
some documentation, please, let me know. I'm stumped. I promise, just as
soon as I work this whole thing out, I will post a giant-ass tutorial on it
so that no one ever has to suffer again.

Reply via email to