Best ajax questions in February 2011

Consecutive Ajax calls

8 votes

I need a little help in my application design. Using Ajax I want to get some PHP resources consecutively but I don't think if it is good to retrieve them using JQuery $.ajax method.

I think something like this means wrong design:

$.ajax({
     url: SERVERURL+'index.php/home/checkAvailability',
     datatype: 'text',
     success: function(data){
        if(data == 'unavailable'){
           // do stuff
        }
        else{
           $.ajax({
              url: SERVERURL+'index.php/home/getWebTree/',
              dataType: 'json',
              success: function(data){
                 // do stuff
              }
           });
        }
     }
  });

Can anybody give me a suggestion to get a better design? How can I do the same in a better way?

Thanks!

EDIT: like @arnorhs tell us, using async parameter could be a solution. But I'm still think that there are other solutions instead of using consecutive ajax calls.

EDIT2: checkAvailability and getWebTree are PHP functions using CodeIgniter that I've developed to get resources from an external server using Http_Request object.

function checkAvailability() {
      $this->load->library('pearloader');
      $http_request = $this->pearloader->load('HTTP', 'Request');
      $http_request->setURL('http://myurl');
      $http_request->_timeout = 5;
      $http_request->sendRequest();
      $res = 'available';
      if (!$http_request->getResponseCode())
         $res = 'unavailable';
      return $res;
   }

Doing the calls all the same time

If you want to do all the ajax calls at the same time, you can simply call an ajax request right after the others. You could even assign them the same success handler. If you want a more "elegant" approach, I would do something like this:

// define a set of requests to perform - you could also provide each one
// with their own event handlers..
var requests = [
    { url: 'http://someurl', data: yourParams   },
    { url: 'http://someurl', data: yourParams   },
    { url: 'http://someurl', data: yourParams   },
    { url: 'http://someurl', data: yourParams   }
];

var successHandler = function (data) {
    // do something
}

// these will basically all execute at the same time:
for (var i = 0, l = requests.length; i < l; i++) {
    $.ajax({
        url: requests[i].url,
        data: requests[i].data,
        dataType: 'text',
        success: successHandler
    });
}

.

Do a single request

I don't know your use case, but of course what you really should be trying to do is retrieve all the data you're retrieving in a single request. That won't put a strain on your server, the site/application will seem faster to the user and is a better long term approach.

I would try to combine checkAvailability and getWebTree into a single request. Instead of receiving the data in Javascript as text objects, a better approach would be to receive them as json data. Luckily PHP provides very easy functions to convert objects and arrays to json, so you'll be able to work with those objects pretty easily.

edit: small modifications in the PHP code now that I understand your use case better.

So something like this in the PHP/CI code:

function getRequestData () {
    if (checkAvailability() == 'available') {
        $retval = array (
            'available' => '1',
            'getWebTree' => getWebTree()
        );
    } else {
        $retval = array (
            'available' => '0'
        );
    }   
    header('Content-type: text/javascript; charset=UTF-8');     
    echo json_encode($retval););
}

And the Javascript code can then access those by a single ajax request:

$.ajax({
    url: 'http://yoururl/getRequestData',
    dataType: 'json',
    success: function (jsonData) {
        // we can now access the parameters like this:
        if (jsonData.checkAvailability) {
            // etc
        }
        //and of course do something with the web tree:
        json.getWebTree
    }
});

.

Execute the requests synchronously

If you set the async parameter in the $.ajax options to false the functions will be made in a synchronous fashion so your code halts until execution has been completed.. or as the documentation says:

asyncBoolean

Default: true

By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active.

See http://api.jquery.com/jQuery.ajax/

Experiences with integrating spring 3 mvc with GWT?

7 votes

Hello,

Given: Spring 3.0 mvc has excellent REST support with one of the representation being JSON.

GWT simplifies development as UI is developed in java. But by default it uses RPC for client server interaction. But there is an option to use JSON.

Questions:

  1. Can you share experiences with using Spring 3.0 mvc with GWT ?

  2. What is the best approach to integrate these two frameworks?

  3. Is the default GWT's MVP architecture only for client side and does it work well with JSON?

