Caching issue with loading partial views into JQuery dialogs - javascript

Imagine a simple list of users with "edit" links. Clicking "Edit" opens up a dialog box with details for the selected user. The "Details" popup is a partial view.
I have an issue with Partial Views being cached when opening them in JQuery dialog windows.
My partial view( Notice the OutputCache attribute as one of the things I tried to solve the caching issue):
[HttpGet]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public PartialViewResult EditUser(int id)
{
var userList = userRepository.GetByRole(id);
return PartialView("EditUser",userList);
}
The PartialView above is requested and loaded from the following Javascript function:
function editUserOpen(id) {
$.ajaxSetup({ ///// Another thing I tried to solve caching
cache: false
});
var url = "/User/PartialViewResult/" + id;
$('#user-wrap').empty().load(url, function () {
$("#dialog-edit-user").dialog({
title: "Edit User",
autoOpen: false,
height: 300,
width: 500,
modal: true
});
$('#dialog-edit-user').dialog("open");
});
}
As shown above "dialog-edit-user" ( along with "dialog-add-user" and "dialog-delete-user" ) are located inside of the "user-wrap" Div in the DOM.
Functionally everything works but when I open a dialog, cancel and then try opening dialogs for other users, until the page is refreshed the dialogs will always contain info from the initially displayed dialog.
I figured its a caching issue but I ran out of ways to solve it.
I would like to stay away from $.ajax({ cache:false; }).html(content) if possible. It seems to me that it's a lot slower than .load().

