Controlling position of a custom confirm dialog with Kendo UI

The native confirm dialog, shown when you use the confirm function in JavaScript can’t be positioned in JavaScript.

A Kendo UI window can be positioned.

 

 

image

 

HTML

<!DOCTYPE html>
<html>
<head>
    <title>Kendo element binding research page.</title>
    <link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.common.min.css" />
    <link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.rtl.min.css" />
    <link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.metro.min.css" />
    <link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.metro.mobile.min.css" />
    <link rel="stylesheet" type="text/css" href="//netdna.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css">
    <style>
        /* Resets */
        div, span, i, p, input, select {
            -moz-box-sizing: border-box;
            -webkit-box-sizing: border-box;
            box-sizing: border-box; /* Border boxing is used, so the padding, margin and borders are within the width and height of de element. */
            color: rgba(112, 112, 112, 1);
            font-family: Arial, Helvetica, sans-serif; /* For know use default fonts used on google.com stackoverflow.com, telerik.com etc. */
            font-size: 13px;
            margin: 0; /* Margin zero is used to prevent unnecessary white space. */
            padding: 0; /* Padding zero is used to prevent unnecessary white space. */
        }        

        html, body {
            height: 100%;
            max-height: 100%;
        }

        body {
            padding: 20px;
        }

        .page {
            border: 1px solid rgb(212, 212, 212);
            height: 100%;
            max-height: 100%;
            padding: 10px;
            position: relative;
        }

        #confirm > p {
            padding-bottom: 20px;
        }

        .k-button {
            cursor: pointer;
        }

        .k-window-titlebar, .k-window-titlebar > span {
            cursor: move;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <div class="page">
        <button class="k-button" data-bind="click: onShowClick">Show confirm</button>
        <div id="confirm"></div>
    </div>
    <script type="text/x-kendo-template" id="confirmTemplate">
        <p>#= ConfirmText #</p>
        <button class="k-button" id="yesButton">Yes</button>
        <button class="k-button" id="noButton"> No</button>
    </script>
    <!-- Libraries -->
    <script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="//cdn.kendostatic.com/2014.1.528/js/kendo.all.min.js"></script>
    
    <!-- Custom -->
    <script type="text/javascript" src="app.js"></script>
</body>
</html>

 

Code

var kendo = kendo || {};

kendo.controller = (function () {
    var self = {};
    var _vm = null;
    var _confirm = null;
    var _confirmTemplate = null;

    self.show = function () {
        _confirm =  $("#confirm").kendoWindow({
            title: "Delete record",
            visible: false, // The window will not appear before its .open method is called.
            width: "230px",
            height: "100px",
        }).data("kendoWindow");
        _confirmTemplate = kendo.template($("#confirmTemplate").html());
        _vm = new kendo.data.ObservableObject({
            onShowClick: function () {
                // Dynamically set some window options.
                _confirm.setOptions({
                    position: {
                        top: 200,
                        left: 200
                    }
                });
                _confirm.content(_confirmTemplate({ ConfirmText: "Delete record?"}));
                _confirm.open();

                $("#yesButton").click(function () {

                    // TODO: Delete record.
                    _confirm.close();
                })
                $("#noButton").click(function () {
                    // User cancelled the window.
                    _confirm.close();
                })
            }
        });

        kendo.bind($(".page"), _vm);
    };

    return self;
})();

kendo.controller.show();

How to pass extra / additional parameters to the deferred.then()function in jQuery, $q (AngularJS) or Q.

 

Q or $q

If you are using Q or $q you can pas extra data to the then function by using the $q.all function:

function execute()
{
    var firstNames = ['Bo', 'Cris', 'Richard'];
    $q.all({
        firstNames: $q.when(firstNames),
        lastNames: $http.get('/api/lastNames')
    }).then(handleGetLastNamesResult)
}

function handleGetLastNamesResult(data)
{
    var firstNames = data.firstNames;
    var lastNames = data.lastNames;
}

 

jQuery

 

In this example I will use jQuery, but the same pattern works for $q and Q.

You can make an Ajax request in jQuery like, so:

var app = (function ()
{
    var self = {};
        
    self.handleGetResult = function (data) {
        // Do something with the result from the server.
    };

    self.start = function ()
    {
        var promise = $.ajax({
            url: 'https://api.github.com/users/roelvanlisdonk/repos',
            type: 'GET'
        });

        $.when(promise).then(self.handleGetResult);
    };

    self.start();

    return self;
})();

The function passed to the .then function can only contain one parameter and will contain the data returned form the server. If you want to pass the function called by the “.then” function some additional data. You can use the following pattern:

 

var app = (function ()
{
    var self = {};
    
    self.handleGetResult = function (data) {
        var resultHandler = this;
        var additionalData = resultHandler.getAdditionalData();

        // Do something with the result from the server and the additional data.
    };

    self.ResultHandler = function (additionalData, handleResultFunc) {
        var self = this;
        var _additionalData = additionalData;
        var _handleResultFunc = handleResultFunc;

        self.getAdditionalData = function () {
            return _additionalData;
        };

        self.handleResult = function (data) {
            _handleResultFunc.call(self, data);
        };

        return self;
    };

    self.start = function ()
    {
        var promise = $.ajax({
            url: 'https://api.github.com/users/roelvanlisdonk/repos',
            type: 'GET'
        });

        var handler = new self.ResultHandler("Some extra data", self.handleGetResult);
        $.when(promise).then(handler.handleResult);
    };

    self.start();

    return self;
})();

How to display a message, when a Kendo UI MVVM grid is empty.

If you want to show an text in a Kendo UI grid, you could use CSS, as suggested on stackoverflow.com:

http://stackoverflow.com/questions/23476978/display-a-message-within-the-kendo-grid-when-its-empty

 

But if you want to completely hide the gird and show a message, you can use a calculated field:

http://docs.telerik.com/kendo-ui/getting-started/framework/mvvm/observableobject#creating-dependent-methods-also-known-as-calculated-fields

 

image

 

HTML

<!DOCTYPE html>
<html>
<head>
    <title>Kendo element binding research page.</title>
    <link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.common.min.css" />
    <link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.rtl.min.css" />
    <link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.metro.min.css" />
    <link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.metro.mobile.min.css" />
    <style>
        /* Resets */
        div, span, i, p, input, select {
            -moz-box-sizing: border-box;
            -webkit-box-sizing: border-box;
            box-sizing: border-box; /* Border boxing is used, so the padding, margin and borders are within the width and height of de element. */
            color: rgb(112, 112, 112);
            font-family: Arial, Helvetica, sans-serif; /* For know use default fonts used on google.com stackoverflow.com, telerik.com etc. */
            font-size: 13px;
            margin: 0; /* Margin zero is used to prevent unnecessary white space. */
            padding: 0; /* Padding zero is used to prevent unnecessary white space. */
        }        

        html, body {
            height: 100%;
            max-height: 100%;
        }

        body {
            padding: 20px;
        }

        .info {
            border: 1px solid rgb(128, 128, 128);
            box-shadow: rgba(0, 0, 0, 0.298039) 0 2px 6px 0, rgba(0, 0, 0, 0.2) 0 -3px 8px 0;
            padding: 10px;
        }

        .no-data {
            border: 1px solid #dadada;
            padding: 10px;
        }
    </style>
</head>
<body>
    <div id="view">
        <div class="info">            
            <script id="productsRowTemplate" type="text/x-kendo-tmpl">
                <tr data-uid="#: uid#">
                    <td>#: Id#</td>
                    <td>#: Name#</td>
                </tr>
            </script>
            <div id="productsGrid" data-role="grid"
                 data-row-template="productsRowTemplate"
                 data-columns="[
                                    { 'field': 'Id' },
                                    { 'field': 'Name' }
                               ]"
                 data-bind="source: products, invisible: productsIsEmpty"></div>
            <div class="no-data" data-bind="visible: productsIsEmpty">No data.</div>
        </div>
    </div>

    <!-- Libraries -->
    <script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="//cdn.kendostatic.com/2014.1.528/js/kendo.all.min.js"></script>


    <!-- Custom -->
    <script type="text/javascript" src="kendo-controller.js"></script>