Thanks

Can you share experiences with using Spring 3.0 mvc with GWT ?

Yes. We've successfully built a whole large application around GWT and Spring MVC (1500 source files, 6 months in development).

Spring was the key to the project's success. Only with Spring we were able to test individually some pieces of the application on the server side.

What is the best approach to marry these two frameworks?

Ignore the default Servlet used by GWT and instead create your own Spring controller to handle incoming GWT-RPC requests. This blog post was the key to integrating the two techs.

We also successfully integrated other components: Flash for animated charts and third-party Javascript components for other stuff. These communicate with the server through JSON. So you have two or more kinds of URLs:

  • the *.rpc urls are for GWT components and are served by the Spring controller for gwt
  • the *.json urls are for other components and are served by another Spring controller.

Also, in our case, we shunned configuration with annotations and instead preferred configuration with the good old Spring XML files. They make it much more clear what's going on. Except for the @Required annotation; it's great to find spring beans that should be connected but aren't.

Is the default GWT's MVP architecture only for client side and does it work well with JSON?

GWT's MVP architecture works best if you follow the guide lines. Use GWT-RPC communication as Google suggests.

You can still have JSON for other client-side components.

Real time collaborative editing - how does it work?

7 votes

I'm writing an application in which I'd like to have near real time collaborative editing features for documents (Very similar to Google Documents style editing).

I'm aware of how to keep track of cursor position, that's simple. Just poll the server ever half second or second with the current user id, filename, line number and row number which can be stored in a database, and the return value of this polling request is the position of other user's cursors.

What I don't know how to do is update the document in such a way that it won't throw your cursor off and force a full reload as that would be far to slow for my purposes.

This really only has to work in Google Chrome, preferably Firefox as well. I don't need to support any other browser.

The algorithm used behind the scenes for merging collaborative edits from multiple peers is called operational transformation. It's not trivial to implement though.

See also this question for useful links.

Rails not reloading session on ajax post

7 votes

Hello,

I'm experiencing a very strange problem with Rails and ajax using jQuery (although I don't think it's specific to jQuery).

My Rails application uses the cookie session store, and I have a very simple login that sets the user id in the session. If the user_id isn't set in the session, it redirects to a login page. This works with no problems. JQuery GET requests work fine too. The problem is when I do a jQuery POST - the browser sends the session cookie ok (I confirmed this with Firebug and dumping request.cookies to the log) but the session is blank, i.e. session is {}.

I'm doing this in my application.js:

$(document).ajaxSend(function(e, xhr, options) {
  var token = $("meta[name='csrf-token']").attr('content');
  xhr.setRequestHeader('X-CSRF-Token', token);
});

and here is my sample post:

$.post('/test/1', { _method: 'delete' }, null, 'json');

which should get to this controller method (_method: delete):

def destroy
  respond_to do |format|
    format.json { render :json => { :destroyed => 'ok' }.to_json }
  end
end

Looking at the log and using Firebug I can confirm that the correct cookie value is sent in the request header when the ajax post occurs, but it seems that at some point Rails loses this value and therefore loses the session, so it redirects to the login page and never gets to the method.

I've tried everything I can think of to debug this but I'm coming around to the idea that this might be a bug in Rails. I'm using Rails 3.0.4 and jQuery 1.5 if that helps. I find it very strange that regular (i.e. non-ajax) get and post requests work, and ajax get requests work with no problems, it's just the ajax posts that don't.

Any help in trying to fix this would be greatly appreciated!

Many thanks,
Dave

I'm going to answer my own question as I've managed to work out what was going on. I'll post it here in case it's useful to anyone else!

After investigating further, I worked out that the code that was supposed to be setting the request header with the CSRF token, wasn't. This was the original code:

$(document).ajaxSend(function(e, xhr, options) {
  var token = $("meta[name='csrf-token']").attr('content');
  xhr.setRequestHeader('X-CSRF-Token', token);
});

