History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: ZF-4494
Type: Improvement Improvement
Status: Open Open
Priority: Major Major
Assignee: Matthew Weier O'Phinney
Reporter: Kristof Vansant
Votes: 1
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
Google issue summary
Zend Framework

propose AutoCompleteDojoExt id=table id for example and label=name

Created: 05/Oct/08 01:44 PM   Updated: 15/Mar/09 04:32 AM
Component/s: Zend_Controller
Affects Version/s: None
Fix Version/s: None

Time Tracking:
Not Specified

Tags:
Participants: Christopher Weldon, Kristof Vansant, Matthew Weier O'Phinney and Regis Leroy


 Description  « Hide
if you have data from a DB table groepen

groepen [id,name]

name is what you want to show the user, id is what you need

I have a table offices
offices [id, name, groepen_id]

groepen_id is a FK tot groepen

with my function you can place a filterselect for offices that shows all the groepen by name.
when I save to the offices table I just use the id instead of the group name.

<select dojoType="dijit.form.FilteringSelect"
name="state3"
autocomplete="false"
value="CA">
<option value="1" selected="selected">California</option>
<option value="2" >Illinois</option>
<option value="3" >New York</option>
<option value="4" >Texas</option>
</select>

id is the value in this case, name is the text the user sees.
When the user clicks submit we can get the value (id) of the record the user selected.

solutions:

Groepen is a Zend_Db_Table and has id and name column

$groepen = new Groepen();
$this->_helper->autoCompleteDojoExt($groepen->fetchAll()->toArray());

<?php
/**

  • Zend Framework
    *
  • LICENSE
    *
  • This source file is subject to the new BSD license that is bundled
  • with this package in the file LICENSE.txt.
  • It is also available through the world-wide-web at this URL:
  • http://framework.zend.com/license/new-bsd
  • If you did not receive a copy of the license and are unable to
  • obtain it through the world-wide-web, please send an email
  • to license@zend.com so we can send you a copy immediately.
    *
  • @category Zend
  • @package Zend_Controller
  • @subpackage Zend_Controller_Action_Helper
  • @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  • @license http://framework.zend.com/license/new-bsd New BSD License
  • @version $Id: AutoCompleteDojo.php 9098 2008-03-30 19:29:10Z thomas $
    */

/**

  • @see Zend_Controller_Action_Helper_AutoComplete_Abstract
    */
    require_once 'Zend/Controller/Action/Helper/AutoComplete/Abstract.php';

/**

  • Create and send Dojo-compatible autocompletion lists
    *
  • @uses Zend_Controller_Action_Helper_AutoComplete_Abstract
  • @category Zend
  • @package Zend_Controller
  • @subpackage Zend_Controller_Action_Helper
  • @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  • @license http://framework.zend.com/license/new-bsd New BSD License
    */
    class Zend_Controller_Action_Helper_AutoCompleteDojoExt extends Zend_Controller_Action_Helper_AutoComplete_Abstract
    {
    /**
  • Validate data for autocompletion
  • @param mixed $data
  • @return boolean
    */
    public function validateData($data)
    {
    if (is_array($data) && isset($data['items']) && is_array($data['items'])) { return true; }

return false;
}

/**

  • Prepare data for autocompletion
  • @param mixed $data
  • @param boolean $keepLayouts
  • @return string
    */
    public function prepareAutoCompletion($data, $keepLayouts = false)
    Unknown macro: { $items = array(); foreach ($data as $value) { $items[] = array('label' => array_pop($value), 'name' => array_pop($value)); } $final = array( 'identifier' => 'name', 'items' => $items, ); return $this->encodeJson($final, $keepLayouts); }

    }



 All   Comments   Work Log   Change History   FishEye   Crucible      Sort Order: Ascending order - Click to sort in descending order
Matthew Weier O'Phinney - 07/Oct/08 07:47 AM
How is this different than the current Dojo AutoComplete action helper? Can you summarize? I'd rather modify that to be more general than to add additional helpers that muddy the waters with more variants.

For the record, we plan to update the Dojo autocomplete action helper to utilize Zend_Dojo_Data, which will also give more flexibility. I'm also thinking that a flag and/or setters for specifying either FilteringSelect or ComboBox would help make it more useful.


Kristof Vansant - 07/Oct/08 08:15 AM
controller:

Schoolgemeenschappen table [id, name]

