Экспромптум

<style>
	.field {position: relative;}
	.invalid_message {display: none;}
	.blured.invalid .invalid_message {display: block; position: absolute; left: 10px; bottom: -2em;}
</style>

<form method="post">
	<span class="field">
		<input name="email" placeholder="Эл. почта" data-xp="type: 'email', required: true"/>

		<span class="invalid_message">Не&nbsp;похоже на&nbsp;эл.&nbsp;почту.</span>
	</span>

	<span class="field">
		<input name="password" placeholder="Пароль" type="password" data-xp="required: true"/>
	</span>

	<input type="submit" value="Войти" data-xp="enabled_on_completed: true"/>
</form>
Не похоже на эл. почту.
<style>
	.uncompleted_fields .pseudo_link {margin-right: 0.5em; cursor: pointer}
</style>

<form method="post" id="feedback">
	<div class="field">
		<label for="field_name">Имя</label><br />
		<input name="name" id="field_name" data-xp="required: true"/>
	</div>

	<div class="field">
		<label for="field_email">Эл. почта</label><br />
		<input name="email" id="field_email" data-xp="type: 'email', required: true"/>
	</div>

	<div class="field">
		<label for="field_message">Сообщение</label><br />
		<textarea name="message" id="field_message" data-xp="required: true"></textarea>
	</div>

	<div class="field">
		<input type="submit" value="Отправить" data-xp="enabled_on_completed: true"/>

		<span class="uncompleted_fields">
			Незаполнены:
			<span class="fields" data-xp="uncompleted_type: 'required'"></span>
		</span>

		<span class="uncompleted_fields">
			Неправильно заполнены:
			<span class="fields" data-xp="uncompleted_type: 'invalid'"></span>
		</span>
	</div>
</form>

<script>
	xP();

	function xp_init_uncompleted_fields(){
		xP('.uncompleted_fields .fields').each(function(){
			var fields = this,
				$parent = fields.$container.parent(),
				list = new xP.list(),
				label_id = '$' + fields.uncompleted_type + '_label';

			fields.root().change(function(){
				var show = false;

				list.each(function(){
					this._[label_id].hide();
				});

				this._param(fields.uncompleted_type)
					.each(function(){
						if(!this.$label){
							return;
						}

						if(list.index(this) < 0){
							var field = this;

							list.append(this);

							this._[label_id] = $(
									' <span class="pseudo_link underline">'
									+ this.$label.text() + '</span>'
								).appendTo(fields.$element).click(function(){
									field.focus();
								});
						}

						this._[label_id].show();

						show = true;
					});

				if(show){
					$parent.show();
				}else{
					$parent.hide();
				}
			});
		});
	};

	xp_init_uncompleted_fields();
</script>



Незаполнены: Неправильно заполнены:
<style>
	.horizontal .field,
	.horizontal .field_label,
	.horizontal .field_control {
		display: inline-block;
		width: auto;
	}

	.card {
		position: relative;
	}
	.card_compact_view {
		position: absolute;
		top: 0;
		right: 0;
	}

	.compact_view .horizontal {
		display: inline-block;
	}
	.compact_view .repeated button,
	.compact_view .field_label,
	.compact_view .hide_in_compact_view,
	.compact_view .hide_nonfirst_in_compact_view {
		display: none;
	}
	.compact_view .hide_nonfirst_in_compact_view.repeated_0 {
		display: inline-block;
	}

	.hide_on_unselected,
	.option.selected .hide_on_selected {
		display: none;
	}
	.option.selected .hide_on_unselected {
		display: inline;
	}
</style>

<form id="address_book">
	<span class="option">
		<input name="all_compact_view" id="all_compact_view" value="true" type="checkbox"/>
		<label for="all_compact_view">
			<span class="hide_on_unselected">Развернуть</span>
			<span class="hide_on_selected">Свернуть</span>
			все
		</label>
	</span>

	<div class="fields card" data-xp="
		name: 'person',
		repeat: true,
		classed: {on: '[id=compact_view] && [id=first_name]', do: 'compact_view'},
		required: true
	">
		<div class="horizontal">
			<dl class="field">
				<dt class="field_label"><label>Фамилия</label></dt>
				<dd class="field_control">
					<input name="last_name"/>
				</dd>
			</dl>

			<dl class="field">
				<dt class="field_label"><label>Имя</label></dt>
				<dd class="field_control">
					<input name="first_name" id="first_name"/>
				</dd>
			</dl>

			<dl class="field hide_in_compact_view">
				<dt class="field_label"><label>Отчество</label></dt>
				<dd class="field_control">
					<input name="middle_name"/>
				</dd>
			</dl>
		</div>

		<dl class="field hide_in_compact_view">
			<dt class="field_label"><label>Пол</label></dt>
			<dd class="field_control">
				<span class="option">
					<input name="gender" id="gender_male" value="male" type="radio"/>
					<label for="gender_male">мужской</label>
				</span>
				<span class="option">
					<input name="gender" id="gender_female" value="female" type="radio"/>
					<label for="gender_female">женский</label>
				</span>
			</dd>
		</dl>

		<dl class="field date hide_in_compact_view">
			<dt class="field_label"><label>Дата рождения</label></dt>
			<dd class="field_control">
				<input name="birthday"/>
			</dd>
		</dl>

		<span class="hide_in_compact_view">Контакты</span>
		<div class="fields horizontal hide_nonfirst_in_compact_view" data-xp="
			name: 'contact',
			repeat: true
		">
			<dl class="field">
				<dd class="field_control">
					<input name="value" data-xp="
						valid:
							'([id=type].val().match(/телефон/i)'
							+ ' && [this].val().match('
							+ xP.controls.phone.prototype.valid
							+ ')) || ([id=type].val().match(/эл\\. почта/i)'
							+ ' && [this].val().match('
							+ xP.controls.email.prototype.valid + '))'
					"/>
				</dd>
			</dl>

			<dl class="field combobox hide_in_compact_view">
				<dt class="field_label"><label>Тип</label></dt>
				<dd class="field_control">
					<input name="type" list="type_list" id="type" data-xp="search_from_start: false"/>
					<select name="type_list" id="type_list">
						<option>Мобильный телефон</option>
						<option>Рабочий телефон</option>
						<option>Домашний телефон</option>
						<option>Персональная эл. почта</option>
						<option>Рабочая эл. почта</option>
					</select>
				</dd>
			</dl>

			<button class="repeat_append_button">+</button>
			<button class="repeat_remove_button">&minus;</button>
		</div>

		<span class="option card_compact_view">
			<input name="compact_view" id="compact_view" value="true" type="checkbox" data-xp="
				enabled: '[id=first_name]',
				computed: '!!([id=all_compact_view]) + \'\''
			"/>
			<label for="compact_view">
				<span class="hide_on_unselected">Развернуть</span>
				<span class="hide_on_selected">Свернуть</span>
			</label>
		</span>

		<div>
			<button class="repeat_append_button">Добавить</button>
			<button class="repeat_remove_button">Удалить</button>
		</div>
	</div>