</body>
</html>

 

JavaScript

var kendo = kendo || {};

kendo.controller = (function () {
    var self = {};
    var _vm = null;

    self.show = function () {

        _vm = new kendo.data.ObservableObject({
            products: new kendo.data.DataSource({
                data: new kendo.data.ObservableArray([
                    
                ])
            }),
            productsIsEmpty: function () {
                return this.get("products").data().length === 0;
            }
        });

        kendo.bind($("#view"), _vm);
    };

    return self;
})();

kendo.controller.show();

Show kendo ui grid total record count with MVVM.

Kendo UI MVVM allows functions of objects to be called in the binding syntax:

<div class="totals"><span>Totals: </span><span data-bind="text: products.data().length"></span></div>

In this case the viewmodel property [products] is a kendo.data.DataSource object.

To get the total count of the records in the DataSource, you can use the function data().

This will return an ObservableArray which has a property length, containing the total record count.

 

image

 

HTML

<!DOCTYPE html> <html> <head> <title>Kendo element binding research page.</title> <link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.common.min.css" /> <link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.metro.min.css" /> <style> /* Resets */ div, span, i, p, input, select { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; /* Border boxing is used, so the padding, margin and borders are within the width and height of de element. */ color: rgb(112, 112, 112); font-family: Arial, Helvetica, sans-serif; /* For know use default fonts used on google.com stackoverflow.com, telerik.com etc. */ font-size: 13px; margin: 0; /* Margin zero is used to prevent unnecessary white space. */ padding: 0; /* Padding zero is used to prevent unnecessary white space. */ } html, body { height: 100%; max-height: 100%; } body { padding: 20px; } .info { border: 1px solid rgb(128, 128, 128); box-shadow: rgba(0, 0, 0, 0.298039) 0 2px 6px 0, rgba(0, 0, 0, 0.2) 0 -3px 8px 0; padding: 10px; } .totals { margin-top: 20px; font-weight: bold; } </style> </head> <body> <div id="view"> <div class="info"> <script id="productsRowTemplate" type="text/x-kendo-tmpl"> <tr data-uid="#: uid#"> <td>#: Id#</td> <td>#: Name#</td> </tr> </script> <div id="productsGrid" data-role="grid" data-row-template="productsRowTemplate" data-columns="[ { 'field': 'Id' }, { 'field': 'Name' } ]" data-bind="source: products"></div> <div class="totals"><span>Totals: </span><span data-bind="text: products.data().length"></span></div> </div> </div> <!-- Libraries --> <script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.min.js"></script> <script type="text/javascript" src="//cdn.kendostatic.com/2014.1.528/js/kendo.all.min.js"></script>


