How to cr开发者_运维知识库eate select/option html tag from find('threaded') data in CakePHP? Function find() return results like this:
Array
( [0] => Array ( [Forum] => Array ( [id] => 1 [name] => Forum
)
[children] => Array
(
[0] => Array
(
[Forum] => Array
(
[id] => 3
[name] => Programowanie
[parent_id] => 1
)
)
[1] => Array
(
[Thread] => Array
(
[id] => 11
[name] => Nowe forumowisko
[parent_id] => 1
)
)
)
)
[1] => Array
(
[Forum] => Array
(
[id] => 4
[name] => Nauka
[parent_id] => 0
)
[children] => Array
(
)
)
)
How?
there is a build in method for tree like results to be made into a list for select option tags:
$this->Model->generateTreeList($conditions, null, null, ' - ', $recursive);
instead of using find(threaded)
that is if you attached the Tree behavior to it (which you probably should have since its obviously a tree like model).
But if you want to keep your find(threaded) method you need to manually transform it via recursive method.
thanks DSkinner, very informative.. i have modified it to be more generic:
/**
* Returns an indented html select based on children depth
*
* @param array $data_array - Array of data passed in from cake's find('threaded') feature
* @param array $model - the model name
* @param array $key - the key field on the model
* @param array $value - the value field on the model
* @param array $list - Used internally, contains array to be returned
* @param int $counter - Used Internally, counter for depth
* @return array
*/
public function threaded_to_list($data_array, $model=null, $key='id', $value='name',
&$list = array(), $counter = 0, $separator='__')
{
if ( ! is_array($data_array))
return array();
foreach ($data_array AS $data)
{
$list[$data[$model][$key]] = str_repeat($separator, $counter).$data[$model][$value];
if ( ! empty($data['children']))
{
$this->threaded_to_list($data['children'], $model, $key, $value, $list, $counter + 1);
}
}
return $list;
}
Here's what worked for me.
Make sure you replace:
- {SELECT_ID} with the value of the drop down
- {SELECT_LABEL} with what is displayed as the option
- {MODEL_NAME} with your model name
/** * Returns an indented html select based on children depth * * @param array $data_array - Array of data passed in from cake's find('threaded') feature * @param array $list - Used internally, contains array to be returned * @param int $counter - Used Internally, counter for depth * @return array */ public function drop_down_from_threaded($data_array, &$list = array(), $counter = 0) { if ( ! is_array($data_array)) return array(); foreach ($data_array AS $data) { $list[$data[{SELECT_ID}]] = str_repeat(' ', $counter).$data[{SELECT_LABEL}]; if ( ! empty($data['children'])) { $this->drop_down_from_threaded($data['children'], $list, $counter + 1); } } return $list; } /** * Get the data from the find('threaded') and pass it to our new function */ $results = $this->{MODEL_NAME}->find('threaded'); $results = $this->drop_down_from_threaded($results);
This may not work 100% for everyone, it works for me, but it should help give you something to start with.
What are "children"? Seems like your tree is spawned across one-to-many relations
It is not necessary to use the Tree behavior to use this method - but all desired results must be possible to be found in a single query.
精彩评论