How can I check to see if a Dojo dialog is loaded? - javascript

I am running a function that needs to close a Dojo dialog if it is loaded. How do I check if a dojo dialog is running? Do I use pure JavaScript and check by id if it is undefined?
if (dijit.byId("blah") !== undefined) {
destroyRecursive dijit;
}
Or do I use a property of the dialog object like:
isFocusable method
isLoaded property

Dialog provides two properties you might want to check: isLoaded and open. By digging the code you'll find the following descriptions:
open: True if Dialog is currently displayed on screen.
isLoaded: True if the ContentPane has data in it, either specified during initialization (via href or inline content), or set via attr('content', ...) / attr('href', ...) False if it doesn't have any content, or if ContentPane is still in the process of downloading href.
So, you could just:
var dialog = dijit.byId("blah");
if( dialog.open ) {
dialog.destroy();
}

Do you want to hide it or destroy it?
If you just want to show/hide it you can do the following:
var dialog = dijit.byId('blah');
if (dialog) {
if (dialog.open) {
dialog.hide();
}
else {
dialog.show();
}
}
If you wanted to destory it to free up memory:
var dialog = dijit.byId('blah');
dialog.destory();
I think destroy is recursive since it calls its parent destroy method and one of its parents is dijit.layout.ContentPane.

Related

jQuery dialog with <object>, cannot call dialog('close') from within object document

I have the following situation on a web application.
A dialog is built and opened on the fly when clicking on a link:
var dialogInitiator = $("<div id='dialog-initiator' style='background-color: "+bgcolor+";'>Loading...</div>");
dialogInitiator.appendTo(parentFrame);
dialogInitiator.dialog({
modal:true,
autoOpen: false
}).on('keydown', function(evt) {
if (evt.keyCode === $.ui.keyCode.ESCAPE) {
dialogInitiator.dialog('close');
}
evt.stopPropagation();
});
dialogInitiator.dialog('open');
Right after that, I load a new html page into the dialog, with an < object >, like this:
var objectFrame = $('<object style="border: 0;width:'+(dlwidth-30)+'px;min-height:'+(dlheight-46)+'px;" type="text/html" style="overflow:auto;" data="'+url+'"></object>');
dialogInitiator.html(objectFrame);
Now, the "url" variable contains a link to this new html document. When that page is ready, it will focus on an input field. This prevents the ESCAPE key from closing the dialog. So, I am trying to manually trigger the .dialog('close') event on escape keypress.
I do the following, from within the loaded document:
$('#dialog-initiator', window.parent.document).dialog('close');
It get the following error:
"Error: cannot call methods on dialog prior to initialization; attempted to call method 'close'"
Strange thing is, when i call:
console.log( $('#dialog-initiator', window.parent.document).html() );
it shows me the html from the dialog. So it actually IS initiated.
Well, I have tried to fix this error with the help of Google, but without success. I guess my situation is quite specific.
Note: we are forced to use the technique with loading this whole webpage into the dialog due to older functionality we used in modalDialogs. Since they are depricated in the latest Google Chrome, we've built a temporary solution with jQuery dialog.
I hope someone can help me out. I appreciate it!
You can try a global method created after the modal is created
dialogInitiator.dialog({
modal: true,
autoOpen: false,
create: funtion(e,ui) {
window.closeMyDialog = function() {
$('#dialog-initiator').dialog('close');
};
}
})...
Then call it by doing window.parent.closeMyDialog();.
Why not use JQuery UI? It's easier than making your own.
http://jqueryui.com/dialog/#default

Silverlight Control Caching in IE