<!-- Custom -->
<script type="text/javascript" src="kendo-controller.js"></script> </body> </html>

 

JavaScript (kendo-controller.js)

var kendo = kendo || {};

kendo.controller = (function () {
    var self = {};
    var _vm = null;

    self.show = function () {

        _vm = new kendo.data.ObservableObject({
            products: new kendo.data.DataSource({
                data: new kendo.data.ObservableArray([
                    { Id: 1, Name: "Product 1" },
                    { Id: 2, Name: "Product 2" },
                    { Id: 3, Name: "Product 3" },
                    { Id: 4, Name: "Product 4" },
                    { Id: 5, Name: "Product 5" }
                ])
            })
        });

        kendo.bind($("#view"), _vm);
    };

    return self;
})();

kendo.controller.show();

CSS / HTML / JavaScript / C# Code Snippets in Visual Studio 2013

Just a reminder: Visual Studio contains code snippets for many different “languages”, like CSS, HTML, JavaScript, C# etc.

When you want to write a for loop in JavaScript, just hit CTRL + SPACE, then type for, then press the TAB twice and a for loop will be inserted:

 

Before

image

CTRL + SPACE

image

for

image

TAB + TAB

image

 

Edit

This snippet can be found in the folder:

C:\Program Files (x86)\Microsoft Visual Studio 12.0\\JavaScript\Snippets\1033\JavaScript

image

For example, by editing the for.snippet you can change it, so the generated for loop adheres to the JSHint rules:

(note: open Notepad.exe as administrator, else the snippet files can’t be edited.)

Now I changed the for.snippet to:

