How to select a single line from a leafletjs polyline when clicked? - vue.js

I have a leaflet map (using Vue and vue2-leaflet) with many predefined nodes and connections between them (stored in a neo4j database). When the user clicks on a node (#mouseup, actually), all its connections are shown as a polyline. I want to be able to click on any of these connections on the map (the lines) and do stuff with it, like delete for example (there would be a popup or something with actions, but that's not important here).
The problem I'm having is that the click event doesn't record the connection ID (or anything that would identify which connection was in fact clicked). I could of course create one polyline for each connection, but I suspect the problem would persist, and it's not a really solution in my case, as I don't know how many connections each node has, and v-for doesn't seem to work with polylines (at least I wasn't able to make it work).
This is the nodes markers code:
<l-marker v-for="mapNode in MapStore.mapNodes"
#mouseup="nodeClick($event, mapNode.index)"
:lat-lng="[mapNode.latLng.lat, mapNode.latLng.lng]"
:key="mapNode.index"
</l-marker>
... and this is the polyline code:
<l-polyline
#mouseup="connectionClick($event)"
:lat-lngs="MapStore.selectedConnections.latlngs"
/>
The nodeClick function populates the MapStore.selectedConnections correctly as the polylines are shown as expected.
The problem is that I don't see anything being passed to the connectionClick function that would identify which connection was clicked, so that I could work with it.
Is that even possible?

Ok, so it turns out I was wrong and v-for works (there was something wrong with my code, I think, but I'm not sure what).
My solution is:
<l-polyline v-for="connection in MapStore.selectedConnections.latlngs"
#mouseup="connectionClick($event, connection)"
:lat-lngs="connection" />
This way it iterates through the connections, generates a separate polyline for each and passes to the connectionClick function the latlngs of the clicked connection.

Related

Show SnackBars stacked instead of overlapping?

In my app there's a page where I am showing several snackbars depending on results from server.
There can be several triggered by the server's result. They are also triggered from different components, so I don't have a single controller that could render them where I want.
So, they all display at once and overlap each other. I linked the official Vuetify docs page because the problem is clearly visible there. Just click on two of the buttons in short enough succession.
Is there any way I could render them such that they would stack one above the other instead of all bottom-centering over each other?
I was thinking I'd need a way to tell them the component that would be their rendering parent. But I can't seem to find a way to do this. Slots don't seem to be much help with this either since I can't declare global ones.
Is there any way I can do this?

Vue components hierarchy and passing data

I'm writing an app in Vue and I have a really hard time understanding the component hierarchy, namely the parent-child relationships and how to pass data around.
I have a view that contains a map which in turn has some navigation controls and options that are overlayed on top of the map. Now, I want these controls to manipulate the map WITHOUT having to nest the buttons inside the actual maps as it will cause severe display issues (for example, clicking on a zoom button falls through the button and also clicks the next element under it).
My app looks like this:
Mapview
Map
Controls
Options
Optionpanel1
Optionpanel2
...
Now, a HTML input element in Optionpanel1 needs to control something in the Map, which is not actually it's parent component. Also, some data from Map needs to be passed down to Optionpanel1 so it would know what to control. To make matters worse, something in Options also needs to pass something down to Optionpanel1, so, even though event bus would allow communication upwards, it would not solve that I need to pass data from parents to indirect children and also components that are not it's children.
I can actually pass the required property down the line if I nest the Options inside Map and pass it down with :myProp="prop" and then in Options, declare it in props and bind to Optionpanel1, where it is again declared as a prop. But as I mentioned earlier, nesting elements that I do not want to be nested in a visual sense causes massive issues like mouse click falling through. Do elements even need to be nested inside eachother in order to define parent-child relationship?
I would want components to exchange read-only data without Y being a child of X in the DOM. Also, even if nesting components like this would not cause visual issues, does it not seem very annoying to have to register and bind it in every component along the way?
I don't understand why is it so difficult to simply read something from another component. It's starting to seem that Vue is causing a problem that it's supposed to solve? Am I missing something here or am I looking at this in a completely wrong way?
Thanks in advance.
Basically you have 2 options to control complex components:
Handle the actions in your so-called "smart component" (in terms of React), which is the common ancestor for the controlling and controlled components. It's a pretty good solution for small components, but that's not the case.
To separate common logic and data in a Vuex store. I'd recommend you doing this.

How to simplify custom multi checkbox component

I have strange (at least to me) problem with multiple checkboxes with v-model. When using multiple checkboxes that are v-model'ed to one property then normal array is produced which is done with code below:
.form-check
input.form-check-input(type=“checkbox” name=“checkbox” v-model=“methodology” value=“issue tracking tool”)
label.form-check-label issue tracking tool
However, when I try to move it to Single File Component I had to copy some magical tricks from Vue.js forum to make it work. I still suspect that there must be easier way to achieve it. I can’t imagine that it wasn’t solved with simple solutions since it’s quite a common pattern (checkbox in a component - nothing exotic, right?). Any help appreciated!
Here is the working jsfiddle - please have in mind that there is no errors. I just want to know if that really has to be that complicated.
The answer is, no. You may be able to do this magic differently, but it needs to be done.
Vue has to do magic behind the scenes for checkbox because unlike all the other inputs, which have a single item that gets updated, the checkbox has to manage whether the a value is in an array. This means that the listeners and values have to be patched between the wrapper and input.

vuestrap spinner unable to listen to shown event

https://github.com/yuche/vue-strap/blob/master/src/Spinner.vue
https://github.com/yuche/vue-strap/blob/master/docs/example/spinnerDocs.vue
Looking at the reference implementation, I've tried to do the same here: https://jsfiddle.net/gw3br69r/2/
I've tried listening to different events like show, show:spinner, spinner, spinner:shown, etc, and have also tried to listen to the event via $on detailed here: https://vuejs.org/api/#vm-on and https://vuejs.org/guide/components.html#Parent-Child-Communication but I'm unable to listen to that event. I have also tried the non minified debug build of vue.js, but I do not know of a way to track down all the events to see if shown:spinner is even getting called.
Your code would work if the Spinner component used $dispatch() to "propagate upward along the parent chain".
But looking at the source code, we see that $broadcast() is used, to "propagate downward to all descendants".
I don't know why they are broadcasting instead of dispatching, and I don't understand how their documentation example works. It seems impossible. Something must have been tweaked or changed.
Anyway, an event broadcasted by a "child" can be listened by its "parent" by using v-on. It goes like this:
<spinner v-on:shown::spinner="doSomething"></spinner>
See the working fiddle: https://jsfiddle.net/x80ph0mk/1/

Skrollr: Multiple instances

I have two columns that I would like to animate separately with a trigger. As I understand it: Skrollr only allows one instantiation on a page. Does anyone know if it's possible to have multiple instances that can be turned off and on?
I've started a working example here:
The grey column will activate the Skrollr instance when clicking on its "Activate!" button. (The "Destroy!" button will remove its instance.)
I would like to isolate the Skrollr animation to just the grey column, but as you can see in this example, the yellow/orange column is also being activated.
Three ways
Remove/add the data attributes between the destroy/init calls and only add them to the elements you want
Use two constants, defined as a function and toggle them between 0 and 1e6 (or something really large). Now the elements with the large one will effectively not be rendered (given you're using edgeStrategy reset)
Monkey patch the refresh method (without touching the skrollr code itself). Skrollr uses it internally when using init. Now you can patch it to use leftColumn.getElementsByTagName('*') or all elements in the right column when no parameter is passed. This way initializing will only affect elements inside one of the columns.