Hi We have a silverlight control hosted in a hidden div (and height 0px) which is then shown within a jquery dialog when a user clicks a button the page
The initial showing of the dialog calls the onLoad param and initialises the silverlight control correctly. However the user has the option to close the dialog and hide the silverlight control.
The user can then show this dialog again (without reloading a page), however, in IE the onLoad param is not fired and consequently our silverlight control is not initialised correctly as we are handling hardware within it. In Chrome, however, the onLoad param is fired everytime the jquery dialog is shown
Two very different behaviours. I cant remove the the hidden div from the dom as it might be needed again
Is there a solution to forcibly reload the silverlight control so that the param onLoad is fired everytime the control is displayed with the jquery dialog?
TIA
Andrew
Not sure I got an overall idea. Raising onLoad is definitely not good.
but let me suggest solution above.
Register communication objects(aka functions) in JS and silverlight as well. So you will be able to communicate JS -> Silverlight
<script type="text/javascript">
function updateSilverlight() {
// call silverlight control method
var control = document.getElementById("silverlightControl");
control.Content.Page.SomeMethod("someData');
}
</script>
Annotate class like this:
[ScriptableType]
public partial class SomePage: UserControl
{
Annotate appropriate method inside SomePage
[ScriptableMember]
public void SomeMethod(string somedata)
{
var data = somedata;
}
where data is your re-init params...
hope that helps
Below is the code for opening dialog that contained the silverlight control
$('#ReadCard').on('click', function (e) {
$('#silverlightControlHost').height('300');
e.preventDefault();
//show the read card dialog
$("#readCardDialog").dialog({
autoOpen: true,
height: 390,
width: 550,
modal: true,
resizable: false,
buttons: {
'Close': function () {
Call_SL_OnBeforeUnload();
$(this).dialog("close");
}
}
});
});
On loading the silverlight control there is a method call to SilverlightInitialisation:
function onSilverlightLoad(sender, eventargs) {
.....
pluginElem.Content.SR_SMT.SilverlightInitialisation(inputArray);
}
Which was called by the optional silverlight paramater:
<param name="onload" value="onSilverlightLoad" />
This started the hardware that the silverlight control was talking to.
When the dialog was closed the method is called to stop the hardware:
Call_SL_OnBeforeUnload();
However when the dialog is shown again in IE the SilverlightInitialisation method is never called unless the user would refresh the page.
A work around was to alter the method (OnLoad) to the silverlight control that was always called when the dialog was opened but that checked a flag (hasLoaded) to see if it loaded previously:
Silverlight
[ScriptableMember]
public string OnLoad()
{
string retVal = G4T.SilverlightBadge.Resources.ResourcesFile.Present_Card;
if (_badgeReadCtrl != null && hasLoaded)
{
if (!_badgeReadCtrl.Initialise())
{
retVal = "Failed to initialise reader device";
}
}
return retVal;
}
The OnFirstLoad method was added which was called when the silverlight control first loaded and set the flag accordingly
[ScriptableMember]
public string OnFirstLoad()
{
string retVal = G4T.SilverlightBadge.Resources.ResourcesFile.Present_Card;
if (_badgeReadCtrl != null)
{
if (!_badgeReadCtrl.Initialise())
{
retVal = "Failed to initialise reader device";
}
}
hasLoaded = true;
return retVal;
}
Javascript
open: function (event, ui) {
try {
var plugin = document.getElementById('SilverlightMainControl');
if (plugin) {
plugin.Content.SR_SMT.OnLoad();
}
}
catch(e){}
},
Like I said above this always worked in Chrome without the modifications but in IE the initialisation is never called more than once
Hope all this makes sense - but i had to document it for future ref

How to check whether a twitter bootstrap popover is visible or not?

I have an element $('#anElement') with a potential popover attached, like
<div id="anElement" data-original-title="my title" data-trigger="manual" data-content="my content" rel="popover"></div>
I just would like to know how to check whether the popover is visible or not: how this can be accomplished with jQuery?
If this functionality is not built into the framework you are using (it's no longer twitter bootstrap, just bootstrap), then you'll have to inspect the HTML that is generated/modified to create this feature of bootstrap.
Take a look at the popupver documentation. There is a button there that you can use to see it in action. This is a great place to inspect the HTML elements that are at work behind the scene.
Crack open your chrome developers tools or firebug (of firefox) and take a look at what it happening. It looks like there is simply a <div> being inserted after the button -
<div class="popover fade right in" style="... />
All you would have to do is check for the existence of that element. Depending on how your markup is written, you could use something like this -
if ($("#popoverTrigger").next('div.popover:visible').length){
// popover is visible
}
#popoverTrigger is the element that triggered that popover to appear in the first place and as we noticed above, bootstrap simply appends the popover div after the element.
There is no method implemented explicitly in the boostrap popover plugin so you need to find a way around that. Here's a hack that will return true or false wheter the plugin is visible or not.
var isVisible = $('#anElement').data('bs.popover').tip().hasClass('in');
console.log(isVisible); // true or false
It accesses the data stored by the popover plugin which is in fact a Popover object, calls the object's tip() method which is responsible for fetching the tip element, and then checks if the element returned has the class in, which is indicative that the popover attached to that element is visible.
You should also check if there is a popover attached to make sure you can call the tip() method:
if ($('#anElement').data('bs.popover') instanceof Popover) {
// do your popover visibility check here
}
In the current version of Bootstrap, you can check whether your element has aria-describedby set. The value of the attribute is the id of the actual popover.
So for instance, if you want to change the content of the visible popover, you can do:
var popoverId = $('#myElement').attr('aria-describedby');
$('#myElement').next(popoverid, '.popover-content').html('my new content');
This checks if the given div is visible.
if ($('#div:visible').length > 0)
or
if ($('#div').is(':visible'))
Perhaps the most reliable option would be listening to shown/hidden events, as demonstrated below. This would eliminate the necessity of digging deep into the DOM that could be error prone.
var isMyPopoverVisible = false;//assuming popovers are hidden by default
$("#myPopoverElement").on('shown.bs.popover',function(){
isMyPopoverVisible = true;
});
$("#myPopoverElement").on('hidden.bs.popover',function(){
isMyPopoverVisible = false;
});
These events seem to be triggered even if you hide/show/toggle the popover programmatically, without user interaction.
P. S. tested with BS3.
Here is simple jQuery plugin to manage this. I've added few commented options to present different approaches of accessing objects and left uncommented that of my favor.
For current Bootstrap 4.0.0 you can take bundle with Popover.js: https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.bundle.min.js
// jQuery plugins
(function($)
{
// Fired immiedately
$.fn.isPopover = function (options)
{
// Is popover?
// jQuery
//var result = $(this).hasAttr("data-toggle");
// Popover API
var result = !!$(this).data('bs.popover');
if (!options) return result;
var $tip = this.popoverTip();
if (result) switch (options)
{
case 'shown' :
result = $tip.is(':visible');
break;
default:
result = false;
}
return result;
};
$.fn.popoverTip = function ()
{
// jQuery
var tipId = '#' + this.attr('aria-describedby');
return $(tipId);
// Popover API by id
//var tipId = this.data('bs.popover').tip.id;
//return $(tipId);
// Popover API by object
//var tip = this.data('bs.popover').tip; // DOM element
//return $(tip);
};
// Load indicator
$.fn.loadIndicator = function (action)
{
var indicatorClass = 'loading';
// Take parent if no container has been defined
var $container = this.closest('.loading-container') || this.parent();
switch (action)
{
case 'show' :
$container.append($('<div>').addClass(indicatorClass));
break;
case 'hide' :
$container.find('.' + indicatorClass).remove();
break;
}
};
})(jQuery);
// Usage
// Assuming 'this' points to popover object (e.g. an anchor or a button)
// Check if popover tip is visible
var isVisible = $(this).isPopover('shown');
// Hide all popovers except this
if (!isVisible) $('[data-toggle="popover"]').not(this).popover('hide');
// Show load indicator inside tip on 'shown' event while loading an iframe content
$(this).on('shown.bs.popover', function ()
{
$(this).popoverTip().find('iframe').loadIndicator('show');
});
Here a way to check the state with Vanilla JS.
document.getElementById("popover-dashboard").nextElementSibling.classList.contains('popover');
This works with BS4:
$(document).on('show.bs.tooltip','#anElement', function() {
$('#anElement').data('isvisible', true);
});
$(document).on('hidden.bs.tooltip','#anElement', function() {
$('#anElement').data('isvisible', false);
});
if ($('#anElement').data('isvisible'))
{
// popover is visible
$('#tipUTAbiertas').tooltip('hide');
$('#tipUTAbiertas').tooltip('show');
}
Bootstrap 5:
const toggler = document.getElementById(togglerId);
const popover = bootstrap.Popover.getInstance(toggler);
const isShowing = popover && popover.tip && popover.tip.classList.contains('show');
Using a popover with boostrap 4, tip() doesn't seem to be a function anymore. This is one way to check if a popover is enabled, basically if it has been clicked and is active:
if ($('#element').data('bs.popover')._activeTrigger.click == true){
...do something
}

Efficiently Composing a Dialog using BlockUI and jQuery

I am creating a small wrapper for the fantastic BlockUI plugin used in my application to easily create dialogs that meet my needs.
Sometimes I am a bit jQuery retarded and would like to know from any of the aficionados out there how they would do this particular task.
This function creates a header, middle and footer custom to my application. Uses some passed in options to fill out the HTML further. Composes the dialog and then inserts it into the BlockUI plugin.
function blockApp(element, options){
var header = jQuery('<div class="modal-header clearfix"><h2></h2><span></span></div>'),
center = jQuery('<div class="modal-content"></div>'),
footer = jQuery('<div class="modal-footer"></div>');
//Compose dialog
var opts = jQuery.extend({}, dialogDefaults, options);
header.find('h2').html(opts.title);
center.html(jQuery(element).html());
var comp = jQuery('<div></div>').append(header).append(center).append(footer);
jQuery('#notificationUI').block(jQuery.extend({}, standardBlock, {
message: comp,
}));
jQuery('.blockOverlay').click(function(){
jQuery('#notificationUI').unblock();
});
}
I tried using wrap() and wrapInner() at first with no success also.
My question is How would John Resig do this?
Not sure if this is what you're looking for but I've recently used BlockUI w/ another jQuery plug-in called jConfirm which you can download from here. With the jConfirm (or jAlert or jPrompt) you can fully customize your alert box via CSS. My scenario is probably way different than yours but in my app, user's can make changes to a document. If they choose to click my "cancel" button to erase all of their changes I have a jConfirm alert pop up while using BlockUI to dim out the interface from them. It looks pretty slick. Using jQuery I can catch the click event of my "cancel" button and do something like:
$('.cancel').click(function () {
$.alerts.dialogClass = 'my_css';
$.blockUI({ message: null });
jConfirm('Are you sure you want to cancel?', 'Cancel Changes?',
function (r) {
if (r.toString() == 'false') {
$.unblockUI();
} else {
//close window
}
});
return false;
});
Hope this helps!

Dojo Widget need event when everything is "ready"

i have an custom widget in dojo. My Problem is to check some kind of access rules wich are passed to the widget.
if check the rules after the widget is fully loaded everything works fine. But i have to remove some text and buttons before it is displayed.
I've tryted the startup, and postcreate hook (-: is there something like "aftercreate" ?
The first solution I can think of is to begin with hiding the restricted elements and then remove them.
In css:
.hidden{ display: none }
In widget's template for all permissions-sensitive elements:
<div class="${permissionsSensitiveElementsClass}">...</div>
In widget's code:
permissionsSensitiveElementsClass: "",
postMixInProperties: function(){
if(!this.hasPermissions()){
this.permissionsSensitiveElementsClass = "hidden";
}
this.inherited(arguments);
},
startup: function(){
// remove elements if necessary
},
hasPermissions: function(){
// permissions check
},
The final rendering function would be startup(). For widgets which are initially hidden, startup gets called automatically when call is made to show(). dijit.layout.Container has 'addChild(widget)' functionality, which will fire widget.startup() when a/multiple child(ren) are added.
You would benifit from:
http://dojotoolkit.org/documentation/tutorials/1.6/understanding_widget/
Widget lifecycle:
([widget].constructor());
[widget].postscript();
[widget].create();
[widget].postMixinProperties();
[widget].buildRendering();
[widget].postCreate(); // this is the most important one!
[widget].startup();
The true answer to your question lies here;
dojo.declare("mydijit", ["dijit/_Widget"], {
startup: function() {
// call superclass functionality before applying hide on specific elements
this.inherited(arguments);
if(foo) dojo.destroy(this.fooNode);
if(bar) dojo.destroy(this.barNode);
},
onShow: function() {
if(foo.changed || bar.changed) {
// act upon it
}
}
}

Categories

Resources