public function schoolgemeenschapAction() { $schoolgemeenschappen = new Schoolgemeenschappen(); $this->_helper->autoCompleteDojoExt($schoolgemeenschappen->fetchAll()->toArray()); }

in form:

$this->addElement(
'FilteringSelect',
'scholengemeenschap_id',
array(
'label'=> 'Scholengemeenschap',
'storeId'=> 'stateStore1',
'storeType'=>'dojo.data.ItemFileReadStore',
'storeParams'=> array('url' => '/studiegids/school/schoolgemeenschap'),
'dijitParams' => array('searchAttr' => 'label',
'required' => 'true', ),)
);

in add and change record

$row->scholengemeenschap_id = $form->getValue('scholengemeenschap_id');

do you understand now?

with my new function you get:

{"identifier":"name","items":[{"label":"CLB-Kempen","name":"1"},{"label":"CLB-1 AMI","name":"2"}]}

with the current you get

{"identifier":"name","items":[{"label":"CLB-Kempen","name":"CLB-Kempen"},{"label":"CLB-1 AMI","name":"CLB-1 AMI"}]}

because of this code:

foreach ($data as $key => $value) { $items[] = array('label' => $value, 'name' => $value); }
$final = array(
'identifier' => 'name',
'items' => $items,
);


Kristof Vansant - 07/Oct/08 09:00 AM
this function keeps the old one working
if one array is given id and name are the same (the old functionality)
when you use a multidimensional array it will use my code.

<?php
/**

  • Zend Framework
    *
  • LICENSE
    *
  • This source file is subject to the new BSD license that is bundled
  • with this package in the file LICENSE.txt.
  • It is also available through the world-wide-web at this URL:
  • http://framework.zend.com/license/new-bsd
  • If you did not receive a copy of the license and are unable to
  • obtain it through the world-wide-web, please send an email
  • to license@zend.com so we can send you a copy immediately.
    *
  • @category Zend
  • @package Zend_Controller
  • @subpackage Zend_Controller_Action_Helper
  • @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  • @license http://framework.zend.com/license/new-bsd New BSD License
  • @version $Id: AutoCompleteDojo.php 9098 2008-03-30 19:29:10Z thomas $
    */

/**

  • @see Zend_Controller_Action_Helper_AutoComplete_Abstract
    */
    require_once 'Zend/Controller/Action/Helper/AutoComplete/Abstract.php';

/**

  • Create and send Dojo-compatible autocompletion lists
    *
  • @uses Zend_Controller_Action_Helper_AutoComplete_Abstract
  • @category Zend
  • @package Zend_Controller
  • @subpackage Zend_Controller_Action_Helper
  • @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  • @license http://framework.zend.com/license/new-bsd New BSD License
    */
    class Zend_Controller_Action_Helper_AutoCompleteDojo extends Zend_Controller_Action_Helper_AutoComplete_Abstract
    {
    /**
  • Validate data for autocompletion
  • @param mixed $data
  • @return boolean
    */
    public function validateData($data)
    {
    if (is_array($data) && isset($data['items']) && is_array($data['items'])) { return true; }

return false;
}

/**

  • Prepare data for autocompletion
  • @param mixed $data
  • @param boolean $keepLayouts
  • @return string
    */
    public function prepareAutoCompletion($data, $keepLayouts = false)
    {

$items = array();
if(count($data)===count($data, COUNT_RECURSIVE)){

foreach ($data as $key => $value) { $items[] = array('label' => $value, 'name' => $value); }

}else{

foreach ($data as $value) { $items[] = array('label' => array_pop($value), 'name' => array_pop($value)); }

}

$final = array(
'identifier' => 'name',
'items' => $items,
);

return $this->encodeJson($final, $keepLayouts);
}

}
?>


Kristof Vansant - 07/Oct/08 09:19 AM
old json output:

{"identifier":"name","items":[{"label":{"id":"1","vestigingnaam":"Geel"},"name":{"id":"1","vestigingnaam":"Geel"}},{"label":{"id":"2","vestigingnaam":"Mol"},"name":{"id":"2","vestigingnaam":"Mol"}},{"label":{"id":"3","vestigingnaam":"Westerlo"},"name":{"id":"3","vestigingnaam":"Westerlo"}},{"label":{"id":"4","vestigingnaam":"Vorselaar"},"name":{"id":"4","vestigingnaam":"Vorselaar"}},{"label":{"id":"5","vestigingnaam":"Turnhout"},"name":{"id":"5","vestigingnaam":"Turnhout"}},{"label":{"id":"6","vestigingnaam":"Zoersel"},"name":{"id":"6","vestigingnaam":"Zoersel"}},{"label":{"id":"7","vestigingnaam":"Hoogstraten"},"name":{"id":"7","vestigingnaam":"Hoogstraten"}},{"label":{"id":"8","vestigingnaam":"Herentals"},"name":{"id":"8","vestigingnaam":"Herentals"}}]}

