passing array of objects to a component in vue.js - javascript

I am having problem to pass an array of objects to component in Vue.js 2.2.
Here is my component
<vue-grid :fields = "[
{name: 'Person Name', isSortable: true},
{name: 'Country', isSortable: true}]"
></vue-grid>
It doesn't work as it renders the curly braces in the browser.
I've tried without the quotation " in the object and without the colon : in front of fields property. None of these work either.
However, if I just pass a simple string that works. I don't know why object is not working.
I have found a similar question but answer was given for php. I need the solution just for JavaScript. I want to hard code the object array in the component.

You are passing it correctly. You must have something else happening behind the scenes. Ensure your template has a wrapping element. See this fiddle
<div id="vue-app">
<h2>
Vue App
</h2>
<vue-grid :fields = "[
{name: 'Person Name', isSortable: true},
{name: 'Country', isSortable: true}]"
></vue-grid>
</div>
<script id="vue-grid-template" type="text/x-template">
<div>
<h3>Grid</h3>
<div class="grid">
Fields are:
<ul>
<li v-for="field in fields">
{{field.name}} - {{field.isSortable}}
</li>
</ul>
</div>
</div>
</script>
<script>
Vue.component('vue-grid', {
props: ['fields'],
template: '#vue-grid-template'
});
new Vue({
el: '#vue-app'
});
</script>

Related

ais-refinement-list in VueInstantSearch(Algolia) doesn't renders list

I have stucked with an issue using refinement list widget of algolia.
First of all my resulting data structure is like that:
[
{
objectID: 999,
title: 'some title',
categories: [
{
id: 444,
name: 'some name',
},
{...},
]
}
]
I have that type of structure on my page:
<ais-instant-search
:search-client="searchClient"
:initial-ui-state="{
index_Name: { query: searchedValue },
}"
index-name="index_Name"
>
<ais-index index-name="index_Name">
<ais-configure
:filters="facetsFilters"
:facets="['categories.id']"
:hits-per-page.camel="items"
/>
<ais-refinement-list attribute="categories.id" />
<div> ...Some other widgets nested in divs as ais-search-box, ais-sort-by, etc </div>
</ais-index>
</ais-instant-search>
Within ais-configure I have passed to filters a facetsFilters variable which contains string with such content:
"categories.id:1 OR categories.id:5"
and it works ok, I'm getting results within selected categories,
problems starts, when i try to get refinement-list here:
<ais-refinement-list attribute="categories.id" />
I have an empty list despite that on dashboard this attribute is added as an attributesForFacetings and in ais-configure filters parameters with categories.id in it also works well.
Any suggestions is highly appreciated !
Problem was in Dashboard of Algolia.
When we clicked on 'searchable' instead of 'filter only' radiobutton for chosen attributeForFaceting - everything starts working good.

Using Vue.js directives within component template

I'm new to Vue.js and trying to create a component that connects to one object within some global-scope data and displays differently based on the specifics of each object. I think I'm misunderstanding how the directives v-if and v-on work within component templates. (Apologies if this should actually be two different questions, but my guess is that the root of my misunderstanding is the same for both issues).
Below is a minimal working example. My goal is to have each member entry only display the Disable button if the associated member is active, and enable changing their status via the button. (I also want to keep the members data at the global scope, since in the actual tool there will be additional logic happening outside of the app itself).
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<member-display
v-for="member in members"
v-bind:member="member"
></member-display>
</div>
<script>
var members = [
{name: "Alex", status: "On"},
{name: "Bo", status: "On"},
{name: "Charley", status: "Off"}
]
Vue.component('member-display', {
props: ['member'],
computed: {
active: function() {
// Placeholder for something more complicated
return this.member.status == "On";}
},
methods: {
changeStatus: function() {
this.member.status = 'Off';
}
},
// WHERE MY BEST-GUESS FOR THE ISSUE IS:
template: `
<div>
{{member.name}} ({{member.status}})
<button v-if:active v-on:changeStatus>Disable</button>
</div>
`
});
var app = new Vue({
el: "#app",
data: {
members: members
}
})
</script>
</body>
</html>
Thanks for your help!
The code v-if and the v-on for the button just have the wrong syntax. The line should look like this:
<button v-if="active" v-on:click=changeStatus>Disable</button>

Using Vue components - setattr - invalid attribute name

I am in the early stages of using Vue.js, and have come unstuck when attempting to use components. The non component version of this code worked fine.
The following returns an error, which I am having trouble deciphering, but it looks like I am passing a comma somewhere where there should be an attribute of the object.
Is it clear where the issue is arising here?
Error
Uncaught DOMException: Failed to execute 'setAttribute' on 'Element':
',' is not a valid attribute name.
HTML
<div id="list_render">
<ol>
<todo-item
v-for="item in todo_list",
v-bind:todo="item",
v-bind:key="item.id">
</todo-item>
</ol>
</div>
JS
Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
})
var todo = new Vue({
el: '#list_render',
data: {
todo_list: [
{ id: 0, text: 'Learn Vue' },
{ id: 1, text: 'Plan project' }
]
}
})
Remove commas here:
<todo-item
v-for="item in todo_list"
v-bind:todo="item"
v-bind:key="item.id">
It should look like a regular HTML element, with no commas inside.
In extension to previous answer
error: <input v-model="text" , type="text"/>
works: <input v-model="text" type="text"/>

bind data to vue model dynamically in component

