Shipping calculator consisting of one field A made a shipping calculator, which consists of one field that is validated.

jsFiddle

HTML:

    &lt;div class="container main-container" id="mainContainer"&gt;
      &lt;h1&gt;Калькулятор доставки&lt;/h1&gt;
      &lt;div class="content-container" id="contentContainer"&gt;&lt;/div&gt;
    &lt;/div&gt;

&lt;script type="text/template" id="calculatorSubmitButtonTemplate"&gt;
  &lt;div class="btn btn-default" id="calculatorSubmitButton"&gt;Рассчитать&lt;/div&gt;
&lt;/script&gt;


&lt;script type="text/template" id="cityOfDepartureTemplate"&gt;
  &lt;div class="panel panel-default"&gt;
    &lt;div class="panel-body"&gt;
      &lt;h2&gt;Город отправления&lt;/h2&gt;
      &lt;div class="input-group"&gt;
        &lt;input type="text" class="form-control" id="fldCityOfDeparture"&gt;
        &lt;div id="errorMessageCityOfDeparture" class="help-block"&gt;&lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/script&gt; 


CSS:

.not_valid{
    border: 1px solid red;
}

.valid{
    border: 1px solid #ccc;
}


JS:

window.APP = window.APP || {};

APP.CityOfDepartureModel = Backbone.Model.extend({
  defaults: {
    cityName: undefined
  }, 

  validate: function(attrs) {   
    var errorsArr = [];

    if($.trim(attrs.cityName).length == 0) { 
        errorsArr.push('Это поле не может быть пустым') 
    } else {
        if(isNaN(attrs.cityName) == false) { errorsArr.push('Это поле не может быть цифрой') };    
    };  

    if(errorsArr.length != 0) { return errorsArr };
  }  
});



APP.CalculatorView = Backbone.View.extend({  

  initialize: function() {  
    this.cityOfDepartureModel = new APP.CityOfDepartureModel();
    this.cityOfDepartureWidjet = new APP.CityOfDepartureView({model: this.cityOfDepartureModel});
    this.render();
  },    

  el: $('#contentContainer'),

  template: _.template($('#calculatorSubmitButtonTemplate').html()),

  render: function () {  
    this.$el.append(this.cityOfDepartureWidjet.render().el);
    this.$el.append(this.template());
    return this;
  },

  events:{
    'click #calculatorSubmitButton' : 'submit'
  },

  submit: function() {
    var cityName = $('#fldCityOfDeparture').val();

    this.cityOfDepartureModel.set({'cityName': cityName});

    if(this.cityOfDepartureModel.isValid()) {        
      this.cityOfDepartureWidjet.validMarkAdd();
    } else {      
      var errorMessagesArr = this.cityOfDepartureModel.validationError;
      this.cityOfDepartureWidjet.notValidMarkAdd(errorMessagesArr);
      this.cityOfDepartureModel.set({'cityName': undefined});
    };

    console.log('-----------------------');
    console.log('city dep: ', this.cityOfDepartureModel.get('cityName'));
  }

});



APP.CityOfDepartureView = Backbone.View.extend({  

  initialize: function() {  

  },    

  tagName: 'div',

  className: 'city_of_departure_container',

  id: 'cityOfDepartureContainer',

  template: _.template($('#cityOfDepartureTemplate').html()),

  render: function () {  
    this.$el.html(this.template());
    return this;
  },

  notValidMarkAdd: function(errorMessagesArr) {
    this.$el.find('#fldCityOfDeparture').removeClass('valid').addClass('not_valid');

    this.$el.find('#errorMessageCityOfDeparture').html('');
    for(key in errorMessagesArr) {
      this.$el.find('#errorMessageCityOfDeparture').append(errorMessagesArr[key] + '&lt;br&gt;');
    };    
  },

  validMarkAdd: function() {
    this.$el.find('#fldCityOfDeparture').removeClass('not_valid').addClass('valid');
    this.$el.find('#errorMessageCityOfDeparture').html('');
  }  

});




var app = new APP.CalculatorView();
Getting rid of backbone, you can simplify this a lot.

HTML

&lt;div class="container main-container" id="mainContainer"&gt;
  &lt;h1&gt;Калькулятор доставки&lt;/h1&gt;
  &lt;div class="content-container" id="contentContainer"&gt;
    &lt;div class="panel panel-default"&gt;
      &lt;div class="panel-body"&gt;
        &lt;h2&gt;Город отправления&lt;/h2&gt;
        &lt;div class="input-group"&gt;
          &lt;input type="text" class="form-control" id="fldCityOfDeparture"&gt;
          &lt;div id="errorMessageCityOfDeparture" class="help-block not_valid"&gt;&lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="btn btn-default" id="calculatorSubmitButton"&gt;Рассчитать&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


JS

function validate(city) {
    return city.length == 0     ? 'Это поле не может быть пустым' :
           isNaN(city) == false ? 'Это поле не может быть цифрой' : '';
}
function showError(error) {
  document.getElementById('errorMessageCityOfDeparture').innerHTML = error;
}
document.getElementById('calculatorSubmitButton').onclick = () =&gt; {
  var city = document.getElementById('fldCityOfDeparture').value,
      error = validate(city);
  showError(error);
};


Here's a new fiddle, which shows the error messages on the page, rather than in the console.

https://jsfiddle.net/5uygd9s1/

NOTE: Currently I'm only using the not_valid class, since the border will not display when the error is empty.  If you want, you can change the class too depending on if there is an error or not.  The important point is finding a simple solution, especially when the problem is simple.  With all the available js frameworks today, it's easy to over-engineer.