<CodeSnippet Format="1.1.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <Header>
    <Title>for</Title>
    <Author>Microsoft Corporation</Author>
    <Shortcut>for</Shortcut>
    <Description>Code snippet for a for loop</Description>
    <SnippetTypes>
      <SnippetType>Expansion</SnippetType>
      <SnippetType>SurroundsWith</SnippetType>
    </SnippetTypes>
  </Header>
  <Snippet>
    <Declarations>
      <Literal>
        <ID>index</ID>
        <ToolTip>Index</ToolTip>
        <Default>i</Default>
      </Literal>
      <Literal>
        <ID>data</ID>
        <ToolTip>Array object</ToolTip>
        <Default>data</Default>
      </Literal>
    </Declarations>
    <Code Language="JavaScript"><![CDATA[for (var $index$ = 0, len = $data$.length; $index$ < len; $index$+=1) {
    $selected$$end$
}]]></Code>
  </Snippet>
</CodeSnippet>

 

Now when I insert the for snippet the following code is generated:

image

 

Manage

To manage Code Snippets just hit CTRL + K, CTRL + B in Visual Studio or menu > TOOLS > Code Snippets Manager…

image

Using drag and drop to order rows in a Kendo UI grid

 

Before drag and drop

image

During drag and drop

image

 

After drag and drop

image

 

Code

<!DOCTYPE html>
<html>
<head>
<title>Kendo element binding research page.</title>
<link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.common.min.css" />
<link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.rtl.min.css" />
<link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.metro.min.css" />
<link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.metro.mobile.min.css" />
<link rel="stylesheet" type="text/css" href="//netdna.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css">
<style>
/* Resets */
* {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box; /* Border boxing is used, so the padding, margin and borders are within the width and height of de element. */
color: rgb(112, 112, 112);
font-family: Arial, Helvetica, sans-serif; /* For know use default fonts used on google.com stackoverflow.com, telerik.com etc. */
font-size: 13px;
margin: 0; /* Margin zero is used to prevent unnecessary white space. */
padding: 0; /* Padding zero is used to prevent unnecessary white space. */
}
html, body {
height: 100%;
max-height: 100%;
}
body {
padding: 20px;
}
.info {
border: 1px solid rgb(128, 128, 128);
box-shadow: rgba(0, 0, 0, 0.298039) 0 2px 6px 0, rgba(0, 0, 0, 0.2) 0 -3px 8px 0;
padding: 10px;
}
.addressRow {
cursor: move;
cursor: -webkit-grab;
cursor: -moz-grab;
height: 10px;
line-height: 10px;
padding: 0;
margin: 0;
}
.addressRow input {
font-family: FontAwesome;
}
#addressGrid tr > td {
height: 1.6em;
line-height: 1.6em;
padding: 1px 4px 1px 4px;
margin: 0;
}
#addressGrid tr > th {
font-weight: bold;
height: 1.6em;
line-height: 1.6em;
margin: 0;
padding: 1px 4px 1px 4px;
}
#addressGrid tr > td:first-child, #addressGrid tr > th:first-child {
width: 56px;
}
#addressGrid tr:last-child td {
padding-bottom: 3px;
}
.km-switch {
cursor: pointer;
height: 1.6em;
line-height: 1.6em;
margin: 0;
padding: 0;
}
#addressGrid tr > td:first-child .km-switch-label-on, #addressGrid tr > td:first-child .km-switch-label-off {
font-family: FontAwesome;
color: rgb(112, 112, 112);
height: 1.6em;
line-height: 1.6em;
}
#addressGrid tr > td:first-child .km-switch-label-on:before {
content: "\f023";
}
#addressGrid tr > td:first-child .km-switch-label-off:before {
content: "\f09c";
}
</style>
</head>
<body>
<div id="view">
<div class="info">
<script id="addressRowTemplate" type="text/x-kendo-tmpl">
<tr data-uid="#: uid#" class="addressRow">
<td>
<input data-role="switch" data-on-label="" data-off-label="" data-bind="checked: IsFixed">
</td>
<td>
#: Address#
</td>
<td>
#: Lat#
</td>
<td>
#: Long#
</td>
<td>
<input data-role="switch" data-on-label="Y" data-off-label="N" data-bind="checked: IsFixed">
</td>
</tr>
</script>
<div id="addressGrid" data-role="grid"
data-row-template="addressRowTemplate"
data-columns="[
{ 'field': 'IsFixed' },
{ 'field': 'Address' },
{ 'field': 'Lat' },
{ 'field': 'Long' },
{ 'field': 'Selected' }
]"
data-bind="source: addresses"></div>
</div>
</div>
<script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="//cdn.kendostatic.com/2014.1.528/js/kendo.all.min.js"></script>
<script type="text/javascript" src="/Client/Libraries/Live/head.min.js"></script>
<script type="text/javascript" src="/Client/Libraries/Live/live.js"></script>
<script type="text/javascript">
kendo.addDragAndDropToGrid = function (gridId, rowClass, viewModel, validateDropTargetFunc)
{
if (!gridId) { throw "Parameter [gridId] is not set."; }
if (!rowClass) { throw "Parameter [rowClass] is not set."; }
$(rowClass).kendoDraggable({
hint: function (element)
{
return element.clone();
}
});
$(gridId).kendoDropTargetArea({
filter: rowClass,
drop: function (e)
{
var srcUid = e.draggable.element.data("uid");
var dstUid = e.dropTarget.data("uid");
var ds = $(gridId).data("kendoGrid").dataSource;
var srcItem = ds.getByUid(srcUid);
var dstItem = ds.getByUid(dstUid);
var dstIdx = ds.indexOf(dstItem);
ds.remove(srcItem);
ds.insert(dstIdx, srcItem);
e.draggable.destroy();
kendo.addDragAndDropToGrid(gridId, rowClass, viewModel, validateDropTargetFunc);
}
});
};
var dataService = (function ()
{
"use strict";
var self = {};
self.getAddresses = function ()
{
var data = new kendo.data.ObservableArray(
[
{ Id: 1, Address: 'Kerkweg 22',   Lat: '52.367443', Long: '4.865275', Selected: false, IsFixed: false },
{ Id: 2, Address: 'Peilstraat 3', Lat: '52.367967', Long: '4.866217', Selected: false, IsFixed: true },
{ Id: 3, Address: 'Bakkerloop 35', Lat: '52.367946', Long: '4.865482', Selected: false, IsFixed: false },
{ Id: 4, Address: 'Eikenlaan 1', Lat: '52.368237', Long: '4.866694', Selected: false, IsFixed: true }
]);
// Manual create a promise, so this function mimicks an Ajax call.
var dfd = new $.Deferred();
dfd.resolve(data);
return dfd.promise();
};
return self;
})(kendo);
var viewModel = new kendo.observable({
addresses: new kendo.data.DataSource({ data: [] })
});
var controller = (function (dataService, viewModel)
{
"use strict";
var _dataService = dataService;            
var _vm = viewModel;
var self = {};
self.handleAdressesRefresh = function (data)
{
_vm.set("addresses", new kendo.data.DataSource({ data: data }));
kendo.bind($(".info"), _vm);
kendo.addDragAndDropToGrid("#addressGrid", ".addressRow", _vm);
};
self.show = function ()
{
$.when(_dataService.getAddresses())
.then(self.handleAdressesRefresh);
};
return self;
})(dataService, viewModel);
controller.show();
</script>
</body>
</html>

