how to use a template inside a kendo mvvm grid column command? - kendo-ui

I have an MVVM Grid binded to the 'LabsViewVM' ViewModel, shown below.
Column commands 'activate', 'suspend', 'abolish' are binded through the 'click' event to the LabsViewVM's transitLab method/handler, which executes just fine.
<div id="labs_view"
data-role="grid"
data-bind="source: labs, visible: isVisible, events: {edit: createLab, dataBound: dataBound, dataBinding: dataBinding}"
data-detail-init="LabsViewVM.detailInit"
data-detail-template= 'lab_details_template'
data-selectable="row"
data-scrollable= "true"
data-resizable= "true"
data-sortable= "{'allowUnsort': false}"
data-pageable="{ 'pageSizes': [5, 10, 15, 20, 25, 30, 50],
'messages': { 'display': '{0}-{1} από {2} Διατάξεις Η/Υ',
'empty': 'Δεν βρέθηκαν Διατάξεις Η/Υ',
'itemsPerPage': 'Διατάξεις Η/Υ ανά σελίδα',
'first': 'μετάβαση στην πρώτη σελίδα',
'previous': 'μετάβαση στην προηγούμενη σελίδα',
'next': 'μετάβαση στην επόμενη σελίδα',
'last': 'μετάβαση στην τελευταία σελίδα' }}"
data-editable="{ 'mode' : 'popup', 'template': $('#lab_create_template').html()}"
data-toolbar="[{ 'template' : $('#lab_toolbar_template_labs_view').html() }]"
data-columns="[{ 'field': 'lab_id', 'title':'Κωδικός Διάταξης Η/Υ', 'width':'65px', 'hidden' : true},
{ 'field': 'lab_name', 'title':'Ονομασία', 'width':'440px'},
{ 'field': 'lab_type', 'title':'Τύπος', 'width':'150px', 'hidden' : true},
{ 'field': 'lab_state', 'title':'Λειτουργική Κατάσταση', 'width':'150px'},
{ 'field': 'rating', 'title':'Αξιολόγηση', 'template' : $('#labs_view_rating_column_template').html(), 'width':'85px'},
{ 'field': 'positioning', 'title':'Τοποθεσία', 'width':'180px', 'hidden' : true},
{ 'field': 'lab_special_name', 'title':'Ειδική Ονομασία', 'width':'180px', 'hidden' : true},
{ 'field': 'creation_date', 'title':'Ημερομηνία Δημιουργίας', 'width':'150px', 'hidden' : true},
{ 'field': 'last_updated', 'title':'Τελευταία Ενημέρωση', 'width':'150px'},
{ 'field': 'created_by', 'title':'Δημιουργία από', 'width':'130px', 'hidden' : true},
{ 'command': [{'text':'Ενεργοποίηση', 'click':LabsViewVM.transitLab, 'name':'activate'},
{'text':'Αναστολή', 'click':LabsViewVM.transitLab, 'name':'suspend', },
{'text':'Κατάργηση', 'click':LabsViewVM.transitLab, 'name':'abolish'}],
'title': 'Ενέργειες', 'width':'500px', 'hidden': LabsViewVM.hideLabTransitColumn() }
]">
</div>
var LabsViewVM = kendo.observable({
transitLab: function(e){
e.preventDefault();
var parent_grid = $(e.delegateTarget).data("kendoGrid");
var transition_dialog = $("#transition_dialog").kendoWindow({
modal: true,
visible: false,
resizable: false,
width: 500,
pinned:true,
open: function(){lots of code...}
}).data("kendoWindow");
var transitTemplate = kendo.template($("#lab_transit_template").html());
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
transition_dialog.content(transitTemplate(dataItem));
transition_dialog.center().open();
}
});
I'm quoting from https://www.packtpub.com/books/content/kendo-mvvm-framework, some information for the click property just to stress the way kendo differentiates its click event from the traditional one.
"The click property binds the click event of a button to a function inside of the View-Model. It is a shortcut to the events binding that we will see later. Unlike a traditional click event wire-up, the Kendo UI framework will pass context data to the event handler to allow for a richer event-handling experience. For example, when a click event is bound within a row template, the event argument passed to the event handler will have access to the item from the source collection. This allows the event handler to operate against that Model data directly without any further DOM exploration and keeps all of the observable functionality in place."
Having that in mind, I was able to access the parent grid, inside transitLab, through the event parameter 'e'.
I then had to change my implementation and use a kendo template for the column commands, because I needed to add some logic to the appearance of the command buttons.
So i replaced
{ 'command': [{'text':'Ενεργοποίηση', 'click':LabsViewVM.transitLab, 'name':'activate'},
{'text':'Αναστολή', 'click':LabsViewVM.transitLab, 'name':'suspend', },
{'text':'Κατάργηση', 'click':LabsViewVM.transitLab, 'name':'abolish'}],
'title': 'Ενέργειες', 'width':'500px', 'hidden': LabsViewVM.hideLabTransitColumn() }
with
{ 'command': [{'name':'commands', 'template': $('#labs_grid_command_column_template').html()}], 'title': 'Ενέργειες', 'width':'270px' }
and template :
<script id="labs_grid_command_column_template" type="text/x-kendo-template">
#if( some condition ){#
<a class="k-button k-button-icontext k-grid-activate" href="\#" data-bind="click: transitLab"><i class="fa fa-check"></i> Ενεργοποίηση </a>
<a class="k-button k-button-icontext k-grid-suspend" href="\#" data-bind="click: transitLab"><i class="fa fa-clock-o"></i> Αναστολή </a>
<a class="k-button k-button-icontext k-grid-abolish" href="\#" data-bind="click: transitLab"><i class="fa fa-ban"></i> Κατάργηση </a>
#}#
</script>
but it doesn't work.
My code crashes inside transitLab handler, because its event
parameter 'e' does not get populated with the same context data as before.
For example e.delegateTarget in the first case points to the grid, whereas in the second case points to the command button itself.
I don't get it. Shouldn't these two implementations have the same effect?? Please help!

