5

I have been trying to figure out how to use the Batch API in an overlay via AJAX, but are not sure that's possible at all? - As far as I can see the batch API, when javascript is enabled, calls the misc/batch.js, which at status=100 performs a window.location to return to the page who requested the batch.

To my knowledge, it's not possible to catch and prevent this event (Without showing the user a popup with the choice of staying on or leaving the page). - So right now I don't see a way to achieve this without running batch as if, javascript was not turned on?

Am I missing some Drupal magic here?

8
  • Don't think it's a duplicate, although the "solution" might be the same.. But initially I'm looking for a solution that doesn't require me to override core files in Drupal (In this case the misc/batch.js file) Mar 18, 2013 at 12:13
  • But there is a working solution for your problem.
    – niksmac
    Mar 18, 2013 at 12:22
  • 1
    The only solution i can see in the thread you linked to is to unset the the "misc/batch.js" and instead implement your own script... This just sound a bit hackish to me.. From all i have learned that's not the way to do stuff in Drupal.. But i might miss something here? Mar 18, 2013 at 12:25
  • Yes i agree with that. Dont hack Core is drupal policy. but i cant find any quick solution for this.
    – niksmac
    Mar 18, 2013 at 12:54
  • Not necessarily looking for a quick solution.. But is finding it hard to see any solution for this... Mar 18, 2013 at 13:21

1 Answer 1

0

It is possible without hacking core. It needs a bit of fiddling, but you can basically just use Drupal.ProgressBar for an existing batch process, providing your own updateCallback to control its behaviour.

I have successfully done this in every version of Drupal since Drupal 7, but can't share my code here unfortunately.

One example I found for Drupal 8 explains the gist of it, although it's not explicitly covering the modal part of the question: https://www.hashbangcode.com/article/drupal-8-running-batch-through-ajax-request

I'll share a slightly modified (and untested) version of the code example from the linked article:

(function ($, Drupal) {
  'use strict';

  Drupal.behaviors.account = {
    attach: function attach(context, settings) {
      var progressBar = void 0;

      function updateCallback(progress, status, pb) {
        $('#updateprogress').html(progress + '%');
        if (progress === '100') {
          pb.stopMonitoring();
          // And do whatever suits your needs, redirecting or updating some DOM
          // elements
        }
      }

      function errorCallback(pb) {
      }

      $.ajax({
        url: Drupal.url('account/loading/ajax'),
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        success: function success(value) {
          progressBar = new Drupal.ProgressBar('updateprogress', updateCallback, 'POST', errorCallback);
          progressBar.startMonitoring(BATCH_URL + '&op=do', 10);
        }
      });
    }
  };
})(jQuery, Drupal);

BATCH_URL is the url that you get after setting up the batch process in PHP. I would also end the process with a BATCH_URL + '&op=finished' to do cleanup on the server, evaluate the process or whatever makes sense in the specific context.

You can also extend the Drupal.ProgressBar.prototype object to further modify the behaviour of it and adapt it your needs, e.g. by overriding its setProgress to do more fine grained updates or provide server side generated messages.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.