123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494 |
- diff --git a/images/bullet_move.png b/images/bullet_move.png
- new file mode 100644
- index 0000000000000000000000000000000000000000..45f869428fd24f50acd6a16be70bf04a9f014e08
- Binary files /dev/null and b/images/bullet_move.png differ
- diff --git a/term_reference_tree.css b/term_reference_tree.css
- index 40ba2cfbe530fa873c2fd7809636b9201eeb2623..5b72ebbfe96c05ff9ea680bf4105ec880c3d7370 100644
- --- a/term_reference_tree.css
- +++ b/term_reference_tree.css
- @@ -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;
- diff --git a/term_reference_tree.js b/term_reference_tree.js
- index 319312f2dd0626ef4545bc66e3310f0467a8fb9e..23e742b3ed68653a749ebbabd0b7e7bbb71af887 100644
- --- a/term_reference_tree.js
- +++ b/term_reference_tree.js
- @@ -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']);
- diff --git a/term_reference_tree.module b/term_reference_tree.module
- index 1aea8b531d81c88ea58f3a1bcd05443483ab19a2..4346ed47a589bd32c68d2982bcd3ff80f82160c6 100644
- --- a/term_reference_tree.module
- +++ b/term_reference_tree.module
- @@ -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;
- }
- diff --git a/term_reference_tree.widget.inc b/term_reference_tree.widget.inc
- index 8bae7a1fb46632d924d2625b9897235506b7da0f..1d4f6b758387564850b55ed9f9d56a185fdacf1c 100644
- --- a/term_reference_tree.widget.inc
- +++ b/term_reference_tree.widget.inc
- @@ -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 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(!$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));
- + }
- + }
- + }
- +
- + }
- + }
- +
- + }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;
|