Take the 2-minute tour ×
Drupal Answers is a question and answer site for Drupal developers and administrators. It's 100% free, no registration required.

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?

share|improve this question
    
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 14 hours ago
    
It just prints single numbers per line like 1, 2, or '(an empty string)'. And the $selects.count line gives 'undefined'. –  Optimus Prime 12 hours ago
    
Try removing $ sign before selects variable as it is not needed in js and may be confusing there. –  Ashish Bairagi 12 hours ago
    
It still prints zeros. And no errors. So it's same with or without $. –  Optimus Prime 12 hours ago
    
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 12 hours ago

1 Answer 1

up vote 4 down vote accepted

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

share|improve this answer
    
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 8 hours ago
    
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 8 hours ago
    
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 8 hours ago
    
I still get the same. Does it work for you if you replace it? –  Optimus Prime 8 hours ago
    
See updated answer for the replacement line and a screenshot. I forgot a backslash in my last comment (sorry). –  Paul 8 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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