Hi guys i know this is a known problem in ASP.NET MVC, basically what i have here is a photo gallery with categories (Red, Blue, Green).
When i choose one category, say 'Red', it will do an ajax call and load the page with photos of red colored products. when i click one of the photos, i expect it to be enlarged (lightbox kinda effect). I use a jQuery plugin called fancybox for that.
but as u all know jQuery using a dynamically loaded content with jquery in it , doesnt actually work in ASP.NET MVC. So i added the jQuery call to fancybox into the ajax.success.
but since it is a plugin, the function $(".fancybox").fancybox() does not register and says that it's not a valid javascript function. How can i solve this problem, so that i can do the image enlarge thing after an ajax call? thank you!
$(document).ready(function() {
$("select#Colors").change(function() {
var color = $("#Colors > option:selected").attr("value");
var tempnric = $(".tempnric").attr("value");
$("#ProductsDiv").hide();
$('#ajaxBusy').show();
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: "/FindProducts/" + color,
data: "{}",
dataType: "json",
success: function(data) {
$('#ProductsDiv > div').remove(); // remove any existing Products
if (data.length > 0) {
var options = '';
for (p in data) {
var product = data[p];
options += "<a href='/GetPhotoSet/" + product.PhotoID + "' class='fancybox load fade'><img src='/GetPhotoSet/" + product.PhotoID + "'/></a>";
}
$("#ProductsDiv").html(options);
$('#ajaxBusy').hide();
$("#ProductsDiv").show();
} else {
$("#Products").attr('disabled', true).html('');
$("#ProductsDiv").append('<div>(None Found)</div>');
}
}
});
});
});
Here is the remaining code it works ok except that when i click on the images, it opens up a new browser..
Before your document.ready call, put this line of code:
var $j = jQuery.noConflict();
Then replace all of the '$' references with '$j' and your code should now work.
There is probably a conflict between some other javascript and the jQuery script, so your document.ready is not being seen. This is the quickest way to work around the problem. And if you're feeling ambitious, you can find out what is going on by using a tool such as FireFox's Error Console.
Related
I have a jQuery mobile panel which slides in from the side, it works great.
But lets say you have a login page, that redirects to a main page with a panel. Now if the user opens the panel, and then clicks the back button, he expects the panel to close. But instead the browser navigates back to the login page.
I´ve tried adding something to the url:
window.location.hash = "panelOpen";
But that just messes up the jQuery mobile history state pattern. I´ve also tried to listen to the navigate event, and prevent it if a panel is open:
$(window).on('navigate', function (e, hans) {
var panels = $('[data-role="panel"].ui-panel-open');
if (panels&&panels.length>0) {
e.preventDefault();
e.stopPropagation();
$('#' + panels[0].id).panel('close');
return false;
}
});
This kind of works, except that the url is changed, and I cannot grab the event that changes the url. Furthermore, it also messes up the jQuery mobile history pattern.
So how does people achieve this expected 'app-like' behaviour with a jQuery mobile panel; open panel > history back > close panel. And thats it.
Thanks alot!
Updated
Instead of retrieving current URL from jQuery Mobile's history, It is safer to retrieve it from hashchange event event.originalEvent.newURL and then pass it to popstate event to be replaceState() with that URL.
Instead of listening to navigate, listen to popstate which fires before. The trick here is manipulate both browser's history and jQuery Mobile's history by replaceState() and reload same page without transition.
var newUrl;
$(window).on("hashchange", function (e) {
/* retrieve URL */
newUrl = e.originalEvent.newURL;
}).on("popstate", function (e) {
var direction = e.historyState.direction == "back" ? true : false,
activePanel = $(".ui-panel-open").length > 0 ? true : false,
url = newUrl,
title = document.title;
if (direction && activePanel) {
$(".ui-panel-open").panel("close");
$(".ui-header .ui-btn-active").removeClass("ui-btn-active");
/* reload same page to maintain jQM's history */
$.mobile.pageContainer.pagecontainer("change", url, {
allowSamePageTransition: true
});
/* replace state to maintain browsers history */
window.history.replaceState({}, title, url);
/* prevent navigating into history */
return false;
}
});
This part is meant to maintain same transition used previously as transition is set to none when reloading same page.
$(document).on("pagebeforechange", function (e, data) {
if (data.options && data.options.allowSamePageTransition) {
data.options.transition = "none";
} else {
data.options.transition = $.mobile.defaultPageTransition;
}
});
Demo - Code
I am a little bit late on the party, but i had recently the same requirements and i would like to share how i did it. So, i extended the requirement in the original question to Panels, Popups and Pages:
...an expected 'app-like' behaviour, history back > close
whaterver is open. And thats it.
In .on("panelopen"), .on("popupafteropen") and .on("pagecontainershow") i simply add another entry to the window history, by using the HTML5 API (https://developer.mozilla.org/en-US/docs/Web/API/History_API) (I believe there is no need to use the JQM navigate browser quirks for that):
window.history.pushState({}, window.document.title, window.location.href);
After that, i'm using more or less Omar's function to intercept the popstate event:
$(window).on("popstate", function (e) {
var pageId = $(":mobile-pagecontainer").pagecontainer("getActivePage").prop("id");
var pageOpen = (pageId != "page-home");
var panelOpen = $(".ui-panel-open").length > 0;
var popupOpen = $(".ui-popup-active").length > 0;
if(pageOpen) {
$.mobile.pageContainer.pagecontainer("change", "#page-home", {reverse: true});
return false;
}
if(panelOpen) {
$(".ui-panel-open").panel("close");
return false;
}
if(popupOpen) {
$(".ui-popup-active .ui-popup").popup("close")
return false;
}
});
As you see, the is just only one level to the home-page, but this can be easily extended by using JQM history implementation to get the previous page:
var activeId = $.mobile.navigate.history.activeIndex;
var jqmHistory = $.mobile.navigate.history.stack; // array of pages
and use pagecontainer to change to the active entry - 1.
As last note, this works well also by completely disabling the built-in JQM Ajax navigation system:
/* Completely disable navigation for mobile app */
$.mobile.ajaxEnabled = false;
$.mobile.loadingMessage = false;
$.mobile.pushStateEnabled = false;
$.mobile.hashListeningEnabled = false;
$.mobile.changePage.defaults.changeHash = false;
$.mobile.popup.prototype.options.history = false;
(Tested in Browser, on real Android and iOS devices)
I have a telerik grid that I am using to do a post to the server when the user double click on a row. It appears to work fine until I place an alert in the code and notice some odd behaviors. When I double click on a row for the first time, the alert comes up twice and continues to display twice the number of times that I click. I mean - it comes up twice the first time, 4 times the second time, 6 times the third times, and it continues on. Below is the scripts that I am using to call the grid.
function DisplayStudent(e) {
if (IsStudentGradeAvailable == "True") {
$('tr', this).live('dblclick', function () {
var row = e.row;
var StudentId= row.cells[0].innerHTML;
var StudentGrade= row.cells[1].innerHTML;
var data = { "StudentId= ": StudentId= , "StudentGrade": StudentGrade };
var url = '#Url.Action("Student", "StudentGrade")';
$.ajax({
url: url,
type: 'post',
dataType: 'text',
data: data,
success: function (data) {
alert("Success");
},
error: function (error) {
alert("Error");
}
});
});
}
}
Live attaches an event handler. You want one event handler, so you should call the live() method only once. Given your code, this implies that DisplayStudent() should only be called once.
If DisplayStudent() is called n times, you will have attached n event handlers, each of which alerts you when you click.
I am sure this must be a basic error on my part - but I am completely failing to see it.
I have a jQuery UI dialog which I use to present a form to edit a record .. at the bottom of the html (which itself is loaded via ajax) it has a div containing an (animated loading gif). The loading div is hidden after loading the html.
The CSS puts the div in an absolute position in the bottom right corner.
When the Save button on the dialog is clicked I call a function to save the info via ajax. In the ajax call I have:
beforeSend: function() {
$("#ajaxLoading").show();
},
complete: function() {
$("#ajaxLoading").hide();
}
The problem is that the image does not show.
If I remove the hide() after the initial dialog load, then the gif is displayed throughout.
I tried putting the show() just before the ajax call rather than in the beforeSend .. still nothing.
I tried putting the show() in the dialog setup - in the "Save" button click. Nothing.
If I put a breakpoint in the script with Chrome and step through then I DO see the gif!
So, I tried putting a couple of second timeout after the show() .. but still nothing.
I have no more ideas what to try.
Thanks for all the suggestions and comments ... I have got to the bottom of the problem - it was ... it was down to a combination of running ajax async and me closing the dialog at the wrong time.
i hope this helps
I had the same issue and i really don't know how it's happening, but it can
be fixed using a small delay in code like follows.
solution 1
$.ajax({
method: "GET",
url: "/",
beforeSend:function(){
$("#ajaxLoading").show(1);
// please note i have added a delay of 1 millisecond , which runs almost same as code with no delay.
},
complete:function(data){
$("#ajaxLoading").hide();
//here i write success code
}
});
solution 2
$.ajax({
method: "GET",
url: "/",
beforeSend:function(){
setTimeout(function(){
$(".loader-image").show();
}, 1);
// please note i have added a delay of 1 millisecond with js timeout function which runs almost same as code with no delay.
},
complete:function(data){
$(".loader-image").hide();
//here i write success code
}
});
How I use and working fine scripts is...
$("#save_button").click(function () {
// start showing loading...
$("#ajaxLoading").show();
// make an ajax call
$.ajax({
type: 'POST',
url: url,
data: $("#form").serialize(),
success: function() {
// when success, hide loading.
$("#ajaxLoading").hide();
// your additional scripts
if( a == null ){
// some script
}
else{
// some script
}
}
});
Use this.
jQuery.ajax({
data: 'your data',
url: 'your url',
type: "POST",
dataType: "html",
async:false,
onLoading:jQuery("#ajaxLoading").html('<img src="http://example.com/images/spinner.gif" />').show(),
success: function(data){
jQuery("#ajaxLoading").fadeOut();
}
});
Add the loader gif as html like this:
beforeSend: function() {
$("#ajaxLoading").html('<img src="image source" />');
},
complete: function() {
$("#ajaxLoading").html('')
}
I want to show progress bar when user submit the form because that process will take time may be around 8 to 10 seconds, so i want to show the progress bar so user must have an idea of how much time it will take. This process will be executed on simple call of a controller action like normal postback no ajax involve. So how can i achieve this task i am using asp.net mvc 2
Fraz,
Whilst i notice you say NO AJax INVOLVED, thought I'd chuck this in for info purposes.
As long as you don't care about the 'plase wait' indicator showing exact progress, then there's a simple way to do this with jquery and my answer here is dependent on that.
basically, create a 'Wait' view that contains a simple message along with an animated gif embedded within it. then just fire off your insert (or long running action) via the following basic outline:
$(document).ready(function() {
$('#btnSave').click(function() {
$.ajax({
type: "POST",
url: '<%=Url.Content("~/Booking/Save") %>',
data: { data: prepareData() }, // your data properties to be saved
beforeSend: beforeQuery(),
success: function(data) {
saveDataResponse(data);
},
error: function(xhr) { alert(xhr.statusText); }
});
});
});
// here we show the 'wait' view prior to processing starting
function beforeQuery() {
var url = '<%= Url.Action("Wait", "Booking") %>';
$("#mainDiv").load(url);
}
// when the long running process has completed (or error'd)
// either populate mainDiv with the details view of the booking
// or show the error appropriately
function saveDataResponse(data) {
if (data.length != 0) {
if (data.indexOf("ERROR:") >= 0) {
$("#mainDiv").html(data).css('backgroundColor','#eeaa00');
}
else {
$("#mainDiv").html(data);
}
}
}
obviously, there would be a little more involved for error conditons etc, but this is the basic 'template'.
hope this helps
I'm using this code:
$(document).ready(function() {
$("#test-list").sortable({
handle : '.handle',
update : function () {
var order = $('#test-list').sortable('serialize');
$("#info").load("process-sortable.php?"+order);
},
});
});
I want a loading indicator (GIF animation if possible) to show up when I drop the item and the request is being sent to the server until the PHP request is done and load is succesful.
How can I do this ?
Thanks.
Show the image in the update function before you start the ajax-call, make a callbackfunction for the load and hide the image there (so after the ajax-call is done)