Payment plugin / One page checkout / javascript

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
11 years ago
wooncherk wrote:
What would you suggest besides closest? The form on the regular checkout has no id or anything to refer to specifically. It was the best way to get the submitting form into a variable in the javascript code.

closest also stops when it finds a match, as opposed to the parents method which will traverse the whole tree and then filter the results.

regardless, I don't think my using closest is causing nopcommerce to strip javascript out of the page :)

When you say it strips off, are you viewing through View Source or the Developer Tool (sounds stupid but just to make sure)? I can't think of a reason why it strips off JS yet, probably due to AJAX? (Need to think harder, might have missed something!)

You can just select 2 sets of form differently. One by #co-payment-info-form and another by .payment-info form.

And just to make sure the original onclick event is not overriding anything, perhaps you can overtake it, and call PaymentInfo.save() inside your very own method? http://stackoverflow.com/questions/2629916/how-do-you-override-inline-onclick-event


That is an excellent suggestion once I can see that the javascript for the payment bridge is being included in the page :)
11 years ago
tfsmag wrote:
What would you suggest besides closest? The form on the regular checkout has no id or anything to refer to specifically. It was the best way to get the submitting form into a variable in the javascript code.

closest also stops when it finds a match, as opposed to the parents method which will traverse the whole tree and then filter the results.

regardless, I don't think my using closest is causing nopcommerce to strip javascript out of the page :)

When you say it strips off, are you viewing through View Source or the Developer Tool (sounds stupid but just to make sure)? I can't think of a reason why it strips off JS yet, probably due to AJAX? (Need to think harder, might have missed something!)

You can just select 2 sets of form differently. One by #co-payment-info-form and another by .payment-info form.

And just to make sure the original onclick event is not overriding anything, perhaps you can overtake it, and call PaymentInfo.save() inside your very own method? http://stackoverflow.com/questions/2629916/how-do-you-override-inline-onclick-event

That is an excellent suggestion once I can see that the javascript for the payment bridge is being included in the page :)


Perhaps you can PM me the source code if you don't mind and I check on my side too! Strip off any code that you think have important IP in it if you need to. :D
11 years ago
wooncherk wrote:
What would you suggest besides closest? The form on the regular checkout has no id or anything to refer to specifically. It was the best way to get the submitting form into a variable in the javascript code.

closest also stops when it finds a match, as opposed to the parents method which will traverse the whole tree and then filter the results.

regardless, I don't think my using closest is causing nopcommerce to strip javascript out of the page :)

When you say it strips off, are you viewing through View Source or the Developer Tool (sounds stupid but just to make sure)? I can't think of a reason why it strips off JS yet, probably due to AJAX? (Need to think harder, might have missed something!)

You can just select 2 sets of form differently. One by #co-payment-info-form and another by .payment-info form.

And just to make sure the original onclick event is not overriding anything, perhaps you can overtake it, and call PaymentInfo.save() inside your very own method? http://stackoverflow.com/questions/2629916/how-do-you-override-inline-onclick-event

That is an excellent suggestion once I can see that the javascript for the payment bridge is being included in the page :)

Perhaps you can PM me the source code if you don't mind and I check on my side too! Strip off any code that you think have important IP in it if you need to. :D


If you have a development copy of 3.00 running on  your machine right now you can probably confirm the behavior by opening up the PaymentInfo.cshtml in the manual payment method and adding a bit of inline javascript to the form. Rebuild, then select the the manual payment method with the one page checkout enabled. But if you need my exact source code I can zip it up and put it on dropbox for you to look at. I literally only have the source code as downloaded from the codeplex site and my added payment method project. Nothing in the actual nop source has been altered from the download.
11 years ago
tfsmag wrote:
What would you suggest besides closest? The form on the regular checkout has no id or anything to refer to specifically. It was the best way to get the submitting form into a variable in the javascript code.

closest also stops when it finds a match, as opposed to the parents method which will traverse the whole tree and then filter the results.

regardless, I don't think my using closest is causing nopcommerce to strip javascript out of the page :)

