Kendo template and field data not exist - kendo-ui

I have this sample :
<ul id="users"></ul>
<script type="text/x-kendo-template" id="myTemplate">
#if(isAdmin){#
<li>#: name # is Admin</li>
#}else{#
<li>#: name # is User</li>
#}#
</script>
<script type="text/javascript">
var templateContent = $("#myTemplate").html();
var template = kendo.template(templateContent);
//Create some dummy data
var data = [
{ name: "John", isAdmin: false },
{ name: "Alex", isAdmin: true }
];
var result = kendo.render(template, data); //render the template
$("#users").html(result); //append the result to the page
</script>
I would like to know if it possible to have a data which not exists and test with a function but apparently, it doesn't work ....
var data = [
{ isAdmin: false },
{ isAdmin: true }
];
Do you have a idea ?
Thanks for your help

In order to ensure there are no issues when using x-kendo-template, ensure to validate the data provided to the template.
For example if you provide:
var data = [
{ name: "John" },
{ name: "Alex", isAdmin: true }
];
To the template, you can modify the template to check like following:
<script type="text/x-kendo-template" id="myTemplate">
#if(typeof(isAdmin) != "undefined" && isAdmin != null){#
#if(isAdmin && name.length > 0){#
<li>#: name # is Admin</li>
#}else if(name.length > 0){#
<li>#: name # is User</li>
#} else {#
<li>No name provided</li>
#}#
#}#
</script>
Dojo example to demonstrate this.

Related

How do clear the search value after deleting the associated filter and to avoid the clearing of all filters after clearing the search value?

How do clear the search value after deleting the associated filter?
For example. I added filter: {gender: 'female'}. After this type in the search Mar.
After this clear filter in column name.
I want to clear the search value. For this, I listen to the event of the filter. And if the value of the filter is equal to the search value then clear this.
Maybe exists a more better approach.
How to avoid clear all filters after the clearing search value?
const dataSource = kendo.data.DataSource.create({
data: [{
name: 'Harry',
gender: 'male'
},
{
name: 'Marry',
gender: 'female'
},
{
name: 'Lora',
gender: 'female'
}
]
});
const gridConfig = {
toolbar: [
'search'
],
search: {
fields: ['name']
},
filterable: true,
dataSource: dataSource,
columns: [{
field: 'name'
}, {
field: 'gender'
}]
};
$('#grid').kendoGrid(gridConfig);
$('#grid').data('kendoGrid').bind('filter', onFilter);
const searchElement = $('#grid input.k-input');
function onFilter(e) {
const searchValue = searchElement.val();
if (e.filter) {
const isExistsFilter = e.filter.filters.some(filter => {
return gridConfig.search.fields.some(field => {
return filter.field === field && filter.value === searchValue;
});
});
if (!isExistsFilter && searchValue) {
searchElement.val('');
}
} else {
searchElement.val('');
}
}
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.3.1021/styles/kendo.common.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.3.1021/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.3.1021/styles/kendo.default.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.3.1021/styles/kendo.mobile.all.min.css">
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.3.1021/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.3.1021/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.3.1021/js/kendo.all.min.js"></script>
<div id="grid"></div>

How to display data on blade from Vue Js?

I had grabbed some code for test purpose, I have tried to fixing "item not define" error but I am stuck.
//Blade View
<v-app id="app" v-cloak><div class="card" :posts="{{$posts}}"></div></v-app>
//Vuejs template
<table striped hover :items="imageList"> <img :scr="'/storage/image/'+data.items.image"></table>
Vue Js:
<script>
export default {
// name: "ExampleComponent",
props: \['posts'\],
data() {
return {
imageList: \[\]
};
},
mounted() {
const fetch = this.fetch_image_list();
},
methods: {
fetch_image_list() {
let items = \[\];
if (Array.isArray(this.posts.data) && this.posts.length.data) {
this.posts.data.forEach((post, key) => {
let currentImage = {
id: post.id,
name: post.name,
image: post.img
};
items.push(currentImage);
});
this.imageList = items;
}
}
}
};
</script>]
item is not define
Isn't it because you are "calling" :
data.items.image instead of items[index].image ?

Vue.js component conflict in laravel blade view

