Clusterize.js making element unclickable - javascript

I'm trying to use Clusterize.js component to display large amount of data in my vue app.
It's showing the dataset perfectly, however, while the clusterize element contains a button or something else which contains a click event, It's not working. I understand this component requires special click event fashion(described in docs FAQ), but can't find a way to use with dynamic data in vue app.
Here is the code sample
<div
id="scrollArea"
class="clusterize-scroll"
style="height: 300px; overflow: auto"
>
<div id="contentArea" class="clusterize-content">
<div v-for="item in dataSet" :key="item">
<button #click="onClick(item)" data-action="onClick">
button {{ item }}
</button>
</div>
</div>
</div>
<script>
mounted() {
new Clusterize({
scrollId: "scrollArea",
contentId: "contentArea",
});
},
</script>
Sandbox link: https://codesandbox.io/s/eloquent-tereshkova-wisf1?file=/src/App.vue

Related

Create my own component vuejs, with two diferents parts

I have a component with an input that when clicking opens a modal.
When I use this component, and insert it inside a div with relative position, the modal that opens, it does not display well. I would need the html of the modal to be outside the div position relative.
It is important that my component contains both the input and the modal, since this component itself will be used several times within another component.
<div class="position-relative">
<MyOwnComponet />
</div>
<div class="position-relative">
<MyOwnComponet />
</div>
My component would be something like this, more or less:
<template>
<input #click="showModal = true" />
<div class="modal" v-if="showModal">
...
</div>
</template>
I am not sure what's your point for this kind of requirement but anyway there is a workaround you can do with props.
You can have props in "MyOwnComponet" like this. And use that prop value to render accordingly.
Your main component
<div class="position-relative">
<MyOwnComponet :isInput="true" />
</div>
<div class="position-relative">
<MyOwnComponet :isInput="false" />
</div>
Your (MyOwnComponent)
<template>
<div v-if="isInput">div-1</div>
<div v-else>div-2</div>
</template>
<script>
export default {
props: {
isInput : Boolean,
},
data() {
}
};
</script>
You can replace div-1 with your input and div-2 with modal.

VueJS: Fixing component order in Bootstrap

I've been having some trouble recently with the order of Vue components in Bootstrap. I'm trying to generate some Bootstrap collapsible content in Vue here's the code so far:
HTML
<div class="col-sm main-content" id="main-content">
<p>
<main-section-button v-for="item in sections"
v-bind:section="item"
v-bind:data-target="'#section-' + item.text"
v-bind:aria-controls="'section-' + item.text">
</main-section-button>
</p>
<main-section v-for="item in sections"
v-bind:id="'section-' + item.text">
</main-section>
</div>
VueJS
Vue.component("main-section-button", {
props: ["section"],
template: String.raw`<button class="btn btn-block btn-dark" type="button" data-toggle="collapse" aria-expanded="false">{{ section.text }}</button>`
});
Vue.component("main-section", {
props: ["section"],
template: String.raw`<div class="collapse"><div class="card card-body"><p>Hello, World!</p></div></div></div>`
});
let app = new Vue({
el: '#main-content',
data: {
sections: [
{ id: 0, text: "example1"},
{ id: 0, text: "example2"}
]
}
});
I have tried to make just one component for main-section and main-section-button, but that did not work because of the requirement to pass an id to the card (collapsible content), and a data-target to the button that collapses and expands the content.
Current Result
Required Result
Is it possible to create a component so that the section content is always below the section button.
Thank you in advance.
I guess you have two options to achieve this:
Create a new component that takes the items and displays both components as you wish.
Do not iterate over the components, instead use a <div> around both components or a non-rendered <template> like this:
<div class="col-sm main-content" id="main-content">
<template v-for="item in sections">
<p>
<main-section-button
v-bind:section="item"
v-bind:data-target="'#section-' + item.text"
v-bind:aria-controls="'section-' + item.text">
</main-section-button>
</p>
<main-section
v-bind:id="'section-' + item.text">
</main-section>
</template>
</div>

In Vue&Vuex, how can I activate onclick method in child component?