Using Kendo UI switch with Font Awsome icons in a Kendo grid

 

If you want to use Kendo UI switch widgets with Font Awsome icons in a Kendo grid with MVVM binding, you can use the code below:

 

image

 

Code

<!DOCTYPE html>
<html>
<head>
<title>Kendo element binding research page.</title>
<link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.common.min.css" />
<link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.rtl.min.css" />
<link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.metro.min.css" />
<link rel="stylesheet" type="text/css" href="//cdn.kendostatic.com/2014.1.528/styles/kendo.metro.mobile.min.css" />
<link rel="stylesheet" type="text/css" href="//netdna.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css">
<style>
/* Resets */
* {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box; /* Border boxing is used, so the padding, margin and borders are within the width and height of de element. */
color: rgb(112, 112, 112);
font-family: Arial, Helvetica, sans-serif; /* For know use default fonts used on google.com stackoverflow.com, telerik.com etc. */
font-size: 13px;
margin: 0; /* Margin zero is used to prevent unnecessary white space. */
padding: 0; /* Padding zero is used to prevent unnecessary white space. */
}
html, body {
height: 100%;
max-height: 100%;
}
body {
padding: 20px;
}
.info {
border: 1px solid rgb(128, 128, 128);
box-shadow: rgba(0, 0, 0, 0.298039) 0 2px 6px 0, rgba(0, 0, 0, 0.2) 0 -3px 8px 0;
padding: 10px;
}
.addressRow {
cursor: move;
cursor: -webkit-grab;
cursor: -moz-grab;
height: 10px;
line-height: 10px;
padding: 0;
margin: 0;
}
.addressRow input {
font-family: FontAwesome;
}
#addressGrid tr > td {
height: 1.6em;
line-height: 1.6em;
padding: 1px 4px 1px 4px;
margin: 0;
}
#addressGrid tr > th {
font-weight: bold;
height: 1.6em;
line-height: 1.6em;
margin: 0;
padding: 1px 4px 1px 4px;
}
#addressGrid tr > td:first-child, #addressGrid tr > th:first-child {
width: 56px;
}
#addressGrid tr:last-child td {
padding-bottom: 3px;
}
.km-switch {
cursor: pointer;
height: 1.6em;
line-height: 1.6em;
margin: 0;
padding: 0;
}
#addressGrid tr > td:first-child .km-switch-label-on, #addressGrid tr > td:first-child .km-switch-label-off {
font-family: FontAwesome;
color: rgb(112, 112, 112);
height: 1.6em;
line-height: 1.6em;
}
#addressGrid tr > td:first-child .km-switch-label-on:before {
content: "\f023";
}
#addressGrid tr > td:first-child .km-switch-label-off:before {
content: "\f09c";
}
</style>
</head>
<body>
<div id="view">
<div class="info">
<script id="addressRowTemplate" type="text/x-kendo-tmpl">
<tr data-uid="#: uid#" class="addressRow">
<td>
<input data-role="switch" data-on-label="" data-off-label="" data-bind="checked: IsFixed">
</td>
<td>
#: Address#
</td>
<td>
#: Lat#
</td>
<td>
#: Long#
</td>
<td>
<input data-role="switch" data-on-label="Y" data-off-label="N" data-bind="checked: IsFixed">
</td>
</tr>
</script>
<div id="addressGrid" data-role="grid"
data-row-template="addressRowTemplate"
data-columns="[
{ 'field': 'IsFixed' },
{ 'field': 'Address' },
{ 'field': 'Lat' },
{ 'field': 'Long' },
{ 'field': 'Selected' }
]"
data-bind="source: addresses"></div>
</div>
</div>
<script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="//cdn.kendostatic.com/2014.1.528/js/kendo.all.min.js"></script>
<script type="text/javascript">
var dataService = (function ()
{
"use strict";
var self = {};
self.getAddresses = function ()
{
var data = new kendo.data.ObservableArray(
[
{ Id: 1, Address: 'Kerkweg 22',   Lat: '52.367443', Long: '4.865275', Selected: false, IsFixed: false },
{ Id: 2, Address: 'Peilstraat 3', Lat: '52.367967', Long: '4.866217', Selected: false, IsFixed: true },
{ Id: 3, Address: 'Bakkerloop 35', Lat: '52.367946', Long: '4.865482', Selected: false, IsFixed: false },
{ Id: 4, Address: 'Eikenlaan 1', Lat: '52.368237', Long: '4.866694', Selected: false, IsFixed: true }
]);
// Manual create a promise, so this function mimicks an Ajax call.
var dfd = new $.Deferred();
dfd.resolve(data);
return dfd.promise();
};
return self;
})(kendo);
var viewModel = new kendo.observable({
addresses: new kendo.data.DataSource({ data: [] })
});
var controller = (function (dataService, viewModel)
{
"use strict";
var _dataService = dataService;            
var _vm = viewModel;
var self = {};
self.handleAdressesRefresh = function (data)
{
_vm.set("addresses", new kendo.data.DataSource({ data: data }));
kendo.bind($(".info"), _vm);
};
self.show = function ()
{
$.when(_dataService.getAddresses())
.then(self.handleAdressesRefresh);
};
return self;
})(dataService, viewModel);
controller.show();
</script>
</body>
</html>

