Is there a way to bind the sortablejs results to the vue data?

How can I pass the result to data in Vue? I am confused with how to implement sortable features using Vue and SortableJS. The project utilizes Bootstrap-Vue.


  <div>
    <b-table v-sortable="sortableOptions" striped hover :items="items"></b-table>
  </div>
</template>

<script>
import Sortable from "sortablejs";

const createSortable = (el, options, vnode) => {
  return Sortable.create(el, {
    ...options,
  });
};

const sortable = {
  name: "sortable",
  bind(el, binding, vnode) {
    const table = el;
    table._sortable = createSortable(
      table.querySelector("tbody"),
      binding.value,
      vnode
    );
  },

};
   

Answer №1

While working on one of my projects, I encountered a particular task that required a unique solution. Despite finding similar solutions on stackoverflow, none seemed to work for me. The key aspect that was missing from those solutions is the importance of providing the Sortable-object with the dataIdAttr property and setting a relevant attribute in the children of the sortable-dom-element. This step is crucial when dealing with a bootstrap-vue table as it enables you to rearrange rows and update vue-reactive-data based on the changed drag indexes.

I believe this information could be helpful for someone facing a similar challenge.

<template>
    <b-table
        v-draggable-rows="{ data: items, orderColumn: '№' }"
        :items="items"
    >
        <template #cell(Dragger)>
            <IconDragHandle />
        </template>
    </b-table>
</template>

<script>
import IconDragHandle from '~/components/icons/table/IconDragHandle.vue';

export default {
  components: {
    IconDragHandle,
  },

  data() {
    return {
      items: [],
    };
  },

  created() {
    this.items = [...Array(8).keys()].map(x => ({
      'Dragger': '',
      '№': x + 1,
      'Cell1': x + 1,
      'Cell2': x + 1,
      'Cell3': x + 1,
    }));
  },
};
</script>
import Vue from 'vue';
import Sortable from 'sortablejs';

Vue.directive('draggable-rows', {
  bind(el, binding, vnode) {
    const table = el;
    table._sortable = createSortable(
      table.querySelector('tbody'),
      binding.value,
      vnode
    );
  },
});

const createSortable = (el, options, vnode) => {
  let order = [];
  const data = options.data;
  const orderColumn = options.orderColumn;
  for (let i = 0; i < el.children.length; i++) {
    el.children[i].setAttribute('sortable-id', i);
  }
  return Sortable.create(el, {
    dataIdAttr: 'sortable-id', // default: data-id
    animation: 150,
    easing: 'cubic-bezier(0.25, 1, 0.5, 1)',
    handle: '.custom-table-draggable-handle',
    ghostClass: 'custom-draggable-rows-ghost',
    chosenClass: 'custom-draggable-rows-chosen',
    dragClass: 'custom-draggable-rows-drag',

    onStart() {
      order = [...this.toArray()];
    },

    onEnd(evt) {
      this.sort(order);
      data.splice(evt.newIndex, 0, ...data.splice(evt.oldIndex, 1));
      if (!orderColumn) return;
      data.forEach((o, i) => {
        o[orderColumn] = i + 1;
      });
    },
  });
};

Draggable Draggable.Vue Bootstrap-Vue SortableJS v-sortable Reorder

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is causing my sorting algorithm to produce inaccurate results?

After finding this sorting function as the best answer to my question, I tested it with example data and it worked perfectly. However, when I tried it with my actual data, it didn't work as expected and I'm not sure why. You can view my data her ...

Tips for transforming numerical date data into a string format

Is there a method to convert the numeric month in a table into a string format? <table style="width: 100%;"> <tr> <th>Date</th> <th>Total</th> </tr> <tr> <td id="date ...

Transforming c# data sourced from entity framework into a proper JSON format

