문제

I have the following form:

  • Publish Start - 2x inputs, one for time, one for date;
  • Publish End - 2x inputs, one for time, one for date;
  • Post Content - 1x textarea.

The inputs for date/time use jQuery InputMask and textarea use CKEditor (with jQuery Adapter, to expose ckeditor to $() and val()).

With the adapter, I can:

  • use $('#idOfTextarea').val() instead of CKEDITOR.instances['idOfTextarea'].getData();
  • use $('#idOfTextarea').val('some value') instead of CKEDITOR.instances['idOfTextarea'].setData('some value');

The problem:

  • IE (v9) and Webkits (Chrome v30 & v31, Safari v5.1): val() stops working the moment I bind the inputs with inputmask;
  • Firefox (v22) and Opera (v12.16): keep working val()

Demo:

Here is the example Fiddle: http://jsfiddle.net/RaphaelDDL/QjVf8/

  1. Write something on CKEditor and test it with both print ckeditor .val() on console and print ckeditor .getData() on console links.

  2. Click on bind inputmask on above inputs and then click on the print tests again. The val() will stop working, while the getData (native ck implementation) will keep working.

I couldn't find if the problem is with the adapter or inputmask :(


Update:

I discovered that both ck adapter and inputmask makes an $.extend on $.fn.val. Seems $.fn.val is getting overwritten on the browsers that adapter stop working, instead of actually extended (imo, had to hold both extends, no?)

$.fn.val before inputmask (chrome):

function(d) {
    if (arguments.length) {
        var k = this,
            i = [],
            f = this.each(function() {
                var b = a(this),
                    c = b.data("ckeditorInstance");
                if (b.is("textarea") && c) {
                    var f = new a.Deferred;
                    c.setData(d, function() {
                        f.resolve()
                    });
                    i.push(f.promise());
                    return !0
                }
                return g.call(b, d)
            });
        if (i.length) {
            var b = new a.Deferred;
            a.when.apply(this, i).done(function() {
                b.resolveWith(k)
            });
            return b.promise()
        }
        return f
    }
    var f = a(this).eq(0),
        c = f.data("ckeditorInstance");
    return f.is("textarea") && c ? c.getData() : g.call(f)
}

$.fn.val after inputmask (chrome):

function() {
    var t, i, r;
    return arguments.length == 0 ? (t = n(this), t.data("inputmask") ? t.data("inputmask").autoUnmask ? t.inputmask("unmaskedvalue") : (i = n.inputmask.val.apply(t), i != t.data("inputmask")._buffer.join("") ? i : "") : n.inputmask.val.apply(t)) : (r = arguments, this.each(function() {
        var t = n(this),
            i = n.inputmask.val.apply(t, r);
        return t.data("inputmask") && t.triggerHandler("setvalue.inputmask"), i
    }))
}

While on Firefox, $.fn.val is always the same (does not change when I call inputmask).

Is there a way I can merge inputmask's extend with ckeditor one?

도움이 되었습니까?

해결책

For those that encounter this error someday, I've talked with RobinHerbots (creator of jquery-inputmask ) and seems that the problem is:

The n.inputmask.val.apply(t, r); does the call to the original fn.val code. So inputmask make the ref when it was inserted onto html (instead of when it's called via $(selector).inputmask()). It caches the $.fn.val onto $.inputmask.val but just actually extend it it when called using .inputmask(). Then ckeditor modifies later the val (was called later) but since inputmask has cached the original val from before ckeditor extend, it overwrites the ckeditor one.


Using this idea as base, I tested moving the ckeditor scripts to before the inputmask script. I made a rev on the fiddle changing the script for last http://jsfiddle.net/RaphaelDDL/QjVf8/8/ (see external resources).

Seems it worked on the browsers who were showing an overwritten $.fn.val now :dancer:

For more info, check https://github.com/RobinHerbots/jquery.inputmask/issues/319

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top