How to get the differences between two arrays, based on a “key” value in JavaScript.

This page shows how you van use the “getDifferences” function in JavaScript to get the differences between 2 arrays, based on the value of a “key” property.

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>General research page containing only vanilla.js.</title>
<style type="text/css">
/* Resets */
*, *:after, *:before {
margin: 0; /* Margin zero is used to prevent unnecessary white space. */
padding: 0; /* Padding zero is used to prevent unnecessary white space. */
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
/* Border boxing is used, so the padding, margin and borders are within the width and height of de element. */
box-sizing: border-box; 
}
html, body {
height: 100%;
max-height: 100%;
}
body {
padding: 20px;
}
button {
padding: 2px 4px 2px 4px;
cursor: pointer;
}
</style>
</head>
<body>
<button onclick="app.onExecuteClick(event);">Execute</button>
<script type="text/javascript">
var app = (function ()
{
var self = {};
self.onExecuteClick = function (e)
{
var array1 = [{ Id: 1, Name: 'Name1' }, { Id: 2, Name: 'Name2' }, { Id: 3, Name: 'Name3' }, { Id: 4, Name: 'Name4' }];
var array2 = [{ Id: 1, Name: 'Name1' }, { Id: 2, Name: 'Name2' }, { Id: 3, Name: 'Name3' }];
debugger;
var differences = self.getDifferences(array1, array2, "Id");
differences = self.getDifferences(array2, array1, "Id");
};
self.getDifferences = function (array1, array2, key)
{
// Directly return arrays, when one array contains elements and the other is empty.
var array1HasValues = (array1 && array1.length && array1.length > 0);
var array2HasValues = (array2 && array2.length && array2.length > 0);
if (array1HasValues && !array2HasValues) { return array1; }
if (!array1HasValues && array2HasValues) { return array2; }
// Determine biggest and smallest array.
var biggestArray = (array1.length >= array2.length) ? array1 : array2;
var smallestArray = (array1.length >= array2.length) ? array2 : array1;               
// Make hashtable of properties "key" in smallestArray
var smallestKeys = {};
smallestArray.forEach(function (obj)
{
smallestKeys[obj[key]] = obj;
});
// Return all elements in biggestArray, unless in smallestArray.
var differences = biggestArray.filter(function (obj)
{
return !(obj[key] in smallestKeys);
});
return differences;
};
return self;
})();
</script>
</body>
</html>

 

