View single item inside kendo ui jquery scrollview - kendo-ui

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

VueDraggable and Laravel

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>

Google column chart y axis start reverse

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()}}],

Update Kendo Tree control datasource MVVM not showing child nodes

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>

Sorting and Filtering ajax data using Laravel and VueJs

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.

data-bind not working in List View template within Grid detail template

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);

Resources