I have a function which opens a jQuery dialog. The user is able to modify some data fields, like a dropdown and save the result. That works fine and the parent page is updated through JQ. Now when the same item is clicked again, the dialog appears without ever hitting the jQuery call and the data is as it was before changed. How do force the JavaScript to go through the same functions again and call the controller again for the new values? Let me know if you need code, but there has to be a command to cause the once invoked dialog to refresh it's data. Is this because of the browser cache? The code is like this:
function showTourDetails(tourId, row) {
$("#divSelectedTour").dialog("open");
$("#divSelectedTour").load('#Url.Action("_SelectedTour", "Tour", null, Request.Url.Scheme))?tourId = ' + tourId);
}
And the div is just an empty div that is filled with the partial view page:
[HttpGet]
public PartialViewResult _SelectedTour(string tourId)
{
SelectedTourModel tour = GetTour(Convert.ToInt64(tourId));
return PartialView(tour);
}
After trying many different approaches, this finally worked:
$.ajaxSetup ({
// Disable caching of AJAX responses
cache: false
});
Related
I am trying to reload the latest data from a database when the browser back button is clicked.
However, even though the following code runs, and the data has already been updated in the database, the page still loads the old data.
window.addEventListener("popstate", getItemsFromDB) // works on first page load and when back button is clicked
...
function getItemsFromDB() {
fetch('http://localhost:4000')
.then(res => {
res.json().then(data => {
console.log('RESP', data) // data is old here on navigating back to index page
})
...
I have buttons that upvote individual items in the list that work fine, ie. a button is clicked for an upvote, the item is updated in the DB and the new data for the item is added on the page.
Now, when I navigate away from the page and then back using the back button, the getItemsFromDB() function gets called but doesn't the fetch() doesn't execute. Hence, the data reverts to the previous state.
Only a manual refresh of the page will load the latest data. Can anyone tell me what's going wrong here?
Also, I would like to do this with plain vanilla JS instead of using jQuery or a framework.
Thanks!
assuming I have a partial view that is just an editor box for inputting some data (asp.net application)
#Html.Editor("New", new { htmlAttributes = new { #class = "my_editor" } })
in my main view, I have a section that I'd like to update with the partial view I mentioned above using an ajax call.
<div id="editor_section"></div>
My question is, is it possible to continuously append to the same div using the same partial view. In other words, I call ajax once, and a new input box appears. Then I click on the ajax link again, and a second input box appears coming from the same partial view obviously. And I should be able to continue doing this as many times as I like each time appending a new input box under the others.
Yes it is possible, but it is not very efficient. You should only have to make the AJAX call once, then you can cache the html you get from the partial view in a JavaScript variable, so when you append it later, you don't have to make the round trip to the server to retrieve HTML you have already requested.
Something like:
var inputHtml = null;
var appendInput = function () {
if (!inputHtml) {
$.get('/input', function (data) {
inputHtml = data;
$('#someDiv').append(inputHtml);
});
} else {
$('#someDiv').append(inputHtml);
}
};
I'm using the hot towel template, and I'm trying to understand how to navigate to a different view via a javascript call. When my page loads, it looks like this:
Then, if I click any other button, then click the apps button again, I wrote some test code to just take the user to the ping page. This is in the apps view model:
function activate() {
if (initialized) { router.navigateTo("#/ping"); return; }
// more code here (doesn't get hit the second time through)
}
But what happens is the URL is correctly the ping URL, and the ping button is selected, but the actual content is still showing the applications:
If I want to navigate to another page without clicking in the navbar at the top, how should that be done?
Your 'router.navigateTo('#/ping') is correct.
But when activate method is called, lots of heavy tasks are being done by durandal, it's too late for
your commanding, if you want to prevent opening a page and instead of that You'd like to go to
another page , then you can use 'CanActivate' method as following :
function canActivate() {
if (initialized) { router.navigateTo("#/ping"); return false;
/* return false to prevent opening a page */ }
else return true;
}
Also your application's performance will be boosted too
Good luck.
Page A:
$(document).ready(function () {
bindData();
});
function bindData() {
$('#searchbtn').bind('click', function () { SearchResult(); });
}
function SearchResult() {
ajax call...
}
Page A HTML:
<input type="button" id="searchbtn" />
Page B Details---> this page comes after selecting a specific search result from page A search list
Back<br />
Now when I go back to the Page A I can see my search criteria's as they were selected but the result Div is gone. What I am trying to do is I want the search list to stay when the Page comes back.
I think what I can do here is some how call the searchbtn click event again when the page comes back so the list will come-up again. Can anyone tell me how to fire the searchbtn click event only when the page comes back from Page B. or point me in the right way of doing this..
Thanks
The Browser Back button has long been problematic with AJAX. There are scripts, workarounds, and techniques out there (depending on the framework that you want to use).
Since it appears that you are using jQuery (based on your posted JavaScript syntax), here is a link to another Stackoverflow post regarding back button jQuery plugins.
history.back() will return you to the last URL visited, meaning that any ajax calls made during the user's visit will not be automatically repeated. Your browser may automatically restore your form selections, but the SearchResults() function is only called by a click event, not a selection event.
You can bind URLs to ajax states using a framework like sammy.js. That way, history.back() would take you to a URL associated with SearchResults().
function bindData() {
var chkinput1 = $("input:checkbox[name=x]:checked").length;
var chkinput2 = $("input:checkbox[name=y]:checked").length;
if (chkinput1 > 0 && chkinput2 > 0) {
SearchResult();
}
$('#searchbtn').bind('click', function () { SearchResult(); });
}
I know this is the worst way to achieve this result but I think instead of using any other plugins to add complexity we will go with this for now. If anyone else is looking for the same question let me tell you again this is not the best practice as on returning back to the history we are calling the search result again depending upon the cached input selection of checkboxes and generating the whole ajax call again to display the list. On the first request I am caching the list and setting sliding expiration so its not taking anytime to comeback and so everyone lives happily.
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.