</form>

<script>
	(function(){
		xP();

		var address_book = xP('#address_book').first();

		if(window.JSON && window.localStorage){
			address_book.val(
				localStorage.address_book
					? JSON.parse(localStorage.address_book)
					: {}
			);

			address_book.change(function(){
				localStorage.address_book = JSON.stringify(this.val());
			});
		}
	})();
</script>
Контакты
<div class="fields" id="calculator">
	<span class="field number">
		<label>Сумма</label>
		<input name="amount" value="100000" data-xp="min: 100000, max: 10000000, step: 100000"/>
		рублей
	</span>
	<span class="field number">
		<label>Ставка</label>
		<input name="rate" value="14" data-xp="min: 0, max: 100, step: 0.5"/>
		%
	</span>
	<span class="field number">
		<label>Срок</label>
		<input name="period" value="12" data-xp="
			min: 1,
			max: 360,
			computed: {
				on: '[name=amount] > 5000000 ? 240 : ([name=amount] > 1000000 ? 120 : 1)',
				do: 'min'
			}
		"/>
		месяцев
	</span>
</div>

<table cellspacing="10">
	<thead>
		<tr>
			<th>Месяц</th>
			<th>Остаток основного долга</th>
			<th>Погашение основного долга</th>
			<th>Погашение процентов</th>
			<th>Платеж</th>
		</tr>
	</thead>
	<tbody id="payments" align="right">
	</tbody>
</table>

<script>
	xP();

	var controls = {
			calculator: xP('#calculator').first(),
			amount:     xP('#calculator [name=amount]').first(),
			rate:       xP('#calculator [name=rate]').first(),
			period:     xP('#calculator [name=period]').first()
		},
		payments_element = $('#payments');

	controls.calculator.change(function(){
		var a = controls.amount,
			amount = a.val(),
			rate = controls.rate.val(),
			period = controls.period.val(),
			payment = (
				amount * (
					Math.pow((1 + rate / 1200), period)
					* rate / 1200 / (Math.pow((1 + rate / 1200), period) - 1)
				)
			).toFixed(2) * 1,
			rate_repayment,
			rate_repayment_sum = 0,
			payment_sum = 0,
			debt_repayment,
			html = '';

		for(var i = 1; i <= period; i++){
			rate_repayment = (amount * rate / 1200).toFixed(2) * 1;
			debt_repayment = (payment - rate_repayment).toFixed(2) * 1;
			amount = (amount - debt_repayment).toFixed(2) * 1;

			if(amount < 0 || (i == period && amount != 0)){
				debt_repayment = (debt_repayment + amount).toFixed(2) * 1;
				payment = (payment + amount).toFixed(2) * 1;
				amount = 0;
			}

			rate_repayment_sum += rate_repayment;
			payment_sum += payment;

			html += '<tr><td>' + i + '</td><td>'
					+ a._format(amount.toFixed(2))
					+ '</td><td>'
					+ a._format(debt_repayment.toFixed(2))
					+ '</td><td>'
					+ a._format(rate_repayment.toFixed(2))
					+ '</td><td>'
					+ a._format(payment.toFixed(2))
					+ '</td></tr>';
		}

		html += '<tr><td colspan="3"></td><td><b>'
				+ a._format(rate_repayment_sum.toFixed(2))
				+ '</b></td><td><b>'
				+ a._format(payment_sum.toFixed(2))
				+ '</b></td></tr>';

		payments_element.html(html);
	});
</script>
рублей % месяцев
Месяц Остаток основного долга Погашение основного долга Погашение процентов Платеж


Заказать дизайн...