Prevent kendo tooltip hide/close when clicking outside the tooltip? - javascript

I know that there are people ask kendo to prevent kendo tooltip from close/hide whenever we click outside the tooltip. They are suggesting it here but seems that it has not been implemented yet.
I couldn't find the method which closes/hides when we click outside kendo tooltip so far. I only found the event triggered when we click on close or cancel button on kendo tooltip. But is there any way/hackish way to achieve this using javascript/jquery/anything?

Like you see in link that you included the kendo tooltip (with autoHide: false property) hides when you:
click outside the tooltip
scroll page
hit Esc
Until Telerik will not implement function to prevent it, the only way is using jquery event.stopImmediatePropagation(). For example for block tootlip from hide when you click outside you can write:
$("#target").kendoTooltip({
autoHide: false
});
$('html').on('mousedown', function(e){
e.stopImmediatePropagation();
});
Working demo: http://dojo.telerik.com/ugUCI
Unfortunately it will prevent any html onmousedown events like DropDownLists/ComboBoxes hiding etc.

You can override the close function of the kendo UI popup class to prevent execution. My solution was to throw a custom exception in the 'hide' handler and prevent the close from happening if this custom exception is caught.
kendo.ui.Popup.fn.close = function (close) {
return function (skipeffects) {
try {
close.call(this, skipeffects);
} catch (err) {
// suppress error if its the right type
if (!(err instanceof PreventTooltipHideException)) {
throw err;
}
}
}
}(kendo.ui.Popup.fn.close);
var tooltip = $('#' + areaId).kendoTooltip({
content: "Hello World!",
hide: function (e) {
throw new PreventTooltipHideException();
},
autoHide: false
});

Related

Kendo UI Chart disable legend item right click event

I have an application that uses a Kendo UI Chart with a legend. When the user clicks on a legend item, the Kendo onLegendItemClick(e) method gets called. However the event that gets passed to this function does not contain the originalEvent, so there is no way to distinguish between right and left clicks.
Here is the relevant API reference: https://docs.telerik.com/kendo-ui/api/javascript/dataviz/ui/chart/events/legenditemclick
I tried adding an event listener and capturing the 'mousedown' event before onLegendItemClick is invoked as shown below. However, this approach will fail on touch screen devices (iPads, tablets, mobile devices, etc).
document.addEventListener("mousedown", saveMouseDown, true);
function saveMouseDown(ev) {
$scope.mouseDownEvent = ev;
}
$scope.$on("$destroy", function () {
document.removeEventListener(saveMouseDown);
});
The application has a separate directive for handling right clicks. Is there a way to prevent Kendo from calling the onLegendItemClick(e) method when a user right clicks the legend item?
Add "click" to the list of saved events1:
document.addEventListener("mousedown click", saveEvent, true);
function saveEvent(ev) {
$scope.savedEvent = ev;
}
$scope.$on("$destroy", function () {
document.removeEventListener(saveEvent);
});
Related question: How to prevent right click from deselecting marker in Kendo-UI

How to catch event when user clicks outside of bootstrap modal dialog?

Scenario:
I click on a button
Ajax call is made to the server
data is returned and modal is shown
Problem:
When user clicks on the close button or the "X" in the corner I catch this event by assigning a class to these two elements and assigning an event to this class.
Code:
$(document).on("click", ".dialogTankClose", function() {
//some code
})
My problem is that i can't figure out how to catch when the user clicks outside of the dialog or presses "escape".
$(document).on("click", "modalCloseEvent",function(){
// how to catch this?
})
How can I catch this?
The Bootstrap modal raises an event when it closes, which you can hook to: hidden.bs.modal. This event fires no matter how the modal is closed. Try this:
$('#bootstrapModal').on("hidden.bs.modal", function() {
$.automation.worker.bindIntervalEvent("#TanksContent", "/Tank/GetTanks", function () {
$.automation.tanks.tableInit();
});
});
You can use a delegated event handler if the modal is dynamically added to the DOM:
$(document).on("hidden.bs.modal", '#bootstrapModal', function() {
$.automation.worker.bindIntervalEvent("#TanksContent", "/Tank/GetTanks", function () {
$.automation.tanks.tableInit();
});
});
More information in the Bootstrap documentation
You can use 'hidden.bs.modal' modal method to run custom code while modal is getting unload / hide from document.
$('#your-modal-ID').on('hidden.bs.modal', function (e) {
console.log("Hey !! I am unloading... ");
});

