1

I am building a configuration form with a few sortable elements. I know, you can build a table using builtin Drupal draggable functionality (drupal_attach_tabledrag), but it's a bit too complicated for my task.

I am saving new order of elements inside a hidden input field value using Jquery UI Sortable function and dynamically set #weights in form elements:

    $weights = $config->get('sort_order');
    parse_str($weights, $weights);


    $form['el1'] = [
        '#type' => 'checkbox',
        '#title' => 'Title1',
        '#default_value' => $config->get('el1'),
        '#weight' => $weights['el1']
    ];

    $form['el2'] = [
        '#type' => 'checkbox',
        '#title' => 'Title2',
        '#default_value' => $config->get('el2'),
        '#weight' => $weights['el2']
    ];

Elements are draggable and sorting works fine. The only difficulty I have is prepending an icon to each element so that others could use that icon to drag elements up and down (just like Drupal does in a lot of configuration UIs).

I know you can create custom elements using #markup with an image tag inside it, or some div with image background. But adding custom markup to each element is problematic for several reasons:

  1. I'll have to write different names for each markup separately. For example if I have a markup element:

    $form['drag-icon'] = [
        '#type' => '#markup',
        '#markup'=> '<p class="drag-icon"></p>'
    ];
    

its name is drag-icon and to prepend it to another element, I'd have to use a different name each time (this is horrible).

  1. Although it can be aligned well with the element using css, dragging on that icon, breaks the line while moving it up/down.

  2. Would have to write this mark up manually for each element.

I also tried using a template file for this form, but among other things, I couldn't keep track of sort order inside it so easily as in buildForm() function using #weight.

I wrote a lot of explanations to show what I have tried.

I just want a simple method to append an icon to each element of the form to achieve something like this:

enter image description here

  • Why not just use css? – Clive Feb 7 '17 at 7:53
  • @Clive, As you know, by default, each form element consists of a label and a field wrapped around by a div. Yes, using css is easy. But for that I need another element inside the div, placed before the label and input, so that I could use a background-image on it and then float it left. Is there a simple way do this? – Davit Magaldadze Feb 7 '17 at 8:28
  • Just use a ::before selector on the element you want it before, position absolute (negative left), with position relative on the original element – Clive Feb 7 '17 at 9:34
0

I want to implement this dragging functionality in Drupal 8, may i know how you achieve draggable functionality in that or can you share the code

  • There were two ways I managed to accomplish making elements draggable: 1. Using Drupal's drupal_attach_tabledrag and 2. Making form elements draggable using JQuery UI's draggable component: jqueryui.com/draggable – Davit Magaldadze Dec 20 '17 at 16:13
  • As for sharing the code, I was doing all that for educational purposes and I've long lost it, sorry. I never got back to it. – Davit Magaldadze Dec 20 '17 at 16:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.