How to hide data that loads in the background? - javascript

I'm currently working on a mobile application in AngularJS under the Ionic Framework, and was wondering how to hide a user from loading some of my pages? Not only at the level of the lists, but on pages containing details of a product, or product sheet for example. :)
I know that the loading system (ionicLoading) can be used until the data is loaded, but when it is too much it is not very clean.
If you have suggestions or tricks, other than the loading, I am grabbing :)

My usual trick is to set a $scope variable to false, and then set it to true whenever whatever I'm waiting on is done. Usually, it's inside a promise, but for the sake of demo, we'll use $timeout.
With a boolean variable, we can then use Angular's built-in ng-hide and ng-show directives to control what DOM elements to hide/show based on our logic.
In the example here, $scope.loaded is false until our job is done (here, simply simulated with a 5 second $timeout)
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $timeout) {
$scope.loaded = false;
//Simulate loading
$timeout(function(){
$scope.loaded = true;
}, 5000);
});
.container {
border: solid 1px #ccc;
background: #eee;
margin: auto;
max-width: 800px;
text-align: center;
font-family: Verdana;
padding: 20px 0 5px;
}
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="http://fontawesome.io/assets/font-awesome/css/font-awesome.css" />
<script data-require="angular.js#1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<div class="container">
<div ng-hide="loaded">
<i class="fa fa-spinner fa-spin fa-3x fa-fw"></i>
<p>Loading...</p>
</div>
<div ng-show="loaded">
<i class="fa fa-check fa-3x fa-fw"></i>
<p>All done.</p>
</div>
</div>
</body>
</html>
Plunker mirror here: http://plnkr.co/edit/zEmdKQ3QBCpqORsb6RdT?p=preview

The implementation of ionicLoading is really easy to understand.
All the logic is allowed in your controller:
$ionicLoading.show({
template: 'Loading Data...', // The html content of the indicator
duration: 3000 // How many milliseconds to wait until automatically hiding the indicator
});
You need to put that before of making your request to your backend service or endpoint. When the request is finished, you only need to hide the overlay using the following method:
$ionicLoading.hide().then(function(){
console.log("The loading indicator is now hidden");
});
On the official docs, you can find more information about use this.

Related

" Cannot read property 'then' of undefined" in angular drag n drop

I am trying to use angular drag and drop http://codef0rmer.github.io/angular-dragdrop, but when I am trying a basic example, i am getting the error. My code -
<apex:page standardStylesheets="false" sidebar="false" showHeader="false">
<style>
table, th , td {
border: 1px solid grey;
border-collapse: collapse;
padding: 5px;
}
</style>
<html ng-app="myApp">
<link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap-responsive.min.css" rel="stylesheet" />
<div ng-controller="dragDropController">
<div class="row-fluid">
<div class="span6">
<div class="btn btn-primary" data-drag="true" ng-model="list" jqyoui-draggable="{animate: true}">{{list.title}}</div>
</div>
<div class="span6">
<div class="thumbnail" data-drop="true" ng-model="droppedList" jqyoui-droppable="{beforeDrop: 'beforeDrop'}"></div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
<script src="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js"></script>
<script src="{!$Resource.AngularDragDrop}" />
<script>
angular.module('myApp', ['ngDragDrop']).controller('dragDropController', function($scope, $http) {
$scope.list = {title : 'Drag me..!!'}
$scope.droppedList = {title: 'Drop place'};
$scope.beforeDrop = function() {
console.log('Before dropping..!!');
};
});
</script>
</html>
</apex:page>
Can someone help me with same.??
I have tried using same different versions of angular and also tried copying angular version from the actual site example but still facing same error
Thanks,
Ray
The beforeDrop function should return a promise (documentation).
The plugin executes your beforeDrop, where you would typically ask the user for confirmation, and then it "drops" (or not).
As you are not waiting for user input, to get rid of the error you could inject $q and return the dummiest promise, so to speak:
$scope.beforeDrop = function () {
console.log('Before dropping..!!');
return $q.when();
}
But the final look of beforeDrop will be more like:
$scope.beforeDrop = function () {
// open modal
// ...
return modalPromise;
}

