Display data in Vue.js with v-for - javascript

I'm making a simple shopping cart system using Laravel and Vue.js. I can successfully add items to my shopping basket and retrieve them to a certain point, but I'm having trouble actually outputting the items to the view.
When I hit my basket route, I load the basket view which triggers the following Vue code:
new Vue({
el: '#basket',
ready: function () {
this.fetchBasket();
},
methods: {
fetchBasket: function(){
this.$http.get('api/buy/fetchBasket', function (basketItems) {
this.$set('basketItems', basketItems);
});
}
}
});
This works and I get data returned in the console:
{027c91341fd5cf4d2579b49c4b6a90da:
{id: 1, name: "A Gnarly Tree", price: 15, quantity: 2}}
027c91341fd5cf4d2579b49c4b6a90da:
{id: 1, name: "A Gnarly Tree", price: 15, quantity: 2}
id:1
name:"A Gnarly Tree"
price:15
quantity:2
However, nothing appears in the view itself. I'm trying to use v-for to populate a table:
<tbody>
<tr v-for="item in basketItems">
<td>#{{ item.name }}</td>
<td>#{{ item.price }}</td>
<td>#{{ item.quantity }}</td>
<td>#<button class="btn btn-primary">Update</button></td>
</tr>
</tbody>
What am I doing wrong?

You didn't initialize the basketItems in the data of your vue instance. Try to add:
...
el: '#basket',
data: { basketItems: [] }, // <-- this line
ready: function(){
this.fetchBasket();
},
...
Also edit
this.$set('basketItems', basketItems);
to
Vue.set(this, 'basketItems', basketItems)

Related

Vue.js method calls on string in tabledata