Result

Result will be the object: { Id: 4, Name: ‘Name4’ }

MVVM – Kendo UI ListView – Get selected items on selection.

This page shows how you can get the selected items when using Kendo UI MVVM:

 

<!DOCTYPE html>
<html>
<head>
<title>Kendo element binding research page.</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
padding: 20px;
}
</style>
<link href="//cdn.kendostatic.com/2014.1.528/styles/kendo.common.min.css" rel="stylesheet" type="text/css" />
<link href="//cdn.kendostatic.com/2014.1.528/styles/kendo.silver.min.css" rel="stylesheet" type="text/css" />    
<script src="//code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="//cdn.kendostatic.com/2014.1.528/js/kendo.all.min.js"></script>

</head>
<body>
<div id="page">
<button onclick="app.onExecuteClick(event);">Execute</button>
<script type="text/x-kendo-tmpl" id="template">
<div class="k-widget">
<dl>
<dt>Product Name</dt>
<dd>#:ProductName#</dd>
<dt>Unit Price</dt>
<dd>#:kendo.toString(UnitPrice, "c")#</dd>
</dl>
</div>
</script>
<div data-role="listview"
data-template="template"
data-selectable="multiple"
data-bind="source: products, events: { change: onProductChange }"
style="width: 420px; height: 200px; overflow: auto"></div>
</div>
<script type="text/javascript">
var app = (function ()
{
var self = {};
self.onExecuteClick = function (e)
{
debugger;
};
self.start = function (e)
{
var products = [
{ Id: 1, ProductName: 'Product1', UnitPrice: 200 },
{ Id: 2, ProductName: 'Product2', UnitPrice: 300 },
{ Id: 3, ProductName: 'Product3', UnitPrice: 400 }
];
var viewModel = kendo.observable({
selectedProducts: null,
products: new kendo.data.DataSource({
schema: {
model: {
id: "Id"
}
},
data: products
}),
onProductChange: function (e)
{
// Get kendo listview.
var $listView = e.sender;
var data = $listView.dataSource.view();
// Get the selected DOM elements as jQuery objects.
var $selectedElements = $listView.select();
// Convert the selected  jQuery DOM elements to a Array containing only "Product" objects.
var selected = $.map($selectedElements, function (item)
{
var index = $(item).index();
return data[index];
});
// Log the selected products to the console.
console.log(selected);
}
});
kendo.bind($("#page"), viewModel);
};
return self;
})();
app.start();
</script>
</body>
</html>