Below is a method I have: [HttpPost] public ActionResult GetData() { var data= (dynamic)null; using (DBContext context = new DBContext()) { data= context.MyObject.Where(i=> i.TypeId == 1).OrderBy(k => ...

Poor initial placement of the Dialogs when the content exceeds the space available

While using material-ui^0.20 with react^16.2, I encountered an issue when initially displaying a Dialog containing a Component with excessive content. The problem is illustrated in this image: https://i.sstatic.net/RF8Mu.png This is the expected appeara ...

Steps to retrieve data (token) from developer tools and incorporate it into a fetch Post request

Is there a simple way to extract data using dev tools and insert it into a fetch request? I am trying to make a POST request through the console, but I am struggling to correctly copy a token. I attempted to use querySelector but instead of finding the t ...

Restrict magnification in THREE.js mousewheel interaction

Seeking advice on limiting zoom in and out of a model in three.js. I have explored trackball controls, but couldn't find a way to restrict zooming. I also experimented with orbit controls, but encountered issues when combined with trackball controls r ...

Why isn't my custom HTML attribute displaying correctly?

In my current React app project, I have been incorporating custom attributes to HTML tags and React components for End-to-End (E2E) tests using Testcafe. However, I am facing an issue where the additional data-test="burger-menu-btn" attribute is ...

"Implementing a nested drawer and appbar design using Material UI, along with incorporating tabs within

I am currently working on an app that includes tabs for different files, each of which requires its own drawer and appbar. I found a codesandbox example that is similar to what I am trying to implement. Here is the link to the codesandbox One issue I hav ...

Protractor: The top tool for testing AngularJS applications

Protractor is a comprehensive testing framework designed specifically for Angular applications, utilizing WebDriverJS as its foundation. As someone who is just beginning to explore web testing, I am curious about the benefits of choosing Protractor over u ...

Tips on how to bring in .js that has brought in .json from an html file

English is not my first language, and I struggle with it, but I did my best. I am attempting to include a js file that imports json from an html .js import menus from '../json/menus.json'; (function () { function parseMenu(ul, menu) { fo ...

Checkbox remains selected even after navigating back

I am currently working on a code that involves using checkboxes. When I click on them, the checkbox value is appended to the URL with a hash. However, when I go back or press the back button, the URL changes but the checkboxes remain checked. Below is the ...

Forcing Reload of HTML5 Video to Avoid Caching Issues

Is there a way to instruct the HTML5 Video tag to stream the video chunks on demand/load without caching them on the client side? Essentially, how can I prevent the browser from storing the HTML5 video in its cache? My main objective is to have the video ...

Is there a way to utilize the child component's method?

I am looking to access a child component's method from the parent in Vue.js. To achieve this, I plan on using $refs. Code Example: <template> <div>Parent!</div> </template> Script: <script> Vue.component('c ...

I can see the JSON data printing to the console in Ionic 3, but it doesn't display on

I seem to be facing a challenge with passing the 'item' to my search function in my Ionic 3 app. Although I was able to successfully connect to a json data file and print objects to the console, I am encountering an error message on the page that ...

Ways to implement a filter pipe on a property within an array of objects with an unspecified value

Currently, I'm tackling a project in Angular 8 and my data consists of an array of objects with various values: let studentArray = [ { Name: 'Anu', Mark: 50, IsPassed: true }, { Name: 'Raj', Mark: 20, IsPassed: false }, { Na ...

Include images in the form of .png files within the td elements of a table that is dynamically generated in the index

I have successfully created a table using embedded JavaScript with the help of messerbill. Here is the code: <table id="Table1"> <tr> <th>Kickoff</th> <th>Status</th> <th>Country</th> < ...

Managing an Angular timer: Starting and resetting it via the controller

Is there a way to start a timer when the user clicks on the recordLogs method and reset the timer when the user clicks on the stopLogs method? According to the angular-timer documentation, we should be able to use the timer-stop and timer-clear methods to ...

How can we implement intricate looping mechanisms in hogan js?

Currently, I am in the process of familiarizing myself with expressjs. In my journey to learn this technology, I have encountered a controller that performs queries on a database and returns a JSON object with certain key-value pairs. An example of such an ...

As someone new to Node.js, I'm curious about the best way to handle the result of a mongoose query. Any insights or tips would be greatly appreciated

I have a Database document stored in MongoDB like this: Users { id: id, name: string, age: string } I am wondering how I can retrieve only the 'age' field in the result of my query, without getting the entire document with all fi ...

What is the best way to extract webpage data in an android application?

Is there a way to automate entry of a string into an input tag on a website form, click a button, and retrieve the link generated on another page in the background using JavaScript or some other method? Specifically, I am looking to achieve this on the w ...