How can I preload css background-image's using angularjs promises
What I want to do is something that I can use in this way:
link: function(scope, element, attrs){
element.hide();
url = attrs.url;
preload(url).then(function(loadedImageURL){
element.css({
background-image: "url('" + loadedImageURL + "')"
});
});
element.fadeIn();
}
Please note that this is not a duplicate question of this one.
Try this:
function preload(url) {
var deffered = $q.defer(),
image = new Image();
image.src = url;
if (image.complete) {
deffered.resolve();
} else {
image.addEventListener('load', function() {
deffered.resolve();
});
image.addEventListener('error', function() {
deffered.reject();
});
}
return deffered.promise;
}
Related
I am using angular way to apply css but it doesn't get applied whenever resize the window. canvas height is changed on resize window but table height only being applied when we scroll the window. I want to set the same height of canvas as soon as we resize the window.
How can I fix this?
angular.element(document).ready(function ($timeout) {
function update_table_height(canvasHeight) {
angular.element('.scrollableContainer').css("height", canvasHeight + 5 + "px");
}
angular.element(window).on("load resize scroll", function() {
var canvasHeight = angular.element('#chartCanvas').height();
update_table_height(canvasHeight);
});
$timeout(function(){
var canvasHeight = angular.element('#chartCanvas').height();
update_table_height(canvasHeight);
});
});
I think you need another timeout to wait for the render.
Maybe like this:
angular.element(window).on("load resize scroll", function() {
updateHeight();
});
function updateHeight(){
$timeout(function(){
var canvasHeight = angular.element('#chartCanvas').height();
table_height(canvasHeight);
});
}
// updateHeight on load
updateHeight();
Finally I did it with help of directive. Please suggest is that okay?
in index.html
<div class="ibox-content" match-window-height="['#chartCanvas']">
in app.directive.js
.directive('matchWindowHeight', function($timeout, $window) {
return {
restrict: 'A',
link: function (scope, el, attrs) {
var window = angular.element($window);
scope.$watch(function () {
var attribute = scope.$eval(attrs['matchWindowHeight']);
var targetElem = angular.element(document.querySelector(attribute[0]));
return targetElem.height();
},
function (newValue, oldValue) {
if (newValue != oldValue) {
el.css('height', newValue + 40 );
}
});
window.bind('load resize', function () {
scope.$apply();
});
}
};
});
I try to access the element in my own function through this.get_element() but it does not work.
Type.registerNamespace("LabelTimeExtender1");
LabelTimeExtender1.ClientBehavior1 = function(element) {
LabelTimeExtender1.ClientBehavior1.initializeBase(this, [element]);
var testelement=this.get_element();
var timestamp= this.get_element().attributes['TimeStamp'].value;
alert("in constructor");
},
LabelTimeExtender1.ClientBehavior1.prototype = {
initialize: function() {
LabelTimeExtender1.ClientBehavior1.callBaseMethod(this, 'initialize');
setInterval (this.timer,1000);
alert("after");
},
dispose: function() {
//Add custom dispose actions here
LabelTimeExtender1.ClientBehavior1.callBaseMethod(this, 'dispose');
},
timer: function(){
debugger;
var date= new Date(this.timestamp);
var datenow= new Date ();
this._element.innerText=" ";
if(date.getUTCFullYear<datenow.getUTCFullYear)
{
var myelement= this.get_element();
myelement .innerHTML= date.getUTCFullYear.toString();
}
if(date.getUTCMonth<datenow.getUTCMonth)
{
this.get_element().innerHTML=date.getUTCMonth.toString();
}
if(date.getUTCDay<datenow.getUTCDay)
{
this.get_element().innerHTML=date.getUTCDay.toString();
}
if(date.getUTCHours <datenow.getUTCHours )
{
this.get_element().innerHTML=date.getUTCHours .toString();
}
if(date.getUTCMinutes<datenow.getUTCMinutes)
{
this.get_element().innerHTML=date.getUTCMinutes.toString();
}
}
}
LabelTimeExtender1.ClientBehavior1.registerClass('LabelTimeExtender1.ClientBehavior1', Sys.UI.Behavior);
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
Here I am trying to access the custom attribute 'TimeStamp' and calcutate the time and assign to the label to show.
Try to invoke your function through delegates.Then you will not have problem with [this] keyword
something like this:
setInterval (Function.createDelegate(this, this.timer),1000)
Now that I have found a way to initialize Google Maps with the help of Andy Joslin in this SO initialize-google-map-in-angularjs, I am looking for a way to asynchronous load a Google Map Object.
I found an example of how to do this in the phonecat project.
Notice how the JS files are loaded in this example: index-async.html
In my Jade Scripts partial that is loaded into my program I tried:
script(src='js/lib/angular/angular.js')
script(src='js/lib/script/script.min.js')
script
$script([
'js/lib/angular/angular-resource.min.js',
'js/lib/jquery/jquery-1.7.2.min.js',
'http://maps.googleapis.com/maps/api/js?key=AIzaSyBTmi_pcXMZtLX5MWFRQgbVEYx-h-pDXO4&sensor=false',
'js/app.js',
'js/services.js',
'js/controllers.js',
'js/filters.js',
'js/directives.js',
'bootstrap/js/bootstrap.min.js'
], function() {
// when all is done, execute bootstrap angular application
angular.bootstrap(document, ['ofm']);
});
When I do this and go to load the map page I get:
A call to document.write() from an asycrononously-loaded
external script was ignored.
This is how Google Maps is being loaded now as a service:
'use strict';
var app = angular.module('ofm.services', []);
app.factory('GoogleMaps', function() {
var map_id = '#map';
var lat = 46.87916;
var lng = -3.32910;
var zoom = 15;
var map = initialize(map_id, lat, lng, zoom);
return map;
});
function initialize(map_id, lat, lng, zoom) {
var myOptions = {
zoom : 8,
center : new google.maps.LatLng(lat, lng),
mapTypeId : google.maps.MapTypeId.ROADMAP
};
return new google.maps.Map($(map_id)[0], myOptions);
}
It appears that this should be returning a promise from what I recall reading. But this AngularJS is very new to me.
here's my solution I came up without using jQuery:
(Gist here)
angular.module('testApp', []).
directive('lazyLoad', ['$window', '$q', function ($window, $q) {
function load_script() {
var s = document.createElement('script'); // use global document since Angular's $document is weak
s.src = 'https://maps.googleapis.com/maps/api/js?sensor=false&callback=initialize';
document.body.appendChild(s);
}
function lazyLoadApi(key) {
var deferred = $q.defer();
$window.initialize = function () {
deferred.resolve();
};
// thanks to Emil Stenström: http://friendlybit.com/js/lazy-loading-asyncronous-javascript/
if ($window.attachEvent) {
$window.attachEvent('onload', load_script);
} else {
$window.addEventListener('load', load_script, false);
}
return deferred.promise;
}
return {
restrict: 'E',
link: function (scope, element, attrs) { // function content is optional
// in this example, it shows how and when the promises are resolved
if ($window.google && $window.google.maps) {
console.log('gmaps already loaded');
} else {
lazyLoadApi().then(function () {
console.log('promise resolved');
if ($window.google && $window.google.maps) {
console.log('gmaps loaded');
} else {
console.log('gmaps not loaded');
}
}, function () {
console.log('promise rejected');
});
}
}
};
}]);
If you using jQuery in your AngularJS app, check out this function which returns a promise for when the Google Maps API has been loaded:
https://gist.github.com/gbakernet/828536
I was able to use this in a AngularJS directive to lazy-load Google Maps on demand.
Works a treat:
angular.module('mapModule') // usage: data-google-map
.directive('googleMap', ['$window', function ($window) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
// If Google maps is already present then just initialise my map
if ($window.google && $window.google.maps) {
initGoogleMaps();
} else {
loadGoogleMapsAsync();
}
function loadGoogleMapsAsync() {
// loadGoogleMaps() == jQuery function from https://gist.github.com/gbakernet/828536
$.when(loadGoogleMaps())
// When Google maps is loaded, add InfoBox - this is optional
.then(function () {
$.ajax({ url: "/resources/js/infobox.min.js", dataType: "script", async: false });
})
.done(function () {
initGoogleMaps();
});
};
function initGoogleMaps() {
// Load your Google map stuff here
// Remember to wrap scope variables inside `scope.$apply(function(){...});`
}
}
};
}]);
Take a look of this i think its more reliable
var deferred = $q.defer();
var script = document.createElement('script');
$window.initMap = function() {
//console.log("Map init ");
deferred.resolve();
}
script.src = "//maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places&callback=initMap";
document.body.appendChild(script);
return deferred.promise;
I'm trying to manually clean the HTML of a Telerik RadEditor with Javascript but I can't seem to find the correct place to store the value so that it gets saved on post back.
Here's the JS I have:
$(function () {
jQuery.fixHash = function ($html) {
// modify $html
return $html;
};
$("#adminEditingArea input[id$='SaveButton']").unbind("click").click(function () {
$("iframe[id$='_contentIframe']").trigger("save");
// call .net postback
return false;
});
});
var editorSaveEventInit = false;
function InitSaveEvent() {
if (!editorSaveEventInit) {
var $EditFrames = $("iframe[id$='_contentIframe']");
if ($EditFrames && $EditFrames.length > 0) {
$EditFrames.bind("save", function (e) {
var $thisFrame = $(this);
var thisFrameContents = $thisFrame.contents();
if (thisFrameContents) {
var telerikContentIFrame = thisFrameContents.get(0);
var $body = $("body", telerikContentIFrame);
var html = $.fixHash($body).html();
$body.html(html);
// also tried storing the modified HTML in the textarea, but it doesn't seem to save:
//$thisFrame.prev("textarea").html(encodeURIComponent("<body>" + html + "</body>"));
}
});
editorSaveEventInit = true;
}
}
};
$(window).load(function () {
InitSaveEvent();
});
Is there any way to access the Telerik RadEditor object with JavaScript (using OnClientCommandExecuted()?) so that I can access the .get_html() and .set_html(value) functions? If not, what values do I need to set before posting back?
Why don't you use custom content filters.
Ah, just discovered Telerik's built-in $find() function: http://www.telerik.com/help/aspnet-ajax/editor_getingreferencetoradeditor.html
Edit: here's the solution I came up with for my InitSaveEvent() function:
var editorSaveEventInit = false;
function InitSaveEvent() {
if (!editorSaveEventInit) {
var $EditFrames = $("iframe[id$='_contentIframe']");
if ($EditFrames && $EditFrames.length > 0) {
$EditFrames.bind("save", function (e) {
var $thisFrame = $(this);
var thisFrameContents = $thisFrame.contents();
if (thisFrameContents) {
var telerikContentIFrame = thisFrameContents.get(0);
var $body = $("body", telerikContentIFrame);
var html = $.fixHash($body).html();
// SOLUTION!
var $radeditor = $thisFrame.parents("div.RadEditor.Telerik:eq(0)");
var editor = $find($radeditor.attr("id"));
editor.set_html(html);
// ☺
}
});
editorSaveEventInit = true;
}
}
};
$(document).ready(function() {
$('#<%=ddlContinents.ClientID %>').change(function() {
var element = $(this);
var totalLength = element.children().length;
if ($(this).disabled == false) { $(this).disabled = true; }
});
});
What I am trying to do is fire off the change event of the dropdownlist and on change making this dropdownlist disabled. The code is firing and everything, but it does not disable the dropdownlist.
This portion of the code is not working:
if ($(this).disabled == false) { $(this).disabled = true; } });
You should use .prop() for jQuery 1.6+ or .attr() for earlier versions of jQuery:
> jQuery 1.6:
$(document).ready(function() {
$('#<%=ddlContinents.ClientID %>').change(function() {
var element = $(this);
var totalLength = element.children().length;
if (!$(this).prop("disabled")) {
$(this).prop("disabled", true);
}
});
});
< jQuery 1.6:
$(document).ready(function() {
$('#<%=ddlContinents.ClientID %>').change(function() {
var element = $(this);
var totalLength = element.children().length;
if (!$(this).attr("disabled")) {
$(this).attr("disabled", "disabled");
}
});
});
if (!$(this).attr("disabled")) { $(this).attr("disabled","disabled"); }
If you want to enable it later on, you gotta do:
$(this).removeAttr("disabled");
I know this post is old..This might help if anyone stuck with disabling dropdown on dropdown chnage function
if ($(this).attr('disabled', false))
{ $(this).attr('disabled', true);
}