<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">Не похоже на эл. почту.</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">−</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>