I have 2 of the same components in my laravel blade view, but they are conflicting.
What i'm trying to accomplish:
I've made a vue component that uploads a file to firebase and stores it in my database. In my blade view i have 2 places where i want to use this component. I configure the component with props so the component knows where to store the file.
What going wrong:
Every time i try to upload a file with the second component, i fire the function in the first component. How do i fix that the components can't conflict?
My laravel balde view:
component 1
<uploadfile
:key="comp100"
:user_data="{{ Auth::user()->toJson() }}"
store_path="/users/{{ Auth::user()->username }}/settings/email_backgrounds"
:store_route="'settings.project_email'"
:size="1000"
fillmode="cover"
></uploadfile>
component 2
<uploadfile
:key="comp200"
:user_data="{{ Auth::user()->toJson() }}"
store_path="/users/{{ Auth::user()->username }}/settings/email_backgrounds"
:store_route="'settings.project_email'"
:size="1000"
fillmode="cover"
></uploadfile>
The Vue component:
<template>
<div class="vue-wrapper">
<FlashMessage position="right top"></FlashMessage>
<div v-if="loading" class="lds-dual-ring"></div>
<div class="field">
<div class="control">
<label class="button main-button action-button m-t-20" for="uploadFiles"><span style="background-image: url('/images/icons/upload.svg')"></span>Kies bestand</label>
<input type="file" name="uploadFiles" id="uploadFiles" class="dropinput" #change="selectFile">
</div>
</div>
</div>
</template>
<script>
import { fb } from '../../firebase.js';
export default {
data() {
return {
fileObject: {
filePath: null,
url: null,
file: null,
resizedPath: null
},
loading: false
};
},
mounted() {
console.log(this.size)
console.log(this.fillmode)
},
props: [
'user_data',
'store_path',
'store_route',
'size',
'fillmode'
],
methods: {
selectFile(event)
{
var file = event.target.files[0];
this.fileObject.file = file
this.fileObject.filePath = this.store_path + '/' + file.name
this.fileObject.resizedPath = this.store_path + '/resized-' + file.name
if(file.type == 'image/png' || file.type == 'image/jpeg')
{
this.uploadFile(this.fileObject)
} else {
this.flashMessage.success({
title: 'Oeps!',
message: 'De afbeelding moet een png of een jpeg zijn!',
blockClass: 'success-message'
});
}
},
uploadFile(fileObject)
{
var vm = this
console.log(fileObject)
var storageRef = fb.storage().ref(fileObject.filePath)
var uploadTask = storageRef.put(fileObject.file)
this.loading = true
uploadTask.on('state_changed', function(snapshot){
var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
},function(error) {
}, function() {
var resizeImage = fb.functions().httpsCallable('resizeImage')
resizeImage({filePath: fileObject.filePath, contentType: fileObject.file.type, watermark: false, size: vm.size, fit: vm.fillmode}).then(function(result){
var downloadRef = fb.storage().ref(fileObject.resizedPath);
downloadRef.getDownloadURL().then(function(url){
fileObject.url = url
vm.loading = false
vm.storeImage(fileObject)
}).catch(function(error){
console.log(error)
})
}).catch(function(error){
});
});
},
storeImage(file)
{
axios.post('/api/app/store_file', {
api_token: this.user_data.api_token,
user: this.user_data,
file: file,
storeRoute: this.store_route
}).then((res) => {
location.reload()
}).catch((e) => {
});
}
}
}
</script>
Does someone know how to fix this?

Kendo UI Grid - Call Function in Column Template

