I am using vuejs v.2, In my data structure I have products and keywords
they have many-to-many relationship. To attach keywords to product I have list of keyword's checkbox and when user submit only checked keyword should be attach to product
<div class="col-md-6" v-for="keyword in keywords">
<div class="checkbox">
<label>
<input type="checkbox" />
{{ keyword.name }}
</label>
</div>
</div>
Here I can not bind keyword.id as value (v-bind:value).
I just want to submit checked keyword ids to server
Please show me the correct way
I think the mistake you might be doing is not using v-model with an array data variable, following is working code:
vue component:
var demo = new Vue({
el: '#demo',
data: function(){
return {
keywords: [
{name: 'key1', id: 1 },
{name: 'key2', id: 2 },
{name: 'key3', id: 3 }
],
checked: []
};
}
})
and in HTML:
<div id="demo">
<div class="checkbox">
<label v-for="keyword in keywords">
<input type="checkbox" :id="keyword.name" v-bind:value="keyword.id" v-model="checked"/>
{{ keyword.name }}
<br>
</label>
<br>
checked value: {{checked}}
</div>
</div>
Working fiddle here
Related
I am new to vue, I found some examples but I could not reproduce in my situation.
I have some inputs user will fill out and once it clicks the button, the information will populate a list of items. I am trying to crete < li > with a OrderListItem component. But I am getting this error:
runtime-core.esm-bundler.js?5c40:217 Uncaught ReferenceError: machines is not defined
at eval (OrderListItem.vue?fb66:14)
Here is the form
<template>
<div>
<div class="flex flex-col mb-4 md:w-full m-1">
<label for="planter_model_id">Planter</label>
<select v-model="registration.planter_model_id" name="planter_model_id">
<option disabled selected>Planter</option>
<option v-for="planter in planters" :key="planter" :value="planter.id">{{planter.brand.name}} {{planter.name }}</option>
</select>
</div>
<div class="flex flex-col mb-4 md:w-full m-1">
<label class=" for="lines">Lines</label>
<Input v-model="registration.lines" type="number" name="lines" />
</div>
<Button type="button" #click="addItemOrder">Add</Button>
</div>
<div>
<ul>
<OrderListItem :machines="machines" />
</ul>
<div>
</template>
Here is my code
export default {
components: {
OrderListItem,
Button,
},
props: {
planters:{
type:Array,
required: true
},
},
data() {
return {
machines: [], //this what I wish to be passed to OrderListItem component
registration:{
lines:null,
planter_model_id:null,
},
}
},
methods:{
addItemOrder(){
let item = {}
item.planter_model_id = this.registration.planter_model_id
item.lines = this.registration.lines
this.machines.push(item)
}
}
};
And here is my OrderListItem component that I created on another file:
<template>
<li v-for="machine in machines" :key="machine">
<div class="flex-initial w-3/5">
<p>Planter: {{machine.planter_model_id}}</p>
<p>Lines: {{machine.lines}}</p>
</div>
</li>
</template>
<script>
export default {
name: 'OrderListItem',
props:{
machines,
}
}
</script>
I don’t know if it is relevant but I am using vue3 and laravel.
I am very newbie here and from what I learned I think if machines array was a prop I would be able to access it on my component. But I will dynamically add a and remove itens from machines array and I think props receive data from server so It should not be declared there, that why I declared inside data().
Thanks =)
You should define the prop by adding its type and default value :
export default {
name: 'OrderListItem',
props:{
machines:{type:Array,default:()=>[]},
}
}
I created a simple real-time chat application using vue js in laravel.
I am having a problem with the automatic scroll of the div when there is a new data.
What I want is the div to automatically scroll down to the bottom of the div when there is a new data.
Here is my code so far.
Chat.vue file
<template>
<div class="panel-block">
<div class="chat" v-if="chats.length != 0" style="height: 400px;" id="myDiv">
<div v-for="chat in chats" style="overflow: auto;" >
<div class="chat-right" v-if="chat.user_id == userid">
{{ chat.chat }}
</div>
<div class="chat-left" v-else>
{{ chat.chat}}
</div>
</div>
</div>
<div v-else class="no-message">
<br><br><br><br><br>
There are no messages
</div>
<chat-composer v-bind:userid="userid" v-bind:chats="chats" v-bind:adminid="adminid"></chat-composer>
</div>
</template>
<script>
export default {
props: ['chats','userid','adminid'],
}
</script>
ChatComposer.vue file
<template>
<div class="panel-block field">
<div class="input-group">
<input type="text" class="form-control" v-on:keyup.enter="sendChat" v-model="chat">
<span class="input-group-btn">
<button class="btn btn-primary" type="button" v-on:click="sendChat">Send Chat</button>
</span>
</div>
</div>
</template>
<script>
export default{
props: ['chats','userid','adminid'],
data() {
return{
chat: ''
}
},
methods: {
sendChat: function(e) {
if(this.chat != ''){
var data = {
chat: this.chat,
admin_id: this.adminid,
user_id: this.userid
}
this.chat = '';
axios.post('/chat/sendChat', data).then((response) => {
this.chats.push(data)
})
this.scrollToEnd();
}
},
scrollToEnd: function() {
var container = this.$el.querySelector("#myDiv");
container.scrollTop = container.scrollHeight;
}
}
}
</script>
I am passing a div id from the Chat.vue file to the ChatComposer.vue file.
As you can see in the ChatComposer.vue file there is a function called scrollToEnd where in it gets the height of the div id from Chat.vue file.
When the sendchat function is triggered i called the scrollToEnd function.
I guess hes not getting the value from the div id because I am getting an error - Cannot read property 'scrollHeight' of null.
Any help would be appreciated.
Thanks in advance.
the scope of this.$el.querySelector will be limited to only ChatComposer.vue hence child component can not able to access div of parent component #myDiv .
You can trigger event as below in ChatComposer
this.$emit('scroll');
In parent component write ScollToEnd method and use $ref to assign new height
<chat-composer v-bind:userid="userid" v-bind:chats="chats" v-bind:adminid="adminid" #scroll="ScollToEnd"></chat-composer>
..
I am learning vue+laravel. I want to pass value from one component to other component? I have used vue router for routing.
Here is the code for first and second component.
SelectPerson.vue
<template>
......
<div>
<input type="number" class="form-control" name="numberOfPersons" placeholder="Enter number of persons here" **v-model="inputPersons"**>
<br>
**<SelectTimeSlot v-bind:numberOfPersons="inputPersons"></SelectTimeSlot>**
</div>
<div>
<button class="btn btn-default float-right mt-2" v-on:click="selectTimeSlots">Next</button>
</div>
......
</template>
<script>
import SelectTimeSlot from './SelectTimeSlot.vue'
export default{
props:['numberOfPersons'],
data(){
return{
**inputPersons:0**
}
},
methods:{
selectTimeSlots(){
this.$router.push({name:'SelectTimeSlot'});
}
}
}
</script>
second component
SelectTimeSlot.vue
<template>
<h5>Welcome, You have selected **{{numberOfPersons}}** persons.</h5>
</template>
Can anybody help me do it?
To pass data from one component to other component, you need to use props:
First component:
<second-component-name :selectedOption="selectedOption"></second-component-name>
<script>
export default {
components: {
'second-component-name': require('./secondComponent.vue'),
},
data() {
return {
selectedOption: ''
}
}
}
</script>
Second Component:
<template>
<div>
{{ selectedOption }}
</div>
</template>
<script>
export default {
props: ['selectedOption']
}
</script>
Please visit this link.
Hope this is helpful for you!
Say I have a page with this HTML.
<div class="select-all">
<input type="checkbox" name="all_select" id="all_select">
<label #click="checkchecker" for="all_select"></label>
</div>
the function checkchecker is called in my methods
checkchecker() {
this.checker = !this.checker
}
This will show or hide my div on that page like this
<div v-show="checker === true" class="select-all-holder">
<button>Select All</button>
</div>
Now if I also want to toggle another div which is inside my child
component on that page I will pass the value like this.
<div class="content-section clearfix">
<single-product :checkers="checker"></single-product> //This is calling my child component
</div>
Now in my Child component I will have a prop declared like this
checkers: {
type: String,
default: false,
},
This is how I will write my div in my child component
<div v-show="checkers === true" class="select-holder clearfix">
<input type="checkbox" class="unchecked" name="single_select" id="1">
</div>
I have controller as follows:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.questionTypes = [
{display: 'Text', 'name': 'text'},
{display: 'Paragraph', 'name': 'textarea'},
{display: 'Multiple Choice', 'name': 'radio'},
];
$scope.top = {
heading: '',
questions: [
{
tite: 'title 1',
choices: ['']
}
]
};
});
And an HTML body as follows:
<body ng-controller="MainCtrl">
<input ng-model="top.heading" placeholder="heading"/>
<br/>
<div ng-repeat="question in top.questions track by $index">
<select ng-model="question.type" ng-options="c.name as c.display for c in questionTypes"></select>
<div ng-if="question.type == 'radio'">
<div ng-repeat="option in question.choices track by $index">
<input type="text" ng-model="option"/>
<button ng-click="question.choices.push('')" ng-disabled="$index < question.choices.length - 1">Add</button>
<button ng-click="question.choices.splice($index, 1)" ng-disabled="question.choices.length == 1">Del</button>
</div>
</div>
</div>
<pre>{{top | json}}</pre>
</body>
When the user makes the Multiple Choice selection, I want to show a fragment that provides the ability to add various choices. The choices are displayed in repeater.
That all works, but data binding on nested repeater is not working. I assuming this has something to do with scoping, but I can't figure it out.
Any help would be appreciated.
I have created a plunkr at http://plnkr.co/edit/6FxY44HgddRjrLOHlQGF
After fumbling around with this for a while, this is what I did to fix the problem.
I changed:
<input type="text" ng-model="option"/> //after changing model to ng-model
To
<input type="text" ng-model="question.choices[$index]"/>
This allowed the input to reference the parent question object and the choices array on the object instead of referencing the option reference within ng-repeat.
I'm using https://drew.tenderapp.com/faqs/autosuggest-jquery-plugin/options-api to render an autocomplete field:
<h1>Quick Tags</h1>
<div class="fieldset">
{{ vocabularies.vocabulary_1.errors }}
<p>{{ vocabularies.vocabulary_1 }}</p>
<script type="text/javascript">
////http://code.drewwilson.com/entry/autosuggest-jquery-plugin
$("input#id_vocabulary_1").autoSuggest("/staff/taxonomy/ajax", {selectedItemProp: "name", selectedValuesProp: "name", searchObjProps: "name", startText: "Enter terms.", keyDelay: 50, minChars: 1, queryParam: "term", asHtmlID: "vocabulary_1", extraParams: "&app=taxonomy&model=TaxonomyData&vocabulary=1"});
</script>
</div>
Which renders a hidden field:
<li class="as-original" id="as-original-vocabulary_1">
<input id="vocabulary_1" type="text" name="vocabulary_1" maxlength="200" autocomplete="off" class="as-input">
<input type="hidden" class="as-values" name="as_values_vocabulary_1" id="as-values-vocabulary_1" value="test,new term,">
</li>
However, the values from this field are not present in the POST dictionary. What could be causing this problem?
I found out the problem; if the div that contains the form opening tag is closed, all fields after that are not contained in the POST dictionary.