2

Continued from here Applied JS to Drupal theme doesn't work correctly, but it works fine outside Drupal

Working JSFiddle: http://jsfiddle.net/tbq8eo8b/10/ (it calculates total, in Drupal it calculates zeros - why?)

Raw:

$(document).ready(function () {
    var $selects = $("select").change(function (e) {
        var total = 0;
        $selects.each(function() {
            var val = this.value.match(/\$(\d+)/);
            total += val ? +val[1] : 0;
        });
        $(".total").val(total);
    });
});

Drupal:

(function ($) {
Drupal.behaviors.totalAmount = {
attach: function(context, settings) {

/*Add your js code here */
    var $selects = $("select").change(function (e) {
        var total = 0;
        $selects.each(function() {
            var val = this.value.match(/\$(\d+)/);
            total += val ? +val[1] : 0;
        });
        $(".total").val(total);
    });
}
};
})(jQuery);

2nd attempt with internal Drupal:

  <script src="http://code.jquery.com/jquery-1.9.0.js"></script>
  <script>
  $(document).ready(function () {
    var $selects = $("select").change(function (e) {
        var total = 0;
        $selects.each(function() {
            var val = this.value.match(/^\$(\d+)$/);
            total += val ? +val[1] : 0;
        });
        $(".total").val(total);
    });
});
  </script>

As you see the code is identical (except Drupal wrappings), so why it's not working on Drupal? Why it prints zeros in .total field, but in JSFiddle it works fine?

  • Add console.log(this.value); just before or after var val = this.value.match(/^\$(\d+)$/); and tell us what's there. Similarly, console.log($selects.count); before ` $selects.each(function() {`, please :) – Mołot Sep 24 '14 at 10:44
  • It just prints single numbers per line like 1, 2, or '(an empty string)'. And the $selects.count line gives 'undefined'. – Optimus Prime Sep 24 '14 at 12:02
  • Try removing $ sign before selects variable as it is not needed in js and may be confusing there. – Ashish Bairagi Sep 24 '14 at 12:05
  • It still prints zeros. And no errors. So it's same with or without $. – Optimus Prime Sep 24 '14 at 12:08
  • OK, and what's in console.log( val ? +val[1] : 0 );? I have my suspicion now, but I need to know this one thing, to confirm or discard it before I'll post answerer. – Mołot Sep 24 '14 at 12:11
4

I've rebuilt the scenario and my guess now is that you don't want the value of the select field but the option text for your parsing purpose. Thus, the script should probably be something like this:

(function ($) {
Drupal.behaviors.totalAmount = {
attach: function(context, settings) {

    /*Add your js code here */
    var selects = $("select").change(function (e) {
        var total = 0;
        selects.each(function() {
          var val = $("#"+this.id+"  option[value='"+this.value+"']").text().match(/\$(\d+)/);
          total += val ? +val[1] : 0;
        });
        $(".total").val(total);
    });
}
};
})(jQuery);

This is how it looks like working:

enter image description here

This is how the first select's options are setup as a webform component

enter image description here

To retrieve prices, one would need to change the regex line to

var val = $("#"+this.id+" option[value='"+this.value+"']").text().match(/\$(\d+(\.\d{2})?)/);

Working example:

enter image description here

To have the total always be display with trailing zeros, replace the last script line with

$(".total").val(total.toFixed(2));

To make the script also work with thousands separator, change the script into

(function ($) {
Drupal.behaviors.totalAmount = {
attach: function(context, settings) {

/*Add your js code here */
    var selects = $("select").change(function (e) {
        var total = 0;
        selects.each(function() {
                var val = $("#"+this.id+" option[value='"+this.value+"']").text().match(/\$(\d{1,3}(,\d{3})*(\.\d{2})?)/);
                        total += val ? +parseFloat(val[1].replace(/,/g,'')) : 0;
        });
        $(".total").val('$'+total.toFixed(2));
    });
}
};
})(jQuery);

enter image description here

  • Wow thanks for helping. I'm about to test it out. I avoid the values, because the end-user would be creating those forms from time to time with various settings and fields and who knows what values they will use and etc. – Optimus Prime Sep 24 '14 at 16:11
  • Woah, looks like it works great. I still don't get it what you did. Also any ideas when selecting $42.30 it gives in total amount only 42, why it strips 30 cents? – Optimus Prime Sep 24 '14 at 16:25
  • 1
    First, the key line is var val = $("#"+this.id+" option[value='"+this.value+"']").text().match(/\$(\d+)/); where I get the option element (child of select) which has the selected value, retrieve the text content and then do the regex. The regex currently only looks for integers as \d+stands for any number of following digits (no period). You would need to change that to \d+(\.d{2})? for price tags. – Paul Sep 24 '14 at 16:38
  • I still get the same. Does it work for you if you replace it? – Optimus Prime Sep 24 '14 at 16:41
  • See updated answer for the replacement line and a screenshot. I forgot a backslash in my last comment (sorry). – Paul Sep 24 '14 at 16:44

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.