[Solved] Drag & Drop sorting List of Elements with BF forms pro

Hi,
Would like to give user the possibility to sort a “List of Elements” by “Drag&Drop”.

Question:

  • Does anybody knows, if there is a built-in solution to build a form in “BF forms pro” for this?

Search does not find any hit in community, google or bricksforge website. Maybe I search wrong terms.

Would be great to get a hint in the right direction.

If not, maybe you know about a working solution with some 3.-party JS-Code.
Something like Drag & Drop • by FormKit or GitHub - SortableJS/Sortable: Reorderable drag-and-drop lists for modern browsers and touch devices. No jQuery or framework required..
Does not have to be with images. Text would be nice. But would be helpfull with kind of real and working solution with Bricks or Bricksforge Forms Pro.
Or some hints about docs for or the right approach to figure it out in a rush.

  • Any ideas, working solutions, experiences?

I have found a working solution with SortableJS.

Maybe someone is interessted in the solution too.
!! NO WARRANTY for code or best-practice solution. But maybe a good startpoint !!

Have built a page with BF forms pro and used checkboxes.
But from documentation it should work with any kind of element, also with div’s.


Each checkbox has his own id (attribute) with particular value.
from 1 till the last item.

CODE for PHP & HTML box in Code-Element:

<script src="https://raw.githack.com/SortableJS/Sortable/master/Sortable.js"></script>

CODE for JavaScript box in Code-Element:

// initialize drag&drop functionality
let sortList = document.querySelector('#sort-list .options-wrapper');
let sort_list = Sortable.create(sortList, {
  animation: 150,
  group: 'shared',
  ghostClass: 'sortable-ghost',
  
  // Run code after Drag-and-Drop
  onEnd: function (evt) {
    //console.log("Drag & Drop beendet");

    // TAke IDs from current sorted listElements
    let sortable_ids = document.querySelectorAll('#sort-list li[id]');
    let sortable_ids_list = [];
    for (let i = 0; i < sortable_ids.length; i++) {
      sortable_ids_list.push(sortable_ids[i].id);
    }

    // Fill hidden input-field
    let sorting_input = document.querySelector('#prefered_sorting input');
    //console.log("Aktualisierte Reihenfolge: " + sortable_ids_list.join(","));
    sorting_input.value = sortable_ids_list.join(",");
  }
});

//console.log("Drag-and-Drop-Funktionalität initialisiert!");

Tried before with event-listener “submit” but this didn’t work.
Always the initial-value from hidden-field was submitted.
Although in dev-Tools Elements-panel, the sorting-value-text was set right… :thinking:

Anyway - with this onEnd-trigger solution it is working fine.

Maybe the json-template code is also helpfull for starting-poit.
Try to add it …
→ Doesn’t worked, there seams to be not allowed to add json-files in forum. Hope this is not against the forum-rules. But I can not find a faster & neater solution. (hints are welcome!)
So I add it as code, you have to copy-paste in a new .json file on your machine:

