Is possible create event on click in object - Vue JS - javascript

new Vue({
el: "#app",
data: {
checking: [
{ text: "Event 1 <a :click='test()' class='click'>click here</a>" },
{ text: "Event 2" },
{ text: "Event 3" },
{ text: "Event 4" }
]
},
methods: {
test() {
console.log("clicked")
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.2/vue.js"></script>
<div id="app">
<ul>
<li v-for="(check, i) in checking" :key="i" v-html="check.test"></li>
</ul>
</div>
Is it possible to create an event click in an object? I tried but always failed, maybe something's wrong in my code. Thank you.
here is my full code fiddle

you can try like below, hope resolve your problem, fiddle
template:
<div id="app">
<ul>
<li v-for="(check, i) in checking" :key="i">
{{check.text}} <a #click='test' class='click'>click here</a>
</li>
</ul>
</div>
Vue instance:
new Vue({
el: "#app",
data: {
checking: [
{ text: "Event 1" },
{ text: "Event 2" },
{ text: "Event 3" },
{ text: "Event 4" }
]
},
methods: {
test() {
console.log("clicked")
}
}
})
Screen will look like this:

You can't do it. According to Vue API's documentation:
Note that the contents are inserted as plain HTML - they will not be compiled as Vue templates. If you find yourself trying to compose templates using v-html, try to rethink the solution by using components instead.
It's even discouraged:
Dynamically rendering arbitrary HTML on your website can be very dangerous because it can easily lead to XSS attacks. Only use v-html on trusted content and never on user-provided content.

You can add click events with the v-on:click property:
new Vue({
el: "#app",
data: {
checking: [
{ text: "Event 1" },
{ text: "Event 2" },
{ text: "Event 3" },
{ text: "Event 4" }
]
},
methods: {
test(input) {
console.log("Element " + (input + 1 ) +" clicked")
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.2/vue.js"></script>
<div id="app">
<ul>
<li v-for="(check, i) in checking" :key="i" >{{ check.text }} <a v-on:click="test(i)">click here</a></li>
</ul>
</div>

Related

How to use the WIZARD component in vue3 correctly

I am using the wizard component, which is a step by step, I am placing a select in each tab, but I have the problem that only the select of the first tab is shown, how could I solve this problem?
component:https://bahadirsofuoglu.github.io/form-wizard-vue3/guide/installation.html
I attach my code:
<template>
<div id="app">
<div>
<h1>Customize with Props</h1>
<Wizard
squared-tabs
card-background
navigable-tabs
scrollable-tabs
:nextButton="{
text: 'test',
icon: 'check',
hideIcon: true, // default false but selected for sample
hideText: false, // default false but selected for sample
}"
:custom-tabs="[
{
title: 'Step 1',
},
{
title: 'Step 2',
},
]"
:beforeChange="onTabBeforeChange"
#change="onChangeCurrentTab"
#complete:wizard="wizardCompleted"
>
<template v-if="currentTabIndex === 0">
<h5>Tab 0</h5>
<v-select
:items="options"
label="Select an option"
v-model="selectedOption"
></v-select>
</template>
<template v-if="currentTabIndex === 1">
<h5>Tab 1</h5>
<v-select
:items="options"
label="Select an option"
v-model="selectedOption"
></v-select>
</template>
</Wizard>
</div>
</div>
</template>
<script>
import "form-wizard-vue3/dist/form-wizard-vue3.css";
import Wizard from "form-wizard-vue3";
export default {
name: "App",
components: {
Wizard,
},
data() {
return {
currentTabIndex: 0,
options: ["Option 1", "Option 2", "Option 3"],
selectedOption: "",
};
},
methods: {
onChangeCurrentTab(index, oldIndex) {
console.log(index, oldIndex);
this.currentTabIndex = index;
},
onTabBeforeChange() {
if (this.currentTabIndex === 0) {
console.log("First Tab");
}
console.log("All Tabs");
},
wizardCompleted() {
console.log("Wizard Completed");
},
},
};
</script>
attached image:
tab 1:
tab2:
From quick look at the documentation it seems that you need all of the steps content to be wrapped with <template #activeStep>. And then inside your v-if logic probably.

Controlling the style of a label in a v-treeview in VuetifyJS

I have the following HTML
<div id="app">
<v-app id="inspire">
<v-treeview :items="items"></v-treeview>
</v-app>
</div>
and the following Javascript:
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
items: [
{
id: 1,
name: 'Applications :',
children: [
{ id: 2, name: 'Calendar : app' },
],
},
{
id: 15,
name: 'Downloads :',
children: [
{ id: 16, name: 'October : pdf' },
],
}
],
}),
})
Let's say that I want to make the font-size of the Downloads label bigger or make it bold.
Is this possible with Vuetify and it's v-treeview? If so, how? There does not appear to be a way to control the styling of the labels.
Everything can be controlled in Vuetify. It's easier with some things and harder with others:
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
items: [{
id: 1,
name: 'Applications :',
children: [{
id: 2,
name: 'Calendar : app'
}, ],
},
{
id: 15,
name: 'Downloads :',
children: [{
id: 16,
name: 'October : pdf'
}, ],
}
],
}),
})
.large {
font-size: 20px;
font-weight: 700;
}
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#5.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<div id="app">
<v-app id="inspire">
<v-treeview :items="items">
<template v-slot:label="{ item }">
<span
:class="{ large: !!(item.id === 15) }"
>
{{ item.name }}
</span>
</template>
</v-treeview>
</v-app>
</div>
Look at the API description on Vuetify's component pages, and look for slots - if a component has the slot you look for, then you can work with it quite easily. If not, then you may have to tweak classes or even the components.
v-treeview's documentation: https://vuetifyjs.com/en/components/treeview/
VTreeview has a slot called label. You can "invoke" that slot by:
<v-treeview :items="items">
<template v-slot:label="{ item, leaf, selected, indeterminate, active, open }">
<!-- your code comes here --->
</template>
</v-treeview>
You can pass in item, leaf, selected, indetermintae, active or open props, that you can use in the scope of the <template></template>. In my snippet, we only needed the item, that's why I only passed that down.
My snippet only works, if you have an item with id: 15 - but you can put any logic there: calling methods, computed properties, etc.
For more information you can look in Vue scoped slots and destructuring slot props.
You must to use the slot label. Try something like this:
<v-treeview :items="items">
<template v-slot:label="{ item }">
<span style="font-weight: bold">{{ item.name }}</span>
</template>
</v-treeview>

