kendo angular menu without typescript - javascript

How I can use the kendo menu without typescript?
html
<kendo-menu [items]="menuItems" [vertical]="true" style="display:inline-block;" (select)="onMenuSelected($event)"></kendo-menu>
TS
menuItems: any[] = [
// {
// text: "Rename",
// },
{
text: "Delete",
},
{
text: "Copy",
},
];
I want to use only html to use of menu

Technically, you can enter the data in the template itself, like this:
<kendo-menu [items]="
[{
text: 'Rename'
},
{
text: 'Delete'
},
{
text: 'Copy'
}]">
</kendo-menu>
Now, while it is possible, it's not good practice. Even if the menu, in this case, is static and simple, it's better to have a const on the component containing the menu entries, or perhaps in a dedicated file if you have many such constants which you in several places.

Related

Vuetify Data-Table Header array not accepting empty child associations

I have a data-table using Vuetify that passes a localAuthority prop from a rails backend. It all works really well until I pass an empty child association (nested attribute). In this case 'county':
<script>
import axios from "axios";
export default {
name: 'LocalAuthorityIndex',
props: {
localAuthorities: {type: Array, default: () => []},
counties: {type: Array, default: () => []},
localAuthorityTypes: {type: Array, default: () => []}
},
data() {
return{
search: '',
dialog: false,
testmh: 'hello',
dialogDelete: false,
headers: [
{ text: 'Name', align: 'start', value: 'name' },
{ text: 'ONS Code', value: 'ons_code' },
{ text: 'ID', value: 'id' },
{ text: 'Population', value: 'population' },
{ text: 'county', value: 'county.name' },
{ text: 'Website', value: 'website' },
{ text: 'Actions', value: 'actions', sortable: false },
],
So in the example above it works as long as all records have a county association (belongs_to). However, if one record does not have a 'county' associated with it then I get the following error:
[Vue warn]: Error in render: "TypeError: Cannot read properties of undefined (reading 'name')"
I have tried lots of things like adding in a conditional statement like below:
{ text: 'county', value: ('county.name' ? 'county.name' : nil )},
But nothing seems to work.
According to your <v-data-table> code at Codepen, I see that you are overriding default table item slots with your own.
Your error are from this part of code:
...
<template #item.county.name="{ item }">
<a :href="'/counties/' + item.county_id">
{{ item.county.name }}
</a>
</template>
...
Take a look at first string. #item.county.name is a short form of v-slot:item.county.name and comes from one of your strings in headers array:
...
{ text: 'county', value: 'county.name' },
So there's no error, this part are correctly parsed by vuetify library even when your item will not contain any county.
The error is in 3rd string of the above code. You are trying to print name of county without checking its existence. That's why you are getting ...Cannot read properties of undefined... error.
I guess you may fix your issue this way:
<template #item.county.name="{ item }">
<a :href="'/counties/' + item.county_id">
{{ item.county ? item.county.name : 'No name' }}
</a>
</template>
Of course, if you need to hide your link to counties in this case, you may also add v-if (or v-show) into a tag.
I also created a small Codepen with some static data. Take a look into item.name.text slot in this playground, maybe it will help you to understand similar object associations.

how to render a specific field dynamically in Material Table React

HI I am using Material Table of React, what I want to do is generate a label tag for every cell, what I did is:
<Table
onChangePage={handleChangePage}
page={props.currentPage}
totalCount={props.totalCount}
options={{
paging:true,
pageSizeOptions:[10, 15, 25, 50],
pageSize: props.rowsPerPage,
padding: "dense",
search: false,
toolbar:false
}}
columns={columns.map((tableColumn) =>{
return{
...tableColumn,
render: (rowData:VulnerabilityData) =>
(<label>
{rowData[tableColumn.field]}. <---- error 'undefined'
</label>)
}
})}
data={vulnerabilityDataAct}
/>
In order to get the specific field, I passed in the tableColumn.field in the render,
but I got the error
TS2538: Type 'undefined' cannot be used as an index type.
I think tableColumn.field is not allowed here, so how do I dynamically pass the tableColumn field and used as an index to render the value???
Edit:
columns variables in above code:
const columns: TableColumn<VulnerabilityData>[] = [
{
title: 'Due Date',
field: 'remediation_due_date',
},
{
title: 'Application',
field: 'primaryApplication'
},
{
title: 'Impact',
field: 'consequence'
},
{
title: 'Mitigation',
field: 'solution'
},
{
title: 'CVE Description',
field: 'cve_urls'
},
{
title: 'Vulnerability Fix',
field: 'vendor_urls'
}
// and other 100 columns
];
and the definition of VulnerabilityData
export interface VulnerabilityData {
primaryApplication: string;
networkEnvironment: string;
remediation_due_date: string,
// ... other fields
}
The First thing is that you don't have to specify index numbers in the custom column rendering. In custom column rendering Material table provides single rowData for that specific talbe field. This means you're not required to specify index number Just use the rowData.FieldName. You can do it as follows
columns={[
{ title: "Any Title", render: rowData => rowData.FieldYouWantToDisplay },
]}
Taking a shot at this. It looks like the error you are seeing here may be a typescript compiler error.
See this post: Type 'undefined' cannot be used as index type
If it is a compiler error, you may fix it by explicitly defining the type of tableColumns in your map function. This type could be {field: string}, in order to let the typescript compiler know that tableColumn.Field will not be undefined.
You could also tackle this by setting a type on columns field before it is mapped.
Or you could also use rowData[tableColumns.field!], as in the SO link.
I hope this solves your problem!

Vue-tables-2 detecting which filter was applied

I am trying to set up a basic server side vue-tables-2 with two filters - one is a dropdown and the other is a search field. I am having trouble detecting which of the two filters were applied within the requestFunction() so I can send a request over to the server. Currently, I am just trying to console log the input filter name and value as the filter is applied / input is changed.
JSFiddle:
https://jsfiddle.net/kbpq5vb3/39/
HTML
<h1 class="vue-title">Vue Tables 2 Demo</h1>
<div id="app">
<v-server-table url="https://jsonplaceholder.typicode.com/users" :columns="columns" :options="options"></v-server-table>
</div>
VueTable:
Vue.use(VueTables.ServerTable);
new Vue({
el: "#people",
data: {
columns: ['name', 'username'],
options: {
requestAdapter(data) {
console.log(data.query); // detect which filter was applied / which input changed
},
responseAdapter(resp) {
return {
data: resp,
count: resp.length
}
},
filterByColumn: true,
filterable: ['name', 'username'],
listColumns: {
name: [{
id: 'ervin',
text: 'Ervin'
}, {
id: 'chelsey',
text: 'Chelsey'
}]
}
}
}
});
According to the vue-tables-2 documentation:
vue-tables.filter/tableName/FILTER fires off when a filter is changed.
After looking a bit deeper, it really is as easy as listening for an event:
Vue developer tools really make this type of stuff easy to diagnose. Now, you'd want to listen to the custom event. You can learn how to do that over on the Vue documentation.
Finally, here is a working fiddle that shows how you listen to these events: https://jsfiddle.net/kbpq5vb3/55/
Hope this helps!

Using ExpressionProperties to access different model templateOptions

Firstly I would like to say Angular Formly is a fantastic library for novices such as myself. I am not a web developer, however find this library to be intuitive and powerful.
However I do need assistance with use of Expression Properties.
I have a model library which contains library items, for example:
{
"itemId":"STX001",
"title":"Grey Wolf",
"category":"White", etc.
}
{
"itemId":"STX002",
"title":"Noble Black",
"category":"Black", etc.
}
etc.
I also have a formly form which uses ui-select in top field to lookup all values from Library, select one of these (I will call this Item), and then populate remaining fields in the form with Items properties, then submit form to Catalogue model.
The problem I am facing is I cannot reference the properties of Item from within other fields. I have tried using expressionProperties but can only extract the valueProp value (which is uniqueID), however I am after Item.title, Item.category, etc.
Code below:
{
//This is form fields for creating a new Catalogue entry
key: 'libraryId',
type: 'ui-select',
templateOptions: {
label: gettextCatalog.getString('Search Library'),
options: [],
valueProp: 'itemId',
itemTitle: 'title',
itemCategory: 'category',
labelProp: 'title',
focus: true,
placeholder: 'Start typing keywords..'
},
controller: function ($scope) {
getLibrary().then(function(data){
$scope.options.templateOptions.options = data;
return data;
});
}
}
{
key: 'title',
type: 'input',
templateOptions: {
label: gettextCatalog.getString('Name'),
required: true
},
expressionProperties : {
//This is what i'm trying to achieve but doesn't work
'templateOptions.placeholder' : 'model.libraryId.itemTitle'
}
},
Use the call back function provided
expressionPropertyObj = {
'templateOptions.required': (model, formState: any, field: FormlyFieldConfig) => {
console.log('model',model);
console.log('state',formState);
console.log('field',field);
},

ExtJS: share store between grid and chart

I'm writing a simple application storing and displaying timestamped messages. Messages are JSON objects containing, say 2 main fields like:
{
"emitted": "2011-12-08 12:00:00",
"message": "This is message #666"
}
I have a model to describe these messages:
Ext.define('Message', {
extend: 'Ext.data.Model',
fields: [
{ name: 'emitted', type: 'date' },
{ name: 'message', type: 'string' }
]
});
I have no problem displaying these messages in a grid. However, i would now like to display these messages in a chart. For instance, I would be able to grab numbers (like the #666 in the above example) and display a line chart.
Ideally, i don't want to create a new store for the chart, i would like to reuse the same message store, but apply a filter on the fields to grab the proper value. I don't know, something that might look like:
var chart = {
xtype: 'chart',
...
series: [{
type: 'line',
axis: ['left', 'bottom'],
xField: 'emitted',
yField: {fieldName:'message', fieldGrabber: function(v) {
new RegExp("This is message #(\d+)$", "g").exec(v)[1]
}}
}]
};
Does this kind of thing is possible in ExtJS ?
I just tried to explain what I'm trying to do, i have no idea where to find such a feature: in the chart class, in the store class, or using a kind pf proxy to the store.
Side note:
I cannot ask the data to be properly formatted to the server. The messages I receive are not backed up anywhere, they are just live events streamed to the client via socketIO.
Any advices greatly appreciated!
You should extract the value inside you model to a separate field:
Ext.define('Message', {
extend: 'Ext.data.Model',
fields: [
{ name: 'emitted', type: 'date' },
{ name: 'message', type: 'string' },
{ name: 'nr', convert: function(v, r){
return r.get('message').replace(/^.*#/, '');
} }
]
});
Or you might be better off just having the 'nr' field and using a renderer in Grid that displays it as "This is message #{nr}".
Then you can use the 'nr' field directly in you chart.
I switched to Highcharts and threw ExtJS out to the trash :P

Categories