--- sidebar: auto --- # Guide ## Quickstart Install the package `vue-draggable-grid` via your favourite package manager. Include the library in your project: ```javascript import draggableGrid from "vue-draggable-grid"; Vue.use(draggableGrid); // Now create your app as usual ``` An example usage could look like this: ```vue <template> <drag-grid v-model="items" :cols="4" :rows="4"> <template #item="item"> {{ item.data.text }} </template> </drag-grid> </template> <script> export default { name: "YourComponent", data() { return { items: [ { x: 1, y: 3, w: 2, h: 2, key: "item1", data: { text: "Hello world 1" }, }, { x: 2, y: 2, w: 2, h: 1, key: "item2", data: { text: "Hello world 2" }, }, { x: 3, y: 1, w: 1, h: 1, key: "item3", data: { text: "Hello world 3" }, }, ], }; }, }; </script> ``` ## Blocking fields A field (or cell) can be blocked via the `disabledFields` prop. The prop receives an array of objects, containing the coordinates of the blocked fields. ```javascript disabledFields: [ { x: 1, y: 1 }, { x: 2, y: 3 }, ]; ``` ## Prevent items from being dragged To disable dragging of a specific item, simply set the attribute `disabled` of the item to `true`. ```javascript{4,5} someDisabledItems: [ { key: "key1", x: 1, y: 3, w: 1, h: 1, data: {} }, { key: "key2", x: 2, y: 2, w: 1, h: 1, data: {} }, { key: "key3", x: 3, y: 1, w: 1, h: 1, data: {}, disabled: true }, { key: "key4", x: 1, y: 2, w: 1, h: 1, data: {}, disabled: true }, ] ``` The highlighted items are not draggable. ## Disabling the grid If the boolean property `disabled` is set for the whole grid, the grid itself is disabled, and items can't be moved. ::: tip NOTICE A disabled grid only prevents changing the data inside the grid. If the data changes from outside of the grid, the grid _will_ rerender. ::: ## Programmatic validation of movements It is also possible to supply a function to dynamically or programmatically hinder fields from being moved to, and items from being moved. This can be done by supplying a function which takes the `x` and `y` coordinates of the field as well as the key of the item. If `false` is returned, the movement is prohibited. The highlight which appears when dragging an element is also disabled for this field. Examples for such methods are the following: ```javascript function blockField(x, y, key) { // We won't move items with ID 'obj8' and nothing into (3, 3) and (4, 3) if (x === 3 && y === 3) return false; if (x === 4 && y === 3) return false; return key !== "obj8"; } function blockAllMoving() { return false; } ``` ## Changing the highlight The highlight is the grey-bordered rectangle which appears when dragging over a field. ### Custom highlight To customize the highlight, use the `highlight` slot inside the grid component. ```html <drag-grid v-model="items" :cols="3" :rows="2"> <template #highlight> <div ref="highlight" class="custom-highlight"> This is a custom highlight with a custom style! </div> </template> </drag-grid> ``` ### Disabled highlight To disable the highlight, use the `no-highlight` prop. ## Displaying the loading of items If the grid is supplied with the `loading` prop, it will be in a loading status. In this status it is disabled, like if `disabled` where true, but the grid is filled with elements inside the `loader` slot. This provides the ability to do something like more realistic skeleton loaders. ## Changing items on move It is possible to make changes to an item once it moved successfully. One can supply a function in the `validate-element` prop which gets called on a moved item and can make (in place) changes to it. Such a function could look like this: ```javascript function randomKey(element) { if (element.key.length !== 1) return; element.key += Math.random().toString(36).replace("0.", ""); } ``` This method changes the key of a moved item to a random string if the key has a length of 1. This is used inside example 2 (the tic-tac-toe game). ## Functional item properties Properties of items don't have to be Numbers, Strings and Objects, they can also be functions returning those types. They will automatically be called with a grid object containing the `gridId` as well as the `context`. A singular item could look like this: ```javascript [ { x: (grid) => { return grid.gridId === "lesson-plan" ? this.lesson1X : 0; }, y: (grid) => { return grid.gridId === "lesson-plan" ? this.lesson1Y : 0; }, w: 1, h: this.lesson1Length, key: "lesson1", data: { text: this.lessonData.lesson1, }, }, ]; ``` Items can also have custom extra properties. They will however be reset after moving. An example where these are used is Example 5. ## Listening to grid changes There are two ways to process changes made by dragging and dropping items: the `input` event and the `itemChanged` event. The `input` event works together with the value prop so one can use `v-model` to supply the grid and have changes made automatically. The event returns the grid how it would look if the item moved to the specific location. ::: warning Notice that this event is only possible if your item properties are basic types, functional items are not supported and the properties will be reset to `undefined`. ::: The `itemChanged` event returns the moved item with following attributes: ```javascript let eventData = { context: String, // Context of the origin grid (same as the target's) data: Object, // Data Object of the item gridId: String, // ID of the target grid h: Number, // Height of the item key: String, // Key of the item mouseX: Number, // Mouse position on the element relative to mouseY: Number, // the center of the top left rectangle originGridId: String, // ID of the origin grid w: Number, // Width of the item x: Number, // New x position (col) of the item y: Number, // New y position (row) of the item }; ``` This event doesn't change the grid, this change has to be made separately. This is useful if e.g. a direct API request is needed. ## Multiple grids To connect multiple grids they need to have the same context. If you supply the same string to the `context` prop of two grids, the items can be moved interchangeably. ::: warning Items are not deleted from the source grid if moved to a different one. You have to build a mechanism for this yourself. Examples for such a mechanism can be found in Examples 4 and 5. ::: To handle movements from one grid to another, the attributes `gridId` and `originGridId` of the event will help.