Close jQuery UI Dialog on mouse click outside of box

So I have some jQuery UI Dialogs and for user usability I think it would be best if users would be able to close the dialog box when clicking outside the box instead of having to click the small close button on the dialog box.
jQuery Code:
$(document).ready(function() {
var dlg=$('#createTeam').dialog({
title: 'Create a Team',
resizable: true,
autoOpen:false,
modal: true,
hide: 'fade',
width:600,
height:285,
clickOutside: true, // clicking outside the dialog will close it
clickOutsideTrigger: "#addEngineer",
close: function(event, ui) {
location.reload();
}
});
$('#createTeamLink').click(function(e) {
dlg.load('admin/addTeam.php');
e.preventDefault();
dlg.dialog('open');
});
});
Can anyone advise on what I need to add to the code above to be able to close the dialog box on mouse click outside of the box?
I'm not sure why the clickOutside : true property isn't working though I can provide a simple workaround. On the page with the modal, you can catch body click events like so:
$(document).click(function() {
dlg.dialog('close');
});
However, this will be ANY click event on the page, so we have to exclude clicking on the modal from firing this event handler. It seems you have already done this with e.preventDefault() however, so add the above code and it should work. A better solution would be to include a modal backdrop in your modal HTML, and catch click events on that. If you provide your HTML I'll give you an example of this.

Remove beforeClose event handler - jQuery UI Dialog

I have a jQuery UI dialog box with a form inside it. I'm trying to implement a feature where if a field in the form has been modified, we'll be showing a confirmation message using noty
Now, unlike an javaScript confirmation box, noty does not stop script execution. So, in the dialog beforeClose event, I'm -
Showing a noty confirmation if form data is modified and then returning false.
Simply returning true if the form data has not been modified.
All is working well. Now we ask the user -
The data in the form has been modified. Are you sure you want to close?
If he clicks no - we simply close the noty and keep the dialog box open.
But if he clicks yes, we try to close the dialog box, which triggers the beforeClose event handler again and we go into the loop again.
I've tried calling .off on the div that has been converted to a dialog box before calling the close event, but that doesn't seem to be removing the click.
Here is a simple pseudo code to explain the issue -
DialogCloseEvent() {
if data has been modified {
Show noty {
// IMPORTANT - This is executed after return false.
in noty user clicks NO - do not close dialog box {
close noty and done
}
in noty user clicks YES - close the dialog box {
// This calls the DialogCloseEvent again.
call the close method of the dialog box.
close noty
}
}
return false
}
no it has not been modifed {
// Closes the dialog without calling the event again
return true;
}
}
Expanding on your pseudo code you could add a flag to force close the dialog:
var forceClose = false;
DialogCloseEvent() {
if data has been modified and !forceClose {
Show noty {
// IMPORTANT - This is executed after return false.
in noty user clicks NO - do not close dialog box {
close noty and done
}
in noty user clicks YES{
forceClose = true;
- close the dialog box {
// This calls the DialogCloseEvent again.
call the close method of the dialog box.
close noty
}
}
}
return false
}
no it has not been modifed {
// Closes the dialog without calling the event again
return true;
}
}
UPDATE with code
var forceClose = false;
$("#dialog").dialog({
open: function (event, ui) {
forceClose = false; //reset the flag each time
},
beforeClose: function (event, ui) {
if(forceClose){
return true;
}
//your dialog close event
//set the flag to true when you want to close the jqueryui dialog
}
});
According to the code for the close API for Jquery UI dialog, there is no way not to force close a dialog without firing events. Ideally there should be an API which just executes the functionality without triggering events. I tried just a way to enable this by replicating the method for now. Best way as an addition to the API itself. So the change is something on the lines of this,
// code from existing
if(!forceClose && this._trigger("beforeClose") === false){
return;
}
// continue with existing
Have a fiddle for the same here http://jsfiddle.net/Lj3Nk/1/
Going to submit a feature/pull request to jquery ui now. Will update with details when done. In the mean while, let me know if this helps.
UPDATE
Jquery ui ticket - http://bugs.jqueryui.com/ticket/9943
Pull request - https://github.com/jquery/jquery-ui/pull/1218
Example 1
Based on the flag approach:
var notyStatus = null;
$("#dialog").dialog({
beforeClose: function (event, ui) {
// possible values for notyStatus are
// null: preventDefault and show the warning
// else: do nothing and let the dialog close
if (notyStatus === null) {
event.preventDefault();
$('<p title="Replace me with noty">Close the dialog?</p>').dialog({
modal: true,
buttons: {
"Close": function () {
notyStatus = true;
$(this).dialog("close");
$("#dialog").dialog("close");
},
"Keep Open": function () {
$(this).dialog("close");
}
}
});
}
}
});
Demo 1
Example 2
Remove the beforeClose event handler. You can use .dialog("option", "beforeClose") to get, set or unset the event handler. The code looks like this:
$("#dialog").dialog({
beforeClose: function (event, ui) {
event.preventDefault();
$('<p title="Replace me with noty">Close the dialog?</p>').dialog({
modal: true,
buttons: {
"Close": function () {
$(this).dialog("close");
$("#dialog")
.dialog("option", "beforeClose", null)
.dialog("close");
},
"Keep Open": function () {
$(this).dialog("close");
}
}
});
}
});
Demo 2
In both examples, replace the inner jQuery UI confirmation dialog code with noty. It allows you to create action buttons with callbacks so the code will be similar.
You can use the dialog widget's "option" method to change or remove the beforeClose event handler.
So when the user clicks 'yes', you could get the dialog to close by executing:
$('#myDialog')
.dialog('option', 'beforeClose', function() {})
.dialog('close');
Here's a fiddle that shows how it works: http://jsfiddle.net/BrDE7/1/
Jquery UI documentation on the "option" method: http://api.jqueryui.com/dialog/#method-option

