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.
Related
I call bindElement of the view to execute the webservice and get data.
The call is executed correctelly if the key of tha path is different.
The event "dataReceived" didn't trigger in the second time of the same path.
Example:
First Time:
I call bindElement with the path 'ABCD', it's working, dataReceived is trigerred.
The second time:
If I call the same path 'ABCD', noting is happend, the event dataReceived didn't trigger.
If I call another path 'EFGH', it's working and dataReceived is trigerred.
So what can I do to trigger the event with bindElement even if the path is the same ?
Thanks.
cb = this.getView().byId("cb").getValue();
vpath = "/ZDECL_INSet('"+ cb +"')";
this.getView().bindElement({
path: vpath,
mode: sap.ui.model.BindingMode.TwoWay,
events: {
dataReceived: function(rData) {
var data = vthis.getView().getModel().getProperty(rData.oSource.sPath);
msg = "";
if(data.TMSG1 == 'E'){
msg = data.Msg1;
sap.m.MessageBox.show(msg, {
icon: sap.m.MessageBox.Icon.ERROR,
title: vtitle,
actions: [sap.m.MessageBox.Action.YES],
onClose: function(oAction) {
oCB.focus();
oCB.setValue(null);
}
}
);
}
else{
sap.m.MessageToast.show("Good", {
duration: 2000,
width: "200px"
});
oCB.focus();
oCB.setValue(null);
}
}
}
});
DataReceived will be fired only if data is received. So second time data will not be requested, so dataReceived won't be fired.
Use "change" event for this.
As example of the three events involved here, in the order they are fired.
events: {
dataRequested: function(){
//Here the code to be executed when a request to server was fired. For example, set a "waitingForData" flag to true
},
change: function(){
//Here your magic to be executed everytime you do ElementBinding. For example, check if your "waitingForData" flag is false, if so, do whatever you want with the data you already have.
},
dataReceived: function(rData){
//Here your logic to be executed when data from server is received. For example, set your "waitingForData" flag to false, and do whatever you want with the data have reveived.
}
}
If you call bindElement with the same path twice, the second time won't actually trigger a new call to get new data, since the path didn't change. Since there won't be a second call, there won't be a second dataReceived event.
You can fire it manually if you want to trigger it again.
this.getView().getElementBinding().fireDataReceived()
Based on your code, it looks like you're trying to execute code from your server when you get the response. I would use the attachEventOnce method from the EventProvider class.
oModel.attachEventOnce("requestCompleted", function(oEvent) {
//execute your code here
}, this);
this.getView().bindElement(sPath);
The requestCompleted event will fire after data comes back once, and then clear the event from happening again, that way you don't always run every response from every request through the same callback function.
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 have a page that is created completely using Knockout. In one of the templates, clicking on a link will display a JQuery Datepicker control to select a date. Upon selecting the date, a function executes using the selected date and the Datepicker closes. That much works just fine.
It can take several seconds from when someone selects a date until the Datepicker closes. This is due to a function that is called (LoadAppointmentTimeSlots) which needs to run synchronously and can take a while to do what it does. To address this, I would like a DIV to appear that provides feedback to the user that the system is working ("#loading").
THE PROBLEM is that the DIV does not appear until after the LoadAppointmentTimeSlots function executes (by which time the DIV gets hidden again). I have experimented with setTimeout in several ways, but nothing has worked.
Below is the "offending" code:
var SchedulingViewModel = function () {
var self = this;
...
self.Date_OnClick = function () {
var selectedDate;
$("#calendarPopup").append('<div id="datepicker" />');
$("#datepicker").datepicker({
dateformat: 'mm-dd-yy',
changeMonth: true,
changeYear: true,
setDate: new Date(),
minDate: 0,
maxDate: self.SelectedRFVInterval() - 1,
onSelect: function (datetext, inst) {
selectedDate = datetext;
$("#loading").show();
self.LoadAppointmentTimeSlots(datetext); // function within view model that uses $AJAX in sync mode to return time slot data
$("#loading").hide();
$('#calendarPopup').dialog('close');
}
});
};
...
}
The difficulty you are running into is because show() is executed asynchronously, and since javascript is executed in a single thread, that means they have to wait until all synchronous code (such as LoadAppointmentTimeSlots) is done.
To get your desired behaviour, put everything after the show() call into the callback for the show command. That way LoadAppointmentTimeSlots won't execute until the show() call is done. Here is how:
// ... other code
$("#loading").show(function() {
self.LoadAppointmentTimeSlots(datetext);
$("#loading").hide();
$('#calendarPopup').dialog('close');
});
However, it might be better to change your ajax call in LoadAppointmentTimeSlots to be asynchronous and move the hide() and dialog('close') calls to the callback of the ajax call. This allows javascript to keep doing other things while you are waiting for LoadAppointmentTimeSlots to finish. That might look more like this:
// ... other code
$("#loading").show()
self.LoadAppointmentTimeSlots(datetext, function() {
$("#loading").hide();
$('#calendarPopup').dialog('close');
});
// ... more code
function LoadAppointmentTimeSlots(datetext, alwaysCallback) {
// Prepare request details
$.ajax( "/myendpoint?param=foo" )
.done(function(data) { alert("success"); }) // do something with data
.fail(function() { alert("error"); })
.always(alwaysCallback); // called on both success and failure of ajax call
}
In Jquery mobile-1.1.1 pagebeforechange, pagebeforeshow events not fired second time call of $mobile.changepage.
From Home page:
function scan() {
window.plugins.barcodeScanner.scan(function(result) {
alert("Barcode-->"+result.text);
barcode=result.text;
$.mobile.changePage("scan.html",{reloadPage:true,transition: "none"});
}, function(error) {
alert("Scanning failed: " + error);
});
}
Page Load:
$("#scan_page").live("pagebeforeshow",function(event){
alert("Scan page Init");
loadScannedItems();
});
function loadScannedItems()
{
//append scanned items to list
// called Scan() again
}
pagebeforeshow event fired first time the page loads,again I go to scan function call the changePage, but pagebeforeshow not fired. What is the problem in this code?
Also created button with data-role="button" dynamically. But still it displayed as link?
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