Kendo UI Window to center after a refresh of large content - asp.net

Using MVC 4 I add a blank window and hide it. On a button click I call this javascript to get content and center the window:
var win = $("#myWindow").data("kendoWindow");
win.content("Loading...");
win.refresh({
url: "#Url.Action("MyAction", "MyController")",
data: { userloginid: "AAA" }
});
win.center();
win.open();
The content is larger than a default window so the win.center() calculation is off, putting the window too far down.
How do I get the window to center based on the content it got via the refresh() command.

The problem seems to be, that you center the window, and than, some time after that, the new content is finished loading.
In other words: The center is called before the window get's its new size through the loaded content.
To prevent this, you should bind to the refresh event of the window, and center in that.
Something along the lines (beware: only register this event once):
var win = $("#myWindow").data("kendoWindow");
win.bind("refresh", function() {
win.center();
win.open();
});

Related

How do I add a notification within a master detail page that slides from the right when a button is pressed

I need to add a notification content that will slide from the right when a button in the header is pressed. The header is a boxview with buttons inside.
This is what I am trying to achieve:
This is what I have now(button does nothing):
I don't think Xamarin.Forms supports two Master pages (Drawers) but what you could do is add a view inside your page with it's TranslationX set to the Width of the screen, then add a ToolbarItem that, when pressed, Translates the X of the view to 0, and when pressed again, translates the view to the screen's width again. The only drawback is that this view would be below the AppBar (not like your picture that the notification panel is in front of the AppBar and the StatusBar).
The code would be something like this:
The notifications panel part:
// I think 260 is a good width (but I didn't test), experiment and see
var notificationsPanel = new StackLayout { WidthRequest = 260 };
// Needed because we don't know the Width yet
SizeChanged += (sender, e) =>
{
if(Width > 0)
notificationsPanel.TranslationX = Width;
}
The Width property is the Width of the page.
The ToolbarItem part:
if(notificationsPanel.TranslationX > 0)
notificationsPanel.TranslateTo(Width - notificationsPanel.Width);
else
notificationsPanel.TranslateTo(Width); // Here the Width will already be set
The Content of the Page:
Content = new Grid
{
Children =
{
actualContent,
notificationsPanel
}
}
Hope it helps!
EDIT
An easier idea would be to create your page without the Notifications Panel and use this library: Rg.Plugins.Popup to add the NotificationsPanel as a Popup instead of as a view inside the page.
This library has a wiki page here: Wiki. You can create a XAML page for your Popup and add a ToolbarItem on the "Root" page that, when clicked, calls a simple method that checks if a Popup is showing, if it's not, add it, if it is, remove it (a toggle-like method). Something like this:
if (PopupNavigation.PopupStack.Count > 0)
PopupNavigation.PopAsync();
else
PopupNavigation.PushAsync(new NotificationsPanel());
If you don't know how to add a ToolbarItem, it's something like this:
ToolbarItems.Add(new ToolbarItem
{
Text = "Notifications",
Icon = "notifications-icon.png" // change this based on your image requirements, Xamarin.Forms has more than one way to store images
Command = new Command(() =>
{
if (PopupNavigation.PopupStack.Count > 0)
PopupNavigation.PopAsync();
else
PopupNavigation.PushAsync(new NotificationsPanel());
})
});
If you want to know more about images with Xamarin.Forms: Working with Images
That's it. If you want you can add animations (to make the NotificationsPanel come from the right side of the screen) and in the NotificationsPanel PopupPage, remember to make the view aligned to the right and with a WidthRequest smaller than the screen's Width.
Hope it helps!

Knockout loses bindings when Google Maps API v3 info window is closed

