I have a scrollview which get json data from an api and render items inside scrollview. From the data i only need to render one item at a time.
Inorder to do that i try adding pageSize:1 to the data source but it does not render anything inside the scrollview. When pageSize change to 2, items render fine with 2 items inside scrollview.
How can i render only a one item inside scrollview?
<div id="example" style="margin:auto; width:60%">
<div id="scrollView" style="height: 600px; width:100%;"></div>
</div>
<script id="scrollview-template" type="text/x-kendo-template">
# for (var i = 0; i < data.length; i++) { #
<div data-role="page" style="width:100%;">
<img class="carousal-image" src="#=
getPreviewImageUrl(data[i].Type,data[i].PreviewImageUrl) #"/>
</div>
# } #
</script>
<script>
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "sample api",
dataType: "json"
}
},
pageSize:1,
schema: {
data: "items"
},
});
$("#scrollView").kendoScrollView({
dataSource: dataSource,
template: $("#scrollview-template").html(),
contentHeight: "100%"
});
</script>
Sample josn data
{
"items": [
{
"PreviewImageUrl": "/images/ui/Default_News.png",
"Type": "NewsType"
},
{
"PreviewImageUrl": "/images/ui/Default_Blog.png",
"Type": "BlogType"
}
],
"total": 2
}
When the pageSize is greater than one, the data passed to the template is a javascript array, but when it equals one, data refers to the JSON object itself. Hence your template needs to be more like this:
<script id="scrollview-template" type="text/x-kendo-template">
# if (data != null) { #
<div data-role="page" style="width:100%;">
<img class="carousal-image"
src="#= getPreviewImageUrl(data.Type,data.PreviewImageUrl) #"/>
</div>
# } #
</script>
Working demo here. Hope this helps.
Related
I'm confused as how to correctly use vueDraggable together with Laravel.
I can drag and sort the elements in the browser but the array is not changing (when I check in the console)/ it seems to me the changes aren't reflected in the array. Shouldn't the array index numbers change after moving items?
In the overview.blade.php I have the component:
<qm-draggable :list="{{ $mylaravelarray }}"></qm-draggable>
In the qm-draggable.vue I have:
<template>
<draggable group="fragenblatt" #start="drag=true" #end="endDrag" handle=".handle">
<li v-for="(item, index) in draggablearray" :key="item.index">
// list items here
</li>
</draggable>
</template>
<script>
data() {
return {
draggablearray:{},
};
},
props: {
list: Array,
},
mounted: function(){
this.draggablearray = this.list; // create a new array so I don't alter the prop directly.
},
[..]
</script>
In the documentation it says, one way to pass the array is:
value
Type: Array
Required: false
Default: null
Input array to draggable component. Typically same array as referenced by inner element v-for directive.
This is the preferred way to use Vue.draggable as it is compatible with Vuex.
It should not be used directly but only though the v-model directive:
<draggable v-model="myArray">
But where do I do that? in overview.blade.php or in the component (.vue), or both?
Try setting v-model on your draggable as that's what will update draggablearray.
Also if draggablearray is supposed to be an array, initialise it as one, so draggablearray:{} should be draggablearray:[].
new Vue({
el: '#app',
data: () => {
return {
drag: false,
draggablearray: [{
id: 1,
name: "1"
}, {
id: 2,
name: "2"
}, {
id: 3,
name: "3"
}]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js">
</script>
<script src="https://cdn.jsdelivr.net/npm/sortablejs#1.7.0/Sortable.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.16.0/vuedraggable.min.js"></script>
<div class="container">
<div id="app">
<draggable v-model="draggablearray" group="fragenblatt">
<li v-for="(item, index) in draggablearray">
{{item.name}}
</li>
</draggable>
{{draggablearray}}
</div>
</div>
<script type="text/x-template" id="tree-menu">
<div class="tree-menu">
<div class="label-wrapper">
<div :style="indent" :class="labelClasses" #click.stop="toggleChildren">
<i v-if="nodes" class="fa" :class="iconClasses"></i>
<input type="checkbox" :checked="selected" #input="tickChildren" #click.stop /> {{label}}
</div>
</div>
<draggable v-model="nodes" :options="{group:{ name:'g1'}}">
<tree-menu v-if="showChildren" v-for="node in nodes" :nodes="node.nodes" :label="node.label" :depth="depth + 1" :selected="node.selected" :key="node">
</tree-menu>
</draggable>
</div>
</script>
Ah, I solved it, now I get the altered array back, I achieved it with this:
Had to add v-model="draggablearray" in the component .vue file
Needed to change my 'draggablearray' in data to an Array, instead of
object.
It looks like this now:
In the overview.blade.php I have the component:
<qm-draggable :list="{{ $mylaravelarray }}"></qm-draggable>
In the qm-draggable.vue I have:
<template>
<draggable v-model="draggablearray" group="fragenblatt" #start="drag=true" #end="endDrag" handle=".handle">
<li v-for="(item, index) in draggablearray" :key="item.index">
// list items here
</li>
</draggable>
</template>
<script>
data() {
return {
draggablearray:[], //has to be an Array, was '{}' before
};
},
props: {
list: Array,
},
mounted: function(){
this.draggablearray = this.list; // create a new array so I don't alter the prop directly.
},
[..]
</script>
As you see in picture: https://imgur.com/kDBu95D column that has 0 data is higher than column with value of 1 and 2. And y axis starting reverse, 0 is on the top instead on bottom. This happened when I use laravel eloquent.
Here is my code:
#extends('layouts.app')
#section('content')
<div class="container">
<script type="text/javascript">
google.charts.load('current', {'packages':['bar']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['User', 'Added'],
#if ($users)
#foreach ($users as $user)
['{{$user->name}}', '{{$user->members->count()}}'],
#endforeach
#endif
]);
var options = {
chart: {
title: 'Users',
},
vAxis: {
format: 'decimal',
},
};
var chart = new google.charts.Bar(document.getElementById('columnchart_material'));
chart.draw(data, google.charts.Bar.convertOptions(options));
}
</script>
<div id="columnchart_material" style="width: 'auto'; height: 500px;"></div>
</div>
#endsection
I tried to add this:
vAxis: { minValue: 0 },
and this:
vAxis: { direction: -1, },
but nothing helps...
looks like the values for the y-axis are strings instead of numbers...
remove the single quotes from the second array value...
change --> ['{{$user->name}}', '{{$user->members->count()}}'],
to --> ['{{$user->name}}', {{$user->members->count()}}],
Trying to refresh the datasource of multiple kendo treeview controls dynamically by updating the view model. Parent nodes are rendered but child nodes wont show.
HTML:
<div id="trees-vm">
<h1>Trees</h1>
<ul data-template="tree" data-bind="source: treesData"></ul>
</div>
<script id="tree" type="text/x-kendo-template">
<li>
<h2 data-bind="text: treeName"></h2>
<div data-role="treeview" data-bind="source: treeData"></div>
</li>
</script>
JS:
var viewModel = kendo.observable({
treesData:[],
setSource:function(){
var trees = [];
for (i = 1; i < 11; i++) {
var tree = {};
tree.treeName = 'Tree ' + i;
tree.treeData = [{ text: "Furniture", items: [
{ text: "Tables & Chairs" },
{ text: "Sofas" },
{ text: "Occasional Furniture" }
]},
{ text: "Decor", items: [
{ text: "Bed Linen" },
{ text: "Curtains & Blinds" },
{ text: "Carpets" }]
}];
trees.push(tree);
}
this.set('treesData', trees);
}
});
kendo.bind($("#trees-vm"), viewModel);
viewModel.setSource();
example: https://jsfiddle.net/63hc9qdd/
Does someone know why this doesn't work?
Telerik support has provided an explanation/solution:
It seems that there is a problem when the DataSource for the Kendo UI TreeView is nested in each object the ul template is bound to. In this http://dojo.telerik.com/ikulA example the treeViewData is a hash object that holds the DataSource for the Kendo UI TreeView.
<html>
<head>
<title>Nested Treeview with Hash OBject and templates</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.607/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.607/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.607/styles/kendo.default.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.607/styles/kendo.mobile.all.min.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.607/js/angular.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.607/js/jszip.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.607/js/kendo.all.min.js"></script>
</head>
<body>
<div id="trees-vm">
<h1>Trees</h1>
<ul data-template="tree" data-bind="source: treesData"></ul>
</div>
<script id="tree" type="text/x-kendo-template">
<li>
<h2 data-bind="text: treeName"></h2>
<div data-role="treeview" data-bind="source: treeViewData['#=treeName#']"></div>
</li>
</script>
<script>
var viewModel = kendo.observable({
treesData:[],
treeViewData: {},
setSource:function(){
var trees = [];
for (i = 1; i < 5; i++) {
var tree = {};
tree.treeName = 'Tree' + i;
this.treeViewData[tree.treeName] = [
{ text: "Furniture", items: [
{ text: "Tables & Chairs", hasChildren: false },
{ text: "Sofas", hasChildren: false},
{ text: "Occasional Furniture", hasChildren: false }
] },
{ text: "Decor", items: [
{ text: "Bed Linen", hasChildren: false },
{ text: "Curtains & Blinds", hasChildren: false },
{ text: "Carpets", hasChildren: false }
] }
];
trees.push(tree);
}
this.set('treesData', trees);
}
});
kendo.bind($("#trees-vm"), viewModel);
viewModel.setSource();
</script>
</body>
</html>
Current code is sorting and filtering data using vue.js. It is working fine but data is dummy, it is hardcoded. I need to get data dynamically from table using vue js and laravel. How can I get dynamic data in gridData?
JS
Vue.component('demo-grid', {
template: '#grid-template',
props: {
data: Array,
columns: Array,
filterKey: String
},
data: function () {
var sortOrders = {}
this.columns.forEach(function (key) {
sortOrders[key] = 1
})
return {
sortKey: '',
sortOrders: sortOrders
}
},
methods: {
sortBy: function (key) {
this.sortKey = key
this.sortOrders[key] = this.sortOrders[key] * -1
}
}
})
// bootstrap the demo
var demo = new Vue({
el: '#app',
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 }
]
}
})
laravel.blade.php
#extends('layouts.app')
#section('title', 'Customers List')
#section('styles')
#endsection
#section('content')
<div class="container">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="panel panel-default">
<div class="panel-heading">Customers List</div>
<div class="panel-body">
<script type="text/x-template" id="grid-template">
<table class="table table-hover table-bordered">
<thead>
<tr>
<th v-for="key in columns" #click="sortBy(key)" :class="{active: sortKey == key}">#{{key | capitalize}}<span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'"></span>
</th>
</tr>
</thead>
<tbody>
<tr v-for="entry in data | filterBy filterKey | orderBy sortKey sortOrders[sortKey]">
<td v-for="key in columns">
#{{entry[key]}}
</td>
</tr>
</tbody>
</table>
</script>
<div id="app">
<form id="search">
Search <input name="query" v-model="searchQuery">
</form>
<demo-grid :data="gridData" :columns="gridColumns" :filter-key="searchQuery"></demo-grid>
</div>
</div>
</div>
</div>
</div>
</div>
#endsection
#section('scripts')
<script src="/js/vue.js"></script>
<script src="/js/vue-resource.min.js"></script>
<script src="/js/customers.js"></script>
#endsection
You will need to do a few things.
First, in Laravel, create a new route in your routes.php file, for ex.:
Route::get('/api/fighters', 'SomeController#index');
Then in your controller (somecontroller.php), you will have a method index which will query your database table and return it as JSON data.
public function index() {
//query your database any way you like. ex:
$fighters = Fighter::all();
//assuming here that $fighters will be a collection or an array of fighters with their names and power
//when you just return this, Laravel will automatically send it out as JSON.
return $fighters;
}
Now, in Vue, your can call this route and grab the data. Using AJAX. You can use any AJAX library that you like, even jQuery. I currently use Superagent.js. Vue will work just fine with any.
So, in your Vue code, create a new method to get your data.:
methods: {
getDataFromLaravel: function() {
//assign `this` to a new variable. we will use it to access vue's data properties and methods inside our ajax callback
var self = this;
//build your ajax call here. for example with superagent.js
request.get('/api/fighters')
.end(function(err,response) {
if (response.ok) {
self.gridData = response.body;
}
else {
alert('Oh no! We have a problem!');
}
}
}
}
Then you can just call this new method using a button or anyway you like. For example, using a button click event:
<button type="button" #click="getDataFromLaravel">Get Data</button>
Or you can even just have the data loaded automatically using Vue's ready function:
// bootstrap the demo
var demo = new Vue({
el: '#app',
data: {
.... }
ready: function () {
this.getDataFromLaravel();
},
methods: {
.... }
});
Done! You now have your database data assigned to Vue's data property gridData.
I need help using a Kendo UI list view which lives within a grid row detail template.
here is something I have done so far.
<div id="grid">
</div>
<script type="text/x-kendo-template" id="gridDetailTemplate">
<div class='grid-edit'>
<div class='edit-list'></div>
</div>
</script>
<script type="text/x-kendo-template" id="editItemtemplate">
<div class='edit-Item'>
#if(Type=='string'){#
<ul><li><b>#:Name#</b></li><li><input class='inputString' value='#:DataVal()#'/></li></ul>
#}else if(Type=='number'){#
<ul><li><b>#:Name#</b></li><li><input class='inputNumber' data-role='numerictextbox' data-type='number' value='#:DataVal()#'/></li></ul>
#}else if(Type=='date'){#
<ul><li><b>#:Name#</b></li><li><input class='inputDate' data-role='datepicker' value='#:kendo.toString(DataVal(),'MM/dd/yyyy')#'/></li></ul>
#}else if(Type=='boolean'){Name #<input type='checkbox'/>
#}#
</div>
</script>
<script type="text/javascript">
$(document).ready(function () {
$.get("http://localhost:4916/DataAttribute", function (data, status) {
var selFields = new Object();
$.each(data, function (index, elem) {
selFields[elem.Name] = new Object();
selFields[elem.Name]["type"] = elem.Type;
});
$("#grid").kendoGrid({
dataSource: {
type: "json",
transport: {
read: { url: "http://localhost:4916/Deal",
dataType: "json"
}
},
schema: {
data: "Data", total: "Total",
model: {
fields: selFields
}
}
},
height: 430,
filterable: true,
sortable: true,
pageable: false,
detailTemplate: kendo.template($("#gridDetailTemplate").html()),
detailInit: detailInit,
columns: [{
field: "SecurityName",
title: "Security Name",
width: 250
},
{
field: "DateOfAcquisition",
title: "Date Of Acquisition",
width: 120,
format: "{0:MM/dd/yyyy}"
}, {
field: "Acres",
title: "Acres",
width: 120
}
]
});
});
});
function detailInit(e) {
$.get("http://localhost:4916/DataAttribute", function (data, status) {
var detailRow = e.detailRow;
detailRow.find(".edit-list").kendoListView({
dataSource: {
data: data,
schema: {
model: {
DataVal: function () {
switch (this.get("Type")) {
case "number"
}
if (e.data[this.get("Name")])
return e.data[this.get("Name")];
else
return '';
}
}
}
},
template: kendo.template($("#editItemtemplate").html())
});
});
}
</script>
My code gets dynamic field list and binds it to the data source for grid.
Then, in the detailInit event, I find the div within row detail and convert it into kendo UI list, for which the template have been created.
Now, when I use data-bind="value: DataVal()" ,it doesn't pick up the values of List data source. It works the way I have done i.e. value="#: DataVal() #". But, data-role does not convert the fields to specified types which are datepicker and numericinput in my case.
I believe that data-role not being used is caused due to same issue as data-bind not being read.
Can anyone help me out with this? Also, feel free to suggest any alternate ways and general code improvements. I am an ASP.NET developer and usually don't work on pure html and javascript.
PS: I would be happy to provide the context on what I am trying to achieve here if anyone is interested.
Thanks in advance.
If you can rig up a jsFiddle or jsBin example that would help debug the issue.
However, try removing the parenthesis:
data-bind="value: DataVal"
Kendo should detect that DataVal is a function and call it on its own.
I experienced a similar situation in a listview template. I created a JSFiddle to demonstrate:
http://jsfiddle.net/zacharydl/7L3SL/
Oddly, the solution is to wrap the contents of the template in a div. It looks like your template already has this, so YMMV.
<div id="example">
<div data-role="listview" data-template="template" data-bind="source: array"></div>
</div>
<script type="text/x-kendo-template" id="template">
<!--<div>-->
<div>method 1: #:field#</div>
<div>method 2: <span data-bind="text: field"></span></div>
<input data-role="datepicker" />
<!--</div>-->
</script>
var model = kendo.observable({
array: [
{ field: 'A'},
{ field: 'B'}
]
});
kendo.bind($('#example'), model);