Jquery ui dialog not closing with `Escape` keypress

When a user opens dialog, there are a bunch of ajax requests that have to be processed and therefore i have a second dialog that just displays loading information and closes once all the requests have been processed.
I am not able to close the user opened dialog with Escape key once it has opened. I have to click on the the dialog itself before I can use escape.
I have tried the following to assign the user opened dialog the focus after the loading dialog closes but to no avail, I still have to click on the dialog before it can close with the escape key.
$(document).ajaxStart(function () {
// IF loading dialog is not allready being shown show it.
if ($("#LoadingData").dialog('isOpen') === false) {
$("#LoadingData").dialog('open');
}
});
$(document).ajaxStop(function () {
//Close the loading dialog once the requests have finished
$("#LoadingData").dialog('close');
//Find the user opened dialog
$('.cmdialog').each(function () {
if ($(this).dialog('isOpen')) {
$(this).trigger('click');//set focus to dialog
// have also replaced .trigger('click') with .focus() but to no avail
}
}).on('click', function() {
//if click is triggerd set the focus of the dialog.
if ($(this).prop('id') != 'LoadingData') {
$(this).focus();
}
});
});
I have also tried setting the focus to the first element within the dialog with $('#DialogName:first-child').focus() and $('#DialogName:first-child').trigger('click') but this is also not working.
Any ideas as to why the focus is not set? Or am I misunderstanding/incorrectly using .focus() and .trigger('event')?
Thanks :)
Try the below code for close the dialog when Escap key is pressed:
$(document).keyup(function(e) {
if (e.keyCode == 27) { $("#LoadingData").dialog('close'); } // esc
});
I had the same issue, and found pretty elegant solution, in case you want to close dialog before actually clicking inside it:
$("#LoadingData").dialog({
...,
focus: function () {
$('#LoadingData').closest('.ui-dialog').focus();
}
});
So, we just need to set focus to parent .ui-dialog container, and in that case Esc will work for all cases. Disadvantage of $(document).keyup solution, if you have nested dialogs, Esc button will close your most top dialog and bottom one too.
the focus event is sent to an element when it gains focus. This event is implicitly applicable to a limited set of elements, such as form elements (, , etc.) and links. docs here
You can try moveToTop method of the dialog, maybe it will help
And in your code, I think, you should bind "click" event before triggering it.
The following code should work even for multiple modals open:
$(document).on('keydown','.modal-dialog',function(event){
if (event.keyCode == 27) {
$(this).closest('.modal-dialog').find('[data-dismiss="modal"]').click();
}
});

Categories

Resources