I'm trying to edit JS library that already existed but it consisted of Vue. So I studied Vue a little.
The problem is that I made child component called 'Analysis' and want to anchor function. I made tag and bind 'moveAnchor' method to onclick, also declared 'moveAnchor' on methods part. but it didn't work. How can I fix? I'm sorry for being inexperienced.. :(
it is script.js of analysis.
import { mapActions, mapState } from 'vuex';
export default {
name: 'Analysis',
computed: {
checkName : function(){
var flag = this.$store.state.analysis.name;
if(flag.indexOf("/PCs/") != -1){
console.log(flag);
}
}
},
methods: {
moveAnchor: function (id){
var div = document.getElementById(id).scrollIntoView();
}
it is template.html of analysis.
<div :class="$style.scrollarea">
<div :class="$style.dropdown">
<button :class="$style.dropbtn">Analysess</button>
<div :class="$style.dropContent">
<a v-for="item in analyData" v-bind:key="item.id" #onclick="moveAnchor(item.id)">
{{ item.title }}
</a>
</div>
</div>
<span>
{{ checkName }}
</span>
<div v-for="item in analyData">
<h1 v-bind:id="item.id">{{ item.title }}</h1>
<img v-bind:src="item.src" style="width: 100%; height: auto">
</div>
Welcome to StackExchange!
The correct binding for Vue's click event is v-on:click, or #click for shorthand. So when you write #onclick, Vue will never call that.
Just change #onclick to #click and all should work fine.

Dynamic component insertion using VueJs, Cordava and Javascript

Using vuejs and Cordova, I could not dynamicaly insert/create a new v-select component.
My goal is to duplicate and insert a copy an existing v-select when my "Add" button gets clicked.
The code of my page is:
<v-select
:items="exerciceList"
v-model="selectedExercice"
label="pick an exercise"
v-validate="'required'"
data-vv-name="select"
required>
</v-select>
</div>
<div id="selectsContainer"></div>
<v-btn flat icon id="btn" v-on:click="newExercice()">
My (not working) click event listener:
methods: {
newExercice: function () {
var container = document.getElementById('selectsContainer');
var select = document.getElementById('exo');
// select.items = this.exerciceList;
select.removeAttribute('id');
select.style.display = 'block';
container.appendChild(select);
}
},
The item with the id expo's code:
<v-select
id="exo"
style="display: none;"
:items="exerciceList"
v-model="selectedExercice"
label="Choisissez un exercice"
v-validate="'required'"
data-vv-name="select"
required>
Thank you for helping me improve my implementation.
What Michael S has said is correct, you do not want to manipulate the DOM directly, causes many issues. Probably the best solution (quick and easy anyway) would be to import that additional v-select component and then add it dynamically with a simple list or in this case an integer increase.
If you're wanting to get a little more customized with it, you can create an object and add and remove styles, attr, etc. from it dynamically the same way this option would work but turning item into an array of objects. then proceed to add an object to it whenever the button is clicked.
<v-select
:items="exerciceList"
v-model="selectedExercice"
label="pick an exercise"
v-validate="'required'"
data-vv-name="select"
required>
</v-select>
</div>
<div id="selectsContainer"
v-for="(item, idx) in items">
<v-select
id="item.id" <!-- or use idx -->
style="item.style" <!-- or use any string statement -->
...etc
>
</div>
<v-btn flat icon id="btn" v-on:click="newExercice()">
...{
components: [componentName],
data: return {
items: 0,
...
}
methods: {
newExercice: ()=>{
this.items++
}
}
...}

in meteor how to stop functionalities to work at a time?

In meteor, I have created a cards dynamically after submitting the form. and the dynamic card contains the show and hide buttons. When I click on show option button the hidden part is showing for all the cards instead of that particular card. the problem is the card is creating dynamically so I thought that is problem .. how to make the functionality to work separately to the each card.
Here I am attaching the code:
<div id="newActionCard">
{{#each newaction}}
<div class="workflowcard">
<div class="module-card">
<div class="res-border"></div>
<div class="card-img"></div>
<div class="res-content">
<div class=" assigned-team">{{team}}</div>
<div class=" newaction-name">{{action_title}}</div><hr>
<div class="description">{{description}}</div>
<div class=" due-on">Due on:{{d_date}}</div><hr>
<div class="subcontent">
{{> actioncardsubcontent}}
</div>
<div class="reqext">
{{> requestextensioncard}}
</div>
</div>
<div class="due">
Due on:
<div>
<span class="day-stamp">THU</span><br>
<div class="date-stamp">26</div>
<div class="month-stamp">AUG
</div>
</div>
</div>
</div>
<div class="btn-box newaction">
<button type="button" class="cancelsub" >New Action</button>
<button type="submit" class="createbtnsub" >Show Options</button>
</div>
<div class="btn-box showoption">
<button type="button" class="hideoption" style="display:none">Hide Options</button>
</div>
{{/each}}
</div>
In JS I have written the hide and show functionalities in the events..now how to stop functionality to all cards at a time.
Here is my JS:
Template.workflow.events({
"click .createbtnsub" : function() {
$( ".subcontent" ).show();
$('.createbtnsub').hide();
$('.cancelsub').hide();
$('.hideoption').show();
$('.requestextension').show();
},
"click .hideoption": function(){
$('.subcontent').hide();
},
"click .hideoption": function(){
$(".subcontent").hide();
$('.cancelsub').show();
$('.createbtnsub').show();
$('.requestextension').hide();
$('.hideoption').hide();
$('.reqext').hide();
},
"click #createActionBtn": function(){
$('#createAction').hide();
$('.editw').show();
$('.hidew').show();
},
});
Template.actioncardsubcontent.rendered = function(){
this.$(".subcontent").hide();
};
Template.requestextensioncard.rendered = function(){
this.$(".reqext").hide();
};
Template.workflow.helpers({
getWorkflow: function(){
return Workflow.find();
},
user: function(){
return Meteor.users.find({});
},
getNewaction: function(){
return Newaction.find();
},
});
Please see the following and adjust the selectors as needed:
"click .showoption": function(event){
$(event.currentTarget).next('button').show();
}
This will work for selecting sibling elements, however as a tip I would recommend rewriting your template.helper that returns the cards data from the database into something more specific.
Something like dynamic classes based on index or id so your class/id names would return as follows .showoption-12kjddfse4 . Then you can just get the attribute of the current target and apply it to your js selector.
Also as kind of an explination to why all buttons were showing, is you were using the class selector, which is meant for grabbing groups of elements/nodes. This is also another reason to created more specific classnames/ids to your use case.
So in your class name you could do something like
<button class="showoption" id="{{_id}}">button</button>
<button id="hiddenoption-{{_id}}" class="hiddenoption">button</button>
Then selecting your elements would be easier as follows:
'click .showoption'(event) => {
let id = event.currentTarget.getAttribute(id);
document.getElementById('hiddenoption-'+id).style.display = 'block';
}

Categories

Resources