Why does Angular binding fail when using <input type="file"/>?

I'm far from an expert on Angular, so I have to try asking a question here. I've added the possibility to upload files in may AngularJS project. I need to display the selected filename in a textbox (or preferably a read-only field) before the user submits the form. It contains a number of fields that need validation. The problem is, the selected filename never shows up. The textblock is still empty after selecting a file. I've tried the following code (Plunker: http://plnkr.co/edit/Ll3GZdpp8Tsqwvo0W1ax):
index.html:
<!DOCTYPE html>
<html ng-app="myApp">
<head lang="en">
<meta charset="utf-8" />
<title>Custom Plunker</title>
<script data-require="jquery#2.1.3" data-semver="2.1.3" src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<link data-require="bootstrap#*" data-semver="3.3.2" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" />
<script data-require="bootstrap#*" data-semver="3.3.2" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="http://angular-ui.github.com/ng-grid/css/ng-grid.css" />
<link rel="stylesheet" type="text/css" href="style.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<script type="text/javascript" src="http://angular-ui.github.com/ng-grid/lib/ng-grid.debug.js"></script>
<script type="text/javascript" src="main.js"></script>
</head>
<body ng-controller="MyCtrl">
<div class="row">
<div class="col-md-12">
<span class="btn btn-default btn-file">
Välj fil... <input type="file" onchange=" angular.element(this).scope().setFile(this) ">
</span>
<input type="text" ng-model="organizationSettings.logotypeFileName" />
</div>
</div>
</body>
</html>
app.js:
var app = angular.module('myApp', []);
app.controller('MyCtrl', function($scope) {
$scope.organizationSettings = {};
$scope.setFile = function(element) {
$scope.fileToUpload = element.files[0];
console.log($scope.fileToUpload.name);
$scope.organizationSettings.logotypeFileName = $scope.fileToUpload.name;
};
});
css:
.btn-file {
position: relative;
overflow: hidden;
}
.btn-file input[type=file] {
position: absolute;
top: 0;
right: 0;
min-width: 100%;
min-height: 100%;
font-size: 100px;
text-align: right;
filter: alpha(opacity=0);
opacity: 0;
outline: none;
background: white;
cursor: inherit;
display: block;
}
The reason is you are using onchange which is an event outside of any of angular's directives.
Whenever you use an event outside of angular that changes the scope, you need to notify that a digest is needed to update the part of the view managed by that scope by using $apply
The simplest fix is to use ng-change instead of native onchange. All of angulars event handling directives will trigger $apply internally
The alternative (not best approach) would be keep the onchange and do:
$scope.setFile = function(element) {
$scope.fileToUpload = element.files[0];
console.log($scope.fileToUpload.name);
$scope.organizationSettings.logotypeFileName = $scope.fileToUpload.name;
$scope.$apply();
};
You can't use ng-change for file upload because binding is not supported for file upload in angularjs., its an issue in angularjs.
In other cases while you are using ng-change(other than file upload) you have to use ng-model to make the ng-change directive work in order to trigger change based on it(so only you are getting "Error: No controller: ngModel") while using it.
The best possible solution is you manually trigger $scope.$apply() to make binding to the input model while programatically setting it.
I think that binding changes could be done easier, and I will explain below how to do it. By setting a ng-model to the input, it will automatically bind the input control to the variable defined in your controller's scope. Therefore, if you specify a new file, it will automatically update the model $scope.fileToUpload. This goes the other way around: any change in $scope.fileToUpload done in JS, will be reflected in the DOM.
index.html - try to replace
<input type="file" onchange=" angular.element(this).scope().setFile(this) ">
with
<input type="file" ng-model="fileToUpload">
In app.js, you could get rid of:
$scope.setFile = function(element) {
$scope.fileToUpload = element.files[0];
console.log($scope.fileToUpload.name);
$scope.organizationSettings.logotypeFileName = $scope.fileToUpload.name;
};

AngularJS: Add a loader element to top of DOM