Vuejs add and remove classes with v-for

i'm making a list of items with vuejs v-for loop. I have some API data from server.
items: [
{
foo: 'something',
number: 60
},
{
foo: 'anything',
number: 15
},
{
foo: 'text',
number: 20,
}
]
Template
<div v-for="(item,index) in items" :key="index">
<div :class="{ active: ????}" #click="toggleActive">
{{ item.foo }}
{{ item.number }}
</div>
</div>
JS
methods: {
toggleActive() {
//
}
}
I need following: When i'm clicking on div add class active, if i have already active class - remove active class.( toggle ). Also i can select multiple items.
How can i do this? I don't have boolean variable in items array, and i shouldn't move item in a separate component
Here you go.
new Vue({
el: "#app",
data: {
items: [{
foo: 'something',
number: 60
},
{
foo: 'anything',
number: 15
},
{
foo: 'text',
number: 20,
}
]
},
methods: {
toggleActive(index) {
let item = this.items[index];
item.active = !item.active;
this.$set(this.items, index, item);
}
}
})
.active {
color: red;
}
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.17/dist/vue.js"></script>
<div id="app">
<div v-for="(item,index) in items" :key="index">
<div :class="{ active: item.active}" #click="toggleActive(index)">
{{ item.foo }} {{ item.number }}
</div>
</div>
</div>
Here's a JS Fiddle:
https://jsfiddle.net/eywraw8t/250008/
App.vue
<template>
<div>
<div
v-for="(item, i ) in items"
:key="i"
:class="{ active: i === activeItem}"
>
// some looped items from data here
// button for active toggle
<button #click="selectItem(i)"> make item active </button>
</div>
</div>
</template>
Data and Methods
<script>
export default {
data() {
return {
activeItem: null,
};
},
methods: {
selectItem(i) {
this.activeItem = i;
},
},
};
</script>

Vue.js survey using browser back/forward buttons