I have a Kendo Grid where I bind it dynamically to a JSON object.
In the generateColumns function, I want to call the getKendoColor function. However, I need to pass the column cell value. In the code below I forced in 'RED' to show how it should work.
How do I pass in the column value to this getKendoColor function?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.3.913/styles/kendo.common.min.css"/>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.3.913/styles/kendo.rtl.min.css"/>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.3.913/styles/kendo.silver.min.css"/>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.3.913/styles/kendo.mobile.all.min.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2017.3.913/js/kendo.all.min.js"></script>
</head>
<body>
<div id="grid" style="width:1000px;"></div>
<script>
var isDateField =[];
var isTaskField =[];
$.ajax({
url: "http://www.mocky.io/v2/59c4dd1e4000005400b25ba7",
dataType: "jsonp",
success: function(result) {
generateGrid(result);
}
});
function generateGrid(response) {
var model = generateModel(response);
var columns = generateColumns(response);
var grid = $("#grid").kendoGrid({
dataSource: {
transport:{
read: function(options){
options.success(response.Table);
}
},
pageSize: 5,
schema: {
model: model
}
},
columns: columns,
pageable: true,
editable:false
});
}
function generateColumns(response) {
var columnNames = response["columns"];
return columnNames.map(function (name) {
if (isTaskField[name]) {
return { field: name, template: '#= getKendoColor("RED") #', format: (isDateField[name] ? "{0:D}" : "") };
}
else
return { field: name, format: (isDateField[name] ? "{0:D}" : "") };
})
}
function generateModel(response) {
var sampleDataItem = response["Table"][0];
var model = {};
var fields = {};
for (var property in sampleDataItem) {
var itemValue = sampleDataItem[property];
if (property.indexOf("ID") !== -1) {
model["id"] = property;
}
var propType = typeof sampleDataItem[property];
if (propType === "number") {
fields[property] = {
type: "number",
validation: {
required: true
}
};
if (model.id === property) {
fields[property].editable = false;
fields[property].validation.required = false;
}
} else if (propType === "boolean") {
fields[property] = {
type: "boolean"
};
} else if (propType === "string") {
var parsedDate = kendo.parseDate(sampleDataItem[property]);
if (parsedDate) {
fields[property] = {
type: "date",
validation: {
required: true
}
};
isDateField[property] = true;
} else {
fields[property] = {
validation: {
required: true
}
};
if ((property !== "Entity") && (property !== "Period") && (property !== "Level"))
{
isTaskField[property] = true;
}
}
} else {
fields[property] = {
validation: {
required: true
}
};
}
}
model.fields = fields;
return model;
}
function getKendoColor(OverallStatus) {
OverallStatus = OverallStatus.toUpperCase();
//alert(OverallStatus);
var htmlRed = kendo.format('<div class="text-center"><div style="color:red"> <i class="fa fa-circle fa-lg"></i> </div> </div>');
var htmlGreen = kendo.format('<div class="text-center"><div style="color:green"> <i class="fa fa-circle fa-lg"></i> </div> </div>');
var htmlOrange = kendo.format('<div class="text-center"><div style="color:orange"> <i class="fa fa-circle fa-lg"></i> </div> </div>');
var htmlYellow = kendo.format('<div class="text-center"><div style="color:yellow"> <i class="fa fa-circle fa-lg"></i> </div> </div>');
switch (OverallStatus) {
case "RED":
return htmlRed;
case "GREEN":
return htmlGreen;
case "ORANGE":
return htmlOrange;
case "YELLOW":
return htmlYellow;
case "CREATED":
return htmlRed;
case "APPROVED":
return htmlGreen;
}
}
</script>
</body>
</html>
https://dojo.telerik.com/AgALaK/2
You can set the template itself as a function and in your case, a slight change to getKendoColor will do the trick:
function getColumnTemplate(dataItem) {
var OverallStatus = dataItem.OverallStatus.toUpperCase();
//All the rest of your getKendoColor function
return someHTML;
}
Then just use this function as the template.
return columnNames.map(function (name) {
if (isTaskField[name]) {
return { field: name, template: getColumnTemplate, format: (isDateField[name] ? "{0:D}" : "") };
}
else
return { field: name, format: (isDateField[name] ? "{0:D}" : "") };
})

Using dijit.filteringselect in a Spring MVC environment