Related

fullpage.js dynamically added sections: how to scroll inside the sections

I am adding the sections in HTML using JS from this object:
var slidesArray = [
{
'id': 1,
'title': '1 title',
},
{
'id': 2,
'title': '2 title',
},
{
'id': 3,
'title': '3 title',
},
{
'id': 4,
'title': '4 title',
}
];
like this:
var $container = $('#fullpage'),
shuffledItems = "",
shuffledItemsTemplate =
"<div class='section fp-scrollable'>" +
"<div class='section_title'>{TITLE}</div>" +
"</div>";
for(var i = 0; i < 3; i++) {
shuffledItems = shuffledItemsTemplate.replace(/{TITLE}/g, slidesArray[i]["title"]);
$container.append(shuffledItems);
}
which results in the following HTML:
<div id="fullpage" class="sections">
<div class="section fp-scrollable">
<div class="section_title">1 title</div>
</div>
<div class="section fp-scrollable">
<div class="section_title">2 title</div>
</div>
<!-- etc -->
</div>
Simple enough.
Here's the fullpage configuration:
new fullpage('#fullpage', {
css3: true,
scrollingSpeed: 1000,
navigation: true,
slidesNavigation: true,
controlArrows: false,
scrollOverflow: true, // even though this is set to true, it's not working
scrollOverflowOptions: {
scrollbars: false,
},
});
My problem is that I cannot scroll inside any div that's scrollable and is inside <div class="section"></div>, even though scrollOverflow: true is set, and I added the files in the correct order in the HTML. Any idea what might cause this issue and how to solve it?
<script src="Scripts/Legacy/vendor/jquery.min.js"></script>
<script src="Scripts/Legacy/third-party/scrolloverflow.min.js"></script>
<script src="Scripts/Legacy/third-party/fullpage.js"></script>
You might need to use the method fullpage_api.reBuid() right after appending a section. Try it out.
That, or initialise fullPage.js after appending the contents.
In any case, fullPage.js won't be able to detect new sections appended dynamically, you would have to put some more work from your part to make it work. Namely, destroying fullPage.js and initialising it again with every section/slide you add/remove dynamically.