Been trying to find out how to do this the best way but haven't found any answers, don't know if I suck at searching or no-one has asked the question. Probably the first one, but anyway.
I'm wondering what the best way is to add an element to the top of the DOM (so that it is on top of everything else) in AngularJS?
My solution to this problem now is to show a modal with the loading spinner in it but I think this is an ugly solution as it shouldn't be that hard to add my own div-element to the DOM that are showing the spinner.
This is the code I have in my modal right now:
<div class="modal-body" style="text-align: center;">
<i class="fa fa-spinner fa-spin fa-5x"></i>
</div>
So you can understand why I think it's unnecessary and ugly to have it in a modal. I've been reading about directives but not really sure how it would look like and how I would show it where I want it to be shown.
I just created something just like this for a project of mine. You can make a div and set the size to 100% of the screen. Set some variable on it so that it shows only when the data is loading.
I used the following CSS for mine:
#overlay {
position: fixed;
width: 100%;
height: 100%;
background: rgba(0,0,0,.5);
z-index:10000;
text-align: center;
vertical-align: middle;
}
Its important to make a large z-index so that it shows on top of everything, and I used a semi-transparent overlay. You can style however you'd like.
And html like the following:
<div id="overlay" data-loading>
<i class="icon-spinner icon-do-spin" ></i>
</div>
FYI - 'icon-do-spin' is a cool class provided by FontAwesome to animate the spinner icon that you are using, and 'data-loading' is a directive I used to check for when all http pending requests are completed. You could just use something like ng-show/ng-hide/ng-if to show or hide the loading div.
In Angular, in order to work with DOM, you need a directive. And to control loader, you need a service. Here is a very simple demo for you. The principle is: directive watches for state change in service and draws "loader" if service says that loader shoud be presented:
index.html
<!DOCTYPE html>
<html data-ng-app="Demo">
<head>
<script data-require="angular.js#1.2.22" data-semver="1.2.22" src="https://code.angularjs.org/1.2.22/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body data-ng-controller="LoaderController as ctrl">
<div data-loader class="loader" data-ng-class="{'visible':Loader.visible}"></div>
<button data-ng-click="ctrl.show(true)">Loader</button>
</body>
</html>
script.js
(function() {
'use strict';
angular.module('Demo', []);
angular.module('Demo').directive('loader', [function(){
return {
'restrict' : 'A',
'controller' : ['$scope', 'Loader', function($scope, Loader){
$scope.Loader = Loader;
}]
}
}]);
angular.module('Demo').factory('Loader', [function(){
var instance = {}
instance.show = function(on){
instance.visible = on;
}
return instance;
}]);
angular.module('Demo').controller('LoaderController', ['$timeout', 'Loader', function($timeout, Loader){
this.show = function(){
Loader.show(true);
$timeout(function(){
Loader.show(false);
}, 5000)
}
}]);
})();
style.css
html, body {
margin: 0;
padding: 0;
}
.loader {
opacity: .5;
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(255, 0, 0, 0.5);
display: none;
}
.loader.visible {
display: block;
}

jQuery UI does not load on $("#content").load page for .button