Here is what I discovered.
Everytime JQuery dialog is initialized with .dialog() as shown above the div that becomes a pop up is being taken out of the DOM and moved the the bottom of the page. Dialog Div cannot be a child of another Div. In my example it was:
<div id="user-wrap">
<div id="dialog-edit-user"> /// <--- Jquery dialog div
</div>
</div>
Dialog cannot be wrapped in other divs.
After the first click, when the dialog is displayed JQuery simply starts accumulating duplicate Divs at the bottom of the page. $("#").dialog('open') opens the very top DIV of accumulated duplicated every time making the programmer/user think it's a caching issue.
So the solution is to either remove the div created by JQuery from the bottom of the page on .dialog({close: } event or to move it back up to the parent wrapper DIV with JQuery .append() / .appendTo() functions.
Hope this helps to a next programmer who runs into similar issue.

Add some random hash to the URL to keep it unique:
...
var url = "/User/PartialViewResult/" + id + "?t=" + new Date().getTime();
...
This will always load new content.

Related

Making jquery Dialog working between two pages

I have a dialog setup as follow
$("#myDialog").dialog({
autoOpen: true,
close: function(event, ui) {
$("#myDialog-content").html("");
$(this).dialog("destroy");
}
});
$("#myDialog").css("min-height","");
$("#myDialog-content").html("Loading...");
$.ajax({
...
success: function(response) {
$("#myDialog-content").html(response);
}
});
This working fine I load and close dialog in same page but not able to make it work properly where I move between pages.
Here is a my page flow
From source page(say PageA) I make AJAX call to load the page containing dialog div(say PageB).
Link on this page call above method to display dialog. (For first time it runs OK).
When I click close button. Dialog close and with firebug I can still see dialog div at the end with UI classes but in hidden state.
If I go back to source page (Page A) and reload the PageB.In firebug I can see two div - one originally from JSP and second one from step 3.
Now if I click button to load dialog box - It used hidden to populate new data and never use new div created by jquery. So I just have blank dialog box.
I am not sure if this is jquery Dialog issue or my page flow. One possible solution I though of is use remove in close function to remove dialog div completely but it puts burden to create this div everytime page PageB is loaded. Is there any other way or any thing I am doing wrong in this scenario?
If i understood correctly the situation, You have 2 options:
If you somehow cleaning the content of "Page B", remove the modal
then.
If you do not have the cleaning mechanism like that, just
.remove() content of modal on close
Sidenote: i would advise not to use jquery for .css and .html('Loading...'). Also, it is good to cache jquery elements in variables e.g var dialog = $("#myDialog");

jquery slideshow dialog for html dynamic content

I'm looking for a slideshow tool (for jquery) which i can load in a dialog and every time i click on the next or previous button i load the content from the database.
If i use the dialog jquery-ui widget and i add buttons, it puts them below the content. And i want them to be on the side, as it is the way the client asked:
with the following js code the dialog looks like this:
$(function() {
var x = 1;
$('#dialog').dialog({buttons:
{
Next: function() {
x++; // Increment counter
$(this).text(x); // Build dialog based on new value
},
Prev: function() {
x--; // Decrement counter
$(this).text(x); // Build dialog based on new value
}
}
});
});
<div id="dialog" title="Basic dialog">
<p>This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.</p>
</div>
Somebody told me that it's better if i load all the content when the page is loading, but, what happens if there are 10000 or 15000 divs, each one with html content and image. My first thougth was "the page will take too long to include those objects, and maybe they will never be clicked by the user" and that's what i told him. And he told me, "as you'll be growing in web developmente you'll want to avoid requests"
If it's better to have a dialog which has next a previous button on the side, which tool can i use?
The page is beeing made on Rails with jquery
Thanks in advance for your opinions.

Open link in same page and once link is open, execute some code

I have several pop-ups on home page. I open and close them by selecting them with ID and using fadeIn() and fadeOut(). Now I want to open a specific pop-up by clicking on link from another window? For example, if from that new window I click on 'Pop Up 1', I want home page to open and then show 'Pop Up 1'.
I tried using this code below but while writing this code I realized that the script gets reloaded and thus my function of loading a pop-up does not work.
So my question is, is there some elegant solution you could recommend to show element in one page while a link that specifies which element has to be shown is in another?
$("#galleryNav a").on('click', function() {
window.open("/pixeleyes",'_self',false);
setTimeout(function() {
var popToShow = $(this).attr('data-pop');
$(".text-content-outer").hide();
$("#" + popToShow).fadeIn();
}, 5000);
});
One idea might work is
When you are opening a new page using the below line then send some parameter or hash value with it.
window.open("/pixeleyes",'_self',false);
like
window.open("/pixeleyes#openpopup",'_self',false);
Then in the page ready of this page check if the hash exists open the popup otherwise do nothing.
Not sure if this is what you are looking for.
$("#galleryNav a").on('click', function() {
window.open("/pixeleyes#showpopup",'_self',false);
});
showpopup could be anything that you want to open as popup...

What's the correct way to link to the same page multiple times?

I'm trying to have a single page that can show the same type of data (lets say fruits). Then I want to load this page anywhere in my website hierarchy but each time with different parameters.
I have my main page like the following with two links to the same page show.html:
<div data-role="navbar" data-iconpos="top" data-theme="a" class="nav-ecommera">
<ul >
<li>
Apples
</li>
<li>
Oranges
</li>
</ul>
</div>
A click on each of the two buttons will create a new instance of the page show.html in the DOM. All of the items in show.html therefore will have duplicate ID's in the DOM.
In my javascript I want to dynamically fill the show.html page:
$('div[id="show"]').live("pagebeforeshow", function(e, data) {
var p = getUrlParameter("p");
show(p);
});
var show = function(p) {
$.ajax({
url:'http://show.com/?p='+p,
success: function(data) {
// Refresh 'show' page with new data
// First time: It's fine.
// Second time: 'show' page is duplicated in the DOM so it's messy.
}
});
}
Now the first time show.html loads everything is fine. However the second time everything in show.html is loaded twice and the DOM includes many duplicate ID's.
Is there a way to remove the first page from DOM before loading the new one?
Or:
Is there a better approach that will do what I'm trying to achieve here?
UPDATE:
I already tried removing previous instances of show pages when loading a new one. It works as far as showing the second page is concerned. But there is a problem when the first page needs to be shown for the second time, after being manually removed.
I think the reason is jQuery mobile seems to think the first page is already loaded, despite the fact that we manually removed it. So it doesn't fully reload the first page when accessed again. I'm talking about this sequence of navigation: Home -> Apples -> Back to home -> Oranges -> Back to home -> Apples (Here you get a defected page).
1) You could change ID`s to classes.
2) You can have wrapper that encloses the show.html and when you try to load it second time find the one you loaded previous and delete it.
Your show.html:
<div class='previous-load'>
... enclosed show.html HTML ...
</div>
JavaScript:
$('div[id="show"]').live("pagebeforeshow", function(e, data) {
var p = getUrlParameter("p");
show(p);
});
var show = function(p) {
$(".previous-load").remove();
$.ajax({
url:'http://show.com/?p='+p,
success: function(data) {
// Refresh 'show' page with new data
// First time: It's fine.
// Second time: 'show' page is duplicated in the DOM so it's messy.
}
});
}
You can load the show.php page via $.mobile.changePage() which has the reloadPage option:
//bind to all links that have an HREF attribute that starts with "show.html"
$('a[href^="show.html"]').bind('click', function () {
//set a default query-string for the page-load
var query = '';
//if this link's HREF attribute has a query-string, use it
if (this.href.indexOf('?') > -1) {
query = this.href.split('?')[1];
}
//forward the user to the page, telling jQuery Mobile to reload the page
//which will use the new query-string sent
$.mobile.changePage('show.html', { reloadPage : true, data : query });
//prevent the default behavior of the click
return false;
});
reloadPage (boolean, default: false)
Forces a reload of a page, even if it is already in the DOM of the
page container. Used only when the 'to' argument of changePage() is a
URL. Here is the documentation for $.mobile.changePage():
Source: http://jquerymobile.com/demos/1.1.0/docs/api/methods.html
When jQuery Mobile loads the same page twice it's because the URL in the HREF attribute does not match the data-url attribute on the pseudo-page elements. For debugging this issue, make sure to check what data-url attribute is being added to your show.html page as it's inserted in to the DOM. If it doesn't seem to match-up, then you can set a data-url attribute on the element like:
<div data-url="/show.html" data-role="page" id="show-page">
...
</div>
Then you would always link to the page using the URL: /show.html

Show Modal Dialog implementation using JQuery

I need to open a page as a Modal Dialog using Jquery .For Example: I have 2 pages say, Parent.aspx & Child.aspx, I need to open child.aspx in a modal dialog using JQuery when i click on a button/link in the parent.aspx. Also Postback can happen in the parent and child pages.
function test(){
openShadowBox("http://www.google.com", 400, 600, 'my google');
}
function openShadowBox(url, height, width, title){
width = parseInt(width)+60;
var horizontalPadding = 30;
var verticalPadding = 30;
$('<iframe id="cdt_shadowbox" src="' + url + '" frameBorder="0"/>').dialog({
title: (title) ? title : 'CDT Shadowbox',
autoOpen: true,
width: width,
height: height,
modal: true,
resizable: true,
autoResize: false,
closeOnEscape: true,
//position: 'top',
overlay: {
opacity: 0.5,
background: "black"
}
}).width(width - horizontalPadding).height(height - verticalPadding);
$('html, body').scrollTop(0);
}
I think the most easiest way is to use iframe in you dialog pointing to Child.aspx.
JQuery has a number of options for creating a Modal "popup" with a page, but as I read your question I think you want to open a page in a separate browser window with a modal relationship to the original page. Javascript (Jquery) allows for Window.Open. This opens your second page in a new window,however, it does not create a modal relationship, nor (I believe) can it.
There are a number of jquery plugins to work with modal dialogs, for instance:
http://plugins.jquery.com/project/modaldialog
Depending on the user experience you're looking for, you'll probably either want an iframe in the modal dialog or perhaps an ajax call to fetch the content and load it into the dialog.
You can either use an iFrame or an UpdatePanel.
A modal dialog is really no different than any other page element. What makes it appear to be "modal" is simply CSS and nothing more.
The one difficulty you make have with ASP.NET and jQuery, though, is that ASP.NET needs everything to be inside it's single form tag. Since jQuery isn't designed specifically for ASP.NET it (and its plugins) may or may not know (or care) about this.
For example if you use simplemodal it has an option to specify where on the form the dialog is appended, you can use this to ensure it's inside #aspnetform and everything it it should work just like any other page element.

Categories