{"id":6285,"name":"sortablejs-testform-ok","title":"SortableJS TestForm-OK","date":"2024-10-01 10:32:07","date_formatted":"1. October 2024","author":{"name":"mh-smarter.design-43s-adm","avatar":"https:\/\/secure.gravatar.com\/avatar\/6be97cf750adc68ae63ee26dd98cfd24?s=60&d=mm&r=g","url":"https:\/\/smarterdesign-ua.lcoal"},"permalink":"https:\/\/smarterdesign-ua.lcoal\/template\/sortablejs-testform-ok\/","thumbnail":null,"bundles":[],"tags":[],"type":"","content":[{"id":"724f9c","name":"section","parent":0,"children":["001016"],"settings":[]},{"id":"001016","name":"container","parent":"724f9c","children":["e1f3ac"],"settings":[]},{"id":"e1f3ac","name":"brf-pro-forms","parent":"001016","children":["925e42","665f41","5b0cf0","ccb4ba","8f0493","a53be0","58d209"],"settings":{"showLabels":false,"checkboxCustomStyle":false,"checkboxCard":false,"radioCustomStyle":false,"radioCard":false,"iconPosition":"row","iconFocusInput":true,"dividerWidth":"100%","submitButtonStyle":"primary","submitButtonHasCondition":false,"submitButtonConditionAction":"disabled","submitButtonConditionsRelation":"and","actions":["email","create_submission"],"successMessage":"Nachricht erfolgreich gesendet. Wir werden uns so schnell wie m\u00f6glich bei Ihnen melden.","emailSubject":"Contact form request","emailTo":"admin_email","fromName":"smarter.design","emailContent":"{{all_fields}}","emailErrorMessage":"\u00dcbermittlung fehlgeschlagen. Bitte laden Sie die Seite neu und versuchen Sie erneut, das Formular abzuschicken.","htmlEmail":true,"mailchimpPendingMessage":"Bitte pr\u00fcfen Sie Ihre E-Mail, um Ihr Abonnement zu best\u00e4tigen.","mailchimpErrorMessage":"Es tut uns leid, aber wir konnten Sie nicht anmelden.","sendgridErrorMessage":"Es tut uns leid, aber wir konnten Sie nicht anmelden.","hCaptchaTheme":"light","multiStepSummary":false,"multiStepShowSteps":false,"multiStepAnimateSteps":false,"multiStepAnimation":"fade","multiStepAnimationDuration":500,"multiStepJumpToTop":false,"multiStepJumpOffset":50,"multiStepAutoFocusFirstField":false,"multiStepSummaryButtonText":"Show Summary","multiStepSummaryMainHeadline":"Summary","multiStepSummaryShowEmpty":false,"multiStepSummaryEmptyText":"\/","multiStepFirstStep":"Start","multiStepStepTopOffset":"-60px","multiStepStepAllowClicks":false,"pro_forms_post_action_post_create_allow_only_for_logged_in":false,"pro_forms_post_action_post_create_post_status":"draft","pro_forms_post_action_post_create_pt":"post","pro_forms_post_action_post_update_allow_only_for_post_author":false,"pro_forms_post_action_post_update_allow_only_if_logged_in":false,"pro_forms_post_action_post_delete_permanently":false,"pro_forms_post_action_post_delete_allow_only_for_post_author":false,"pro_forms_post_action_post_delete_allow_only_if_logged_in":false,"resetUserPasswordNotificationNewPassword":"Please enter a new password","resetUserPasswordNotificationPasswordsDoNotMatch":"Passwords do not match","resetUserPasswordNotificationCurrentPasswordIncorrect":"Current password is incorrect","createPdfPaperSize":"A4","createPdfOrientation":"portrait","createPdfTemplateType":"html","createPdfHtmlTemplate":"<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<title>Form Submission<\/title>\n\t<\/head>\n\t<body>\n\t\t<h1>Fields<\/h1>\n\t\t{{all_fields}}\n\t<\/body>\n<\/html>","_cssId":"sortable-form","submission_form_title":"SortableJS-TestForm"},"themeStyles":[]},{"id":"925e42","name":"brf-pro-forms-field-text","parent":"e1f3ac","children":[],"settings":{"label":"Name","id":"zxolxw","showLabel":true},"label":"Text"},{"id":"665f41","name":"brf-pro-forms-field-email","parent":"e1f3ac","children":[],"settings":{"label":"Email","id":"1a87ab","showLabel":true},"label":"Email"},{"id":"5b0cf0","name":"brf-pro-forms-field-textarea","parent":"e1f3ac","children":[],"settings":{"label":"Message","id":"971798","showLabel":true},"label":"Textarea"},{"id":"ccb4ba","name":"brf-pro-forms-field-checkbox-wrapper","parent":"e1f3ac","children":["54a52a","06d99c","7a660b","7e332e"],"settings":{"id":"73c115","label":"Label","showLabel":true,"width":"100%","customRequired":false,"customRequiredCount":1,"hasConditions":false,"conditionsRelation":"and","_cssId":"sort-list"}},{"id":"54a52a","name":"brf-pro-forms-field-checkbox","parent":"ccb4ba","children":[],"settings":{"showLabel":true,"value":"1","label":"Item 1","_attributes":[{"id":"ciuiqj","name":"id","value":"1"}]},"label":"Checkbox"},{"id":"06d99c","name":"brf-pro-forms-field-checkbox","parent":"ccb4ba","children":[],"settings":{"showLabel":true,"label":"Item 2","id":"rksbio","value":"2","_attributes":[{"id":"cibxxz","name":"id","value":"2"}]},"label":"Checkbox","themeStyles":[]},{"id":"7a660b","name":"brf-pro-forms-field-checkbox","parent":"ccb4ba","children":[],"settings":{"showLabel":true,"label":"Item 3","id":"sfjjvf","value":"3","_attributes":[{"id":"pxhsje","name":"id","value":"3"}]},"label":"Checkbox","themeStyles":[]},{"id":"7e332e","name":"brf-pro-forms-field-checkbox","parent":"ccb4ba","children":[],"settings":{"showLabel":true,"label":"Item 4","id":"yxywll","value":"4","_attributes":[{"id":"xmxtgd","name":"id","value":"4"}]},"label":"Checkbox","themeStyles":[]},{"id":"8f0493","name":"brf-pro-forms-field-submit-button","parent":"e1f3ac","children":[],"settings":{"label":"Submit","submitButtonIconPosition":"left","submitButtonStyle":"primary"},"label":"Submit"},{"id":"a53be0","name":"code","parent":"e1f3ac","children":[],"settings":{"code":"<script src=\"https:\/\/raw.githack.com\/SortableJS\/Sortable\/master\/Sortable.js\"><\/script>\n","user_id":1,"time":1727768273,"javascriptCode":"\/\/ initialize drag&drop functionality\nlet sortList = document.querySelector('#sort-list .options-wrapper');\nlet sort_list = Sortable.create(sortList, {\n  animation: 150,\n  group: 'shared',\n  ghostClass: 'sortable-ghost',\n  \n  \/\/ Run code after Drag-and-Drop\n  onEnd: function (evt) {\n    \/\/console.log(\"Drag & Drop beendet\");\n\n    \/\/ TAke IDs from current sorted listElements\n    let sortable_ids = document.querySelectorAll('#sort-list li[id]');\n    let sortable_ids_list = [];\n    for (let i = 0; i < sortable_ids.length; i++) {\n      sortable_ids_list.push(sortable_ids[i].id);\n    }\n\n    \/\/ Fill hidden input-field\n    let sorting_input = document.querySelector('#prefered_sorting input');\n    \/\/console.log(\"Aktualisierte Reihenfolge: \" + sortable_ids_list.join(\",\"));\n    sorting_input.value = sortable_ids_list.join(\",\");\n  }\n});\n\n\/\/console.log(\"Drag-and-Drop-Funktionalit\u00e4t initialisiert!\");","executeCode":true},"label":"SortableJS-CODE"},{"id":"58d209","name":"brf-pro-forms-field-hidden","parent":"e1f3ac","children":[],"settings":{"id":"preferred_sorting","_cssId":"prefered_sorting","value":"default-value"}}],"templateType":""}

Have fun with :heavy_heart_exclamation:
And if anyone has better idea/code please share :heart: