Kendo UI grid dropdown and angular - angularjs

I try to setup custom dropdown in Kendo UI.
I have a reference to my issue.
http://dojo.telerik.com/aFIZa/13
My issue is that I do not know how I can setup the selected text in the template attribute? I want to show the text field but save the id as a value. And I do not want to use external datasource. I would like it as inline in the json.
The code is below:
$scope.mainGridOptions = {
dataSource: $scope.dataSource,
pageable: true,
height: 550,
toolbar: ["create"],
columns: [
{ field: "Category", title: "Category", width: "180px",
editor: function(container, options) {
var editor = $('<input kendo-drop-down-list required k-data-text-field="\'cat\'" k-data-value-field="\'id\'" k-data-source="{data:[{id: 1, cat: \'test\'}, {id: 2, cat: \'test2\'}]}" data-bind="value:Category"/>')
.appendTo(container);
$compile(editor)($scope);
editor.css("visibility", "visible");
}
, template:"selected text in the combo "
}
], editable: true
}

Ok, this was a tough one, but I think I could achieve what you want, or at least I got closer:
$scope.mainGridOptions =
{
dataSource: $scope.dataSource,
pageable: true,
height: 550,
toolbar: ["create"],
columns: [
{
field: "Category", title: "Category", width: "180px",
editor: function(container, options)
{
// #1
var editor = $('<input kendo-drop-down-list required k-data-text-field="\'cat\'" k-data-value-field="\'id\'" k-data-source="{data:[{id: 1, cat: \'test\'}, {id: 2, cat: \'test2\'}]}" data-bind="value:Category,events:{ change: onChange }"/>')
.appendTo(container);
$compile(editor)($scope);
editor.css("visibility", "visible");
},
// #2
template:kendo.template($("#column-template").html())
}],
editable: true,
// #3
edit: function(e)
{
var ko = kendo.observable(
{
onChange: function(e)
{
var el = $(e.sender.element);
var ddl = el.data("kendoDropDownList");
var ds = $scope.dataSource.getByUid(el.closest("tr").data("uid"));
ds.OptionText = ddl.text();
},
});
var widget = $(e.container).find("input");
kendo.bind(widget, ko);
}
}});
Demo.
In the code you can notice 3 changes:
data-bind="value:Category,events:{ change: onChange }" Look that I have added an events object in the bind, which I declare onChange as the change event handler. We'll talk about this in the 3rd item below;
For a complex template(with javascript code and logic) I created a script content and rendered it at the template property. The template is this:
<script id="column-template" type="text/x-kendo-template">
# if (data.hasOwnProperty('OptionText')) { #
#: OptionText #
# } else { #
#: "selected text in the combo" #
# } #
</script>
In the template I simply check for the property OptionText in the model(dataSource's current item) and: if it exists, use it; else, use the default text. We'll talk about OptionText in the 3rd item, below;
Now, here I have added an edit event to the grid. In that event I created an observable object, where I define the onChange function handler. In that function I seek for the current dataSource(ds) and I add text of the selected item in the dropdownlist in it, as the property OptionText, which I use in the template above explained.
I hope this explains how it works(in fact I hate working with those binders and observables, but sometimes they are needed).
Good luck.

Related

AngularJS TypeScript Kendo UI DropDownList - bug with default value selected

I have list of objects for items and everything works fine, but now I want to add default value selected, but I have issues with it.
Here's the HTML code for the drop-down:
<select kendo-drop-down-list
k-options="selectItems"
k-ng-model="selectedItem">
</select>
And in AngularJS (using TypeScript) I'm making the drop-down:
this.itemsToSelect = [{id: 1, name: "One"}, {id: 2, name: "Two"}];
this.selectItems = {
optionLabel: "Select items...",
dataTextField: "name",
dataValueField: "id",
dataSource: new kendo.data.DataSource({
transport: {
read: (options) => {
options.success(this.itemsToSelect);
}
}
}),
value: this.itemsToSelect[0]
};
I don't have default value selected with this.
I tried the code from their documentation and it works with items as strings, but with items as objects works when I say something like:
value: this.itemsToSelect[0].id
So, their code looks like this:
<script>
let items = [{id: 1, name: "one"}, {id: 2, name: "two"}];
$("#dropdownlist").kendoDropDownList({
dataTextField: "name",
dataValueField: "id",
dataSource: items,
value: items[1].id
});
</script>
I tried this in my code and it doesn't work.
Code doesn't have any errors. Any suggestions?
EDIT
What I can do is this:
this.selectedItem = this.itemsToSelect[0];
I've set k-ng-model in the HTML and I can just set the selected value like this.
But, is there a way to do it through value in this.selectItems object?
Make a local object representing your default value, like
{
id: 1,
name: "bob"
}
then on the control set autoBind to false.
https://docs.telerik.com/kendo-ui/api/javascript/ui/dropdownlist/configuration/autobind

Kendo grid export to excel header title shows html characters

When I export my grid to excel,headers are like: Product Name,{{'unitsOrder'| translate}} in excel. My grid supports 2 languages and I am showing it with angularjs translate way. Any offer?
<script>
$("#grid").kendoGrid({
toolbar: ["excel"],
excel: {
fileName: "Kendo UI Grid Export.xlsx"
},
dataSource: {
type: "odata",
transport: {
read: "http://demos.telerik.com/kendo-ui/service/Northwind.svc/Products"
},
pageSize: 7
},
sortable: true,
pageable: true,
columns: [
{ width: 300, field: "ProductName", title: "<b>Product Name</b>" },
{ field: "UnitsOnOrder", title: "{{'unitsOrder'| translate}}" },
{ field: "UnitsInStock", title: "Units In Stock" }
]
});
</script>
I had a similar problem but I use i18next translation instead of angular but maybe it helps you find a solution to your case:
I use the 'excelExport' event to manually update the generated worksheet. Within the worksheet object I search for the header cells and manually trigger the translation for the text it contains:
excelExport: function(e) {
// First I loop through all rows in the worksheet
e.workbook.sheets[0].rows.forEach(function(row){
// Ignore 'data' rows (only use 'header' and 'footer')
if(row.type != 'data'){
// Loop through all cells of the row
row.cells.forEach(function(cell){
// Here I overwrite the cell value with its translation
// You have to implement translate() so it works with angular
cell.value = translate(cell.value)
});
}
});
},
You now have to write your own translate function which can handle your angular translation. As I use i18next for translations my solution won't help here (I use jquery to generate a jquery html object on which I can trigger the translation)

Add filter condition to Dojo ComboBox

I have a dijit/form/ComboBox control that has a JsonStore as a object store.
// Prepare the datasource for combobox
settings.JsonStore = new JsonRestStore({ target: settings.dataUrl });
settings.ObjectStore = new ObjectStore({ objectStore: settings.JsonStore });
var ComboBox = new ComboBox({
id: settings.id,
name: settings.id,
value: settings.value,
style: {
width: settings.width.value + 'px',
display: (settings.visible) ? 'visible' : 'none'
},
maxHeight: settings.dropHeight.value,
store: settings.ObjectStore,
searchAttr: settings.comboValue,
labelType: "html",
labelFunc: function (item, store) {
var labelText = '....';
return labelText;
},
onChange: function (evt) {
}
}
When I try to query the combobox, the following http request are made:
http://<settings.dataUrl>/?<settings.comboValue>?A*
http://<settings.dataUrl>/?<settings.comboValue>?AB*
I would like to know if I can add a filter on the combobox based on the value of another control. Like for example:
http://<settings.dataUrl>/?CustomerNo=0001&<settings.comboValue>?AB*
I already tried the following, I tried to change the store of the combobox when the filter is changed by changing the url. But it does not work. I tried to reset the store by setting the store value again, and it causes error.
I am finally able to get the answer thru another question here.
Combobox.set( 'query', { 'CustomerNo' : dijit.byId('<Customer control ID>').getValue() } );
The query becomes:
http://<settings.dataUrl>/?CustomerNo=0001&<settings.comboValue>?AB*

Kendo UI Grid: is it supported to initialize grid with dataSource with empty data array?

I would like to know if the following approach is supported:
Define grid schema and columns and initialize with an empty array:
var dataSource = new kendo.data.DataSource({
data: [] // intentionally empty!
});
$("#grid").kendoGrid({
dataSource: dataSource,
schema: {
model: {
fields: {
arrive: {type: "number"},
depart: {type: "number"},
src: {type: "string"}
}
}
},
columns: [
{ field: "arrive", groupable: false, title: "arrive",width:88},
{ field: "depart", groupable: false, title: "depart",width:88},
{ field: "src", groupable: true, title: "src", width:44 }
]
etcetera
});
Then, after configuration/initialization, bind to the Change event:
var grid = $('#grid').data('kendoGrid');
grid.dataSource.bind("change", function (e) {
dataChanged();
});
function dataChanged() {
var grid = $("#grid").data("kendoGrid");
grid.refresh();
}
Then do this:
function populateDatasource(event, data) {
var grid = $('#grid').data('kendoGrid');
var parsedData = $.parseJSON(data);
grid.dataSource.data(parsedData);
}
which would trigger the changed event and refresh the grid. I am thinking that the observe pattern might have some trouble if the dataSource is initialized with an empty array.
I am not sure what you mean by observe pattern. But the grid can have an empty data source. Here is a demo: http://jsbin.com/izizut/1/edit
Your grid configuration is wrong. The schema setting is part of the data source configuration not the grid. You can find more information in the data source API reference.
Also there is no need to subscribe to the change event of the data source in this case. The grid is listening to it by default and will get refreshed automatically.

ExtJS Pop-up Window Form data loading

I use Grid panel. When I select the row in the grid I get the following results:
If I render the Form in 'document.body' everything is OK, and form
fields are filled.
If I, same Form start in Window panel, Form fields are empty.
When I use both, Form which is rendered in the 'document.body' is
closed, and Form fields in Window are filled.
Where I make mistake.
// Grip panel part
sm: new Ext.grid.RowSelectionModel({
singleSelect: true,
listeners: {
rowselect: function(sm, index, record) {deleteWindow.show();}
}
})
// End Grid panel part
var myForm = new Ext.form.FormPanel({
title:"Basic Form",
width:425,
frame:true,
items: [
new Ext.form.TextField({
id:"to",
fieldLabel:"To",
width:275,
allowBlank:false,
blankText:"Please enter a to address",
readOnly: true
}),
new Ext.form.TextField({
id:"subject",
fieldLabel:"Subject",
width:275,
allowBlank:false,
blankText:"Please enter a subject address",
readOnly: true
}),
],
buttons: [
{text:"Cancel"},
{text:"Save"}
]
});
var deleteWindow = new Ext.Window({
id: 'id_deleteWindow',
title: 'Delete',
closable:true,
width: 750,
height: 380,
plain:true,
layout: 'fit',
items: myForm
});
var id_test = 2; // This is only for this problem
//myForm.render(document.body); // When using this code everything is ok, and form fields are filled
myForm.getForm().load({
url:'ggg.php',
params:{
id: id_test
}
});
JSON data
{success:true,results:[{"id_test":"1","to":"a","subject":"aa"}]}
I would suggest the following changes to the code:
In place of using the id property on the TextField (say, id: 'subject'), use name property (name: 'subject')
Just curious....since you are handling the rowselect event on the grid, you might want to load the selected record in the form panel rather than loading it again. If this is the case, then you may call the loadRecord() method on the form panel and pass the record object to it and then call the show() method on the window
I figured out that when load is called on form, ExtJS tries to access form dom element to determine form method. I've found 2 solutions:
Add method to the form config
Load data to form after window is showed
Here is code for second solution:
var deleteWindow = new Ext.Window({
id: 'id_deleteWindow',
title: 'Delete',
closable:true,
width: 750,
height: 380,
plain:true,
layout: 'fit',
items: myForm,
listeners: {
show: function() {
var form = this.items.get(0);
form.getForm().load({
url:'ggg.php',
params:{
id: id_test
}
});
}
}
});
deleteWindow.show();

Resources