mine json output:

{"identifier":"name","items":[{"label":"Geel","name":"1"},{"label":"Mol","name":"2"},{"label":"Westerlo","name":"3"},{"label":"Vorselaar","name":"4"},{"label":"Turnhout","name":"5"},{"label":"Zoersel","name":"6"},{"label":"Hoogstraten","name":"7"},{"label":"Herentals","name":"8"}]}


Kristof Vansant - 24/Oct/08 12:33 AM
There is an issue with my multi column detection
when only one row is given the detection uses the old dojo generation code even if it should use mine.

So don't use the code which I proposed.

Matthew if you need a tester for your code, let me know I'm happy to beta test it.


Regis Leroy - 25/Oct/08 02:49 PM
Personnally I just changed 2 few things to get this autocompleteDojo working:

public function prepareAutoCompletion($data, $keepLayouts = false)
{
$items = array();
foreach ($data as $key => $value) {
$items[] = array('label' => $value, 'name' => $value, 'key' => $key);
}
$final = array(
'identifier' => 'key',
'items' => $items,
);
return $this->encodeJson($final, $keepLayouts);
}

--> added key in the line and changed the 'identifier from 'name' to 'key'

Then with this HTML code I get my autocomplete working, showing names and using Id on my form destination:

<form id="Find_Form" action="/ce/fiche/edit" method="get" dojoType="dijit.form.Form">
<div dojoType="custom.FindAutoCompleteReadStore" jsId="NameStore" url="/ce/fiche/find/format/json" requestMethod="get"></div>
<label for="id" class="optional">Recherchez un nom:</label>
<span class="formelement">
<select name="id" id="FindByName" hasDownArrow="" store="NameStore" size="25" tabindex="99" autocomplete="1" dojoType="dijit.form.FilteringSelect" pageSize="10" >
</select></span>
<span class="actionbuttons"><input id="Find_go" name="Find_go" value="Go:" type="submit" label="go:"dojoType="dijit.form.Button" /></span>
</form>


Regis Leroy - 25/Oct/08 02:51 PM
one more point, for your sub-array detection why don't you use is_array($value) ?

Kristof Vansant - 25/Oct/08 07:12 PM
your probably right

how would you do following code?

'onChange'=> "stateStore2 = new dojo.data.ItemFileReadStore({url: '/studiegids/overzichtschool/studierichting/onderwijsvormid/'+ dijit.byId('onderwijsvorm_id').getValue() }); dijit.byId('studierichting_id').store = stateStore2; dijit.byId('studierichting_id').setDisplayedValue('');",
b
adding this will requery statestore2. Because it passes an id, the query will give other results. Because of this the dojo datastore gets other values.


Regis Leroy - 27/Oct/08 12:36 AM
I'm not sure of what you're asking for. But I think that if you want to re-query your store you should use soething based on QueryReadStore instead. I wrote an example here:
http://www.makina-corpus.org/2008/10/26/autocomplete-ajax-search-with-dojo-and-zend-framework/

Christopher Weldon - 14/Mar/09 04:39 PM
What's the status of this? This gets to be particularly problematic for things such as trying to do State Code => State name mapping with either a ComboBox or FilteringSelect and the only thing being outputted to the screen is just the State name...

Matthew Weier O'Phinney - 15/Mar/09 04:32 AM
The Dojo autocomplete action helper was converted to Zend_Dojo_Data in 1.7.0, released in November 2008. It can either create a Zend_Dojo_Data object, or consume one. If you need to specify different keys for the identifier and/or label, pass your data to a new instance of Zend_Dojo_Data, and then pass that to the helper:
// Use "id" as the identifier, "name" as the label:
$data = new Zend_Dojo_Data('id', $items, "name");
$this->_helper->autoCompleteDojo($data);

If I do not hear any feedback one way or the other on whether or not the above solution addresses this issue (at this point, I'm not even entirely certain what issue is actually being reported), I will close the bug.