I'm trying to make a simple form that will accept user's input for different types of currency.
Here's a (broken) fiddle that hopefully gets across what I want to do:
https://jsfiddle.net/4erk8yLj/7/
I'd like my component to bind data to my root vue instance, but I'm not sure if my v-model string is allowable. Check it out:
Vue.component('conversion-row', {
props: ['currency', 'values'],
template: '<div>{{currency}}:</div><div><input v-model="values[currency]></div><',
});
var vm = new Vue({
el: "#app",
data: {
currencies: ['USD', 'BTC'],
values: {
'BTC': '',
'USD': ''
}
}
});
template:
<div id="app">
<li>
<conversion-row is li v-for="currency in currencies" v-bind:currency="currency">
</conversion-row>
</li>
</div>
What's a good way to fix this?
Couple of things you might need to correct:
First, the data property must be a function rather than an object. This allows every instance to get data recomputed every time it is being created, see:
var vm = new Vue({
el: "#app",
data() {
return {
currencies: ['USD', 'BTC'],
values: {
'BTC': 'BTC Value',
'USD': 'USD Value',
},
};
}
});
Second, <conversion-row> doesn't have values property bound. Here's what you can do:
<div id="app">
<li v-for="currency in currencies">
<conversion-row :currency="currency" :values="values"></conversion-row>
</li>
</div>
Last, the component should always aim for one root element (wrapper) and then you can nest as many children inside as you want. What's more, instead of using v-model, you can bind value which is the proper way to pass a value to an input (one-way data binding), check the following:
Vue.component('conversion-row', {
props: ['currency', 'values'],
template: '<div>{{currency}}:<input type="text" :value="values[currency]"></div>'
});
There's more improvements you could possibly make here like re-thinking if you need to pass values as well as currency to the conversion-row but I'm pretty sure you'll figure it out later on.
All that above will make your code run and execute properly, here's the working example (fork of yours):
https://jsfiddle.net/maciejsmolinski/mp8m0ben/1/
Does this help?
Not sure what you're aiming for in terms of using v-model, but here's an example of working v-model (based on your example):
Vue.component('conversion-row', {
props: ['currency', 'values'],
template: '<div>{{currency}}:<input type="text" v-model="values[currency]"></div>'
});
And the corresponding template:
<div id="app">
<p><strong>USD Value:</strong> {{ values.USD }}</p>
<p><strong>BTC Value:</strong> {{ values.BTC }}</p>
<br>
<li v-for="currency in currencies">
<conversion-row :currency="currency" :values="values"></conversion-row>
</li>
</div>
You can find it under the following URL:
https://jsfiddle.net/maciejsmolinski/0xng8v86/2/

Checkbox form array data Vue 2

I have a checkbox list which is generated using a for loop that consists of an id and a name:
Data:
yards[{id:1,name:'test'}] etc
HTML:
<ul class="checkbox-list">
<template v-for="(yard, index) in yards">
<li>
<input type="checkbox"
v-bind:id="'yardlist_'+yard.name"
v-bind:value="yard.id"
v-model="newSchedule.yards.id">
<label v-bind:for="'yardlist_'+yard.name">{{ yard.name }}</label>
</li>
<li>
<input type="text"
class="form-control"
placeholder="Yard notes..."
v-model="newSchedule.yards.notes">
</li>
</template>
</ul>
I want to save the selected checkbox with the id and notes field in an array:
newSchedule: {
due_at: '',
notes: '',
users: [],
yards: [{id:'',notes:'']
}
I have tried using the index from the yards array: newSchedule.yards[index].notes but am getting the following error "TypeError: undefined is not an object (evaluating 'newSchedule.yards[index].id')"
Any ideas how I can achieve this?
** Update **
Here is a basic fiddle of what I am wanting to achieve:
https://jsfiddle.net/j7mxe5p2/13/
I think you are trying to mix the old jQuery or javascript way of doing things with Vue framework. You should not have to set id on <input> elements to capture or set its value.
The correct way to do this is as follows:
new Vue({
el: '#app',
data: function() {
return {
yards: [
{id: 1, name: 'test', selected: true},
{id: 2,name: 'test 2', selected: false},
{id: 3,name: 'test 3', selected: false},
{id: 4,name: 'test 4', selected: true}
]
};
},
template: `
<div class="list-of-yards"> <!-- You cannot use v-for on the top-level element -->
<label for="jack" v-for="yard in yards">
<input type="checkbox" v-model="yard.selected"> {{yard.name}}
</label>
</div>
`,
});
Here is a jsFiddle of the above code: https://jsfiddle.net/z48thf9a/
Things to note:
You cannot use v-for on the template tag itself
You cannot use v-for on the top-level element just inside template. The template should contain one and only enclosing element, typically a <div>
There is no need to set id on input elements. You need to use v-model for your model-view bindings
If you still have issues, please provide a jsFiddle to debug further.
Edited after comment #1 and #2:
My above response is focused more on constructing the Vue component and rendering the list with proper binding to the checkboxes.
To get the checked items into a separate array, you can use a computed property in the same component to run through the original array this.yards and create a new array of selected items only.
Here is the jsFiddle for capturing the checked values: https://jsfiddle.net/z48thf9a/1/
You may modify the above to capture only the id part, and rename selectedYards to newSchedule or whatever your app requires.
I am not sure if I understood your question correctly, and if this solves your issue. Can you please provide more code samples?

Categories

Resources