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:
-
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).
-
Although it can be aligned well with the element using css, dragging on that icon, breaks the line while moving it up/down.
-
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: