Can't open Telerik Kendo window twice - asp.net-mvc

I have a Kendo window which is defined as follows:
With Html.Kendo().Window().Name("tranferwindow")
.Title("Select Transfer Destination")
.Content("")
.Resizable()
.Modal(True)
.Events(Function(events) events.Open("WindowToCenter"))
.Events(Function(events) events.Refresh("transferopen"))
.Draggable()
.Width(400)
.Visible(False)
.Render()
End With
The window is opened each time by using the refresh and passing a new URL.This is to allow dynamic data to be displayed dependent on what the user clicked on a grid.
function transferitem(e) {
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
wwindow.data("kendoWindow").open(); //Display waiting window while refresh happens
var twindow = $("#tranferwindow")
twindow.data("kendoWindow").refresh('/Home/TransferList?agentid=' + agentid + '&tenantid=' + tenantid + '&SessionID=' + dataItem.MediaID);
}
The Window is opened at the end of the refresh event to make sure the user doesn't see the previous content.
function transferopen() {
wwindow.data("kendoWindow").close(); //Close the 'wait' window
var twindow = $("#tranferwindow")
twindow.data("kendoWindow").center().open();
}
This all works well and the window can be closed and reopened as often as I like.
However I needed to access the resize event of the window from within the Partial View to resize the Grid which is inside the window. To achieve this I added the following to the partial view that is returned from the url.
$("#tranferwindow").kendoWindow({
resize: function (e) {
// resizeGrid();
}
});
Adding this event mapping causes the issue where I cannot open the Window more than once.
I assume I need to 'unregister' for the event somehow before closing?

Found a solution: much cleaner and no VB Razor needed :)
I changed the approach to create a new window each time I wanted to display one.
I created a div to hold the Window.
<div id="windowcontainer"></div>
Then when the user selected a command on the grid , I create the whole window appending it to the div. The key here is the this.destroy in the deactivate event.
function transferitem(e) {
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
$("#windowcontainer").append("<div id='tranferwindow'></div>");
var mywindow = $("#tranferwindow")
.kendoWindow({
width: "400px",
title: "Select Transfer Destination",
visible: false,
content: '/Home/TransferList?agentid=' + agentid + '&tenantid=' + tenantid + '&SessionID=' + dataItem.MediaID,
deactivate: function () {
this.destroy();
},
open: WindowToCenter,
refresh:transferopen
}).data("kendoWindow");
mywindow.refresh();
}
Then on the refresh function
function transferopen() {
var twindow = $("#tranferwindow")
twindow.data("kendoWindow").center().open();
}
Now I can have the event binding inside the Partial View which works fine and the window can be re opened as many times as I want. :)
Update: Adding the event binding inside the Partial View stops 'Modal' from working. Working on trying to fix this...

Related

How do know Kendo grid.savechanges() method is success or fail

I have a kendo MVC grid in a page.in that page i have button. when i click button i want to open a kendowindow popup.
so here is my issue.
when i am clicking that button am saving grid values and i am opening kendo window popup. so if i have a errors in grid then i dont want to open kendo window popup. how to achieve this. below is my button click code.
$("#btnAddProject").click(function (e) {
var grid = $("#Grid").data("kendoGrid");
grid.saveChanges();
var myWindow = $("#AddProjectWindow");
myWindow.data("kendoWindow").open();
myWindow.data("kendoWindow").center();
});
Here am included below datasource events.
events.Error("error_handler").RequestEnd("gridRequestEnd")
but these datasources functions are calling after click event finish.
but i want wait for grid.saveChanges() to finish and check whether save is success or fail. if fail i dont want to open kendo popup. here datasource functions are calling after finishing button click function
This is because save changes is an asynchronous function. So the rest of the code will execute not matter the result of the save function.
A simple and quick method will be to set a global variable just before you call save changes. Then once the save result is received from server, the grid will fire the onRequestEnd method. You can open the popup window there if the global variable is set.
$("#btnAddProject").click(function (e) {
var grid = $("#Grid").data("kendoGrid");
isSavingChanges = true;
grid.saveChanges();
});
function gridRequestEnd(e) {
if (e.Response){//Response is not null means it is most probably ajax result
if(isSavingChanges == true){
isSavingChanges = false;
var myWindow = $("#AddProjectWindow");
myWindow.data("kendoWindow").open();
myWindow.data("kendoWindow").center();
}
}
}

Flipswitch in lightswitch is going in an infinite loop

I got this piece of code for rendering and using Flipswitch as a custom control in lightswitch application.
function createBooleanSwitch(element, contentItem, trueText, falseText, optionalWidth) {
var $defaultWidth = '5.4em';
var $defaultFalseText = 'False';
var $defaultTrueText = 'False';
var $selectElement = $('<select data-role="slider"></select>').appendTo($(element));
if (falseText != null) {
$('<option value="false">' + falseText + '</option>').appendTo($selectElement);
}
else {
$('<option value="false">' + $defaultFalseText + '</option>').appendTo($selectElement);
}
if (trueText != null) {
$('<option value="true">' + trueText + '</option>').appendTo($selectElement);
}
else {
$('<option value="true">' + $defaultTrueText + '</option>').appendTo($selectElement);
}
// Now, after jQueryMobile has had a chance to process the
// new DOM addition, perform our own post-processing:
$(element).one('slideinit', function () {
var $flipSwitch = $('select', $(element));
// Set the initial value (using helper function below):
setFlipSwitchValue(contentItem.value);
// If the content item changes (perhaps due to another control being
// bound to the same content item, or if a change occurs programmatically),
// update the visual representation of the control:
contentItem.dataBind('value', setFlipSwitchValue);
// Conversely, whenver the user adjusts the flip-switch visually,
// update the underlying content item:
$flipSwitch.change(function () {
contentItem.value = ($flipSwitch.val() === 'true');
});
// To set the width of the slider to something different than the default,
// need to adjust the *generated* div that gets created right next to
// the original select element. DOM Explorer (F12 tools) is a big help here.
if (optionalWidth != null) {
$('.ui-slider-switch', $(element)).css('width', optionalWidth);
}
else {
$('.ui-slider-switch', $(element)).css('width', defaultWidth);
}
//===============================================================//
// Helper function to set the value of the flip-switch
// (used both during initialization, and for data-binding)
function setFlipSwitchValue(value) {
$flipSwitch.val((value) ? 'true' : 'false');
// Having updated the DOM value, refresh the visual representation as well
// (required for a slider control, as per jQueryMobile's documentation)
$flipSwitch.slider(); // Initializes the slider
$flipSwitch.slider('refresh');
// Because the flip switch has no concept of a "null" value
// (or anything other than true/false), ensure that the
// contentItem's value is in sync with the visual representation
contentItem.value = ($flipSwitch.val() === 'true');
}
});
}
This piece of code works fine. It renders the flipswitch on the screen. I am showing the data in an Edit screen, which is coming in a popup. Problem arises when I open that popup which contains the flipswitch and without changing any data on UI, I just try to close that popup screen. The IE hangs and it gives error saying that long script is running. When I debug the createBoolenaSwitch function, I came to know that it is going in infinite loop inside the function called setFlipSwitchValue(value){}
Why is this function getting called and this is going in an infinite loop?

jQuery UI Accordion - does refresh method overwrites initialisation settings?

Currently I am working on a project for which I use the jQuery UI Accordion.
Therefore I initialise the accordion on an element by doing
<div id="accordion"></div>
$('#accordion').accordion({
collapsible: true,
active: false,
heightStyle: "content"
});
After init the accordion I append some data coming from an AJAX request. (depends on user interaction)
In a simplified jsfiddle - which does exact the same thing as the ajax call - you can see how this looks like.
So far it seems to be working quite well but there is one problem I face.
In my initialisation I say that I want all panels to be closed but after calling refresh on the accordion everything of those settings seems to be gone and one panel opens.
Note that I implemented jQuery UI v1.10.2 in my fiddle. Update notes say
The refresh method will now recognize panels that have been added or removed. This brings accordion in line with tabs and other widgets that parse the markup to find changes.
Well it does but why has it to "overwrite" the settings I defined for this accordion?
I also thought about the possibility that it might be wrong to create the accordion on an empty <div> so I tested it with a given entry and added some elements afterwards.
But the jsfiddle shows exactly the same results.
In a recent SO thread I found someone who basically does the same thing as I do but in his jsfiddle he faces the same "issue".
He adds a new panel and the first panel opens after the refresh.
My current solution for this issue is to destroy the accordion and recreate it each time there's new content for it.
But this seems quite rough to me and I thought the refresh method solves the need to destroy the accordion each time new content gets applied.
See the last jsfiddle
$(document).ready(function () {
//variable to show "new" content gets appended correctly
var foo = 1;
$('#clickMe').on('click', function () {
var data = '';
for (var i = 0; i < 3; i++) {
data += '<h3>title' + foo + '</h3><div>content</div>';
foo++;
}
if ($('#accordion').hasClass('ui-accordion')) {
$('#accordion').accordion('destroy');
}
$('#accordion').empty().append(data).accordion({
collapsible: true,
active: false,
heightStyle: "content"
});
});
});
Unfortunately it is not an option for me to change the content of the given 3 entries because the amount of panels varies.
So my questions are the one in the title and if this behaviour is wanted like that or if anybody faces the same problem?
For the explanation of this behaviour, have a look in the refresh() method of the jquery-ui accordion widget, the problem you are facing is at line 10 :
refresh: function() {
var options = this.options;
this._processPanels();
// was collapsed or no panel
if ((options.active === false && options.collapsible === true) || !this.headers.length) {
options.active = false;
this.active = $();
// active false only when collapsible is true
} if (options.active === false) {
this._activate(0); // <-- YOUR PROBLEM IS HERE
// was active, but active panel is gone
} else if (this.active.length && !$.contains(this.element[0], this.active[0])) {
// all remaining panel are disabled
if (this.headers.length === this.headers.find(".ui-state-disabled").length) {
options.active = false;
this.active = $();
// activate previous panel
} else {
this._activate(Math.max(0, options.active - 1));
}
// was active, active panel still exists
} else {
// make sure active index is correct
options.active = this.headers.index(this.active);
}
this._destroyIcons();
this._refresh();
}

