order track list item done

Signed-off-by: bachy <git@g-u-i.net>
This commit is contained in:
bachy 2012-05-18 18:15:49 +02:00
parent 292f704f37
commit b4b346b8a5
5 changed files with 235 additions and 54 deletions

BIN
images/bullet_move.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@ -94,6 +94,37 @@
background-position: middle left;
}
.term-reference-tree-track-list.order-list li.track-item {
padding-left:0;
}
.term-reference-tree-track-list.order-list li.track-item:hover {
color:#000;
background-image: none;
}
.term-reference-tree-track-list.order-list .term-reference-tree-button-move, .term-reference-tree-track-list.order-list .term-reference-tree-button-delete{
display:inline-block; vertical-align:middle; zoom:1;
width:16px; height:16px;
background-repeat: no-repeat;
background-position: bottom center;
margin:0 5px;
}
.term-reference-tree-track-list.order-list li.track-item .term-reference-tree-button-move{
background-image: url("images/bullet_move.png");
}
.term-reference-tree-track-list.order-list li.track-item .term-reference-tree-button-move:hover{
cursor:move;
}
.term-reference-tree-track-list.order-list li.track-item .term-reference-tree-button-delete{
background-image: url("images/bullet_delete.png"); float:right;
}
.term-reference-tree-track-list.order-list li.track-item .term-reference-tree-button-:hover{
cursor:pointer;
}
.term-reference-tree-track-list li.term_ref_tree_nothing_message {
list-style-type: none;
list-style-image: none;

View File

@ -28,7 +28,26 @@
//currently selected items to it.
if($(this).hasClass('term-reference-tree-track-list-shown')) {
var track_list_container = $(this).find('.term-reference-tree-track-list');
var tracklist_is_orderable = track_list_container.is('.order-list');
if(tracklist_is_orderable){
track_list_container.sortable({
update: function(event, ui) {
console.log('sort update : event', event);
console.log('sort update : ui', ui);
$.each(event.target.children, function(index, val) {
var $item = $(val),
// event.target = ul.list
// ui.item = li.track-item
control_id = $item.data('control_id'),
$hiddenInput = $('#'+control_id).parent('.form-item').next('input[type=hidden]');
// $hiddenInput.attr('value', $item.index());
$hiddenInput.val($item.index());
});
},
});
}
//Var to track whether using checkboxes or radio buttons.
var input_type =
( $(this).has('input[type=checkbox]').size() > 0 ) ? 'checkbox' : 'radio';
@ -40,14 +59,22 @@
var labels = checked_controls.next();
var label_element;
//get delta
if(tracklist_is_orderable){
var weights = checked_controls.parent('.form-item').next('input[type=hidden]');
}
//For each label of the checked boxes, add item to the track list.
labels.each(function(index) {
label_element = $(labels[index]);
delta = tracklist_is_orderable ? $(weights[index]).val() : -1;
addItemToTrackList(
track_list_container, //Where to add new item.
label_element.html(), //Text of new item.
$(label_element).attr('for'), //Id of control new item is for.
input_type //checkbox or radio
input_type, //checkbox or radio
delta //delta
);
}); //End labels.each
@ -62,10 +89,14 @@
//Remove the "nothing selected" message if showing - add it later if needed.
//removeNothingSelectedMessage(track_list_container);
var event_target = $(event.target);
var control_id = event_target.data('control_id');
if(control_id) {
event_target.remove();
var event_parent_list = event_target.parent('li');
var control_id = event_parent_list.data('control_id');
// console.log('event', event);
// console.log('event_target.parent("li")', event_target.parent('li'));
// console.log('control_id', control_id);
// console.log('event_target.is(term-reference-tree-delete)', event_target.is('term-reference-tree-delete'));
if(event_target.is('.term-reference-tree-button-delete') && control_id) {
event_parent_list.remove();
var checkbox = $('#' + control_id);
checkbox.removeAttr('checked');
@ -89,7 +120,8 @@
track_list_container, //Where to add new item.
label_element.html(), //Text of new item.
$(label_element).attr('for'), //Id of control new item is for.
input_type //checkbox or radio
input_type, //checkbox or radio
-1 // delta
);
}
else {
@ -144,8 +176,9 @@
*
* @param control_type Control type - 'checkbox' or 'radio'.
*/
function addItemToTrackList(track_list_container, item_text, control_id, control_type) {
var new_item = $('<li class="track-item">' + item_text + '</li>');
function addItemToTrackList(track_list_container, item_text, control_id, control_type, delta) {
console.log('addItemToTrackList');
var new_item = $('<li class="track-item" delta="'+ delta +'"><div class="term-reference-tree-button-move"></div>' + item_text + '<div class="term-reference-tree-button-delete"></div></li>');
new_item.data('control_id', control_id);
//Add an id for easy finding of the item.
@ -173,35 +206,66 @@
}
return;
}
//Using checkboxes, so there can be more than one selected item.
//Find the right place to put the new item, to match the order of the
//checkboxes.
//Using checkboxes, so there can be more than one selected item.
//Find the right place to put the new item,
// to match the order of the checkboxes.
// OR order of delta
var list_items = track_list_container.find('li');
var item_comparing_to;
//Flag to tell whether the item was inserted.
var inserted_flag = false;
list_items.each(function(index){
item_comparing_to = $(list_items[index]);
if(!track_list_container.is('.order-list')){
list_items.each(function(index){
item_comparing_to = $(list_items[index]);
//If item is already on the track list, do nothing.
if ( control_id == item_comparing_to.data('control_id') ) {
inserted_flag = true;
return false; //Returning false stops the loop.
}
else if ( control_id < item_comparing_to.data('control_id') ) {
//Add it here.
item_comparing_to.before(new_item);
inserted_flag = true;
return false; //Returning false stops the loop.
}
});
//If item is already on the track list, do nothing.
if ( control_id == item_comparing_to.data('control_id') ) {
inserted_flag = true;
return false; //Returning false stops the loop.
}
else if ( control_id < item_comparing_to.data('control_id') ) {
//Add it here.
item_comparing_to.before(new_item);
inserted_flag = true;
return false; //Returning false stops the loop.
}
});
//If not inserted yet, add new item at the end of the track list.
if ( ! inserted_flag ) {
track_list_container.append(new_item);
}
//If not inserted yet, add new item at the end of the track list.
if ( ! inserted_flag ) {
track_list_container.append(new_item);
}
}else{
if( ! track_list_container.find('#'+new_item.attr('id')).size() ){
if(delta == -1){
track_list_container.append(new_item);
inserted_flag = true;
}else{
list_items.each(function(index){
item_comparing_to = $(this);
if ( delta < item_comparing_to.attr('delta') ) {
//Add it here.
item_comparing_to.before(new_item);
inserted_flag = true;
return false; //Returning false stops the loop.
}
});
//If not inserted yet, add new item at the end of the track list.
if ( ! inserted_flag )
track_list_container.append(new_item);
}
track_list_container.sortable('refresh');
}
}
}
/**
@ -246,7 +310,7 @@
// This helper function checks if the maximum number of choices is already selected.
// If so, it disables all the other options. If not, it enables them.
function checkMaxChoices(item, checkbox) {
function checkMaxChoices(item, checkbox, order_list) {
var maxChoices = -1;
try {
maxChoices = parseInt(Drupal.settings.term_reference_tree.trees[item.attr('id')]['max_choices']);

View File

@ -33,7 +33,7 @@ function term_reference_tree_element_info() {
'#input' => false,
'#theme' => array('checkbox_tree_track_list'),
'#pre_render' => array('form_pre_render_conditional_form_element'),
),
)
);
return $types;
@ -183,6 +183,7 @@ function _term_reference_tree_flatten($element, &$form_state) {
$children = element_children($element);
foreach($children as $c) {
$child = $element[$c];
// dsm($child, '$child');
if (array_key_exists('#type', $child) && ($child['#type'] == 'radio' || $child['#type'] == 'checkbox')) {
$output[] = $child;
}

View File

@ -19,6 +19,7 @@ function term_reference_tree_field_widget_info() {
'select_parents' => 0,
'cascading_selection' => 0,
'track_list' => 0,
'track_list_order' => 0,
'token_display' => '',
'parent_term_id' => '',
'max_depth' => '',
@ -171,7 +172,18 @@ function term_reference_tree_field_widget_settings_form($field, $instance) {
'#default_value' => $settings['track_list'],
'#return_value' => 1,
);
$form['track_list_order'] = array(
'#type' => 'checkbox',
'#title' => t('Track list drag and drop order'),
'#description' => t(
'Allow drag and drop selected terms ordering on tracklist.'),
'#default_value' => $settings['track_list_order'],
'#return_value' => 1,
'#element_validate' => array('_term_reference_tree_track_list_order_validate'),
);
$form['max_depth'] = array(
'#type' => 'textfield',
'#title' => t('Maximum Depth'),
@ -251,6 +263,18 @@ function _term_reference_tree_cascading_selection_validate($element, &$form_stat
}
}
function _term_reference_tree_track_list_order_validate($element, &$form_state){
if ($form_state['values']['instance']['widget']['settings']['track_list'] == 0 && $form_state['values']['instance']['widget']['settings']['track_list_order'] == 1) {
// This is pretty wonky syntax for the field name in form_set_error, but it's
// correct.
form_set_error('field][track_list_order', t('You must enable Track List if Track List Order is enabled.'));
}
/*
TODO check if number of values is diffrent from 1
*/
}
/**
* Process the checkbox_tree widget.
*
@ -310,6 +334,7 @@ function term_reference_tree_process_checkbox_tree($element, $form_state) {
$element[] = array(
'#type' => 'checkbox_tree_track_list',
'#max_choices' => $max_choices,
'#track_list_order' => $element['#track_list_order'],
);
}
}
@ -443,7 +468,8 @@ function theme_checkbox_tree_label($variables) {
function theme_checkbox_tree_track_list($variables) {
//Should the label be singular or plural? Depends on cardinality of term field.
static $nothingselected;
// dsm($variables, 'theme_checkbox_tree_track_list : $variables');
if(!$nothingselected) {
$nothingselected = t('[Nothing selected]');
//Add the "Nothing selected" text. To style it, replace it with whatever you want.
@ -459,17 +485,17 @@ function theme_checkbox_tree_track_list($variables) {
'Selected item (click the item to uncheck it)',
'Selected items (click an item to uncheck it)'
);
$order = $variables['element']['#track_list_order'] ? 'order-list' : '';
$output =
'<div class="term-reference-track-list-container">
<div class="term-reference-track-list-label">' . $label . '</div>
<ul class="term-reference-tree-track-list"><li class="term_ref_tree_nothing_message">'.$nothingselected.'</li></ul>
<ul class="term-reference-tree-track-list '.$order.'"><li class="term_ref_tree_nothing_message">'.$nothingselected.'</li></ul>
</div>';
return $output;
}
/**
* Implements hook_widget_field_form().
*/
@ -512,6 +538,7 @@ function term_reference_tree_field_widget_form(&$form, &$form_state, $field, $in
$element['#select_parents'] = $settings['select_parents'];
$element['#cascading_selection'] = $settings['cascading_selection'];
$element['#track_list'] = $settings['track_list'];
$element['#track_list_order'] = $settings['track_list_order'];
$element['#parent_tid'] = $settings['parent_term_id'] || $field['settings']['allowed_values'][0]['parent'];
$element['#vocabulary'] = $voc->vid;
$element['#token_display'] = module_exists('token') ? $settings['token_display'] : '';
@ -523,7 +550,11 @@ function term_reference_tree_field_widget_form(&$form, &$form_state, $field, $in
'#element_validate' => array('_term_reference_tree_widget_validate'),
'#properties' => $properties,
);
if ($settings['track_list_order']) {
drupal_add_library('system', 'ui.sortable');
}
return $element;
}
@ -544,25 +575,58 @@ function term_reference_tree_field_widget_form(&$form, &$form_state, $field, $in
* The validated element.
*/
function _term_reference_tree_widget_validate(&$element, &$form_state) {
dsm($element, '_term_reference_tree_widget_validate | $element');
$items = _term_reference_tree_flatten($element, $form_state);
dsm($items, '$items');
$value = array();
if ($element['#max_choices'] != 1) {
foreach($items as $child) {
if (array_key_exists('#value', $child) && $child['#value'] !== 0) {
array_push($value, array($element['#value_key'] => $child['#value']));
if(!$element['#track_list_order']){
foreach($items as $child) {
if (array_key_exists('#value', $child) && $child['#value'] !== 0) {
array_push($value, array( $element['#value_key'] => $child['#value']));
// If the element is leaves only and select parents is on, then automatically
// add all the parents of each selected value.
if ($element['#select_parents'] && $element['#leaves_only']) {
foreach($child['#parent_values'] as $parent_tid) {
if (!in_array(array($element['#value_key'] => $parent_tid), $value)) {
array_push($value, array($element['#value_key'] => $parent_tid));
}
}
}
}
}
// If the element is leaves only and select parents is on, then automatically
// add all the parents of each selected value.
if ($element['#select_parents'] && $element['#leaves_only']) {
foreach($child['#parent_values'] as $parent_tid) {
if (!in_array(array($element['#value_key'] => $parent_tid), $value)) {
array_push($value, array($element['#value_key'] => $parent_tid));
}
}
}
}
}
}else{
$selected_terms = array();
foreach($items as $child) {
if (array_key_exists('#value', $child) && $child['#value'] !== 0) {
$delta = $form_state['input'][$child['#value'].'-weight'];
$selected_terms[$delta] = array($element['#value_key'] => $child['#value']);
// If the element is leaves only and select parents is on, then automatically
// add all the parents of each selected value.
if ($element['#select_parents'] && $element['#leaves_only']) {
foreach($child['#parent_values'] as $parent_tid) {
if (!in_array(array($element['#value_key'] => $parent_tid), $selected_terms)) {
$delta = $form_state['input'][$parent_tid.'-weight'];
$selected_terms[$delta] = array($element['#value_key'] => $parent_tid);
}
}
}
}
}
// reorder items
ksort($selected_terms);
// record in value
foreach ($selected_terms as $delta => $term) {
$value[] = $term;
}
}
}
else {
// If it's a tree of radio buttons, they all have the same value, so we can just
@ -575,6 +639,8 @@ function _term_reference_tree_widget_validate(&$element, &$form_state) {
}
}
dsm($value, '$value');
if ($element['#required'] && empty($value)) {
// The title is already check_plained so it's appropriate to use !.
form_error($element, t('!name field is required.', array('!name' => $element['#title'])));
@ -701,7 +767,23 @@ function _term_reference_tree_build_item(&$element, &$term, &$form_state, &$valu
$parents_for_id = array_merge($element['#parents'], array($term->tid));
$e['#id'] = drupal_html_id('edit-' . implode('-', $parents_for_id));
$e['#parents'] = $element['#parents'];
}
}else if($element['#track_list_order']){
$delta = 0;
$i = -1;
if(isset($value[$term->tid])){
foreach ($value as $tid) {
$i++;
if($term->tid == $tid)
break;
}
}
$e_weight = array(
'#type' => 'hidden',
'#value' => $i,
'#name' => $term->tid.'-weight',
);
}
}
else {
$e = array(
@ -710,9 +792,12 @@ function _term_reference_tree_build_item(&$element, &$term, &$form_state, &$valu
);
}
$container[$term->tid] = $e;
if(isset($e_weight)){
$container[$term->tid.'-weight'] = $e_weight;
}
if (($depth + 1 <= $element['#max_depth'] || !$element['#max_depth']) && property_exists($term, 'children') && count($term->children) > 0) {
$parents = $parent_tids;
$parents[] = $term->tid;