How to use angular in a fancybox dynamically shown by jquery

In a brownfield application I encountered a old fancybox jquery plugin. This plugin was used throughout the whole application. This fancybox is just a modal dialog.

I wanted the content of the fancybox to be handled by angular.

 

To accomplish this, I used the following code:

 

image

 

 

You can find the code at:

 

https://github.com/roelvanlisdonk/Research/tree/master/Base/Web/src/Web/wwwroot/blog/fancybox

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;
})();

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

jQuery tip: Add an element as hidden and show on click.

If you want to add an element initially as hidden, just use CSS display: none.

In the onclick event, use jQuery to show the element.

 

TIP: Don’t use CSS visibility: hidden, because this will not work.

 

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Research</title>
<style type="text/css">
#page 
{
position: relative;
}
span.action 
{
cursor: pointer;
text-decoration: underline;
}
#elementToShow 
{
position: absolute;
width: 100px;
left: 30px;
top: 60px;
display: none;
/* visibility: hidden; */ /* <== This will not work*/
}
</style>
<script type="text/javascript" src="Scripts/jquery-2.0.0.min.js"></script>
<script type="text/javascript">
App = {};
$(document).ready(function ()
{
});
</script>
</head>
<body>
<div id="page">
<div id="elementToShow">Hello world!</div>
<span onclick="$('#elementToShow').show();" class="action">show</span>
<span onclick="$('#elementToShow').hide();" class="action">hide</span>
</div>
</body>
</html>

Initial

image

After clicking on "show"

image

How to add a CSS class to a HTML element, only when not present, by using jQuery.

You can add a CSS class to a HTML element, only when this class is not present on the HTML element, by using the jQuery function .toggleClass and using the switch parameter:

If your HTML page contains a div like:

<div id="title">
...
</div>

Adding the JavaScript code:

$(document).ready(function ()
{
// The CSS class "titleStyling", will now be added, because it is does not exist on the title yet.
$("#title").toggleClass("titleStyling", true);
// Subsequent calls will not add extra classes, where the jQuery .addClass will.
$("#title").toggleClass("titleStyling", true);
// Subsequent calls will not add extra classes, where the jQuery .addClass will.
$("#title").toggleClass("titleStyling", true);
});

Will result in

<div id="title" class="titleStyling">
...          
</div>

How to clear all canvases found in a div with jQuery

 

If you want to clear all canvases found in a given div with jQuery, you can use the following code:

    // Clear all canvases found in the given div, including all child canvases and sub child canvases.
$('#DivToFind canvas').each(function(idx, item) {
var context = item.getContext("2d");
context.clearRect(0, 0, item.width, item.height);
context.beginPath();        
});