I'm data binding to a div which I am then setting as the content of an InfoWindow. When markers on the map are clicked I'm changing the bound observable, which updates the content in the info window. All of this works fine until the info window is closed. Google Maps removes the info window from the DOM, along with my div which had the bindings on it. Re-opening the info window results in its contents being frozen in the state it was in at its closing.
Any changes to the observable no longer update the ui, including using valueHasMutated. I've tried just resetting the content of the info window and rebinding, but the JQuery element still exists and I get duplicated content. I've also tried using cleanNode and rebinding but also get duplicate content with that.
The div which I'm binding too:
<div id="placeTmpl" data-bind="with: place">
<h3>
<a data-bind="text: name, attr: { 'href': detailsUrl($data) }"></a>
</h3>
</div>
The Google Maps InfoWindow:
window.infoWindow = new window.google.maps.InfoWindow({
content: ''
});
window.infoWindow.setContent($('#placeTmpl')[0]);
Event listener and updating observable
window.google.maps.event.addListener(marker, "click", function() {
window.viewModel.openInfoWindow(marker, data);
});
self.openInfoWindow = function (marker, data) {
for (var i = 0; i < self.places().length; i++) {
if (self.places()[i].placeId == data.PlaceId) {
self.place(self.places()[i]);
}
}
window.infoWindow.open(map, marker);
};
Like I said, this all works great until the info window is closed. I'm just looking for a way to force knockout to start updating the ui again or to clear and rebind when the info window is closed.
I was able to go around this by setting the InfoWindow content as an html string rather than a DOM node.
i.e:
window.infoWindow.setContent($('#placeTmpl').html());
rather than:
window.infoWindow.setContent($('#placeTmpl')[0]);
By doing this the html with the knockout bindings remains in place, rather than being transferred into the info window where it was subsequently being destroyed on close. Knockout now updates the bounded DOM elements as usual and I just update the info window with the html string on each click.
If you try to put knockout bindings in a Google Maps InfoWindow, you're gonna' have a bad time.
I was able to solve this without having to resort to using strings when calling setContent. In my case, the info window had dynamic elements that would update while the info window was open, so the string solution would not have taken this into account.
I added a closeclick handler in which I keep track of the original DOM element I passed to the info window and just add the element back to the body after the info window took it out. This keeps knockout happy and the info window doesn't care.
var $node = $('#placeTmpl');
var infoWindow = new google.maps.InfoWindow({
content: $node[0]
});
google.maps.event.addListener(infoWindow, "closeclick", function () {
//google maps will destroy this node and knockout will stop updating it
//add it back to the body so knockout will take care of it
$("body").append($node);
});

iFrame Click event not fired

How to catch click on an iframe using JQuery. I have an Amazon banner, and I need to close its container DIV when the user clicks the iframe. I've tried 'contents', onclick on iframe, binding the event but nothing works. When I click the iframe it opens Amazon's page on another tab, but the click event never fires. I put a breakpoint and alert just to make sure.
I am using latest JQuery version 1.9 and tested it on Chrome. I also thought about capturing a global click ($(document).click) and check the area of the click, but when I click the iframe, $(document).click doesn't fire. Any suggestions?
Again, it's an Amazon banner iframe, it's hosted on Amazon not on my server.
Example of the regular on binding that doesn't work: http://jsbin.com/oyanis/4/edit
There is a neat trick to get a "click" on on iframe content.
You could do:
<div id="iframeinside">
<iframe />
</div>
This now makes it possible to say in js something like:
var oldActive = document.activeElement; /* getting active Element */
var frame = $('#iframeinside iframe')[0];
$('#iframeinside').mouseenter(function() {
/* Setting interval to 1ms for getting eventually x,y mouse coords*/
oldActive = document.activeElement;
setInterval('doSomething()', 1);
});
$('#iframeinside').mouseleave(function () {
/* clear interval cause we arent over the element anymore*/
clearInterval(intervalId);
});
These intervals do call:
function doSomething() {
/* if the focus has changed to the iframe */
if(oldActive != frame && document.activeElement == frame) {
oldActive = document.activeElement;
alert(myQuery);
alert('click did happen to the iframe');
}
}
I used this for several things and it always worked. What i didnt check was how about ie6,7 and older brothers.

Iframe breaking script

How can create an iframe breaking script which shows a alert box if the page is loaded in an iframe and when the alert box is clicked, it should break the frame and the script should be seen.
if (top != window) {
alert("please don't load my in a frame, thx.");
top.location.href = location.href;
}
might do the trick.

Preventing a page to be shown outside a iframe

I have a page which work like a navigation and a iframe in this page which show the content.
Now there are some situation when the inner page is directly shown in the browser.
eg: if somebody types the inner page's url in the browser address bar, the page is displayed in the window.
I want to prevent this.
Better still, I would like to redirect to any other page.
window.parent: The window object that contains the frame. If the the window is the top level window then window.parent refers the window itself. (It is never null.)
window.top: The top level window object, even if the current window is the top level window object.
window.self: The current window object. (It is a synonym of window.)
So, I'd write my check like this:
if (window.top == window.self) {
window.location = "index.html";
}
Which would be identical to the slightly more ambiguous:
if (window.top == window) {
window.location = "index.html";
}
<script language="Javascript"><!--
if (top.location == self.location) {
top.location = "index.html" // must be viewed in main index
}
//--></script>
modified it from a situation where an an iframe decides to become the main frame.

Resources