I seem to make a mistake in the following:
html: index.html, main.html, etc
js: jQuery, jQuery UI, own.js, own_main.js
The end result should be an index page that based on a menu choice loads a html in a div.
The HTML that loads has a button element that I want to use with jQuery UI.
Index.html
<html lang="us">
<head>
<meta charset="utf-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Dev</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/kendo.dataviz.default.min.css" rel="stylesheet" />
<link href="css/kendo.dataviz.min.css" rel="stylesheet" />
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/bootstrap-theme.min.css">
<link rel="stylesheet" href="css/main.css">
<link href="css/jquery-ui-1.10.3.custom.css" rel="stylesheet">
<link href="css/typ.css" rel="stylesheet" />
<script src="js/modernizr-2.6.2-respond-1.1.0.min.js"></script>
<script src="Scripts/jquery-2.0.3.js"></script>
<script src="js/jquery-ui-1.10.3.custom.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/typ.js"></script>
<script src="js/typ-persons.js"></script>
</head>
<body>
<div id="content"></div>
</body>
</html>
typ.js file
function currentLoc(goToLoc) {
if (CheckLogin() == 0) {
//Not logged in, go to main
$("#content").load("/main.html");
window.localStorage.globalLocation = "/main.html";
} else {
if (goToLoc == '') {
console.log("No GoToLoc: " + goToLoc);
if (window.localStorage.globalLocation == '') {
console.log("No Global location");
$("#content").load("/main.html");
window.localStorage.globalLocation = "/main.html";
} else {
console.log("Global Location " + window.localStorage.globalLocation);
$("#content").load(window.localStorage.globalLocation);
}
} else {
console.log("GoToLoc " + goToLoc);
$("#content").load(goToLoc);
window.localStorage.globalLocation = goToLoc;
}
}
}
persons.html
<script src="js/typ-persons.js"></script>
<div class="container">
<style>
#toolbar {
padding: 4px;
display: inline-block;
}
/* support: IE7 */
* + html #toolbar {
display: inline;
}
</style>
<div id="toolbar" style="width:100%;" class="ui-widget-header ui-corner-all">
<button id="btnNew" ></button>
<button id="btnSave"></button>
<label for="persons">Find Person by Name or ID: </label>
<input type="text" class="input-sm" id="persons">
<input type="hidden" id="person-id">
</div>
</div>
typ-persons.js
$(function () {
$("#btnNew").button({
text: false,
label: "New Person",
icons: {
primary: "ui-icon-document"
}
})
.click(function () {
});
$("#btnSave").button({
text: false,
label: "Save",
disabled: true,
icons: {
primary: "ui-icon-disk"
}
})
.click(function () {
});
});
On the persons page there is also an autocomplete element with json data.
This works like a charm.
The problem is that the toolbar does not get the buttons applied from the typ-persons.js.
When I add the jQuery UI to the persons.html the buttons do work and get styled as they are supposed to.
The problem then is that jQuery UI loads twice and the autocomplete drowdown disappears on mouse over.
Kind of a paradox here and I would like both to work.
Thanks for your help,
Joris
I have the hunch that your persons.html file is the main.html addressed in the code. Otherwise I can't see where do you load persons.html or what are you loading when you load main.html.
Why are you adding typ-persons.js to persons.html, if you already have it in your main html file? In the way it's added, there's going to be double binding on button clicks. More than once, I believe. It would work on first load and then screw button behavior for good.
EDIT: After OP clarifications, these are my suggestions.
First: instead of putting new JS into persons html, make it just plain html. Make sure you don't use id attributes when that content is prone to be loaded several times. In that case, it's best to use classes.
<div class="container">
<style>
#toolbar {
padding: 4px;
display: inline-block;
}
/* support: IE7 */
* + html #toolbar {
display: inline;
}
</style>
<div id="toolbar" style="width:100%;" class="ui-widget-header ui-corner-all">
<button class="btnNew" ></button>
<button class="btnSave"></button>
<label for="persons">Find Person by Name or ID: </label>
<input type="text" class="input-sm" id="persons">
<input type="hidden" id="person-id">
</div>
</div>
Second: since you won't load new JS in that ajax call, you need to give the new buttons their behavior somewhere, right? Try to do that after they're appended, using jQuery's callback. I'd reccomend you use get method instead of load to have a bit more control on new content. Instead of
$("#content").load("/persons.html");
Try
$.get("/persons.html",function(responseText) {
var newElement=jQuery(responseText);
$("#content").append(newElement);
$(".btnNew", newElement).button({
text: false,
label: "New Person",
icons: {
primary: "ui-icon-document"
}
}).click(function () {
});
$(".btnSave",newElement).button({
text: false,
label: "Save",
disabled: true,
icons: {
primary: "ui-icon-disk"
}
}).click(function () {
});
});
Third: whatever listener you need to be set on dynamic elements, delegate them to the document to avoid needing to redeclare it (with the risk of double binding). I see no examples of this in your original post, but if you have any case of click, focus, or blur listeners (to name a few) I'll include a practical example.

Application requires a refresh to initialize