Have been task to have a look at a Vue app (gulp....react dev here) for a colleague that left the company. However it is built with a string that renders the table data in a for loop such as this:
var table = "";
for (var i = 0; i < companies.length; i++) {
table += "<tr>";
table += `<td id="checkUpdateBox"><input onClick=${this.updateSomeCompanies(companies[i].id)}
type="checkbox"/></td>`;
table += `<td>${companies[i].id}</td>`;
table += `<td>${companies[i].name}</td>`;
table += `<td>${companies[i].custom_fields.seno}</td>`;
table += `<td>${companies[i].created_at}</td>`;
table += "</tr>";
}
methods: {
updateSomeCompanies(id) {
console.log(id);
},
// next method and so on
Am trying to do an update based on the id of the company. Right now, I am just console.logging the id on the method updateSomeCompanies.
However, when the page is loading I am getting the id of the company in the console even though the checkbox haven't been clicked, how come it works like this, is the strange string loop that build the tabledata or am something strange in the code above?
Furthermore, when clicking the checkbox nothing happens?
Have tried with the v-on:clicked and the #Click (same results as above).
Console.logs all of the id's then checkbox do not work.
Suggestions :
As you are using Vue.js then no need to use Vanilla JS to create a table. You can do it dynamically in the template itself.
Use #click/v-on:click directive of Vue to trigger the click event instead of JS onClick.
Live Demo :
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!',
companies: [{
id: 1,
name: 'Alpha',
created_at: 'test'
}, {
id: 2,
name: 'Beta',
created_at: 'test'
}, {
id: 3,
name: 'Gamma',
created_at: 'test'
}]
},
methods: {
updateSomeCompanies(id) {
console.log(id);
}
}
})
table, th, td {
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<table>
<tr>
<th></th>
<th>ID</th>
<th>Name</th>
<th>Created At</th>
</tr>
<tr v-for="company in companies" :key="company.id">
<td id="checkUpdateBox">
<input v-on:click="updateSomeCompanies(company.id)" type="checkbox"/>
</td>
<td>{{ company.id }}</td>
<td>{{ company.name }}</td>
<td>{{ company.created_at }}</td>
</tr>
</table>
</div>

How to display a text for non-filtered elements

I am trying to create a calendar like in the below:
As you see I have tickets object and according to the date of these tickets, I am displaying them.
What I need to do, as you see in the picture I want to display a text 'No available ticket' when it is empty. For example, for Monday and Tuesday (actually all days except Wednesday). So to take the ticket, I am filtering tickets:
findTickets(tickets, date) {
return tickets.filter((ticket) => {
return (
ticket.date.getDate() === date.getDate() &&
ticket.date.getMonth() === date.getMonth() &&
ticket.date.getFullYear() === date.getFullYear() &&
this.getWeekNumber(ticket.date) === this.currentWeekNumber
);
});
},
And basically display inside the table with v-for:
<tr class="list-content" v-for="ticket in findTickets(tickets, date)">
<td>{{ ticket.time }}</td>
<td>{{ ticket.date }}</td>
<td>{{ ticket.name }}</td>
</tr>
So do you know how can I write 'no available date' when the ticket is empty?
Instead of calling findTickets() directly in the HTML you could call findTickets() in the Javascript code and use a list directly in the v-for loop. You can use v-if to check if the tickets array is empty, if so, print a message.
<tr v-for="ticket in tickets" v-bind:key="ticket.name">
<td>{{ ticket.time }}</td>
<td>{{ ticket.date }}</td>
<td>{{ ticket.name }}</td>
</tr>
<div v-if="tickets.length == 0">No available tickets</div>
This is the data:
data: function () {
return {
tickets: [],
};
},
For this example the findTickets() method should return an empty array if there's no tickets.
methods: {
findTickets() {
// Here you do your stuff.
// Let's say you found your tickets
var ticketsFound = true;
if (ticketsFound) {
this.tickets = [
{
time: "11:02",
date: "23/85/2009",
name: "Ticket 1",
},
{
time: "11:02",
date: "23/85/2009",
name: "Ticket 2",
},
{
time: "11:02",
date: "23/85/2009",
name: "Ticket 3",
},
{
time: "11:02",
date: "23/85/2009",
name: "Ticket 4",
},
];
} else {
this.tickets = [];
}
},
}
And then you only need to call the findTickets() method from wherever you like. In my example I call it when the component is mounted.
mounted() {
this.findTickets();
},
Here's a working example:
https://codesandbox.io/s/patient-wave-u8uk7
You can try with map instead of filter, something like this:
return tickets.map((ticket) => {
if (ticket.date.getDate() === date.getDate() &&
ticket.date.getMonth() === date.getMonth() &&
ticket.date.getFullYear() === date.getFullYear() &&
this.getWeekNumber(ticket.date) === this.currentWeekNumber) return ticket;
ticket = {time: '', date: 'No available ticket', name: ''}
return ticket
});
Maybe better way is to create computed property...

Mutiple checkboxes, bound to the same Array in Vue JS

I'm starting out with vuejs and a vue grid at https://jsfiddle.net/kc11/7fqgavvq/
I want to display the checked row objects in the:
<pre> {{ selected| json}} </pre>
area of code,
as in the documentation at http://vuejs.org/guide/forms.html#Checkbox in the "Mutiple checkboxes, bound to the same Array:" example
As you can see when I check 1 checkbox, all are selected. Why is this happening? How can I fix this?
You made a few wrong assumptions in your code (mainly in respect to the scope).
You have your selected array in your main instance, instead of the demo-grid component, where you have your checkboxes:
var demo = new Vue({
el: '#demo',
data: {
searchQuery: '',
gridColumns: ['name', 'power'],
gridData: [
{name: 'Chuck Norris', power: Infinity},
{name: 'Bruce Lee', power: 9000},
{name: 'Jackie Chan', power: 7000},
{name: 'Jet Li', power: 8000}
],
selected: [] // <- This one
}
})
And there is no selectAll method defined on your demo-grid component either, even though you reference it in your template:
<input #click="selectAll" type="checkbox" v-model="selected" id="{{ entry.name }}" value="{{ entry.name }}"></td>
If you thus pass your selected property into your demo-grid, (and define it in the props), you should be fine:
<demo-grid
v-bind:data="gridData"
v-bind:columns="gridColumns"
v-bind:filter-key="searchQuery"
v-bind:selected="selected"> <!-- here -->
</demo-grid>
And define a selectAll method:
methods: {
...
selectAll: function () {
...
}
Here you can see a working example:
https://jsfiddle.net/7fqgavvq/3/
You should add the selected key to the component's data, not to the main instance of vue.
https://jsfiddle.net/7fqgavvq/4/

access properties in v-repeat over array from objects in vue.js

I have a json-result with 5 categories that I want to loop over with v-repeat. I use the push-method to pass the result to my vue-model.
The setup is 5 different categories to which my records belong. Each category must be shown in a different tab (I removed the category-filter on my results cause is not related to the issue).
The records are showing perfectly (v-repeat="results") and I also get 5 tabs but no values (text neither value).
console.log(this.categories) gives me an array of 5 objects from which I don't succeed to show the properties...what am I doing wrong?
I tried all kinds of things like $value, categorie:categories, ...
JSON-result from my api-call over my categories:
{
status: "success",
data: {
results: {
general: "Algemeen",
metadata: "Meta-data",
facebook: "Facebook",
twitter: "Twitter",
googleplus: "Google+"
}
}
}
The fetching in my Vue-file:
fetchCategories: function(){
this.$http.get('/api/tokens/categories', function (response) {
for(var prop in response.data.results) {
this.categories.push({text: response.data.results[prop], value: prop});
}
});
},
And my view:
<tabs>
<tab v-repeat="category in categories" header="#{{ category.text }}">
<div id="#{{ category.value }}">
<table id="#{{ category.value }}-token-list" class="data-list">
<tr>
<th>id</th>
<th>categorie</th>
<th>naam</th>
<th>slug</th>
</tr>
<tr v-repeat="results" v-class="odd: (index%2!=0)">
<td>#{{ id }}</td>
<td>#{{ category }} </td>
<td>#{{ name }} </td>
<td>#{{ slug }}</td>
</tr>
</table>
</div>
</tab>
</tabs>
EDIT:
I do get my value when I write this:
#{{ categories[0].text }} or #{{ categories[0].value}}
EDIT 2:
it is a problem with the tab-functionality from VueStrap. When I use just a list with #{{ value }} it all work just fine
Seems to be a 0.12 issue. Upgrading to 1.0.x will be the solution!

VueJS Resource plugin example

I am attempting to display a JSON response from PHP. I was pointed in the direction of the VueJS resource plugin. Unfortunately, the examples it gives are vague at best.
Is anyone able to provide a simple example of how to display the return JSON object in a list?
HTML:
<table id="list-items">
<tr v-for="item in items">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
</tr>
</table>
JS:
new Vue({
el: '#list-items',
data: {
items: []
},
ready: function() {
this.items = this.getItems();
},
methods: {
getItems: function() {
this.$http.get('items.php', function(data){
this.items = data;
});
}
}
});
items.php must return a JSON encoded array like this:
[{id: 1, name: 'foo'},{id: 2, name: 'bar'}]
In vue 1.0.1 you can use v-for instead of v-repeat like this:
<table id="list-items">
<tr v-for="item in items">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
</tr>
</table>
I think you are looking for
{{ $data | json }}

Categories