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

Fix: JSCS: The requireLeftStickedOperators rule is no longer supported.

After an update of web essentials I was getting the error:

23-6-2014 08:02:04: JSCS: vctmp6788_81613.js compilation failed: JSCS: The requireLeftStickedOperators rule is no longer supported.
Please use the following rules instead:

disallowSpaceBeforeBinaryOperators
disallowSpaceBeforePostfixUnaryOperators
disallowSpacesInConditionalExpression

 

 

To fix this just edit the global JSCS settings file in Visual Studio 2013:

image

 

Then remove the line: "requireLeftStickedOperators": [","],

 

{
"requireCurlyBraces": ["if", "else", "for", "while", "do", "try", "catch"],
"requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"],
"disallowLeftStickedOperators": ["?", "+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="],
"disallowRightStickedOperators": ["?", "+", "/", "*", ":", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="],
"requireRightStickedOperators": ["!"],
"requireLeftStickedOperators": [","],
"disallowImplicitTypeConversion": ["string"],
"disallowKeywords": ["with"],
"disallowMultipleLineBreaks": true,
"disallowKeywordsOnNewLine": ["else"],
"excludeFiles": [],
"validateJSDoc": {
"checkParamNames": true,
"requireParamTypes": true
}
}

Fix table-cell height overflow-y (scroll) in a CSS 3 full page 100% height layout

 

If you are using display: table, display: table-row and display: table-cell in CSS to structure your HTML, then restricting the height of a content cell is difficult. If you want to have a content cell scroll correctly vertically, when the content of a cell exceeds the height of the table, like cell 2 in the following screen dump:

 

image

 

Then you can use a “relative” positioned div inside the table-cell and in the relative positioned div a absolute positioned div. This div should get the overflow-y property, like:

<div class="table" style="height: 100%;">
<div class="row">
<div class="cell" style="border: 1px solid #000000; padding: 10px;">Cell 1</div>
<div class="cell" style="border: 1px solid #000000; padding: 10px;">
<!-- Use inner div's with position relative and absolute, to fix cell height,
making it overflow correctly. -->
<div style="position:relative; height: 100%">
<div style="overflow-y: scroll; position: absolute; top: 0; right:0; bottom: 0; left: 0;">

To see the code live: http://plnkr.co/edit/HWTsCsUpddHP3rZsMUtz?p=preview

How to fix: top row border is invisible, when highlighting the borders of a row using display table and display table-row in CSS.

If you want to highlight the borders of a row, when using display table and display table-row, like:

 

image

 

You must style the row bottom, left and right borders, but for the top border you need to style the cells, otherwise the top border of the row will not show, for rows that have other rows before it.

 

image

 

