2014-10-22 1 views
1

Я пытаюсь выполнить следующие функции. Покажите количество символов, оставшихся в текстовом поле, и запретите вводить что-либо еще, если вы уже превысили максимальное число.Не допускайте ввода текста в текстовом поле, если у него слишком много символов.

Я смущен тем, как достичь этого. Теперь у меня есть something like this:

<textarea data-bind="textInput: message"></textarea> 
<p>Characters left : <span data-bind="text: charLeft"></span></p> 

function Vm_app() { 
    var self = this; 
    this.message = ko.observable(''); 
    this.charLeft = ko.pureComputed(function(){ 
     return 128 - self.message().length; 
    }); 
} 
ko.applyBindings(new Vm_app()); 

Любой идея, как я должен поступить?

P.S. Я знаю, как достичь задачи с прослушиванием событий, но я не хочу нарушать парадигму MVVM.

P.S.2 связанный ответ не позволяет продолжить добавление текста после его отключения. Я хочу только запретить писать новые символы (человек сможет щелкнуть delete, backspace).

+0

Приведен пример одного из них. http://jsfiddle.net/3uhNP/1/ – KRUKUSA

+1

@ KRUKUSA спасибо. Я знаю, как добиться этого, слушая события, но это нарушает парадигму MVVM. –

+1

Вам лучше не пытаться ограничить количество символов, но вместо этого применять длину при отправке. –

ответ

5

Как я уже говорил ранее, вам лучше не пытаться ограничить ввод текста за определенную длину. Есть много вещей, которые следует учитывать, когда вы хотите перехватить такие вещи, многие угловые случаи, которые вам придется работать, чтобы они работали естественным образом. И что еще более важно, для пользователя было бы намного лучше иметь возможность напечатать все, что они хотят напечатать без каких-либо ограничений, по крайней мере, пока они не попытаются отправить. Тогда вы можете обеспечить, чтобы она была определенной длины.

С учетом этого : некоторые вещи, которые вы можете сделать, чтобы сделать эту работу достаточно близко. Есть много подходов, которые вы можете предпринять для обеспечения этого. Вероятно, самым простым подходом было бы создание делегирующего наблюдаемого, которое может перехватывать записи на ваш наблюдаемый. Затем вы можете проверить длину, если это необходимо, и установить значение или проигнорировать его. Вы можете сохранить это все в автономном режиме в расширителе.

ko.extenders.maxlength = function (target, maxlength) { 
    var view = ko.dependentObservable({ 
     read: target, 
     write: function (value) { 
      if (value.length <= maxlength) { 
       target(value); 
      } else { 
       view.notifySubscribers(target()); // "refresh" the view 
      } 
     } 
    }); 
    target.view = view; 
    target.maxlength = maxlength; 
    return target; 
}; 

Затем, чтобы использовать его:

this.message = ko.observable('').extend({ maxlength: 128 }); 

Затем просто связываются с точки зрения:

<textarea data-bind="textInput: message.view"></textarea> 

Просто обратите внимание, что, когда «освежающий», курсор всегда будет перемещен в конец , Просто характер установки значений. Если вы хотите сохранить позицию курсора, вам также придется сбросить его.

fiddle

+0

Это прекрасно работает, но вы должны иметь knockoujs 3.0.0 и выше! :) –

1

я решил его с многоразовой ViewModel

define(["knockout"], function(ko) { 
    var ctor = function(limit, limitWarning) { 
     this.text = ko.observable(""); 
     this.isEditing = ko.observable(); 

     this.limitedText = ko.computed({ 
      write: this.setText, 
      read: this.text 
     }, this); 

     this.limit = limit; 
     this.limitWarning = limitWarning; 
     this.charactersLeft = ko.computed(this.getCharactersLeft, this); 
     this.charactersLeftWarning = ko.computed(this.getCharactersLeftWarning, this); 
     this.limitReached = ko.computed(this.getLimitReached, this); 
    }; 


    ctor.prototype = { 
     setText: function(text) { 
      if (text.length > this.limit) { 
       text = text.substring(0, this.limit); 
      } 

      this.text(text); 
     }, 
     getCharactersLeft: function() { 
      return this.limit - this.text().length; 
     }, 
     getCharactersLeftWarning: function() { 
      return this.getCharactersLeft() <= (this.limit * this.limitWarning); 
     }, 
     getLimitReached: function() { 
      return this.text().length >= this.limit; 
     }, 
     writing: function(model, e) { 
      return e.keyCode < 65 || !this.getLimitReached(); 
     } 
    }; 

    return ctor; 
}); 

Посмотреть

<textarea data-bind="text: limitedText,valueUpdate: 'afterkeydown', event: { keydown: writing }" class="form-control" rows="5"></textarea> 
<div data-bind="css: { 'limit-warning': charactersLeftWarning, 'limit-reached': limitReached }"> 
    Characters left <span data-bind="text: charactersLeft"></span> 
</div> 

enter image description here

enter image description here

enter image description here

Смежные вопросы