Creating a web mapping application in Javascript/Dojo:
When I load the app in a browser it loads the html elements but then stops processing. I have to refresh the browser to get it to load the rest of the page and the javascript.
I have done testing and debugging all day and figured out I had my external JS files in the wrong spot (I'm a rookie). Fixed that and the app loads great...EXCEPT one of my files isn't getting read correctly, or at all.
When I move the contents of the external JS file in question to the main code in the default, the functionality that they contain, work fine... BUT the map requires the refresh again.
Stumped. Below is the code in the external JS file that is causing my issue. I can't figure out why it is a problem because the functions work as expected when it is not external.
Any help is greatly appreciated.
//Toggles
function basemapToggle() {
basemaptoggler = new dojo.fx.Toggler({
node: "basemaptoggle",
showFunc : dojo.fx.wipeIn,
showDuration: 1000,
hideDuration: 1000,
hideFunc : dojo.fx.wipeOut
})
}
dojo.addOnLoad(basemapToggle);
function layerToggle() {
layertoggler = new dojo.fx.Toggler({
node: "layertoggle",
showFunc : dojo.fx.wipeIn,
showDuration: 750,
hideDuration: 750,
hideFunc : dojo.fx.wipeOut
})
}
dojo.addOnLoad(layerToggle);
function legendToggle() {
legendtoggler = new dojo.fx.Toggler({
node: "legendtoggle",
showFunc : dojo.fx.wipeIn,
hideFunc : dojo.fx.wipeOut
})
}
dojo.addOnLoad(legendToggle);
EDIT
Edited to show additional code. Genuinely stumped by this. Would love to get some feedback. I've tried moving it to the main file, reformatting the functions and all of those things work, except they require the refresh. I'm also losing some information on a refresh. Very odd behavior. Any good way to track this down?
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=7, IE=8, IE=9" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
<link rel="Stylesheet" href="ZoningClassifications.css" />
<link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/dojo/dijit/themes/claro/claro.css">
<link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/esri/dijit/css/Popup.css">
<link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/dojo/dojox/grid/resources/Grid.css">
<link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/dojo/dojox/grid/resources/claroGrid.css">
<style type="text/css">
</style>
<script src="JS/layers.js"></script>
<script src="JS/search.js"></script>
<script src="JS/basemapgallery.js"></script>
<script src="JS/toggles.js"></script>
<script src="JS/identify.js"></script>
<script type="text/javascript">
var djConfig = {
parseOnLoad: true
};
</script>
<script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=3.0"></script>
<script type="text/javascript">
dojo.require("dijit.dijit"); // optimize: load dijit layer
dojo.require("dijit.layout.BorderContainer");
dojo.require("dijit.layout.ContentPane");
dojo.require("esri.map");
dojo.require("dijit.TitlePane");
dojo.require("esri.dijit.BasemapGallery");
dojo.require("esri.arcgis.utils");
dojo.require("esri.tasks.locator");
dojo.require("esri.dijit.Legend");
dojo.require("esri.dijit.Popup");
dojo.require("dijit.form.Button");
dojo.require("dojo.fx");
dojo.require("dijit.Dialog");
dojo.require("dojo.ready");
dojo.require("dijit.TooltipDialog");
dojo.require("dojox.grid.DataGrid");
dojo.require("dojo.data.ItemFileReadStore");
dojo.require("esri.tasks.find");
var map, locator, layer, visible = [];
var legendLayers = [];
var resizeTimer;
var identifyTask,identifyParams;
var findTask, findParams;
var basemaptoggler = null;
var layertoggler = null;
var legendtoggler = null;
var findTaskParcel, findParamsParcel;
// var gridParcel, storeParcel;
EDIT 2
I've completely rewritten the app placing all the code (except the css) in the main default.html file. I tested piece by piece to make sure it functioned how I want. Adding the toggles code is the only code that throws it and causes the extra refresh.
So for now I am using dijit.TitlePane to hold the drop down elements (basemap gallery, layers, legend). However with this you can not change the look and feel to make them images, which is my end goal.
Can anybody suggest an alternative so I can use 3 different images so that when you click on the image and drop down menu opens holding the basemap gallery, layer list and legend?
EDIT 3
It'll probably help to show the code I use to call the toggle functions: I suspect this might be where my issues are.
<!--Legend-->
<div id="subheader">
<div style="position:absolute; right:60px; top:10px; z-Index:98;">
<div id="legendbutton">
<button dojoType="dijit.form.Button" baseClass="tomButton" title="Show Legend">
<img src="images/Legend.png" />
<script type="dojo/method" event="onClick">
legendtoggler[(dojo.style("legendtoggle","display") == "none") ? 'show':'hide']();
</script>
</button>
<div id="legendtoggle" dojoType="dijit.layout.ContentPane" style="border: 1px solid black; display: none">
<div id="legendDiv"></div>
</div>
</div>
<!--Layer Toggle-->
<div id="layerbutton">
<button dojoType="dijit.form.Button" baseClass="tomButton" border="0" title="Toggle Layers">
<img src="images/layers.png"/>
<script type="dojo/method" event="onClick">
layertoggler[(dojo.style("layertoggle","display") == "none") ? 'show':'hide']();
</script>
</button>
<div id="layertoggle" dojoType="dijit.layout.ContentPane" style="border: 1px solid black; display: none">
<span id="layer_list"><input type='checkbox' class='list_item' id='0' value=0 onclick='updateLayerVisibility();'
</span>
</div>
</div>
<!--Basemap Gallery-->
<div id="basemapbutton">
<button dojoType="dijit.form.Button" baseClass="tomButton" title="Switch Basemap">
<img src="images/imgBaseMap.png"/>
<script type="dojo/method" event="onClick">
</script>
</button>
<div id="basemaptoggle" dojoType="dijit.layout.ContentPane" style="#900;display: none;">
<span id="basemapGallery">
</span>
</div>
</div>
As a Workaround here is something similar I did:
http://www.martindueren.de/paperwriting/
The Icons on the right hand side of the app make dijit.TitlePanes wipe in and out. The effect used for this can be found on this page:
http://dojotoolkit.org/documentation/tutorials/1.8/effects/
The code for this would be something like this:
<button id="slideAwayButton">Slide block away</button>
<button id="slideBackButton">Slide block back</button>
<div id="slideTarget" class="red-block slide">
A red block
</div>
<script>
require(["dojo/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(fx, on, dom) {
var slideAwayButton = dom.byId("slideAwayButton"),
slideBackButton = dom.byId("slideBackButton"),
slideTarget = dom.byId("slideTarget");
on(slideAwayButton, "click", function(evt){
fx.slideTo({ node: slideTarget, left: "200", top: "200" }).play();
});
on(slideBackButton, "click", function(evt){
fx.slideTo({ node: slideTarget, left: "0", top: "100" }).play();
});
});
</script>
Feel free to look at my source-code and copy stuff from it! If I understood you correctly this is exactly what you need too.
Quite the story youve put up here, its difficult to pinpoint, excactly what your issue is.. But since youre saying 'map need an extra refresh', then im guessing it could be due to the flow of things you call require for. Problem may very well be, that youre rolling out legacy loader code from a dojo-version which is AMD loader capeable.
Since i really havent run any esri components before, this is kind of a wild guess - but from my pov it could be worth a shot. Im sure google maps has an onload listener - and i suspect esri to follow this behavior.
Try initializing everything in your application before loading any esri modules, like such:
dojo.addOnLoad(function() {
basemapToggle();
layerToggle();
legendToggle();
dojo.require("esri.map");
dojo.require("esri.dijit.BasemapGallery");
dojo.require("esri.arcgis.utils");
dojo.require("esri.tasks.locator");
dojo.require("esri.dijit.Legend");
dojo.require("esri.dijit.Popup");
dojo.require("esri.tasks.find");
});
As goes for the effects youre looking for, personally i'd make use of dojo.animateProperty and combine it with dijit/TooltipDialog.
This http://jsfiddle.net/seeds/a8BBm/2/ shows how to 'hack' the onShow mechanizm, leaving optional effects possible in the opening animation. By default, DropDownButton simply fades in.
See http://livedocs.dojotoolkit.org/dijit/TooltipDialog#programmatic-example for alternate ways to popup the tooltipdialog - i.e. connecting dijit.popup to any click/mouseover event.

Categories

Resources