<!DOCTYPE html>
<html>
<head>
<title>Basic styling research page.</title>
<style>
* {
margin: 0;
padding: 0;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
body {
padding: 20px;
}
.table {
display: table;
/* Show borders, when using display: table. */
border-collapse: collapse;
}
.tablerow {
display: table-row;
border: 1px solid rgb(218, 218, 218);
}
/* Add some spacing between the first and second column. */
.tablerow div:first-child {
padding-right: 10px;
}
.tablecell {
display: table-cell;
}
/* Style the bottom, left and right row borders. */
.selected {
border: 1px solid #1984c8;
}
/* Style the top of each cell to fake the row top border. */
.selected div {
border-top: 1px solid #1984c8;
}
</style>
</head>
<body>
<div class="table">
<div class="tablerow">
<div class="tablecell">Cell 1.1</div>
<div class="tablecell">Cell 1.2</div>
</div>
<div class="tablerow">
<div class="tablecell">Cell 2.1</div>
<div class="tablecell">Cell 2.2</div>
</div>
<div class="tablerow selected">
<div class="tablecell">Cell 3.1</div>
<div class="tablecell">Cell 3.2</div>
</div>
<div class="tablerow">
<div class="tablecell">Cell 4.1</div>
<div class="tablecell">Cell 4.2</div>
</div>
<div class="tablerow">
<div class="tablecell">Cell 5.1</div>
<div class="tablecell">Cell 5.2</div>
</div>
</div>
</body>
</html>

How to do basic two-way html element data binding with Kendo UI.

To see the code in action, see this Plunker: http://plnkr.co/SpYSwv

 

The following HTML page shows a input box.

When the users start typing in the input box the SPAN element next to it will show the value just entered (onkeypress).

 

image

<!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="view">
<input data-bind="value: inputValue, events: { keypress: showValueOnLabel }" />
<span data-bind="text: label"></span>
</div>
<script>
var viewModel = kendo.observable({
inputValue: "Enter some text",
label: "",
showValueOnLabel: function (e) {
var pressedKey = String.fromCharCode(e.charCode);
var currentValue = e.currentTarget.value;
this.set("label", currentValue + pressedKey);
}
});
kendo.bind($("#view"), viewModel);
</script>
</body>
</html>

Solving: Unable to perform operation on … The item … is locked in workspace … in Visual Studio 2012

 

I wanted to check-in a file, that was check-out by myself on an other pc.

 

You can revert those changes by using the tf.exe.

Open a command prompt AS ADMINISTRATOR

cd "C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE"

tf undo /workspace:"MYPC;MYDOMAIN\rlisdonk" /collection:http://1.1.1.1:8080/tfs/MyCollection $/MyProduct/Main/Source/MyProject/Staging.cs

Create kendo ui tooltip with template and correct position on element click.

Just a code snippet, that shows a tooltip, when the user clicks on a button:

 

image

 

<!DOCTYPE html>
<html>
<head>
<title>RLI research page.</title>
<link rel="stylesheet" type="text/css" href="../../../Libraries/Kendo/styles/kendo.common.min.css" />
<link rel="stylesheet" type="text/css" href="../../../Libraries/Kendo/styles/kendo.rtl.min.css" />
<link rel="stylesheet" type="text/css" href="../../../Libraries/Kendo/styles/kendo.metro.min.css" />
<link rel="stylesheet" type="text/css" href="../../../Libraries/FontAwesome/css/font-awesome.min.css" />
<style type="text/css">
#toonTooltip_tt_active {
background-color: #FFFFFF;
left: 14px;
}
</style>
</head>
<body>
<div id="page">
<h3 class="page-header">RLI research page.</h3>
<div class="content">
<div style="position:absolute;top:100px;"><button id="toonTooltip" class="button">...</button></div>
</div>
<script type="text/x-kendo-template" id="template">
<div>
<button class="button" style="margin-top: 4px; margin-bottom: 4px; width: 200px;">Exporteer to .csv&nbsp;<i class="fa fa-file-text-o" title="Exporteer to *.csv."></i></button>
</div>
<div>
<button class="button" style="margin-bottom: 4px; width: 200px;">Exporteer naar .kml&nbsp;<i class="fa fa-file-text-o" title="Exporteer to *.kml."></i></button>
</div>
<div>
<button class="button" style="margin-bottom: 4px; width: 200px;">Show route&nbsp;<i class="fa fa-road" title="Show route."></i></button>
</div>
<div>
<button class="button" style="margin-bottom: 4px; width: 200px;">Delete route&nbsp;<i class="fa fa-minus-square" title="Delete route."></i></button>
</div>
</script>
</div>
<script type="text/javascript" src="../../../Libraries/jQuery/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="../../../Libraries/Kendo/js/kendo.web.min.js"></script>
<script type="text/javascript" src="../../../Libraries/Kendo/js/cultures/kendo.culture.nl-NL.min.js"></script>
    <script type="text/javascript" src="Rli.js"></script>
</body>
</html>

 

Rli.js

var app = (function ()
{
var self = this;
// The "main" entry point for this application.
self.start = function ()
{
$("#toonTooltip").kendoTooltip({
autoHide: false,
content: kendo.template($("#template").html()),
position: "right",
showOn: "click"
});
};
    
return self;
})();
// Start the application.
app.start();

Note: Spaces in Visual Studio project folder names will be converted to underscores ("_") in embeded resouce name, but spaces in filenames not.

 

If you have an embedded resource file, like:

 

image

 

The embedded resource filename will be:

 

Research.UnitTests.Folder_path_with_spaces.Text file with spaces.txt

 

The spaces in the foldername will be replaced by underscores (“_”), see Folder_path_with_spaces .

But the filename will contain spaces, see Text file with spaces.txt