While website development it very often happens that sorting should be done by a specific criterion in which case Views, Nodequeue, Flag and other similar modules are used. Sometimes, however, those modules' functional does not suffice to meet the client's tough demands. Of course, one can create multiple nodequeues which means that your client will later need educating in the responsibilities each of the nodequeues has been assigned with. This approach seems to be doubtful, though, from the point of view of the site's usability. Another option might suggest adding of the "weight" cck-field along with manual identifying of its weight, to eventually sort by it. And again, having thousands of nodes at hand makes this method irrelevant.
In view of the above, "drag-and-drop" interface is likely to be the most valid of the sort options in question. Realization of this method will be outlined in this post.
First of all we do add cck-field "weight" to the necessary type of content. Then in hook_menu we declare the page to host both draggable-interface and form itself:
function my_module_drag_form($form_state, $node) { $form['my_items']['#tree'] = TRUE; $vids = my_module_select_vids_function(); // выбираем нужные ноды //правильный способ выполнения запроса к ссk-полям $type_name = 'product'; $field_name = 'field_product_weight'; $type = content_types($type_name); $field = $type['fields'][$field_name]; $data = content_database_info($field); $join = $data['table']; $field = $data['columns'][end(array_keys($data['columns']))]['column']; //выбираем тайтлы нод и значение поля "weight" $q = db_query("SELECT f.%s, n.title, n.nid, n.vid FROM {node} n INNER JOIN {%s} f ON f.vid = n.vid WHERE n.vid IN (" . db_placeholders($vids, 'int') . ") ORDER BY f.%s ASC", array_merge(array($field), array($join), $vids, array($field))); //собственно сама форма while ($d = db_fetch_array($q)) { $form['my_items'][$d['vid']] = array( 'name' => array( '#type' => 'markup', '#value' => l($d['title'], 'node/' . $d['nid']), ), 'weight' => array( '#type' => 'weight', '#delta' => 10, '#default_value' => $d[$field], '#attributes' => array('class' => 'weight'), ), ); } $form['submit'] = array( '#type' => 'submit', '#value' => t('Save Changes'), ); return $form; }
To log on the changes in the database, we add submit function to the form:
function my_module_drag_form_submit($form, &$form_state) { $type_name = 'product'; $field_name = 'field_product_weight'; $type = content_types($type_name); $field = $type['fields'][$field_name]; $data = content_database_info($field); $join = $data['table']; $field = $data['columns'][end(array_keys($data['columns']))]['column']; //обновляем значение поля "weight" в базе данных foreach ($form_state['values']['my_items'] as $k => $item) { $q = db_query("UPDATE {%s} SET %s=%d WHERE %s.vid=%d", $join, $field, $item['weight'], $join, $k); } }
We declare the theming function for our form:
function my_module_theme() { return array( 'my_module_drag_form' => array( 'arguments' => array('form' => NULL), ), ); }
Theming function will look as follows:
function theme_my_module_drag_form($form) { // переменная, которая будет содержать возвращаемое значение $output = ''; // проходимся по каждому элементу массива таблицы foreach($form['my_items'] as $id => $row) { // если $id не число - пропускаем эту строчку if (!intval($id)) continue; // этот массив будет содержать ячейки строки $this_row = array(); // генерируем markup name $this_row[] = drupal_render($row['name']); // добавляем поле с весом $this_row[] = drupal_render($row['weight']); // добавляем строку в массив строк $table_rows[] = array('data' => $this_row, 'class'=>'draggable'); } // убеждаемся, что количесво заголовков совпадает с количеством столбцов $header = array( 'Name', 'Weight', ); $table_id = 'my_items'; // добавляем draggable drupal_add_tabledrag($table_id, 'order', 'sibling', 'weight'); // переопределяем элемент формы 'my_items' маркапом, сгенерированным нашей таблицей $form['my_items'] = array( '#type' => 'markup', '#value' => theme('table', $header, $table_rows, array('id' => $table_id)), '#weight' => '1', ); // генерируем форму $output = drupal_render($form); return $output; }
As a result, our Drupal development agency will have a happy client and the picture as described at the top of this page.