Open Grawl opened 7 years ago
Hi there! Have you applied the CSS 'selectorClass' class to the <g>
elements?
Could you perhaps show me some code?
I use vue-drag-select
like this gist and import
it using Rollup:
import dragSelect from './vendor/vue-drag-select'
const app = new Vue({
el: '#hallApp',
components: {
'drag-select-container': dragSelect
}
})
And I put my SVG right into template, inline:
<div id="hallApp">
<drag-select-container selectorClass="cls-1">
<template scope="{ selectedItems }">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="6602.848 -554.785 878.112 543.45">
<g id="Group_1089" transform="translate(-957.152 -3588.785)">
<g id="Rectangle_1128" class="cls-1" data-sector="pew-2" data-row="row-1"
data-seat="0" transform="translate(7812.659 3529.023)">
<rect class="cls-7" width="10.221" height="10.221"/>
<rect class="cls-8" x="0.1" y="0.1" width="10.021" height="10.021"/>
</g>
</g>
…
</svg>
</template>
</drag-select-container>
</div>
It's a map of a concert hall. I handle clicks on elements with [data-seat]
attribute and use data-attributes to do some, it works.
I want to select a multiple <g class="cls-1">
elements using vue-drag-select
.
I added console.log(el)
to isItemSelected
method to debug this and I see that el
is an <svg>
element when I drag to select some elements.
If I use regular HTML elements into <template>
, it works properly:
<template>
<drag-select-container selectorClass="cls-1">
<template scope="{ selectedItems }">
<div class="cls-1">
…
</template>
</drag-select-container>
</template>
In that case, isItemSelected
shows me how many <div class="cls-1">
is selected.
Hi there! Thanks for demonstrating me your code. The reason why it's not working is because Vue Drag Select only looks one level deep for children. Since the drag-select-container
is defined as a parent of svg
, the only child it can find is svg
.
Therefore this is not a bug related to SVG, but rather to nested children.
A potential solution to this problem is to recursively look for children, though I'm not sure if that's a good idea.
Why you think it's a bad idea? In that case, performance is due to library user, not on a library itself. You requires CSS class name for child elements, and it's obvious must be equal to CSS selector query. I see it like drag-select-container .cls-1
, so if you mean drag-select-container > .cls-1
you must specify it in documentation.
I agree. Let's refactor the code to allow nested child elements.
Unfortunately no, nested child elements are currently not supported. Feel free to send a pull request, though!
I need to select rows in a table build with BootstrapVue's b-table.
I have a working solution in my fork. I added a function property that returns the items to work on. It works for me, but I'm not sure it's generic for all use cases. I also added a select
event triggered only on onMouseUp.
Is this approach worthy a PR? If yes, what is missing (apart from documentation)?
<drag-select selectorClass="selectable" :selectorFunction="selectableItems">
<template slot-scope="{ selectedItems }">
<b-table :items="items" tbody-tr-class="selectable">
</b-table>
</template>
</drag-select>
[…]
methods: {
selectableItems() {
return this.$el.getElementsByTagName('tr')
}
}
Hi Jochen, thanks for showing interest in this project!
Having a more composable way of defining the selectable items is definitely a better solution. Doing it this way, we should be able to get rid of the whole selectorClass
property and make vue-drag-select
smarter when it looks for elements that are 'selected'.
In my opinion, a more intuitive approach to this would be to define a property selectableItems
that's simply an array of DOM elements. We can then simply check if the selected elements are in this array, or if they are a child of one of the elements in the array.
If we can get that to work properly, I'm definitely open to pull requests!
Ok, good to know you are open to greater changes.
I removed selectorClass
.
Passing the items as array does not work in my case, because the <b-table>
is a child node of <drag-select>
, so I also support a function returning the array of items. I kept the usage of the child nodes as default if no items are passed explicitly. This fallback still uses Vue components if available instead of DOM nodes as I'm not sure of that feature's use cases.
Still missing documentation.
Does this meet your idea of more composable? Should I open a PR?
Hi, I would really appreciate this functionality. @stephan281094 Are you planning accept this pull request and release new version?
@JochenLutz I am also looking to use this with BootstrapVue's b-table
and took a look at your fork and I'm interested in using the changes you made, but having a little trouble wrapping my brain around how you get b-table
to recognize what was selected. Could you post a codepen of how you got that part to work?
I tried to select
<g>
inside SVG inside my Vue app, but when I tried toconsole.log(el)
inisItemSelected
method, I just see<svg>
element in colsole.