I am using https://github.com/matfish2/vue-tables with Laravel.
This is the vue code:
Vue.use(VueTables.client, {
compileTemplates: true,
highlightMatches: true,
pagination: {
dropdown:true,
chunk:5
},
filterByColumn: true,
texts: {
filter: "Search:"
},
datepickerOptions: {
showDropdowns: true
}
});
new Vue({
el: "#people",
methods: {
deleteMe: function(id) {
alert("Delete " + id);
}
},
data: {
options: {
columns: ['created_at', 'name', 'profession', 'footage_date', 'type', 'link', 'note'],
dateColumns: ['footage_date'],
headings: {
created_at: 'Added',
name: 'Name',
profession: 'Profesion',
footage_date: 'Footage Date',
type: 'Type',
link: 'Link',
note: 'Note',
edit: 'Edit',
delete: 'Delete'
},
templates: {
edit: "<a href='#!/{id}/edit'><i class='glyphicon glyphicon-edit'></i></a>",
delete: "<a href='javascript:void(0);' #click='$parent.deleteMe({id})'><i class='glyphicon glyphicon-erase'></i></a>"
},
},
tableData: [{ InsertDataHere }],
}
});
How do I get the data from DB for tableData ? Vue-resources?
I have a route /api/footage that gives me the following
[
{
"id": 2,
"user_id": 11,
"profession": "profession",
"type": "GvG",
"footage_date": {
"date": "2016-04-01 00:00:00.000000",
"timezone_type": 2,
"timezone": "GMT"
},
"link": "some link",
"note": "description",
"created_at": "1 hour ago",
"updated_at": "2016-04-03 23:06:32"
}
]
Now, User and Footage have a one to many relationship. How would I go about to show the user for each entry as well? ( also the ID for edit and delete )
This is the blade code
<div id="people" class="container">
<v-client-table :data="tableData" :options="options"></v-client-table>
</div>
Thank you in advance.
You can add a ready() function to call the API when the component is built:
ready:function(){
this.$http.get('/api/footage')
.then(function(response){
this.tableData = response.data
}.bind(this))
}
You may have to tweak the code based on the format of your API response. Cleaner version if youre using es2016:
ready(){
this.$http.get('/api/footage')
.then(({data})=>{
this.tableData = data
})
}
You should include vue-resource before this, yes. That allows you to use this.$http
As per #BillCriswell you could do this in the created() function to fire off the API call even sooner
When fetching async data use v-if along with some "loaded" flag on the component to ensure smooth compilation of templates.
<v-client-table v-if="loaded" :data="tableData" :options="options"></v-client-table>
See: https://github.com/matfish2/vue-tables/issues/20, last comment
Related
I have this array:
data() {
return {
landingInfo: null,
slides: [
{
title: `this`,
},
{
title: "that",
},
{
title: "those",
},
],
};
},
Which is being displayed this way:
<div
class="slide"
v-for="(slide, index) in slides"
:key="index",
}"
>
<div>
<h1 class="text-bold">{{ slide.title }}</h1>
</div>
The problem is that I'm fetching info from and api and once I try to do:
slides: [
{
title: {{ landingInfo.data.subtitle }},
},
{
title: {{ landingInfo.data.subtitle2 }},
},
{
title: {{ landingInfo.data.subtitle3 }},
},
],
Everything explodes, I am new in vue using Nuxt.js and I cannot find any solution in how to achieve that.
Can someone show me how to include the fetched info inside the array property?
PD: I already tried using "{{thefetchedinfo}}" but it takes it literally that way and displays "{{thefetchedinfo}}"
The OP doesn't provide much info on the fetch, like when it is performed or what the returned data looks like, but the common pattern goes like this...
// <template> as in the OP, then...
data() {
return {
landingInfo: null,
slides: [], // empty before the fetch
};
},
mounted () {
fetchFromTheAPI().then(landingInfo => {
// More commonly, you'd map over the returned data to form slides,
// or, trying to match the OP...
this.slides = [
{ title: landingInfo.data.subtitle },
{ title: landingInfo.data.subtitle2 }, // ... and so on
]
});
},
Right now, the code is working for all the strings I passed however, I can't retrieve my images from storage and see the fieldId needed. I followed the documentation of flamelink-js-sdk but it doesn't seem to clarify what should be done for images.
Here's a sample of my code:
async created() {
app.content
.get({
schemaKey: "teamPage",
populate: [
{
field: "title"
},
{
field: "description"
},
{
field: "executiveBoard",
fields: [
"title",
"position",
"image",
"facebook",
"github",
"linkedin"
]
}
]
})
.then(teamPage => {
this.teamPage = teamPage;
console.log(this.teamPage.executiveBoard[0].image);
})
.catch(error => console.log(error));},
Here's where I render them
<team-circle
v-for="board in teamPage.executiveBoard"
:key="board.title"
class="col-12 col-sm-12 col-md-4"
:name="board.title"
:image="board.image"
:facebook="board.facebook"
:linkedin="board.linkedin"
:github="board.github"
>{{ board.position }}</team-circle>
Check this link to see what data is passed in the src of the img tag
Thank you again. Hope you can help me out on this!
You can do the following
app.content
.get({
schemaKey: "teamPage",
populate: [
{
field: "title"
},
{
field: "description"
},
{
field: "executiveBoard",
fields: [
"title",
"position",
"image",
"facebook",
"github",
"linkedin"
],
populate: ["image"]
}
]
})
note the populate: ["image"] addition (see this)
this.teamPage.executiveBoard[0].image will now be an array of objects example
[{
contentType: "image/png",
id: "xxx",
...
url: "https://firebasestorage.googleapis.com/v0/b/....."
}]
you can then access the url for example like this
this.teamPage.executiveBoard[0].image[0].url
The documentation at https://sapui5.hana.ondemand.com/#/controls provides many SAPUI5 samples. But all the views are written in XML. I can find examples written in Javascript elsewhere but I'm asking for a general rule to apply on XML code. Here is an example List.view.xml wich I need to manually convert to List.view.js
<mvc:View
height="100%"
controllerName="sap.m.sample.ListSelectionSearch.List"
xmlns:l="sap.ui.layout"
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m">
<Page
showHeader="false" >
<subHeader>
<Toolbar>
<SearchField
liveChange="onSearch"
width="100%" />
</Toolbar>
</subHeader>
<content>
<List
id="idList"
items="{/ProductCollection}"
selectionChange="onSelectionChange"
mode="MultiSelect"
includeItemInSelection="true" >
<infoToolbar>
<Toolbar
visible="false"
id="idInfoToolbar" >
<Label id="idFilterLabel" />
</Toolbar>
</infoToolbar>
<items>
<StandardListItem
title="{Name}"
description="{ProductId}"
icon="{ProductPicUrl}"
iconDensityAware="false"
iconInset="false" />
</items>
</List>
</content>
</Page>
Any help will be appreciated.
Here is the same in SAPUI5's JSView with list aggregation done in the controller:
Alternatively, have a look at this full application Example SAPUI5 JSView Application
OR
Make use of the Diagnostic tool by pressing CTRL+SHIFT+ALT+S and API References
sap.ui.define(["sap/m/Page", "sap/m/List", "sap/m/Toolbar", "sap/m/SearchField", "sap/m/Label", "sap/m/Text"], function(Page, List, Toolbar, SearchField, Label, Text) {
"use strict";
return sap.ui.jsview("sap.m.sample.ListSelectionSearch.View", {
getControllerName: function() {
return "sap.m.sample.ListSelectionSearch.List";
},
createContent: function(oController) {
var oToolbar = new Toolbar({
visible: true,
content: [
new SearchField({
liveChange: function() {
oController.onSearch();
},
width: "100%"
})
]
});
var oInfoToolbar = new Toolbar({
content: new Toolbar(this.createId("idInfoToolbar"), {
visible: true,
content: new Text({
text: "Label Text"
})
})
});
var oList = new List(this.createId("idList"), {
mode: "MultiSelect",
includeItemInSelection: true,
infoToolbar: oInfoToolbar
});
var oPage = new Page(this.createId("oPageId"), {
height: "100%",
title: "Page Title",
showHeader: true,
showSubHeader: true,
headerContent: oToolbar,
content: [oList]
});
var app = new sap.m.App();
app.addPage(oPage);
app.placeAt("content");
return app;
}
});
});
//in Controller
sap.ui.define(["sap/m/StandardListItem", "sap/ui/model/json/JSONModel"], function(StandardListItem, JSONModel) {
"use strict";
var oData = {
"ProductCollection": [{
"titleId": 0,
"Name": "Olayinka Otuniyi",
"ProductId": "001",
"ProductPicUrl": "sap-icon://competitor"
}, {
"titleId": 1,
"Name": "Maria Anders",
"ProductId": "002",
"ProductPicUrl": "sap-icon://badge"
}, {
"titleId": 2,
"Name": "Ana Trujillo",
"ProductId": "003",
"ProductPicUrl": "sap-icon://broken-link"
}, {
"titleId": 3,
"Name": "Thomas Hardy",
"ProductId": "004",
"ProductPicUrl": "sap-icon://create"
}, {
"titleId": 4,
"Name": "Christina Berglund",
"ProductId": "005",
"ProductPicUrl": "sap-icon://pending"
}, {
"titleId": 5,
"Name": "Hanna Moos",
"ProductId": "006",
"ProductPicUrl": "sap-icon://decision"
}, {
"titleId": 6,
"Name": "MartÃn Sommer",
"ProductId": "007",
"ProductPicUrl": "sap-icon://process"
}, {
"titleId": 7,
"Name": "Laurence Lebihans",
"ProductId": "008",
"ProductPicUrl": "sap-icon://accept"
}, {
"titleId": 8,
"Name": "Elizabeth Lincoln",
"ProductId": "009",
"ProductPicUrl": "sap-icon://alert"
}]
};
return sap.ui.controller("sap.m.sample.ListSelectionSearch.List", {
// onInit: function() {
// },
onAfterRendering: function() {
var oModel = new JSONModel(oData);
this.getView().setModel(oModel, "products");
var oTemplate = new StandardListItem({
title: "{products>Name}",
description: "{products>ProductId}",
icon: "{products>ProductPicUrl}",
iconDensityAware: false,
iconInset: false,
type: "Active"
});
oTemplate.attachPress(this.onSelectionChange, this);
this.getView().byId("idList").bindItems({
path: "/ProductCollection",
template: oTemplate,
model: "products"
});
},
onSearch: function() {
console.log("Searching");
},
onSelectionChange: function() {
console.log("changing Selection");
}
});
});
Should not be that difficult:
new sap.m.Page({
showHeader: false,
subHeader: new sap.m.Toolbar({
content: [ // (**)
new sap.m.SearchField({
liveChange: onSearch, // event handler
width: "100%"
})
]
}),
content: [
new sap.m.List({
//...
})
]
});
OR you can keep writing XML and then create JS instances from it using API:
sap.ui.xmlfragment
sap.ui.xmlview
(**) here is probably the trickiest part. How could you know that this should be wrapped inside "content" property? Very easy! If you see one control inside another directly (without any tags around it), it means inner control is in default aggregation of parent control. So, all you need to do is check what is the name of the default aggregation of the parent control. In case of sap.m.Toolbar it's a content.
UPDATE: however, it might be difficult to understand which aggregation is default, because in our docs we do not show this information. I will contact responsible team on this matter. As a work around it's possible to get this information from the source code, e.g. sap.m.Page - see defaultAggregation definition in metadata description.
Please see the example below
View:
sap.ui.jsview("ResourceRootName.view.ViewName", {
getControllerName: function() {
return "ResourceRootName.view.ViewName";
},
createContent : function(oController) {
this.oList = new sap.m.List({
showUnread: true,
mode: sap.ui.Device.system.phone ? sap.m.ListMode.None : sap.m.ListMode.SingleSelectMaster,
itemPress: [oController.onListSelect, oController]
});
this.page = new sap.m.Page({
title: "{i18n>pageTitle}",
navButtonText: "Home",
showNavButton: true,
navButtonPress: function() {
oController.handleNavBack();
},
subHeader: new sap.m.Bar({
contentMiddle: [
new sap.m.SearchField(oController.createId("searchFieldTasks"), {
width: "100%"
})
]
}),
content: [this.oList]
});
return this.page; //Note: if you need to return more than two controls you can do so by using array
}
});
In controller you can bind your list as below
Controller:
this.getView().oList.bindAggregation("items", {
path: "/EntityCollectionSet",
template: new sap.m.StandardListItem({
title: "{Title}",
description: "{Description}"
}),
filters: []//If you want to pass any filters
});
I am using jquery's DataTables which is really working great. Then only problem I got is, that I am facing (in non-edit-view) the value of the select-field (which is an id). The user of course doesn't want to see the id of course.
Therefore I am looking for a possibility to configure that column in a way to show always the value of label property.
Here a some snippets:
$(document).ready(function() {
var table = $('#overviewTable').DataTable({
dom: "Tfrtip",
ajax: "/Conroller/GetTableData",
columns: [
{ data: "Id", className: "readOnly", visible: false },
{
data: "LoanTransactionId",
className: "readOnly readData clickable",
"fnCreatedCell": function(nTd, sData, oData, iRow, iCol) {
$(nTd).html("<a href='#'>" + oData.LoanTransactionId + "</a>");
}
},
{ data: "Id", className: "readOnly" },
{ data: "property_1", className: "readOnly" },
{ data: "Priority" },
{ data: null, className: "action readOnly", defaultContent: 'Info' }
],
order: [1, 'asc'],
tableTools: {
sRowSelect: "os",
sRowSelector: 'td:first-child',
aButtons: []
}
});
// data reload every 30 seconds
setInterval(function() {
table.ajax.reload();
}, 30000);
editor = new $.fn.dataTable.Editor({
ajax: "PostTable",
table: "#overviewTable",
fields: [
{
label: "Id",
name: "Id"
},
{
label: "Column 1",
name: "property_1"
},
{
label: "Priority",
name: "Priority",
type: "select",
options: [
{ label: "low", value: 0 },
{ label: "mid", id: 1 },
{ text: "high", id: 2 }
]
}
]
});
// Inline Edit - only those who are not readOnly
$('#overviewTable').on('click', 'tbody td:not(:first-child .readOnly)', function(e) {
editor.inline(this, {
submitOnBlur: true
});
});
How it looks in the display mode
How it looks in the edit mode
See the documentation on columns.render
You want to modify your column options for priority
Preferred Option: Your data source has a field with the priority as a string
This is the best option, as you don't want to have two places with this business logic. Keep it out of the client code.
Also, you will want to modify the editor as well so that the options used have been retrieved dynamically from the server to keep this business logic out of the client too. This is left as an exercise for the reader.
Since you don't provide details on what your data structure looks lik, I'm assuming it is an object, and it has an attribute priorityAsString so use the string option type for render.
columns: [
...
{
data: "Priority" ,
render: "priorityAsString",
},
Option 2) You write a function to map priority to string
Do this if you can't get the data from the server. But remember you will need to update many places when the priority list changes.
columns: [
...
{
data: "Priority" ,
render: renderPriorityAsString,
},
...
function renderPriorityAsString(priority) {
const priorityToString = {
0: 'low',
1: 'med',
2: 'high',
};
return priorityToString[priority] || `${priority} does not have a lookup value`;
}
"render": function ( data, type, full ) { return label;}
I use can.Component to dispay JSON on the page.
can.Component.extend({
tag: "some-app",
scope: {
items: new Items.List({}),
displayedItems: function () {
...
return items;
}
},
helpers: {
...
},
events: {
"{Items} created": function (Items, ev, newItem) {
...
}
}
})
How can I get "meta" section of received JSON (below) to the scope or helpers?
{
"data": [
{
"description": "Some text",
"id": 1,
"measurement": "pcs",
"name": "Name of item",
"resource_uri": "/api/v1/item/1/"
},
{....}, {....}
}
],
"meta": {
"limit": 20,
"next": null,
"offset": 0,
"previous": null,
"total_count": 3
}
}
I can get it in console with Items.findAll().then(function(info){console.log(info.attr('meta'))}) , but I'm noob in (can.)js and can't understand how to get it in the place I need.
Instead of this:
scope: {
items: new Items.List({})
}
make the request:
scope: {
items: Items.findAll()
}
There are other ways to do this as well, in the template(not advised), or creating the request in another controller or component and passing in to the instantiation of the component.
If you want more specifics, you would nee to update your question with more details on your model.