JSFiddle - React, Tailwind, and code Playground

by shtrih

HTML

<div ng-app ng-controller="servicesCtrl">
							<div class="calc">
								<select ng-model="current_service" ng-options="service.name for service in services"></select>

								<div ng-show="current_service.options.measurer">
									<label><input type="checkbox" ng-model="mmeasurer" /> Выезд замерщика, город </label> <!--select ng-model="current_city" ng-options="t for t in current_service.fields.measurer.options"></select-->
									<select ng-model="mfields.measurer" ng-init="mfields.measurer = 0" ng-disabled="!mmeasurer">
										<option value="0">Выберите</option>
										<option value="1">Иркутск</option>
										<option value="2">Ангарск</option>
										<option value="3">За город</option>
									</select>
								</div>
								<div ng-show="current_service.options.delivery">
									<label><input type="checkbox"  ng-model="mfields.delivery"/> Монтаж, доставка, подъем на этаж</label>
								</div>
								<div ng-show="current_service.options.hole">
									<label>Отверстия (шт) <input type="number" min="0"  ng-model="mfields.hole"/></label>
								</div>
								<div ng-show="current_service.options.fastener">
									<label>Крепежи (шт) <input type="number" min="0"  ng-model="mfields.fastener"/></label>
								</div>
								<div ng-show="current_service.options.socket">
									<label>Розетки (шт) <input type="number" min="0"  ng-model="mfields.socket"/></label>
								</div>

								<div ng-repeat="option in ['profile_end', 'profile_connecting', 'profile_corner', 'lacquer_mat', 'lacquer_glossy']"
								     ng-show="current_service.options[option]">
									<label><input type="checkbox"  ng-model="mfields[option]"/>{{current_service.options[option].title}}</label>
								</div>

								<p>Количество элементов: {{dimensions.length}}</p>
								<ul>
									<li ng-repeat="dimension in dimensions">
										<input type="number" min="0.0" placeholder="Ширина (м)" ng-model="dimension.width"/>&times;
										<input...

CSS

</style> <!-- Ugly Hack due to jsFiddle issue: http://goo.gl/BUfGZ --> 
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.min.js"></script>
<style>
.calc,
.result {
    width: 49.999%;
}
.calc {
    float: left;
}
.result {
    float: right;
}

JavaScript

function servicesCtrl($scope) {
	'use strict';

	$scope.options_formulas = {
		measurer: {
			toString: function (value) {
				return '';
			},
			exec: function (value) {
				if ('undefined' === value)
					return this.price[0];

				return this.price[value];
			}
		},
		delivery: {
			toString: function () {
				return '';
			},
			exec: function () {
				return this.price;
			}
		}
	};

	// свойство, цена по дефолту зависит от площади
	var property = function (title, price, methods) {
			this.title = title;
			this.price = price;

			if (!methods) {
				methods = $scope.properties_formulas.workWithSquare;
			}

			for (var name in methods) {
				if (methods.hasOwnProperty(name)) {
					this[name] = methods[name];
				}
			}
		}
	;

	$scope.properties_formulas = {
		workWithPerimeter: {
			toString: function () {
				return this.price + '×' + $scope.perimeterAll() + ' = ';
			},
			exec: function () {
				return this.price * $scope.perimeterAll();
			}
		},
		workWithSquare: {
			toString: function () {
				return this.price + '×' + $scope.squareAll() + ' = ';
			},
			exec: function () {
				return this.price * $scope.squareAll();
			}
		},
		workFixedPrice: {
			toString: function () {
				return this.price;
			},
			exec: function () {
				return this.price;
			}
		},
		workWithCount: {
			toString: function (count) {
				return this.price + '×' + count + ' = ';
			},
			exec: function (count) {
				return this.price * count;
			}
		}
	};

	$scope.services = [
		{
			name: 'Стекло 6 мм с печатью + травмобезопасная пленка',
			properties: [
				new property('Печать + стекло + Травм. пленка', 5380/*, $scope.properties_formulas.workWithSquare*/),
				new property('Обработка кромки', 230, $scope.properties_formulas.workWithPerimeter),
				new property('Упаковка', 100, $scope.properties_formulas.workWithCount)
			],
			options: {
				measurer: new property('Выезд замерщика',...