When you say it strips off, are you viewing through View Source or the Developer Tool (sounds stupid but just to make sure)? I can't think of a reason why it strips off JS yet, probably due to AJAX? (Need to think harder, might have missed something!)

You can just select 2 sets of form differently. One by #co-payment-info-form and another by .payment-info form.

And just to make sure the original onclick event is not overriding anything, perhaps you can overtake it, and call PaymentInfo.save() inside your very own method? http://stackoverflow.com/questions/2629916/how-do-you-override-inline-onclick-event

That is an excellent suggestion once I can see that the javascript for the payment bridge is being included in the page :)

Perhaps you can PM me the source code if you don't mind and I check on my side too! Strip off any code that you think have important IP in it if you need to. :D

If you have a development copy of 3.00 running on  your machine right now you can probably confirm the behavior by opening up the PaymentInfo.cshtml in the manual payment method and adding a bit of inline javascript to the form. Rebuild, then select the the manual payment method with the one page checkout enabled. But if you need my exact source code I can zip it up and put it on dropbox for you to look at. I literally only have the source code as downloaded from the codeplex site and my added payment method project. Nothing in the actual nop source has been altered from the download.


Tested and works!

Code: http://i.minus.com/ibarlKmKriMge9.JPG
Result: http://i.minus.com/iINjzEvaERFdl.JPG
11 years ago
so it does... i was testing by just going to view source or into firebug to see if I could view the js... when i tried an alert like you did it fired just fine. I wonder why it  is that cannot see the js?

Either way, I will try to implement what is called in the submit button's onclick event and override the hardcoded onclick. Thanks for your help so far.
11 years ago
Okay, the javascript bridge is working and jquery is updating the value of the hidden field on the form with the token from  paymill... my problem now is trying to recreate what onclick="PaymentInfo.save()" was doing.

I tried copying the code from the onepagecheckout.js file for that method, but it doesn't seem to be working.
11 years ago
Okay finally got it working, but the workaround seems really sloppy basically I copied this section out of onepagecheckout.js
into the document.ready on my paymill javascript

var Checkout = {
                loadWaiting: false,
                failureUrl: false,
                steps: new Array(),

                init: function (failureUrl) {
                    this.loadWaiting = false;
                    this.failureUrl = failureUrl;
                    this.steps = ['billing', 'shipping', 'shipping_method', 'payment_method', 'payment_info', 'confirm_order'];

                    Accordion.disallowAccessToNextSections = true;
                },

                ajaxFailure: function () {
                    location.href = Checkout.failureUrl;
                },

                _disableEnableAll: function (element, isDisabled) {
                    var descendants = element.find('*');
                    $(descendants).each(function () {
                        if (isDisabled) {
                            $(this).attr('disabled', 'disabled');
                        } else {
                            $(this).removeAttr('disabled');
                        }
                    });

                    if (isDisabled) {
                        element.attr('disabled', 'disabled');
                    } else {
                        element.removeAttr('disabled');
                    }
                },

                setLoadWaiting: function (step, keepDisabled) {
                    if (step) {
                        if (this.loadWaiting) {
                            this.setLoadWaiting(false);
                        }
                        var container = $('#' + step + '-buttons-container');
                        container.addClass('disabled');
                        container.css('opacity', '.5');
                        this._disableEnableAll(container, true);
                        $('#' + step + '-please-wait').show();
                    } else {
                        if (this.loadWaiting) {
                            var container = $('#' + this.loadWaiting + '-buttons-container');
                            var isDisabled = (keepDisabled ? true : false);
                            if (!isDisabled) {
                                container.removeClass('disabled');
                                container.css('opacity', '1');
                            }
                            this._disableEnableAll(container, isDisabled);
                            $('#' + this.loadWaiting + '-please-wait').hide();
                        }
                    }
                    this.loadWaiting = step;
                },

                gotoSection: function (section) {
                    section = $('#opc-' + section);
                    section.addClass('allow');
                    Accordion.openSection(section);
                },

                back: function () {
                    if (this.loadWaiting) return;
                    Accordion.openPrevSection(true, true);
                },

                setStepResponse: function (response) {
                    if (response.update_section) {
                        $('#checkout-' + response.update_section.name + '-load').html(response.update_section.html);
                    }
                    if (response.allow_sections) {
                        response.allow_sections.each(function (e) {
                            $('#opc-' + e).addClass('allow');
                        });
                    }

                    //TODO move it to a new method
                    if ($("#billing-address-select").length > 0) {
                        Billing.newAddress(!$('#billing-address-select').val());
                    }
                    if ($("#shipping-address-select").length > 0) {
                        Shipping.newAddress(!$('#shipping-address-select').val());
                    }

                    if (response.goto_section) {
                        Checkout.gotoSection(response.goto_section);
                        return true;
                    }
                    if (response.redirect) {
                        location.href = response.redirect;
                        return true;
                    }
                    return false;
                }
            };
            var PaymentInfo = {
                form: false,
                saveUrl: false,

                init: function (form, saveUrl) {
                    this.form = form;
                    this.saveUrl = saveUrl;
                },

                save: function () {
                    if (Checkout.loadWaiting != false) return;

                    Checkout.setLoadWaiting('payment-info');
                    $.ajax({
                        cache: false,
                        url: this.saveUrl,
                        data: $(this.form).serialize(),
                        type: 'post',
                        success: this.nextStep,
                        complete: this.resetLoadWaiting,
                        error: Checkout.ajaxFailure
                    });
                },

                resetLoadWaiting: function () {
                    Checkout.setLoadWaiting(false);
                },

                nextStep: function (response) {
                    if (response.error) {
                        if ((typeof response.message) == 'string') {
                            alert(response.message);
                        } else {
                            alert(response.message.join("\n"));
                        }

                        return false;
                    }

                    Checkout.setStepResponse(response);
                }
            };