What was happening was that this code wasn't setting the header, Rails was receiving an Ajax request, the token didn't match and it was resetting the session. This used to raise an ActionController::InvalidAuthenticityToken error (I suppose I would have caught this earlier if an error was raised... oh well), but since Rails 3.0.4 it now just quietly resets the session.

So to send the token in the header, you have to do this (many thanks to this marvellous blog post):

$.ajaxSetup({
  beforeSend: function(xhr) {
    xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
  }
}); 

And now it all works as it should. Which is nice.

Why need to use JSON in php and AJAX

6 votes

I just started doing jQuery last week, and so far I already made some basic systems with ajax, like basic jQuery CRUD and simple chat system without referencing on other's work for I decided to test myself on how far I can do systems alone in jQuery(without JSON and XML yet).

But when I decided to look at other's work (hoping to get/learn good practices and codes out there) many or almost every program that deals with ajax have some JSON in it. So I decided to study and read JSON specially this one, but I guess because it's my first time dealing with it, I'm having a problem sinking it into my brain. Yeah I know it is a "lightweight way of describing hierarchical data", I also know how to make JSON like mixing a literal array and object in JS, and how to dsplay it in js.

But my question is, what's the difference and what's the advantage than not using it? When I can still get and store data on the server using ajax and database without JSON. By the way I haven't focus on XML yet because based from my research it's better to use JSON in AJAX.

Can you give me some actual scenario dealing with

s1. ajax php mysql (this with what disadvantages?)

and

s2. ajax php mysql json (this with what advantages?)

I mean, my focus is to send and get data, and I already can do it with s1.

Sorry if you find my question stupid. Tia. :)

Why use JSON? The answer is portability and structure.

JSON is portable because parsers and writers are available for many, many languages. This means that JSON that a PHP script generates can be very easily understood by a JavaScript script. It is the best way to transmit complex structures like arrays and objects, and have it still be compatible with multiple languages.

JSON provides structure because the data you transmit with it can have consistent formatting. This is instead of transmitting back plain-text (i.e. unformatted) data, like comma-separated or delimited data.

Data that is merely delimited (for example, "BookName1,BookName2,BookName3") is more difficult for humans to understand, debug, and work with. If you wanted to debug a response between your server and your browser and the data was delimited (like my example above), you might have a hard time understanding it. Also, if you want to add different data types, provide separate records, etc., then your custom data format becomes more complicated. Eventually, you might end up reinventing JSON.

As a side note, JSON is indeed better than XML. It is much more efficient space-wise. There are no tag names to take up space. Structure is created via nested braces, instead of verbose tags.

Resources

Here is an interesting article on the differences and pros/cons of XML and JSON: http://www.json.org/xml.html

Examples

Per your request, here is an example of encoding JSON with PHP. This is ripped from the docs:

$arr = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);

echo json_encode($arr);

Output:

{"a":1,"b":2,"c":3,"d":4,"e":5}

Contrast this to something like this, without JSON:

a,1
b,2
c,3
d,4
e,5

To parse that, you'd have to iterate through each line, split the values yourself, and then create the array. This isn't that difficult, but imagine you have a nested object:

$arr = array ('a'=> array(1,2,3),'b'=> array('a' => 1, 'b' => 2),'c'=>3,'d'=> array(1,2,3,4,5) ,'e'=>5); // etc.

With JSON, it's no different to encode it. Just use json_encode. But, encoding this manually, and then decoding it manually would be significantly more work.

ASP.NET MVC 3 - Ajax.BeginForm vs jQuery Form Plugin

6 votes

I'm starting a new ASP.NET MVC 3 project and am going to implement some screens that are read only by default but allow the user to edit information by clicking on an Edit button. I want these screens to be AJAXed. I have previously used the jQuery Form Plugin to implement similar screens on an ASP.NET MVC 2 project.

I've just discovered the existence of Ajax.BeginForm() and was wondering whether I should use that since it is built in, instead of using the jQuery Form Plugin. I've done a Google search on the difference between the two techniques but couldn't find anything.

What I would like to know is which one (or a different one altogether) should I use with ASP.NET MVC 3.

