开发者

Why doesn't the change event fire on selector.val(1234)? [duplicate]

开发者 https://www.devze.com 2023-02-19 08:09 出处:网络
This question already has answers here: Closed 10 years ago. Possible Duplicate: jQuery textbox.val('xxxx') not causing change to fire?
This question already has answers here: Closed 10 years ago.

Possible Duplicate:

jQuery textbox.val('xxxx') not causing change to fire?

I have a plug-in that is supposed to fire when the value of a "selector" is updated. During normal UI interaction it works like a champ. However, it doesn't fire if the "selector" is updated via JavaScript or jQuery.

  • Update directly through the text-box...it works.
  • Press the button...it fails.
  • Update using a jQuery call to selected.val(xxx)...it fails.

The general idea for the plug-in is to automatically round totals in things like grids and panels etc.

Any help would be great...I've been wrestling with this all day!

Given the following HTML:

<input id="myDecimalTotal" type="text" value="0.00" class="rounder-decimal" />
<input id="btnDecimalTotalTest" type="button" value="Run Total" />

Test using the following selector(s) and JavaScript:

jQuery(document).ready(function() {
   jQuery('input.rounder-decimal').numericRounder();
   jQuery('#btnDecimalTotalTest').click(overwriteDecimalTotal);    // fails
   jQuery('#myDecimalTotal').val(777);                             // fails
});

function overwriteDecimalTotal() {
   jQuery('#myDecimalTotal').val(123);
}

For the following plug-in:

(function($) {
    $.fn.numericRounder = function(options) {

        switch (typeof (options)) {
            case 'object':
                options = $.extend({}, $.fn.numericRounder.defaults, options);
                break;
            case 'string':
                options = $.extend({}, $.fn.numericRounder.defaults, { onEvent: options });
                break;
            default:
                options = $.fn.numericRounder.defaults;
        }

        return this.each(function() {

            var element = $(this);

            if (element.is('input.rounder-decimal')) {
                switch (options.onEvent) {
                    case 'change':
                        element.change(roundDecimal);
                        break;
                    case 'blur':
                        element.blur(roundDecimal);
                        break;
                    case 'click':
                        element.click(roundDecimal);
                        break;
                 开发者_开发技巧   default:
                        element.blur(roundDecimal);
                }
            }

            if (element.is('input.rounder-wholeNumber')) {
                switch (options.onEvent) {
                    case 'change':
                        element.change(function() { roundWholeNumber(this, options.factorOf); });
                        break;
                    case 'blur':
                        element.blur(function() { roundWholeNumber(this, options.factorOf); });
                        break;
                    case 'click':
                        element.click(function() { roundWholeNumber(this, options.factorOf); });
                        break;
                    default:
                        element.blur(function() { roundWholeNumber(this, options.factorOf); });
                }
            }

            /// <summary>Rounds a numeric value to the nearest place.</summary>
            function roundDecimal() {

                var value = $(this).val();
                value = extractValue(value);

                if (isNaN(value))
                    value = $(this).val();
                else
                    value = Math.round(value).toFixed(2);

                $(this).val(value);
            }
            /// <summary>Rounds a numeric value to the nearest place.</summary>
            function roundWholeNumber(element, factorOf) {

                var value = $(element).val();
                value = extractValue(value);

                if (isNaN(value))
                    value = $(element).val();
                else
                    value = Math.round(value / factorOf) * factorOf;

                $(element).val(value);
            }
            /// <summary>Extracts the number.</summary>
            function extractValue(value) {
                var numericRegEx = /([\d\.])/g;

                try {
                    return value.match(numericRegEx).join('');
                }
                catch (error) {
                    return value;
                }
            }
        });
    };

    /// <summary>Default options.</summary>
    $.fn.numericRounder.defaults = { onEvent: 'change', factorOf: 10 };
})(jQuery);


As far as I know, that's just the way it is. The change event is not fired when the value is changed from JavaScript. Getting it to fire is easy (with jQuery):

jQuery('#myDecimalTotal').val(123).change();

This will fire all change event handlers on that element.


jQuery doesn't trigger events when a textbox is updated using .val()

Try to manually trigger the event after changing the value:

jQuery('#myDecimalTotal').val(777).trigger('change');


It's browser limitation in event processing, but you can declare your own event and set the listener for your event. All you have to do is to fire your event when it's exatcly needed.

//callback function
function overwriteDecimalTotal() {
   jQuery('#myDecimalTotal').val(123);
}

//add event listener
jQuery('#myDecimalTotal').bind('changeValue', function () { 
 overwriteDecimalTotal();
})

//trigger your event when needed
jQuery('#myDecimalTotal').val(777).trigger('changeValue');


Here's a fiddle showing how you can use triggering change to get your numbers to update properly

http://jsfiddle.net/dLfmV/3/

Fixed the link

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号