I'm trying to use Vue.js to hide/show an element of my page based on a checkbox's value. Here's what I have so far:
<div id="myDiv" v-show="????">
<!-- stuff to be hidden -->
</div>
...
Vue.component('tab-gar-var-cb', {
props: ['cmp_name','cmp_checked_init', 'cmp_garantie_id'],
data: function(){
return {
'cmp_checked' : ''
};
},
template:`
<span>
<input :name="cmp_name" type="hidden" value="0">
<input :name="cmp_name" type="checkbox" value="1" v-model="cmp_checked">
</span>
`,
mounted: function(){
this.cmp_checked = (this.cmp_checked_init == '1');
}
});
new Vue({
el: "#vue-rptrenouedit-root"
});
Basically, what I'd like to do is bind the 'v-show' attribute to the 'cmp-checked' data of my tab-gar-var-cb component. However, I can't figure out how to do it. Anyone knows how to do it? Thanks in advance.
Related
I've been working on this problem and I searched about this for an hour, but none of the answers led me to the correct answer.
I have three items(sorry I hard coded) which every single item contains one input(checkbox), and what I want to achieve is when one of the checkboxes is clicked, make others disable to click in vue.js.
<template>
<input type="checkbox" #click="addContents(c)" :id="c.id" :disabled="selectedContent.length > 0">
<input type="checkbox" #click="addContents(c)" :id="c.id" :disabled="selectedContent.length > 0">
<input type="checkbox" #click="addContents(c)" :id="c.id" :disabled="selectedContent.length > 0">
</template>
<script>
export default {
data: function () {
selectedContent: [],
},
methods: {
addContent: function(data) {
if (this.selectedContent.length === 0){
this.selectedContent.push(data);
}
}
}
}
</script>
I read I need :disabled to make input disable, so I thought after I push one item to selectedContent, it'd disable my inputs, but it doesn't. I can still clickable other inputs even after I checked one of them. Can anyone point me out what I'm doing wrong?
you missed spelled #click="addContent(c)"
new Vue({
el: "#app",
data: {
selectedContent: [],
c: {
id: 1,
content: 'something'
}
},
methods: {
addContent: function(data) {
if (this.selectedContent.length === 0) {
this.selectedContent.push(data);
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"><template>
<input type="checkbox" #click="addContent(c)" :disabled="selectedContent.length > 0">
<input type="checkbox" #click="addContent(c)" :disabled="selectedContent.length > 0">
<input type="checkbox" #click="addContent(c)" :disabled="selectedContent.length > 0">
</template>
</div>
https://codepen.io/Maximusssssu/pen/KKzLzxg
<td><input class="input" v-model="user.name" /></td>
If you click the link above, is it possible to extract a specific text value (such as a,b,c) in the textbox using .getElementById or other method? This is a very weird input textbox.
You have access to the inputs value as the input and user.name have a two-way binding through v-model:
new Vue({
el: "#app",
data: {
user: {
name: ""
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input v-model="user.name" /> {{ user.name }}
</div>
After get API call with a string input attached, I get the result alright. The problem I have is incorporating it to my frontend. I have tried a lot of solutions that I found online but nothing working and cannot understand. So far I have done this:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type = text/javascript src = https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/vue.resource/1.0.3/vue-resource.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<form action="http://127.0.0.1:1880/" target="_self">
<label for="request"><strong>Please insert the input here:</strong></label><br>
<input type="text" id="request" name="input"><br>
<button v-on:click="getOverview($event)">Submit</button>
</form>
<h1 id="results" v-for="overview in overview">
{{overview}}
</h1>
<script type = text/javascript >
new Vue({
el: "#results",
data() {
return {
overview: []
}
},
methods: {
async getOverview(event) {
try {
const {data:{json:{sub_regions}}} = await axios.get('http://127.0.0.1:1880/');
console.log('results data', sub_regions);
this.overview = sub_regions;
}
catch (error) {
console.log(error);
return [];
}
}
},
created(){
this.getOverview()
}
})
</script>
</body>
</html>
I am a bit lost with javascript as I am new to it, all kinds of help are welcome,
Thank you in advance! :)
EDIT: the file I get from the API is JSON
Looks as though you are trying to call a method outsides of the vue app itself.
You have the el: "results" but you are trying to invoke a vue method within your button outside of its context.
Try something like this:
<div id="results">
<form action="http://127.0.0.1:1880/" target="_self">
<label for="request"><strong>Please insert the input here:</strong></label><br>
<input type="text" id="request" name="input"><br>
<button v-on:click="getOverview($event)">Submit</button>
</form>
<h1 v-for="overview in overview">
{{overview}}
</h1>
</div>
Some problems here...
You're including Vue twice (https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js and https://unpkg.com/vue/dist/vue.js). Don't do that
You cannot use a v-for directive on your root Vue element
Your form is outside your Vue root so you won't be able to use v-on
Your submit button will submit the form normally. There's nothing stopping that from happening
Your input value is never used. You should try binding it to a data property
Change your HTML to
<div id="results">
<form action="http://127.0.0.1:1880/" #submit.prevent="getOverview">
<label for="request">
<strong>Please insert the input here:</strong>
</label>
<br>
<input type="text" id="request" name="input" v-model="input">
<br>
<button type="submit">Submit</button>
</form>
<h1 v-for="item in overview">
{{ item }}
</h1>
</div>
and in your JS, replace data with
data: () => ({
overview: [],
input: ''
})
Then you can use this.input if you ever need to get the value the user types in.
Here's an example using a placeholder API
new Vue({
el: "#results",
data: () => ({
overview: [],
input: ''
}),
methods: {
async getOverview ($event) {
let url = 'https://jsonplaceholder.typicode.com/users'
if (this.input) {
url += `/${encodeURIComponent(this.input)}`
}
try {
const { data: sub_regions } = await axios.get(url)
console.log('results data', sub_regions);
this.overview = Array.isArray(sub_regions) ? sub_regions : [ sub_regions ]
} catch (error) {
console.log(error);
this.overview = []
}
}
},
created() {
this.getOverview()
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<div id="results">
<form action="http://127.0.0.1:1880/" #submit.prevent="getOverview">
<label for="request">
<strong>Please insert the user ID here:</strong>
</label>
<br>
<input type="number" id="request" name="input" v-model.number="input">
<br>
<button type="submit">Submit</button>
</form>
<h1 v-for="item in overview">
{{ item.name }}
</h1>
</div>
Other notes:
Avoid using the same variable name for your array and iterable.
Bad - v-for="overview in overview"
Good - v-for="thing in things"
VueResource is long dead. Avoid using it or at least update to the latest version (1.5.1)
In my code I create a lot of elements dynamicly on serverside, store the html of these elements in a javascript object,remove them and dynamicly/conditionally add them to different parts of the page.
For one particular element I want a data binding, such that I can refer to that binding in a v-if directive. However, if I add the v-bind on the server side, it gets lost after I copy the html.
Since I do only add the elements in my javascript code, I can not register the v-bind in my template. Neither can I provide the content in a component, since it is not static but relys on the input from the server.
How do I register the binding?
Sample Code:
Dynamicly generated form elements (server side):
<div id="archive" style="display: none;">
<div><input type="text" name="purpose" v-bind:value="purpose" id="id_purpose"></div> <!-- v-bind has no effect -->
<div><input type="text" name="purpose__iexact" id="id_purpose__iexact"></div>
<div><input type="text" name="purpose__contains" id="id_purpose__contains"></div>
<div><input type="text" name="purpose__icontains" id="id_purpose__icontains"></div>
<div><input type="text" name="purpose__in" id="id_purpose__in"></div>
...
</div>
Code to copy the html:
var input = {};
var archive = document.getElementById('archive');
for(var i = 0; i < archive.children.length; i++) {
var div = archive.children[i];
input[div.firstChild.name] = div.innerHTML
}
archive.parentNode.removeChild(archive);
Template code to display a certain input field dynamicly (client side):
<div class="inline" v-html="input[SOME CONDITIONAL COMPUTATIONS]"></div>
the correct way to rendering vue scene is:
<template>
<div>
<input type="button" value="Add new item" #click="addItem">
<hr>
<div v-for="(item,index) in data" :key="index">
<span v-html="item.html"></span>
<h3>Model data {{item.model}}</h3>
<input type="text" v-model="item.model">
<input type="button" value="Click me" #click="item.action(index)">
<input v-if="item.show" type="button" value="Remove me" #click="removeItem(index)">
</br>
</div>
</div>
</template>
<script>
export default {
data() {
return {
item: {
model: "",
show:true,
html: "<b>mydata html</b>",
action: function(index) {
console.log(`Clicked ${index} element.`);
}
},
data: [
{
model: "",
show:false,
html: "<b>mydata html</b>",
action: function(index) {
alert(`Clicked ${index} element.`);
console.log(`Clicked ${index} element.`);
}
},
{
model: "",
show:true,
html: "<b>mydata html</b>",
action: function(index) {
alert(`Clicked ${index} element.`);
console.log(`Clicked ${index} element.`);
}
}
]
};
},
methods: {
addItem() {
let item = Object.assign({}, this.item); // other way dublicating Observer
this.data.push(item);
},
removeItem(index){
this.data.splice(index,1)
}
}
};
</script>
You can add a show boolean prop to item object and v-if="" atribut to div to hide it.
I hope this example will help you.
I'm building a component in Vue.js. I have an input on the page where the user can request a certain credit amount. Currently, I'm trying to make a function that will log the input amount to the console, as I type it in. (Eventually, I'm going to show/hide the requested documents based on the user input. I don't want them to have to click a submit button.)
The code below logs it when I tab/click out of the input field. Here's my component.vue:
<template>
<div class="col s12 m4">
<div class="card large">
<div class="card-content">
<span class="card-title">Credit Limit Request</span>
<form action="">
<div class="input-field">
<input v-model="creditLimit" v-on:change="logCreditLimit" id="credit-limit-input" type="text">
<label for="credit-limit-input">Credit Limit Amount</label>
</div>
</form>
<p>1. If requesting $50,000 or more, please attach Current Balance Sheet (less than 1 yr old).</p>
<p>2. If requesting $250,000 or more, also attach Current Income Statement and Latest Income Tax Return.</p>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'licenserow',
data: () => ({
creditLimit: ""
}),
methods: {
logCreditLimit: function (){
console.log(this.creditLimit)
}
}
}
</script>
If I change methods to computed, it works - but I get an error saying Invalid handler for event: change every time it logs the value.
Use the input event.
<input v-model="creditLimit" v-on:input="logCreditLimit" id="credit-limit-input" type="text">
change only fires when the element loses focus for input elements. input fires each time the text changes.
Binding #input event alongside with v-model is unnecessary. Just bind v-model and thats all. Model is automatically updated on input event.
new Vue({
el: '#app',
data: {
message: ''
}
})
<script src="https://unpkg.com/vue#2.4.4/dist/vue.min.js"></script>
<div id="app">
<input type="text" v-model="message"><br>
Output: <span>{{ message }}</span>
</div>
And if you need log it on change to console, create particular watcher:
new Vue({
el: '#app',
data: {
message: ''
},
watch: {
message: function (value) {
console.log(value) // log it BEFORE model is changed
}
}
})
<script src="https://unpkg.com/vue#2.4.4/dist/vue.min.js"></script>
<div id="app">
<input type="text" v-model="message"><br>
Output: <span>{{ message }}</span>
</div>
<input v-model="yourVariableName" #input="yourFunctinNameToBeCall" id="test" type="text">
You can use #change to it trigger the function when is done
Ex- Select a value from drop down
But here you need to call the function when pressing keys (enter values). So use #click in such cases