What are the best practices and libraries for implementing AJAX forms in ASP.NET MVC?

What are the strengths and weaknesses of Ajax.BeginForm vs the jQuery Form Plugin?

I would use the Form Plugin.

In MVC 3, the Ajax helper is basically implemented using jQuery Ajax. (See Brad's Wilsons post on unobtrusive Ajax in MVC 3.) The upside to using the Form Plugin is that you'll have more control over your pages and you don't have to use the clunky BeginForm API.

Return HTML or build HTML using javascript?

6 votes

I am returning data about contacts to build a list

the basic html looks like

{repeat:20}
<div class="contact">
  <a rel="123">FirstName LastName</a>
  <div class="info">
    {repeat:5}
    <div>
      <div class="infoLabel">Age:</div>
      <div class="infoPiece">56</div>
    </div>
    {endrepeat}
  </div>
</div>
{endrepeat}

The {repeat:20} is not actual code
That block of code is repeated 20 times

My question is.

What is more benificial:

  1. Create the markup server side, return the actual html.
  2. Return Json data with the information and build the list client side.


For the purpose of this discussion let us assume some constants

  • Server load is not an issue (we are using a high performance server)
  • The returned data is for display purposes only (not to be manipulated)
  • We are not factoring in users without javascript enabled.
  • We are not factoring in any browsers < Internet Explorer 7

As most of the times during web development, you need to decide what is more important to you.

If you're just after performance no matter what, it is of course faster to do all the render action on your server and just deliver HTML code. But this in turn, most times costs flexability plus, you've got more traffic over the wire.

On the other hand, just sending JSON data for instance and do the render stuff on the client, is much less traffic over the wire, but it's more CPU load on the clientside. Browsers (DOM + ECMAscript) have increased performance like a lot over the past years and month, so it is what lots of applications do.

But this is not the end of story. JSON is optimized, but not highly optimized. Again if you're really after performance you need to create your own transport of data. For instance

|box1|item1|item2

is less code then JSON notation

'{"box1": ["item1", "item2"]}'

This of course is highly specific, but it saves lots of traffic if we're going really big. I recommend the book High performance Javascript by Nicholas C. Zakas. Execellent book about this topic.

How to Improve Entity Framework and Javascript Interaction

6 votes

Hi Everyone,

This is a pretty vague/subjective question. I want to know if this is the best way to send/retrieve data to/from the browser using ajax calls. On the back end webservice, I want to use the entity framework. Below are two example functions.

The criteria for "best" is speed of writing code, readable code, and robust architecture.

Thanks for any feedback and suggestions and comments.

Get Function

[WebMethod]
public AjaxEmployee EmployeeGetById(int employeeID, bool getTimeOff)
{
    using (Time_TrackerEntities ctx = new Time_TrackerEntities())
    {
        var results = from item in ctx.Employees
                      where item.ID == employeeID
                      orderby item.Last_Name
                      select new AjaxEmployee
                      {
                          ID = item.ID,
                          Employee_ID = item.Employee_ID,
                          First_Name = item.First_Name,
                          Middle_Name = item.Middle_Name,
                          Last_Name = item.Last_Name,
                          Supervisor_ID = item.Supervisor_ID,
                          Active = item.Active,
                          Is_Supervisor = item.Is_Supervisor
                      };
        var emp = results.FirstOrDefault();
        if (getTimeOff)
        {
            var results2 = from item2 in ctx.Time_Off
                           where item2.Employee_ID == emp.Employee_ID
                           select new AjaxTime_Off
                           {
                               ID = item2.ID,
                               Employee_ID = item2.Employee_ID,
                               Date_Off = item2.Date_Off,
                               Hours = item2.Hours
                           };
            emp.Time_Off = results2.ToList<AjaxTime_Off>();
        }

        return emp;
    }
}

Save Function

[WebMethod]
public bool EmployeeSave(AjaxEmployee emp)
{
    using (Time_TrackerEntities ctx = new Time_TrackerEntities())
    {
        var results = from item in ctx.Employees
                      where item.ID == emp.ID
                      select item;

        var myEmp = results.FirstOrDefault();
        if (myEmp == null)
        {
            myEmp = new Employee();
            ctx.Employees.AddObject(myEmp);
        }

        myEmp.Employee_ID = emp.Employee_ID;
        myEmp.First_Name = emp.First_Name;
        myEmp.Middle_Name = emp.Middle_Name;
        myEmp.Last_Name = emp.Last_Name;
        myEmp.Supervisor_ID = emp.Supervisor_ID;
        myEmp.Active = emp.Active;
        myEmp.Is_Supervisor = emp.Is_Supervisor;

        return ctx.SaveChanges() > 0;
    }
}

There are a few improvements to be made.

Save() Method - Don't left-to-right copy, use EF built in logic

Instead of this:

myEmp.Employee_ID = emp.Employee_ID;
myEmp.First_Name = emp.First_Name;
myEmp.Middle_Name = emp.Middle_Name;
myEmp.Last_Name = emp.Last_Name;
myEmp.Supervisor_ID = emp.Supervisor_ID;
myEmp.Active = emp.Active;
myEmp.Is_Supervisor = emp.Is_Supervisor;

You can do this:

ctx.Employees.ApplyCurrentValues(emp).

What this does, is look for an entity with the same key in the graph (which there is, since you have just retrieved it with FirstOrDefault()), and override the scalar values with the entity you pass in - which is exactly what your doing.

So your 7 lines becomes 1, plus if you add any extra scalar properties - you won't have to refactor your code. Just remember - only works for scalar properties, not navigational properties.

Why build query for primary key retrieval? Just use predicate to SingleOrDefault()

Instead of this:

var results = from item in ctx.Employees
              where item.ID == emp.ID
              select item;

var myEmp = results.FirstOrDefault();

Do this:

var myEmp = ctx.Employees.SingleOrDefault(x => x.ID == emp.Id);

Or even better, use a pipe/filter technique:

var myEmp = ctx.Employees.WithId(emp.Id).SingleOrDefault();

Where WithId is an IQueryable<Employee> extension method, which filters the query based on the supplied employee ID. This allows de-coupling of filtering/business logic from your repository/DAL. It should go in your domain model, so you can have a nice fluent API for query your domain entities via your ORM.

When your retrieving an entity via the primary key, you should always use SingleOrDefault() or Single(), never FirstOrDefault() or First(). If it's a primary key - there should only be one of them, so you should throw an exception if more than one exists, which is what SingleOrDefault() does. And as @Shiraz mentions - your FirstOrDefault() will crash the query below. You always need null checking when you use <First/Single>OrDefault().

The same improvements can be made to your Get method.

Overall, there is nothing functionally wrong with your code - it just needs subtle improvements, null checking and exception handling.

The only functional improvement i highly recommend is refacting your web service code into a Generic Repository. As the code is very trivial and can be re-used across any entity. The web service shouldn't be concerned with transactions, primary key's or EF logic whatsoever. It shouldn't even have a reference to the EF DLL. Encapsulate this logic behind a repository and delegate the persistence logic to there (via an interface of course).

After making the changes i've mentioned above, your web service methods should have no more than 5-7 lines of code each.

You have far too much intelligence in your web service - it should be dumb and persistent ignorant.

jQuery Submit Refreshing Page

6 votes

The following code is intended to do a purely ajax POST request, instead it seems to do the POST via ajax and then the browser navigates to the response.

The HTML...

<div id="bin">
    <form class="add" method="post" action="/bin/add/">
        <p>I'm interested! Save for later.</p>
        <input type="hidden" name="product_id" value="23423">
        <input type="submit" value="Save">
    </form> 
    <form style="display:none;" class="remove" method="post" action="/bin/remove/">
        <p>I changed my mind--I'm not interested.</p>
        <input type="hidden" name="product_id" value="23423">
        <input type="submit" value="Unsave">
    </form>
</div>

The jQuery...

$('#bin form').submit(function() {
                $.post($(this).attr('action'),{
                    success: function(data) { $(this).hide().siblings('form').show() },
                    data: $(this).serialize()

                });
                return false;
            })

As far as I understand it, the return false; line should mean that no matter what, any calls to the submit function or clicks on the 'Submit' button or the hitting of enter means that my function will execute and the browser will not navigate to /bin/add or /bin/remove. But for some reason, the browser is changing pages.

Any idea what I'm doing wrong here? Thanks.

my bet it's because of the $(this), try it this way....

$('#bin form').submit(function() {
    var $this = $(this);
    $.post($this.attr('action'), {
        success: function(data) {
            $this.hide().siblings('form').show()
        },
        data: $this.serialize()

    });
    return false;
});

demo no error

demo with the error

Cufon loaded asynchronously doesn't render in IE

5 votes

I'm creating a site which uses Cufon and is particularly heavy in terms of page-weight due to a large amount of Javascript. Therefore I'm trying to load in the script asynchronously with head.js ( http://headjs.com/ ) like so:

head.js("http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js", function() {
 head.js("/js/libs/cufon-yui.js", function() {
    head.js("/js/shared/Stag_Bold_700.font.js" , function() {
            Cufon.replace('h1', { fontFamily: 'Stag Bold' });
    });
 });
});

So Jquery is downloaded first, the subsequent cufon lib file and cufon font are downloaded in sequence and then Cufon is finally called to replace the H1. Obviously, this is a trimmed down example with fewer replacements but this still doesn't work when just attempting to replace the H1.

The problem is that ONLY in Internet Explorer (6/7/8), the text is not replaced but I can see that Cufon has definitely been called. I can ascertain this because the tag has the class "cufon-active cufon-ready" added to it. When I inspect the markup using the IE Developer toolbar, the cufon/cufoncanvas tags are there inside the selected elements but are, for want of a better word, invisible.

In IE9, the script behaves as intended similar to Chrome and Firefox. I have tried adjusting the Cufon drawing engine and have updated to the latest 1.09i version for good measure. If I move the Cufon calling statements to the document ready event instead of loading asynchronously, it works but I am trying to optimize page load and my site will be using a number of Cufon fonts as well as many other JS plug-ins. I've also tried using both labs.js and head.js to load the appropriate files asynchronously.

I had the same problem - I addressed this by using the browser detection of head.js to do the following:

if (head.browser.mozilla || head.browser.webkit || head.browser.opera ||
        (head.browser.ie && (head.browser.version == '9.0'))) {
        head.js('script/jquery.min.js',
                'script/cufon.js', function () {
                    head.js('script/bebas_neue_400.font.js', function () {
                        Cufon.replace('h1', {
                            textShadow: '1px 1px rgba(0, 0, 0, 0.2)'
                        }).now();
                        // or a head.js('scripts/file.with.cufon.replacement.js');
                    });
                });
            } else {
        // here we load scripts depending on GZIP support for this browser
        document.write('\x3Cscript type="text/javascript" src="script/jquery.min.js">\x3C/script>');
        document.write('\x3Cscript type="text/javascript" src="script/cufon.js">\x3C/script>');
        document.write('\x3Cscript type="text/javascript" src="script/bebas_neue_400.font.js">\x3C/script>');
        document.write('\x3Cscript type="text/javascript" src="script/file.with.cufon.replacement.js">\x3C/script>');            
    }

You could also use conditional comments (I didn't because I am also doing GZIP support detection in JavaScript and needed to adjust the scripts which are loaded dynamically.)

It's a hack, but should be useful enough until it's addressed within the library itself.

(I have also posted GIST with a more complete example here)

Long polling timeout issue

5 votes

Hi guys,

I'm doing a long poll method chatroom. But it seems that, when a long poll occurs and I refresh the page in chrome OR i try to send another async request everything times out (i.e i cant load my domain again until i close/reopen the browser).

My client side code is:

 $(document).ready(function() {
    setTimeout(
      function () {
        longPollForMessages();
      },
      500
    );
  });

function longPollForMessages()
{
  $.ajax({
    url: url,
    dataType: 'json',
    success: function(data) {     
        $('#chat_messages').append('<div>'+data.messages+'</div>');

        longPollForMessages();
    }
  });
}

And my serverside:

while(true) {
      $messages = $db->getMessages();

      if (!$messages || sizeof($messages)==0) {
        sleep(1);
      } else {
        echo '{"message":'.json_encode($messages).'}';
        die();
      }
    }

Any ideas? Assume no syntax errors.

I figured it out from this question: stackoverflow.com/questions/4457178/… - php locks a given session until the page is done loading so the second ajax call wasn't able to go through. You have to release the lock by calling session_write_close();

jQuery Load Progress Bar

5 votes

So, I'm sure this question HAS to have been asked, but after searching through the 'Related Questions' here as well as several Google searches...I have come up empty.

I'm simply trying to implement a true bytes_loaded/bytes_total type of progress bar in jQuery or even traditional Js. This was so easy in the AS3 days :) ...but of course Flash comes with it's drawbacks. All I really need to know is how to calculate the current bytes loaded and bytes total during any download. Calculating the uploaded bytes would be sweet too. Anyone have another posted question to direct me to? Or have knowledge of the subject? Thanks guys.

There is a Q/A on progress bars for long process reporting on the server. Also check out how to get AJAX download progress in every browser but IE.

How can I drop an image to a container and then update the container based on what was dropped to it?

5 votes

I'd like to be able to drag an image into one of two containers (container 1 and container 2). From there, depending on which container the image was dropped to, I'd like to update that container with a database call (or just update a row in one of my tables).

I'd like to use http://jqueryui.com/demos/droppable/ to achieve this, but I'm not sure how to process the request, and how to get each container to listen for an event handler (dropping of the image).

I've drawn a really bad diagram below to explain what I mean:

Diagram of Droppable System

The droppable demo shows exactly how to do this sort of thing.

$(function() {
    $( "#draggable" ).draggable();
    $( "#droppable" ).droppable({
        drop: function( event, ui ) {
            $( this )
                .addClass( "ui-state-highlight" )
                .find( "p" )
                    .html( "Dropped!" );
        }
    });
});

My own really basic demo → (updated)

Ajax.ActionLink not working, Response.IsAjaxRequest() is always false

4 votes

Hi. I have been googling/SO:ing this issue for a while and many seem to be sharing this, but I haven't found any successful solution to my problem.

Using MVC3 and Razor.

  1. Master page contains:

    <script src="@Url.Content("~/Scripts/jquery-1.5.min.js")" type="text/javascript"></script>

    <script src="@Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"></script>

    <script src="@Url.Content("~/Scripts/MicrosoftMvcAjax.js")" type="text/javascript"></script>

  2. AjaxTest.cshtml contains:

    <div id="AjaxTestDiv">content</div>

    @Ajax.ActionLink("Update", "AjaxTester", new AjaxOptions { UpdateTargetId = "AjaxTestDiv" })

  3. AjaxTester action method:

    public string AjaxTester()
    {
        if (Request.IsAjaxRequest())
        {
            return DateTime.Now.ToString();
        }
        else
        {
            return "FAIL";
        }
    }
    

I always get the "FAIL" returned, to a blank page, not in the targeted div.

Edit: Also note that if I remove the if (Request.IsAjaxRequest()), I still don't get back anything to the targeted div, but instead a blank page.

Edit2: Looking at the HTML generated, this is my link:

<a data-ajax="true" data-ajax-method="POST" data-ajax-mode="replace"
data-ajax-update="#AjaxTestDiv" href="/Area/AjaxTester">Update</a>

Have tried switching the method to GET, to no avail.

By default ASP.NET MVC 3 uses unobtrusive jquery with all the Ajax.* helpers. So start by getting rid off all MicrosoftAjax scripts (this useless c**p) and put the following instead:

<script src="@Url.Content("~/Scripts/jquery-1.5.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>

and then simply activate unobtrusive AJAX in your web.config (if not already done):

<appSettings>
    <add key="ClientValidationEnabled" value="true"/> 
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/> 
</appSettings>

Now jquery is going to unobtrusively AJAXify all the links containing those HTML 5 data-* attributes.

Or even better IMHO:

In your view simply:

@Html.ActionLink("Update", "AjaxTester", new { id = "mylink" })

and in a separate javascript file AJAXify this anchor:

$(function() {
    $('#mylink').click(function() {
        $('#AjaxTestDiv').load(this.href);
        return false;
    });
});

Django CSRF check failing with an Ajax POST request

4 votes

I could use some help complying with Django's csrf protection mechanism via my AJAX post. I've followed the directions here:

http://docs.djangoproject.com/en/dev/ref/contrib/csrf/

I've copied the AJAX sample code they have on that page exactly:

http://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

I put an alert printing the contents of getCookie('csrftoken') before the xhr.setRequestHeader call and it is indeed populated with some data. I'm not sure how to verify that the token is correct, but I'm encouraged that it's finding and sending something.

But django is still rejecting my AJAX post.

Here's my Javascript:

$.post("/memorize/", data, function (result) {
    if (result != "failure") {
        get_random_card();
    }
    else {
        alert("Failed to save card data.");
    }
});

Here's the error I'm seeing from Django:

[23/Feb/2011 22:08:29] "POST /memorize/ HTTP/1.1" 403 2332

I'm sure I'm missing something, and maybe it's simple, but I don't know what it is. I've searched around SO and saw some information about turning off the CSRF check for my view via the csrf_exempt decorator, but I find that unappealing. I've tried that out and it works, but I'd rather get my POST to work the way Django was designed to expect it, if possible.

Just in case it's helpful, here's the gist of what my view is doing:

def myview(request):

    profile = request.user.profile

    if request.method == 'POST':
        """
        Process the post...
        """
        return HttpResponseRedirect('/memorize/')
    else: # request.method == 'GET'

        ajax = request.GET.has_key('ajax')

        """
        Some irrelevent code...
        """

        if ajax:
            response = HttpResponse()
            profile.get_stack_json(response)
            return response
        else:
            """
            Get data to send along with the content of the page.
            """

        return render_to_response('memorize/memorize.html',
                """ My data """
                context_instance=RequestContext(request))

Thanks for your replies!

Real solution

Ok, I managed to trace the problem down. It lies in the Javascript (as I suggested below) code.

What you need is this:

$.ajaxSetup({ 
     beforeSend: function(xhr, settings) {
         function getCookie(name) {
             var cookieValue = null;
             if (document.cookie && document.cookie != '') {
                 var cookies = document.cookie.split(';');
                 for (var i = 0; i < cookies.length; i++) {
                     var cookie = jQuery.trim(cookies[i]);
                     // Does this cookie string begin with the name we want?
                 if (cookie.substring(0, name.length + 1) == (name + '=')) {
                     cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                     break;
                 }
             }
         }
         return cookieValue;
         }
         if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
             // Only send the token to relative URLs i.e. locally.
             xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
         }
     } 
});

instead of the code posted in the official docs: http://docs.djangoproject.com/en/1.2/ref/contrib/csrf/#ajax

The working code, comes from this Django entry: http://www.djangoproject.com/weblog/2011/feb/08/security/

So the general solution is: "use ajaxSetup handler instead of ajaxSend handler". I don't know why it works. But it works for me :)

Previous post (without answer)

I'm experiencing the same problem actually.

It occurs after updating to Django 1.2.5 - there were no errors with AJAX POST requests in Django 1.2.4 (AJAX wasn't protected in any way, but it worked just fine).

Just like OP, I have tried the JavaScript snippet posted in Django documentation. I'm using jQuery 1.5. I'm also using the "django.middleware.csrf.CsrfViewMiddleware" middleware.

I tried to follow the the middleware code and I know that it fails on this:

request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')

and then

if request_csrf_token != csrf_token:
    return self._reject(request, REASON_BAD_TOKEN)

this "if" is true, because "request_csrf_token" is empty.

Basically it means that the header is NOT set. So is there anything wrong with this JS line:

xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));

?

I hope that provided details will help us in resolving the issue :)