Unable to get text in kendo dropdownlist control using MVVM from another viewmodel

I have a simple dropdown list defined like this:
<div id="ActionMenu">
<input id="ddlActionList"
data-role="dropdownlist"
data-text-field="text"
data-value-field="value"
data-value-primitive="true"
data-bind="value: selectedAction, source: actionList"/>
</div>
And in another div I have a simple pop up window:
<div id="window"
data-role="window"
data-title="Message panel"
data-actions="['close']"
data-bind="visible: isVisible, enabled: isEnabled">
<p>Action selected: <span data-bind="text: getSelectedAction()"></span></p>
</div>
and it's all wrapped under an ActionMenu div.
this.ActionMenu = kendo.observable({
actionList: [{ text: 'Option A', value : 0 },
{ text: 'Option B', value : 1 },
{ text: 'Option C', value : 2 },
{ text: 'Option D', value : 3 }],
selectedAction: 0,
selectedActionText: function() {
// return what ?
}
}
});
My problem is that I have no way of grabbing the selected text from the Window view model:
this.MessageWindow = kendo.observable({
actions: ["Close"],
getSelectedAction: function (e) { return that.ActionMenu.get("selectedActionText"); }
});
If I do something like this:
var ddlActionList = that.kWidgetHelper.getWidgetInstance("ddlActionList");
ddlActionList.text();
That always returns the first text "Option A", not the selected one.
It would appear like an easy thing to do , but so far it's impossible for me to grab the selected text.
I also tried:
this.actionList[this.get("selectedAction")].text which produces an error.
I also tried:
selectedActionText: function(event) {
return event.sender.text();
}
Which doesn't work.
Also
selectedActionText: function() {
return that.ActionMenu.actionList[that.ActionMenu.selectedAction].text;
},
Always returns the first Option.
I believe my problem is that I am trying to get the current value of one viewmodel from another viewmodel.
Any ideas how to do that?
The text() method of the DDL should do the work if the DDL selection has changed, it should show the corresponding text.
The result should also be the same if you use the dataItem() method and then get the text property out of it.

Data and button in same column kendo grid

I am working on HTML5 and javascript.
Is it possible to add data and button in the same column in kendo grid.
Need help.
Also in view page, you can use ClientTemplate to achieve this:
#(Html.Kendo().Grid<ViewModel>().Name("grid")
.DataSource(src => src.Ajax().PageSize(10).Read(read => read.Action("Action", "Controller"))
.Columns(col =>
{
col.Bound(e => e.Name).ClientTemplate("<input type='button' value='CLICK' onclick='XYZ();'><label>#= (Name== null) ? ' ' : Name #</label>");
})
.Selectable()
.Scrollable()
)
Yes, it is! Simply use a template for it. Example:
Define the following template:
<script id="template" type="kendoui/template">
<button class="ob-click-me k-button">Click me</button>
<span>#= LastName #</span>
</script>
and the grid as:
var grid = $("#grid").kendoGrid({
dataSource: ds,
...
columns :
[
{ field: "FirstName", width: 90, title: "First Name" },
{
field: "LastName",
width: 200,
title: "Last Name",
template: $("#template").html()
}
]
}).data("kendoGrid");
You can see a running example even defining a handler for the button here: http://jsfiddle.net/OnaBai/qe3tf4tx/

ng-grid/ui-grid celltemplate on click causes row to be selected.