I'm using Vue.js to create a survey with multiple pages. Everything works, except I need to make browser back/forward buttons to do the same as Previous/Next buttons on the page.
I have googled multiple times, but I couldn't come up with any solution for the moment...
I know that I could use vue-router, but I don't know how to adapt it.
How can I achieve this?
HTML
<!DOCTYPE html>
***head***
<body>
<div id="app">
<h1>{{ survey.title }}</h1>
<div id="survey" v-for="(question, index) in survey.questions">
<div v-show="index === questionIndex">
<h3>{{ question.text }}</h3>
<div v-if="questionIndex === 2">
<input type="text" v-model="userResponses[2]" placeholder="Please enter your location:">
</div>
<div v-else-if="questionIndex === 4">
<select v-model="question4" multiple>
<option v-for="response in question.responses"> {{ response.text }} </option></select>
</div>
<div v-else-if="questionIndex === 5">
<select v-model="question5" multiple>
<option v-for="response in question.responses"> {{ response.text }} </option></select>
</div>
<div v-else>
<ol>
<li v-for="response in question.responses">
<label>
<input type="radio" v-bind:value="response"
v-bind:name="index"
v-model="userResponses[index]"> {{ response.text }}
</label>
</li>
</ol>
</div>
<div id="container">
<button id="left" v-if="questionIndex > 0" v-on:click="prev">Previous</button>
<button id="right" v-on:click="next">Next</button>
</div>
</div>
</div>
<div v-show="questionIndex === survey.questions.length">
<h2>Thank you for taking our survey!</h2>
<p>{{ userResponses }}</p>
<p>{{ question4 }}</p>
<p>{{ question5 }}</p>
</div>
</div>
<footer>© 2018 George Salukvadze for ***</footer>
</body>
</html>
Vue.js
window.onload = survey;
function survey(){
var survey = {
title: 'Welcome to online survey for Liquid!',
questions: [
{
text: "What is your age group?",
responses: [
{text: '15-24'},
{text: '25-34'},
{text: '35-44'},
]
}, {
text: "What is your gender?",
responses: [
{text: 'Male'},
{text: 'Female'},
{text: 'Do not identify'},
]
}, {
text: "Where do you live?",
responses: [
{text: 'Please enter your location'},
]
}, {
text: "Do you like to shop?",
responses: [
{text: 'Yes'},
{text: 'No'},
]
}, {
text: "Select your favorite things to buy:",
responses: [
{text: 'Clothing'},
{text: 'Lingerie'},
{text: 'Shoes'},
{text: 'Devices'},
{text: 'Cars'},
]
}, {
text: "Please select your favorite brands:",
responses: [
{text: 'Sandro'},
{text: 'Maje'},
{text: 'Sony'},
{text: 'Ferrari'},
{text: 'BMW'},
{text: 'Asus'},
]
}
]
};
new Vue({
el: '#app',
data: {
survey: survey,
questionIndex: 0,
userResponses: Array(survey.questions.length),
question4: Array(5),
question5: Array(9),
},
methods: {
next: function() {
this.questionIndex++;
},
prev: function() {
this.questionIndex--;
}
}
});
}
You could use the vue-router as you implied. The simplest solution for your example, though, is to just use the browser's history API. Steps:
When moving to previous/next questions, use history.pushState to add a state to the browser's history:
methods: {
next: function() {
this.questionIndex++;
this.updateHistory(); // added this line
},
prev: function() {
this.questionIndex--;
this.updateHistory(); // added this line
},
updateHistory: function() { // added this method
history.pushState({questionIndex: this.questionIndex}, "Question " + this.questionIndex);
}
}
And now all you have to do is listen to those history state changes. A good spot to hook a listener to this event is the mounted:
mounted: function() {
var vm = this;
window.addEventListener('popstate', function(event) {
vm.questionIndex = (event.state || {questionIndex: 0}).questionIndex;
});
},
And that's it.
Click here for the a demo page at JSBin (check the history button).
You'll find the source for that demo here.

Identifying "Aria-Selected" State - Jquery

I'm using Kendo-UI's Drag and Drop Tree View for an application I'm working on.
I'm looking to append some text to the selected list-item.
I can not find anything in the documentation and am having a hard time selecting the appropriate item.
This is the Kendo-UI code:
<script>
$("#treeview-left").kendoTreeView({
dragAndDrop: true,
dataSource: [
{ text: "Furniture", expanded: true, items: [
{ text: "Tables & Chairs" },
{ text: "Sofas" },
{ text: "Occasional Furniture" }
] },
{ text: "Decor", items: [
{ text: "Bed Linen" },
{ text: "Curtains & Blinds" },
{ text: "Carpets" }
] }
]
});
$("#treeview-right").kendoTreeView({
dragAndDrop: true,
dataSource: [
{ text: "Storage", expanded: true, items: [
{ text: "Wall Shelving" },
{ text: "Floor Shelving" },
{ text: "Kids Storage" }
]
},
{ text: "Lights", items: [
{ text: "Ceiling" },
{ text: "Table" },
{ text: "Floor" }
]
}
]
});
</script>
This is a snippet of the generated code (notice the "aria-select='true'" , this is because I've selected the element, now I want to append text to this element):
<li role="treeitem" class="k-item" data-uid="82bceebe-f6a8-4d44-80ec-76f4b3db5041" aria-selected="true" id="treeview-left_tv_active">
<div class="k-top">
<span class="k-icon k-plus" role="presentation"></span>
<span class="k-in k-state-selected">Alberta</span>
</div>
<ul class="k-group" style="display:none" role="group">.....</ul>
</li>
This is my code at this point, I've tried a few other things, but have reverted back to this, which I know is incorrect:
<script>
$(function () {
$(".k-treeview li:first").click(function () {
$(this).append("test");
});
});
</script>
Any help is appreciated.
The aria attributes are for accessibility and not really meant to be used for other purposes.
You can use the select event and access the selected element in e.node:
$("#treeview").kendoTreeView({
dataSource: ds,
select: function(e) {
var model = this.dataItem(e.node);
model.set("text", model.get("text") + "test");
}
})
You can play with it here.
If you want to get the selected node at other times, use the select method.

Categories

Resources