Merge / Flatten / Concat / Join the result of multiple ajax calls with promises.

 

The following code will add a function to the jQuery ($).

It can be used to merge the result of multiple ajax calls.

 

$.whenall = function ($promises)
{
/// <summary>
/// Executes the given promises and merges the result to one array.
/// </summary>
/// <param name="promises" type="array">Array of jQuery promises.</param>
/// <returns>A promise.</returns>
// promises: is aan array of promises.
return $.when.apply($, promises).then(function ()
{
// Convert the special "arguments" object to a real "Array".
var args = Array.prototype.slice.call(arguments);
// When the promisses array contains just one element, [args] will be an array containing 3 records: ["array of items", "promises status", "promise"].
// When the promisses array contains more then one element, [args] will be an array of arrays, where each array 3 records: ["array of items", "promises status", "promise"].
// This is handled by only handeling args items that are of type "Array" and foreach handled "Array", we check if the first item is of type "Array".
var merged = [];
for (var i = 0, len = args.length; i < len; i++)
{
var record = args[i];
// Only handle args items, that are of type "Array".
if (record && Array.isArray(record) && record.length > 0)
{
// Check if first item is of type "Array".
var firstItem = record[0];
if (Array.isArray(firstItem))
{
merged = merged.concat(firstItem);
} else
{
merged = merged.concat(record);
}
}
}
return merged;
});
};

 

Example HTML page:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>General research page containing only vanilla.js.</title>
<style type="text/css">
/* Resets */
*, *:after, *:before {
margin: 0; /* Margin zero is used to prevent unnecessary white space. */
padding: 0; /* Padding zero is used to prevent unnecessary white space. */
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box; /* Border boxing is used, so the padding, margin and borders are within de width and height of de element. */
}
html, body {
height: 100%;
max-height: 100%;
}
body {
padding: 20px;
}
button {
padding: 2px 4px 2px 4px;
cursor: pointer;
}
</style>
<script type="text/javascript" src="/Client/Libraries/jQuery/jquery-1.9.1.js"></script>
<script type="text/javascript" src="/Client/Libraries/Live/head.min.js"></script>
<script type="text/javascript" src="/Client/Libraries/Live/live.js"></script>
</head>
<body>
<button onclick="app.onExecuteClick(event);">Execute</button>
<script type="text/javascript">
$.whenall = function (promises)
{
// promises: is aan array of promises.
return $.when.apply($, promises).then(function ()
{
// Convert the special "arguments" object to a real "Array".
var args = Array.prototype.slice.call(arguments);
// When the promisses array contains just one element, [args] will be an array containing 3 records: ["array of items", "promises status", "promise"].
// When the promisses array contains more then one element, [args] will be an array of arrays, where each array 3 records: ["array of items", "promises status", "promise"].
// This is handled by only handeling args items that are of type "Array" and foreach handled "Array", we check if the first item is of type "Array".
var merged = [];
for (var i = 0, len = args.length; i < len; i++)
{
var record = args[i];
// Only handle args items, that are of type "Array".
if (record && Array.isArray(record) && record.length > 0)
{
// Check if first item is of type "Array".
var firstItem = record[0];
if (Array.isArray(firstItem))
{
merged = merged.concat(firstItem);
} else
{
merged = merged.concat(record);
}
}
}
return merged;
});
};
var app = (function ()
{
var self = {};
self.handleRestSponse = function (data)
{
console.log(data);
};
self.onExecuteClick = function (e)
{
console.log('onExecuteClick start.');
var promises = [];
promises.push(
$.ajax({
url: 'https://api.github.com/users/roelvanlisdonk/repos',
type: 'GET'
})
);
promises.push(
$.ajax({
url: 'https://api.github.com/users/roelvanlisdonk/repos',
type: 'GET'
})
);
$.whenall(promises).then(self.handleRestSponse);
console.log('onExecuteClick end.');
};
return self;
})();
</script>
</body>
</html>

Result

The arguments is an “array” of 2 objects, each object containing “data”, “promise status”, “promise”.

The merged result is an real array containing the merged “data” objects:

image