then i removed the onclick from the submit button for payment info
            $(".payment-info-next-step-button").removeAttr("onClick");


then i altered the code that submits the form to this...
                    if (document.location.href.indexOf('onepagecheckout') > -1) {
                        PaymentInfo.init('#co-payment-info-form', 'http://nop1/checkout/OpcSavePaymentInfo/');
                        PaymentInfo.save();
                    }
                    else {
                        form.get(0).submit();
                    }


order went through, and when i switch to regular checkout it still works. Seems really sloppy, if anyone has some suggestions to clean this up I'd love to hear it.
11 years ago
tfsmag wrote:
Okay finally got it working, but the workaround seems really sloppy basically I copied this section out of onepagecheckout.js
into the document.ready on my paymill javascript

var Checkout = {
                loadWaiting: false,
                failureUrl: false,
                steps: new Array(),

                init: function (failureUrl) {
                    this.loadWaiting = false;
                    this.failureUrl = failureUrl;
                    this.steps = ['billing', 'shipping', 'shipping_method', 'payment_method', 'payment_info', 'confirm_order'];

                    Accordion.disallowAccessToNextSections = true;
                },

                ajaxFailure: function () {
                    location.href = Checkout.failureUrl;
                },

                _disableEnableAll: function (element, isDisabled) {
                    var descendants = element.find('*');
                    $(descendants).each(function () {
                        if (isDisabled) {
                            $(this).attr('disabled', 'disabled');
                        } else {
                            $(this).removeAttr('disabled');
                        }
                    });

                    if (isDisabled) {
                        element.attr('disabled', 'disabled');
                    } else {
                        element.removeAttr('disabled');
                    }
                },

                setLoadWaiting: function (step, keepDisabled) {
                    if (step) {
                        if (this.loadWaiting) {
                            this.setLoadWaiting(false);
                        }
                        var container = $('#' + step + '-buttons-container');
                        container.addClass('disabled');
                        container.css('opacity', '.5');
                        this._disableEnableAll(container, true);
                        $('#' + step + '-please-wait').show();
                    } else {
                        if (this.loadWaiting) {
                            var container = $('#' + this.loadWaiting + '-buttons-container');
                            var isDisabled = (keepDisabled ? true : false);
                            if (!isDisabled) {
                                container.removeClass('disabled');
                                container.css('opacity', '1');
                            }
                            this._disableEnableAll(container, isDisabled);
                            $('#' + this.loadWaiting + '-please-wait').hide();
                        }
                    }
                    this.loadWaiting = step;
                },

                gotoSection: function (section) {
                    section = $('#opc-' + section);
                    section.addClass('allow');
                    Accordion.openSection(section);
                },

                back: function () {
                    if (this.loadWaiting) return;
                    Accordion.openPrevSection(true, true);
                },

                setStepResponse: function (response) {
                    if (response.update_section) {
                        $('#checkout-' + response.update_section.name + '-load').html(response.update_section.html);
                    }
                    if (response.allow_sections) {
                        response.allow_sections.each(function (e) {
                            $('#opc-' + e).addClass('allow');
                        });
                    }

                    //TODO move it to a new method
                    if ($("#billing-address-select").length > 0) {
                        Billing.newAddress(!$('#billing-address-select').val());
                    }
                    if ($("#shipping-address-select").length > 0) {
                        Shipping.newAddress(!$('#shipping-address-select').val());
                    }

                    if (response.goto_section) {
                        Checkout.gotoSection(response.goto_section);
                        return true;
                    }
                    if (response.redirect) {
                        location.href = response.redirect;
                        return true;
                    }
                    return false;
                }
            };
            var PaymentInfo = {
                form: false,
                saveUrl: false,

                init: function (form, saveUrl) {
                    this.form = form;
                    this.saveUrl = saveUrl;
                },

                save: function () {
                    if (Checkout.loadWaiting != false) return;

                    Checkout.setLoadWaiting('payment-info');
                    $.ajax({
                        cache: false,
                        url: this.saveUrl,
                        data: $(this.form).serialize(),
                        type: 'post',
                        success: this.nextStep,
                        complete: this.resetLoadWaiting,
                        error: Checkout.ajaxFailure
                    });
                },

                resetLoadWaiting: function () {
                    Checkout.setLoadWaiting(false);
                },

                nextStep: function (response) {
                    if (response.error) {
                        if ((typeof response.message) == 'string') {
                            alert(response.message);
                        } else {
                            alert(response.message.join("\n"));
                        }

                        return false;
                    }

                    Checkout.setStepResponse(response);
                }
            };