When I use celltemplate for ahref link, once the link is clicked the row highlights because i have RowSelection enabled...but i dont want the row to highlight when the link is clicked..only if the row is clicked anywhere but the link.
Also in my below example picture, how do I remove the little arrow so no Menuitems can be displayed for that column?
Code:
$scope.gridOptions = {
showFooter: true,
enableFiltering: true,
enableRowSelection: true,
enableRowHeaderSelection: false,
enableSelectAll: true,
multiSelect: true,
enableColumnResizing: true,
columnDefs: [
{ field:'date', displayName: 'Date', width: 200, aggregationType: uiGridConstants.aggregationTypes.count },
{ field:'notes', displayName: 'Notes', width: 65, enableFiltering: false, enableSorting: false, enableHiding: false, cellTemplate:'View' }
],
data: data
}
Pic:
Here is a possible answer to ui-grid (which is not ng-grid anymore!).
The cell template for a button that does not select the row is:
cellTemplate: '<button class="btn primary" ng-click="$event.stopPropagation();getExternalScopes().showMe(row)">Click Me</button>'
Note the $event.stopPropagation() in the ng-click directive. This will hinder the click to reach the underlying functions of the rowTemplate.
(Note also that I didn't found another way to pass a click event to the controller than by using externalScopes. I'm sure there is a better way but ui-grid is still beta and I'm also pretty new to it)
Second part of your question: Use this headCellTemplate
var headCelltpl = '<div ng-class="{ \'sortable\': sortable }">' +
'<div class="ui-grid-vertical-bar"> </div>' +
'<div class="ui-grid-cell-contents" col-index="renderIndex">' +
'{{ col.displayName CUSTOM_FILTERS }}' +
'</div>' +
'</div>';
and add it to the respective columns in your columnDefs.
headerCellTemplate: headCelltpl
Here is a Plunker with everything included.
Please don't tell me you meant ng-grid:-)
The simple solution is change the row.setSelected to false
cellTemplate: '<button class="btn primary" ng-click="grid.appScope.deSelectRow(row)">Click Me</button>'
$scope.deSelectRow = function(row) {
row.setSelected(false);
};

Grouping Tile view in PhoneJS

I am trying to show products from database into tileview item in devexpress phonejs. Successfully I can load items from datasource into tileview but I would like to group items by the category name and really dont have any idea howto do it. Any help will be appreciated.
JS Code
return {
sale: sale,
departmansSource: {
store: PosApplication.db.Departmans,
select: ["DepartmanID", "DepartmanName"]
},
categoriesSource: {
store: PosApplication.db.Categories,
select: ["CategoryID", "CategoryName"]
},
productsSource: {
store: PosApplication.db.Products,
filter: ["DepartmanID","=", 2],
select: ["ProductID", "ProductName", "DepartmanID", "DepartmanName", "CategoryID", "CategoryName"]
},
approversSource: {
store: PosApplication.db.Approvers,
select: ["ApproverId", "ApproverName"]
},
handleSave: handleSave,
handleCancel: handleCancel,
viewShown: handleViewShown,
notifiy: notifiy
};
Html Code
<div id="urunlertile" data-bind="dxTileView: { height: '550', dataSource: productsSource, itemClickAction: notifiy, baseItemHeight: 70, baseItemWidth: 150, itemMargin: 3, }">
<div data-options="dxTemplate:{name:'item'}">
<p><span data-bind="text: $data.CategoryName"></span></p>
<p><span data-bind="text: $data.ProductName"></span></p>
</div>
</div>
</div>
You can use postProcess callback to group/sort data in your dataSource.
See doc with example:
http://js.devexpress.com/Documentation/Howto/Data_Layer/Data_Layer?version=14_1#Data_Layer_Data_Layer_Reading_Data_Data_Transformation_Post_Processing
Note that dxTileView doesn't support displaying grouped data out of box. Having grouped data like
[{ key: "Category1", items: [{ name: "Product1" }, ...], ...]
you could put nested dxTileView in item template to display products for each category.

Resources