2

I'm working on an extension for Magento and need to wrap a method (nextStep) in the Payment class of opcheckout.js

In my JS file, loading after the original checkout.js file, I have tried many variations of the following code, but none seem to work. The object definitely exists however.

Payment.prototype.nextStep
   = Payment.prototype.nextStep.wrap(function(parentMethod){
                 alert("hello world");
});

I've also tried Payment.addMethod and replaced the method completely with my own, but this did not work.

Essentially in this method, I need to add a check to see if the JSON response 'error' comes back with a specific value that I define in my observer event. For the sake of the example, it returns like this:

"error" => "popup1"

Here is the nextStep function and a little idea of what I need. My code is added between the comments

nextStep: function(transport){
    if (transport && transport.responseText){
        try{
            response = eval('(' + transport.responseText + ')');
        }
        catch (e) {
            response = {};
        }
    }

    /* START MY CODE - Need code added here  as shown below */

    if (response.error) {
        if(response.error == 'popup1'){
            // my code
        }
    }

    /* END MY CODE */

    /*
     * if there is an error in payment, need to show error message
     */
    if (response.error) {

        if (response.fields) {
            var fields = response.fields.split(',');
            for (var i=0;i<fields.length;i++) {
                var field = null;
                if (field = $(fields[i])) {
                    Validation.ajaxError(field, response.error);
                }
            }
            return;
        }
        alert(response.error);
        return;
    }

    checkout.setStepResponse(response);

    //checkout.setPayment();
},

This is the last issue in making my extension installable and the developer prior to me simply commented out the base opcheckout.js file and loaded a modified version which is not acceptable.

Any pointers? Suggestions?

Thanks

1

I don't know if this will suit you, but you can overwrite existing class methods using addMethods() function.

Class#addMethods is a method available on classes that have been defined with Class.create. It can be used to add new instance methods to that class, or overwrite existing methods, after the class has been defined.

New methods propagate down the inheritance chain. If the class has subclasses, those subclasses will receive the new methods — even in the context of $super calls. The new methods also propagate to instances of the class and of all its subclasses, even those that have already been instantiated.

More info

So, I created a new file and named it opcheckoutmod.js. Here is what it looks like:

if (typeof Payment !== 'undefined') {
    Payment.addMethods({
        nextStep: function(transport){
            alert('my code');
            if (transport && transport.responseText){
                try{
                    response = eval('(' + transport.responseText + ')');
                }
                catch (e) {
                    response = {};
                }
            }
            /*
             * if there is an error in payment, need to show error message
             */
            if (response.error) {
                if (response.fields) {
                    var fields = response.fields.split(',');
                    for (var i=0;i<fields.length;i++) {
                        var field = null;
                        if (field = $(fields[i])) {
                            Validation.ajaxError(field, response.error);
                        }
                    }
                    return;
                }
                alert(response.error);
                return;
            }

            checkout.setStepResponse(response);

            //checkout.setPayment();
        }
    });
}

As you can see whole nextStep() method has been pasted from the original file, I just added alert('my code'); on the first line to verify that my code is being executed. It is also wort mentioning that opcheckoutmod.js should be included after opcheckout.js file.

Hope this helps.

  • I've used this exact same method, using prototype's addMethods() but the result was nothing. I've tried console.log as well just to see if it was interfering with another popup that I have generated when the JSON response returns. I mentioned using this in the original post, sorry if I was not clear. Also this does in fact load after the original file, as this is needed for the object to even exist. – Jbevan Dec 31 '14 at 0:48
  • I've tested this and it's working for me. You must be missing something on your end. – Lord Skeletor Dec 31 '14 at 5:47
  • In DOM (firebug), it shows the object Payment and the method nextStep shows the updated file path of the custom method whether I define in checkout.js (my file) or if included inline. I've been seeing a console.log message from the original Magento definition which I've added to see which it was using when proceeding past payment step. Is there any way I can privately provide you access to the site, to see the code on the front-end? – Jbevan Dec 31 '14 at 16:03
  • I noticed in the Payment.initialize method is being called using "this" and it may be keeping the scope local. I'm still not fully familiar with scopes in Javascript as I work primarily with PHP, but this screenshot is where I am referring to. prntscr.com/5nmnkj – Jbevan Jan 2 '15 at 16:42
1

I ended up finding out what the issue was by running a console.trace() I'm going to add this for other developers having the same issue.

The steps in the Payment class creation started for me at the file:

app/design/frontend/[TEMPLATE]/default/template/checkout/onepage/payment.phtml

This may not be the case for everyone. My particular extension sets this template differently which I'm going to be revising.

The code it begins at is when the class is first initiated.

Line # 791 in my page source

var payment = new Payment('co-payment-form', '<?php echo $this->getUrl('checkout/onepage/savePayment') ?>');

Even though my file opcheckoutmod.js (on line 1084) was included AFTER opcheckout.js (on line 375), the class was initiated before the second file (my override) loaded.

Now I successfully can run my own modified method. Hope this helps anyone down the road.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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