how to add standard textbox command to jqgrid context menu

If context menu is added to jqGrid using Custom values to Context Menu Items in JQgrid and text filed inline editing is used, textbox standard context menu is not available, it is replace with jqGrid context menu.
How to add standard textbox context menu commands ( Undo, Cut, Copy, Paste, Delete, Select all ) to jqGrid conext menu or how to show standard context menu for textbox inline editing?
Update
On inline edit, if standard menu is opened by right clicking on yellow background or in autocomplete box and after that standard browser context menu is opened, custom menu is not closed, two menus appear.
How to fix this ?
It's not easy to implement in context menu commands like "Copy", "Paste", ... so I decide to modify my demo from the answer on your previous question. In the new demo the context menu appears only if the page contains no selected text.
The first problem is that the original code of the jquery.contextmenu.js contains the following code fragment:
$(this).bind('contextmenu', function(e) {
// Check if onContextMenu() defined
var bShowContext = (!!hash[index].onContextMenu) ? hash[index].onContextMenu(e) : true;
if (bShowContext) display(index, this, e, options);
return false;
});
So the contextmenu handler return always false and prevent creating of the standard context menu. I fix the code to the following (you can download full modified code here):
$(this).bind('contextmenu', function(e) {
// Check if onContextMenu() defined
var bShowContext = (!!hash[index].onContextMenu) ? hash[index].onContextMenu(e) : true;
currentTarget = e.target;
if (bShowContext) {
display(index, this, e, options);
return false;
}
});
The code of createContexMenuFromNavigatorButtons functions described here I modified
onContextMenu: function (e) {
var rowId = $(e.target).closest("tr.jqgrow").attr("id"), p = grid[0].p, i,
lastSelId;
if (rowId && getSelectedText() === '') {
...
return true;
} else {
return false; // no contex menu
}
}
to use getSelectedText() and to create the context menu only if no text is selected. As the result you will be see your custom context menu only if no text is selected and see the standard context menu (which depend on web browser) if the text selection exist:
UPDATED: I modified my bug report about jquery.contextmenu.js with additional information based on the answer. I hope that the changes will be soon in the main code of jquery.contextmenu.js included in the plugins subdirectory.
UPDATED 2: How you can see here all the fixes are already in the main code of jqGrid on the github and in included in the jqGrid 4.3.
UPDATED 3: If you want to have the standard context menu for all enabled <input type="text" ...>, <input type="textarea" ...> and <textarea ...> elements you should just modify a little the code inside of onContextMenu callback. For example
onContextMenu: function (e) {
var p = grid[0].p, i, lastSelId,
$target = $(e.target),
rowId = $target.closest("tr.jqgrow").attr("id"),
isInput = $target.is(':text:enabled') ||
$target.is('input[type=textarea]:enabled') ||
$target.is('textarea:enabled');
if (rowId && !isInput && getSelectedText() === '') {
...
see one more demo where inline editing will be activate by double-click.

jquery tabs back button

This post talks about the problem that jQuery tabs is still having with the back button. What the customer needs is fairly simple - when they press back, they want to go back to what they were just looking at. But jQuery tabs loads the first tab, not the one that was selected when the user left the page.
I've read the accompanying link and it says "It is planned and Klaus is working on it whenever he finds the time."
Has anyone solved the back button problem with jQuery UI tabs?
Using the solution to the history problem easement posted, a dirty fix for the back button problem would be to periodically check the location.hash to see if it has changed, and if it has, fire the click event of the appropriate link.
For example, using the zachstronaut.com updated jQuery Tabs Demo, you could add this to the $(document).ready callback, and it would effectively enable the back button to switch tabs, with no more than a 500ms delay:
j_last_known_hash = location.hash;
window.setInterval(function() {
if(j_last_known_hash != location.hash) {
$('#tabs ul li a[href="'+ location.hash +'"]').click();
j_last_known_hash = location.hash;
}
}, 500);
Have you tired updating the browsers location as you switch tabs?
http://www.zachstronaut.com/posts/2009/06/08/jquery-ui-tabs-fix.html
if you had a class on your tab container that was tabContainer, to update the url when user clicks a tab, you could do this:
$(".tabContainer").tabs({
select: function(event, ui) {
window.location.hash = ui.tab.hash;
}
});
then, instead of firing click, you could use the tabs select method if you have some getIndexForHash method that can return the right tab number for the selected hash value:
var j_last_known_hash = location.hash;
window.setInterval(function() {
var newHash = location.hash;
if(j_last_known_hash != newHash) {
var index = getIndexForHash(newHash);
$('.tabContainer').tabs("select",index);
j_last_known_hash = newHash;
}
}, 100);
window.onhashchange = function () {
const $index = $('a[href="' + location.hash + '"]').parent().index();
$('.tabContainer').tabs('option', 'active', $index);
}

Resources