It works, but I need to click the button twice before the function triggers.
How can I make it when I click once it triggers the function?
export default {
methods: {
remove(){
$('.remove-me button').click( function() {
removeItem(this);
});
function removeItem(removeButton) {
var productRow = $(removeButton).parent().parent();
productRow.slideUp(fadeTime, function() {
productRow.remove();
recalculateCart();
});
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template>
<div class="remove-me">
<button type="button" #click="remove">Remove</button>
</div>
</template>
You dont need jquery in there, the remove function is triggered without it by adding the #click to the button.
More Info: https://v2.vuejs.org/v2/guide/events.html
There is already a good sample for deletion item in https://v2.vuejs.org/v2/guide/list.html#Caveats
You don't need jquery for this. This code was simplified version from the link above
In HTML:
<ul>
<li v-for="(todo, index) in todos" :key="index" >
<button #click="todos.splice(index, 1)">Remove {{ todo }}</button>
</li>
</ul>
Add some todo in data inside <script> :
data: {
todos: ["one", "two", "three"]
}
You write jquery to manipulate DOM. In Vue data will render the DOM for you.
Sample : https://codesandbox.io/s/twilight-darkness-jpbd8
Related
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.
So I'm creating a simple To-Do List app using VueJS:
<template>
<div>
<br/>
<div id="centre">
<div id="myDIV" class="header">
<h2 style="margin:5px">My To Do List</h2>
<input type="text" id="myInput" v-model="text" v-on:keyup.enter="AddNote()" placeholder="Title...">
<span v-on:click="AddNote()" class="addBtn">Add</span>
</div>
<ul id="myUL">
<li v-on:click="ToggleClass(index)" v-for="(item, index) in array" v-bind:class="{ checked: isChecked[index] }">
{{item}}
<span class="close">×</span>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: "Notepad",
data() {
return {
array: [],
text: "",
isChecked: []
}
},
methods: {
AddNote: function() {
if(this.text!=="") {
this.array.push(this.text);
this.isChecked.push(false);
this.text = "";
}
},
ToggleClass(index) {
console.log(index);
this.isChecked[index]=!this.isChecked[index];
console.log(this.isChecked);
}
}
}
</script>
However when I click on an item the v-bind attribute doesn't bind the class when I click on it. Instead it binds it when I type something in the text field above.
Can anyone please help?
The isChecked array is not reactive and vue cannot detect changes.
You have to trigger it, for example via $set or splice.
Read more about it here: https://v2.vuejs.org/v2/guide/list.html#Caveats
You can change your code like this:
ToggleClass(index) {
console.log(index);
this.isChecked.splice(index, 1, !this.isChecked[index])
// or this.$set(this.isChecked, index, !this.isChecked[index])
console.log(this.isChecked);
}
What is the Vue.js equivalent of the following jQuery?
$('.btn').click(function(){ $('.hideMe').hide() });
jQuery works out of the box, Vue.js does not. To initialize Vue.js component or App you must bind that component with its data to one specific HTML tag inside your template.
In this example the specified element is <div id="app"></div> and is targeted through el: #app. This you will know from jQuery.
After you declare some variable that holds the toggle state, in this case been isHidden, the initial state is false and has to be declared inside the data object.
The rest is Vue-specific code like v-on:click="" and v-if="". For better understand please read the documentation of Vue.js:
The Vue Instance
Template Syntax
Event Handling
Conditionals
Note: consider reading the whole or at least longer parts of the documentation for better understanding.
var app = new Vue({
el: '#app',
data: {
isHidden: false
}
})
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.13/dist/vue.js"></script>
<div id="app">
<button v-on:click="isHidden = true">Hide the text below</button>
<button v-on:click="isHidden = !isHidden">Toggle hide and show</button>
<h1 v-if="!isHidden">Hide me on click event!</h1>
</div>
This is a very basic Vue question. I suggest your read the guide, even the first page will answer your question.
However, if you still need the answer this is how you hide/show elements in Vue.
new Vue({
el: '#app',
data () {
return {
toggle: true
}
},
})
<script src="https://unpkg.com/vue#2.5.3/dist/vue.js"></script>
<div id="app">
<button #click='toggle = !toggle'> click here </button>
<div v-show='toggle'>showing</div>
</div>
<div>
<div>
<button v-on:click="isHidden = !isHidden">Toggle hide and show</button>
<h1 v-if="!isHidden">Hide me on click event!</h1>
</div>
</div>
name: "Modal",
data () {
return {
isHidden: false
}
}
The up-voted answer is definitely a way to do it, but when I was trying to do this it was with a dynamic array instead of a single Div, so a single static Vue variable wouldn't quite cut it.
As #samayo mentions, there isn't a difference between the hide action from jQuery vs Vue, so another way to do this is to trigger the jQuery through the #click function.
The Vue Dev kit will tell you not to mix JS inline with #click events and I had the same problem as #user9046370 trying to put the jQuery command inline with #click, so anyway,
Here's another way to do this:
<tr v-for="Obj1,index in Array1">
<td >{{index}}</td>
<td >
<a #click="ToggleDiv('THEDiv-'+index)">Show/Hide List</a><BR>
<div style='display:none;' :id="'THEDiv-'+index" >
<ul><li v-for="Obj2 in Array2">{{Obj2}}</li></ul>
</div>
</td>
</tr>
Method:
ToggleDiv: function(txtDivID)
{
$("#"+txtDivID).toggle(400);
},
The other perk of this is that if you want to use fancy jQuery transitions you can with this method.
<template>
<button class="btn btn-outline-secondary" type="button"><i class="fas fa-filter" #click="showFilter = !showFilter"></i></button>
</template>
<script>
export default {
methods:{
showFilter() {
eventHub.$emit('show-guest-advanced-filter');
}
}
}
</script>
But it's not worked this method.
<template>
<button class="btn btn-outline-secondary" type="button"><i class="fas fa-filter" #click="filtersMethod"></i></button>
</template>
<script>
export default {
data: () => ({
filter: true,
}),
methods: {
showFilter() {
eventHub.$emit('show-guest-advanced-filter');
this.filter = false;
},
hideFilter() {
eventHub.$emit('hide-guest-advanced-filter');
this.filter = true;
},
filtersMethod() {
return this.filter ? this.showFilter() : this.hideFilter();
}
}
}
</script>
This is worked.
I am developing an application and I am using Vue 2 as my javascript framework, I tried to declare some components and use them in my html pages
this is my html:
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.3.1/css/bulma.css" />
</head>
<body>
<div id="modal_element" >
<modal v-if="showModal" ></modal>
<button #click="showModal = true" >Show Modal</button>
</div>
<div id="root">
<ul>
<li v-for="task in incompeletedTasks" >
{{ task.description }}
</li>
</ul>
</div>
</body>
<script src="https://unpkg.com/vue#2.1.10/dist/vue.js" ></script>
<script src="main.js"></script>
<script src="modal.js" ></script>
<script>
let main_data = {
tasks : [
{ description : "Go to the store ", completed : true },
{ description : "Leave the store" , completed : false }
]
}
new Vue({
el : "#root",
data : main_data,
computed : {
incompeletedTasks() {
return this.tasks.filter(task => !task.completed);
}
}
});
and this the modal.js file:
Vue.component('modal',{
template : '<div id="modal_element">
<div class="modal is-active">
<div class="modal-background"></div>
<div class="modal-content box">
<p>
Some Modal Text here ...
</p>
</div>
<button class="modal-close" #click="showModal = false" >
</button>
</div>',
data : function(){
return {
showModal : false
};
}
});
new Vue({
el : '#modal_element',
});
but the modal is not displayed, and I am getting the following error in the chrome console
[Vue warn]: Property or method "showModal" is not defined on the instance
but referenced during render. Make sure to declare reactive data
properties in the data option.
Question:
what modification do I have to make to get the code working? and html page successfully displays modal?
I think there are a couple of things.
You are creating 2 vue instances in this example (#root and #modal-element), so the data will not be able to be shared unless you have some store. Much better to have just a single instance and put components in that.
You will need to pass the component into the vue instance in order for it to be aware of the component.
Here is an example with alot of the stuff trimmed out.
https://jsfiddle.net/Austio/vhgztp59/2/
The gist of it is
var component = ...createComponentStuff
new Vue({
...otherVueStuff,
components: [component]
})
I just worked through the Google Polymer tutorial and I am building my first own element. And I am missing some DOM-Scripting Functions I know from Prototype and jQuery that made my life very easy. But maybe my methods are just not right. This is what I have done so far:
<polymer-element name="search-field">
<template>
<div id="searchField">
<ul id="searchCategories">
<li><a id="search-categories-text" data-target="text" on-click="{{categoryClick}}">Text</a></li>
<li><a id="search-categories-videos" data-target="videos" on-click="{{categoryClick}}">Videos</a></li>
<li><a id="search-categories-audio" data-target="audio" on-click="{{categoryClick}}">Audio</a></li>
</ul>
<div id="searchContainer">
<input id="searchText" type="text" />
<input id="searchVideos" type="text" />
<input id="searchAudio" type="text" />
</div>
</div>
</template>
<script>
Polymer({
ready: function() {
},
categoryClick: function(event, detail, sender) {
console.log(sender.dataset.target);
console.log(this.$.searchField.querySelector('#searchContainer input'));
this.this.$.searchField.querySelector('#searchContainer input');
}
});
</script>
</polymer-element>
What I want to do is to set an active class to the bottom input-fields when one of the above links are clicked. On jQuery I would just observe a link and deactivate all input fields and activate the one input field I want to have. But I am not sure how to do it without jQuery. I could just use all the native javascript functions with loops etc but is there anything polymer can offer to make things easier?
Does this example do what you want?
<script src="//cdnjs.cloudflare.com/ajax/libs/polymer/0.3.3/platform.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/polymer/0.3.3/polymer.js"></script>
<polymer-element name="search-field">
<template>
<style>
.hideMe {
display: none;
}
</style>
<div id="searchField">
<ul id="searchCategories">
<template repeat="{{category in searchCatergories}}">
<li><a on-click="{{categoryClick}}">{{category}}</a></li>
</template>
</ul>
<div id="searchContainer">
<template repeat="{{category in searchCatergories}}">
<div class="{{ { hideMe: category !== selectedCategory} | tokenList }}">
<label>Search for {{category}}</label>
<input id="search{{category}}" type="text">
</div>
</template>
</div>
</div>
</template>
<script>
Polymer({
searchCatergories: [
"Text",
"Video",
"Audio"
],
selectedCategory: 'Text',
categoryClick: function(event, detail, sender) {
// grab the "category" item from scope's model
var category = sender.templateInstance.model.category;
// update the selected category
this.selectedCategory = category;
// category
console.log("category", category);
// you can also access the list of registered element id's via this.$
// try Object.keys(this.$) to see registered element id's
// this will get the currently showing input ctrl
selectedInputCtrl = this.$["search" + category];
}
});
</script>
</polymer-element>
<search-field></search-field>
I've created an array for the categories and added two repeat templates.
I've setup a .hideMe class which is set on all input elements that aren't the currently selected category.
Info on dynamic classes - https://www.polymer-project.org/docs/polymer/expressions.html#tokenlist
Info on repeat - https://www.polymer-project.org/docs/polymer/binding-types.html#iterative-templates
Hope that helps