后端转发器字段上的十月 CMS javascript 事件

October CMS javascript event on backend repeater fields

在一个项目中使用 October CMS,我尝试在后端转发器字段上添加一个 javascript 事件。但是似乎转发器动态添加的输入字段在 javascript 与其他相同形式的输入字段一起工作时看不到

我的脚本如下:

<script>
  $('input').on('keypress', function(e){
      // only numbers
      if ( charCode < 48 || charCode > 57 ) {
          return false;
      }
      return true;
  });
</script>

你有什么想法让它发挥作用吗?

在此先感谢您的问候, 帕特里克

您说:-
似乎转发器动态添加的输入字段在 javascript 中看不到,而它与其他相同形式的输入字段一起工作

这是正确的行为,因为事件绑定已在页面加载时完成,并且您随后创建了新元素,因此事件不会绑定到这些元素上。

您必须使用称为事件委托的技术。喜欢:

  $(document).on('keypress', 'input', function(e){
      // the code 
  });

在此代码中,您可以将 $(document) 更改为最接近的静态父级,如任何 div, form etc.

$('form').on('keypress', 'input', function(){
   // code here
});

所以,语法是:

$(staticParent).on(event, selector, callback);  

其中 staticParent 是加载页面时作为父元素的元素。它不应该是动态创建的父级。

October 在通过 $.request 或其他方法添加新元素后在页面上触发事件 "render"。

所以,你可能会听:

$(window).on('render', function() {
    $('input').on('keypress', function(e){
    }
});

唯一的问题是,事情会得到"double"次按键。

为此,october 建议使用基础框架模式。这样事件侦听器将只绑定一次,如果页面上已经存在元素则不会绑定两次。

https://octobercms.com/docs/ui/foundation

+function ($) { "use strict";
    var Base = $.oc.foundation.base,
        BaseProto = Base.prototype

    var SomeDisposableControl = function (element, options) {
        this.$el = $(element)
        this.options = options || {}

        $.oc.foundation.controlUtils.markDisposable(element)
        Base.call(this)
        this.init()
    }

    SomeDisposableControl.prototype = Object.create(BaseProto)
    SomeDisposableControl.prototype.constructor = SomeDisposableControl

    SomeDisposableControl.prototype.init = function() {
        this.$el.on('click', this.proxy(this.onClick))
        this.$el.one('dispose-control', this.proxy(this.dispose))
    }

    SomeDisposableControl.prototype.dispose = function() {
        this.$el.off('click', this.proxy(this.onClick))
        this.$el.off('dispose-control', this.proxy(this.dispose))
        this.$el.removeData('oc.someDisposableControl')

        this.$el = null

        // In some cases options could contain callbacks, 
        // so it's better to clean them up too.
        this.options = null

        BaseProto.dispose.call(this)
    }

    SomeDisposableControl.DEFAULTS = {
        someParam: null
    }

    // PLUGIN DEFINITION
    // ============================

    var old = $.fn.someDisposableControl

    $.fn.someDisposableControl = function (option) {
        var args = Array.prototype.slice.call(arguments, 1), items, result

        items = this.each(function () {
            var $this   = $(this)
            var data    = $this.data('oc.someDisposableControl')
            var options = $.extend({}, SomeDisposableControl.DEFAULTS, $this.data(), typeof option == 'object' && option)
            if (!data) $this.data('oc.someDisposableControl', (data = new SomeDisposableControl(this, options)))
            if (typeof option == 'string') result = data[option].apply(data, args)
            if (typeof result != 'undefined') return false
        })

        return result ? result : items
    }

    $.fn.someDisposableControl.Constructor = SomeDisposableControl

    $.fn.someDisposableControl.noConflict = function () {
        $.fn.someDisposableControl = old
        return this
    }

    // Add this only if required
    $(document).render(function (){
        $('[data-some-disposable-control]').someDisposableControl()
    })

}(window.jQuery);

我建议阅读上面的内容 link 因为它解释了很多陷阱等。以及为什么清理很重要。

就个人而言,我扩展了 october 基础,使 'cleanup' 和管理变量更容易。

https://github.com/tschallacka/october-foundation/blob/master/src/october-foundation-base.js

基本上它所做的是确保函数自动解除绑定,当通过 jquery 命令从 dom 中删除元素时清除变量,并在 jquery 时自动绑定到标记元素=44=] 事件被触发。

我的脚本会变成:

// ..... foundation code

    Application.prototype.handlers = function(type) {
        this.bind('keypress',this.$el, this.keypressHandler);
    };

    Application.prototype.init = function() {
        /**
         * example;
         */
        this.alloc('foobar',42);
        console.log(this.foobar);
    }

    Application.prototype.keypressHandler = function(e) {
        if(!e.defaultPrevented) {
            // only numbers
            if ( charCode < 48 || charCode > 57 ) {
                e.preventDefault();
                return false;
            }
            return true;
        }
    }

//  foundation code ....