I am trying to code two filteringselects which should both change according to data entered into any of the forms.
So data entered into fs1 should trigger changes in fs2.
Data entered into fs2 should trigger changes in fs1.
I am in a spring environment which in my case means that the dojo code is in a jsp file and the filtering select fields are populated through a Controller class on the server side using #ModelAttribute annotations to make the data available as a variable in the jsp file.
I have the relation data on the Java side so it's available through the controller.
Here is what confuses me at the moment.
I am new to DOJO and the documentation on the DOJO support site is a little hard to grasp for me. I would like to see a conceptual list of what is needed to accopmplish and connect the separate stores of my filteringselects.
When there is a change in one of the filteringselects, how do I inform the controllerclass of the changes and send the data that remains in the filteringselect?
This question could also be read as: how can I call a method with input parameters that hold the data available in the edited filteringselect?
I suggest we work on this in two incremental parts:
Get the first FilteringSelect's onChange event working
Wire them up to use server data stores
The following code sample takes a Dojo Campus' codependent FilteringSelect example and simplifies it so that its data stores are local. It shows how to programmatically instantiate two FilteringSelects with the second being dependent on the first by an onChange event handler.
Can you please try running it and let me know if you get it working?
Once we get your first FilteringSelect triggering filtering on the second, I will edit to add an explanation on how to convert them to use server side data stores.
<html>
<head>
<title>Test File</title>
<link type="text/css" rel="stylesheet" href="dijit/themes/tundra/tundra.css"/>
</head>
<body class="tundra">
<label for="state">State:</label>
<input id="state">
<label for="city">City:</label>
<input id="city">
<script type="text/javascript" src="dojo/dojo.js"
djConfig="isDebug: true, parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require("dijit.form.FilteringSelect");
dojo.require("dojo.data.ItemFileReadStore");
dojo.addOnLoad(function() {
var cityJson = {
label: 'name',
items: [{ name: 'Albany', state: 'NY' },
{ name: 'New York City', state: 'NY' },
{ name: 'Buffalo', state: 'NY' },
{ name: 'Austin', state: 'TX' },
{ name: 'Houston', state: 'TX' }]
};
var stateJson = {
identifier: 'abbreviation',
label: 'name',
items: [ { name: 'New York', abbreviation: 'NY' },
{ name: 'Texas', abbreviation: 'TX' } ]
};
new dijit.form.ComboBox({
store: new dojo.data.ItemFileReadStore({
data: cityJson
}),
autoComplete: true,
query: {
state: "*"
},
style: "width: 150px;",
required: true,
id: "city",
onChange: function(city) {
dijit.byId('state').attr('value', (dijit.byId('city').item || {
state: ''
}).state);
}
},
"city");
new dijit.form.FilteringSelect({
store: new dojo.data.ItemFileReadStore({
data: stateJson
}),
autoComplete: true,
style: "width: 150px;",
id: "state",
onChange: function(state) {
dijit.byId('city').query.state = state || "*";
}
},
"state");
});
</script>
</body>
</html>
in the namespace of the jsp:
xmlns:springform="http://www.springframework.org/tags/form"
sample form:
<springform:form action="#" >
<label for="country">Country:</label>
<springform:select id="country" path="country" items="${countryList}" itemLabel="country" itemValue="id"/>
<div id="citySelectDiv"></div>
</springform:form>
javascript code:
<script type="text/javascript">
<![CDATA[
dojo.require("dojo.parser");
dojo.require("dojo.data.ItemFileReadStore");
function countryChanged(dataFromServer){
//convert json to dojo filteringSelect options
var options = {
identifier: 'id',
label: 'city',
items: dataFromServer
};
var cityStore =new dojo.data.ItemFileReadStore({data : options});
// create Select widget, populating its options from the store
if (!dijit.byId("citySelectDiv")) {
//create city selction combo
new dijit.form.FilteringSelect({
name: "citySelectDiv",
store: cityStore,
searchAttr : "city",
}, "citySelectDiv");
}else{
//if already created the combo before
dijit.byId('citySelectDiv').set('value',null);
dijit.byId('citySelectDiv').store = cityStore;
}
}
Spring.addDecoration(new Spring.ElementDecoration({
elementId : "country",
widgetType : "dijit.form.FilteringSelect",
widgetAttrs : {
promptMessage: "Select a Country",
required : true,
onChange : function(){
var xhrArgs = {
url: "ajax/country/" +dijit.byId('country').get('value'),
handleAs: 'json',
load: function(dataFromServer) {
countryChanged(dataFromServer);
}
};
//make the ajax call
dojo.xhrGet(xhrArgs);
}
}
}));
Sample Controller method:
#ResponseBody
#RequestMapping("/ajax/country/{country}")
public List<City> clientSelection(#PathVariable("country") String country ) {
log.info("Country = {} ",country);
return cityService.findCitiesByCountry(country);
}

Resources