then i removed the onclick from the submit button for payment info
            $(".payment-info-next-step-button").removeAttr("onClick");


then i altered the code that submits the form to this...
                    if (document.location.href.indexOf('onepagecheckout') > -1) {
                        PaymentInfo.init('#co-payment-info-form', 'http://nop1/checkout/OpcSavePaymentInfo/');
                        PaymentInfo.save();
                    }
                    else {
                        form.get(0).submit();
                    }


order went through, and when i switch to regular checkout it still works. Seems really sloppy, if anyone has some suggestions to clean this up I'd love to hear it.


Why can't you just call the same method in your code? Does it work? :D
11 years ago
Tried, it didn't work, apparently in jquery you can't call methods that aren't in the document.ready block, so I had to recreate those inside of it.
11 years ago
tfsmag wrote:
Tried, it didn't work, apparently in jquery you can't call methods that aren't in the document.ready block, so I had to recreate those inside of it.


I don't think this is the case. You definitely can call method outside of document.ready (and not in another document.ready). In fact I've tried:

1. Temporary disable the original onclick event to isolate the case:

<input type="button" class="button-1 payment-info-next-step-button" @*onclick="PaymentInfo.save()"*@ value="@T("Common.Continue")" />


2. Added the following code in Payments.Manual PaymentInfo.cshtml:


<script type="text/javascript">
    $(document).ready(function () {
        $(".payment-info-next-step-button")[0].onclick = null;
        $(".payment-info-next-step-button").click(function () {
            alert("calling...")
            PaymentInfo.save();
        });
    });
</script>


3. Try on one-page checkout. Everything works. The alert is calling, and PaymentInfo.save() is called. (Remember that we've disabled the original onclick in step 1. So if the form is able to continue to next step or throw validation error, it means that the call of PaymentInfo.save() inside our own code-block is successful).

:D
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.