Cleaned up date manipulation code. Updated data mapping to use ko.toJS.
This commit is contained in:
parent
eac942bfc2
commit
af30952228
@ -36,16 +36,16 @@ class EntryAPI extends RestAPI {
|
||||
$connection=$this->get_db_connection();
|
||||
|
||||
if($entry['id'] != null) {
|
||||
$statement=$connection->prepare("update entry set value_date=:value_date, operation_date=:operation_date, label=:label, value=:value, account_id=:account, category=:category where id=:id");
|
||||
$statement=$connection->prepare("update entry set value_date=:value_date, operation_date=:operation_date, label=:label, value=:value, account_id=:account_id, category=:category where id=:id");
|
||||
} else {
|
||||
$statement=$connection->prepare("insert into entry (value_date, operation_date, label, value, account_id, category) values (:value_date, :operation_date, :label, :value, :account, :category)");
|
||||
$statement=$connection->prepare("insert into entry (value_date, operation_date, label, value, account_id, category) values (:value_date, :operation_date, :label, :value, :account_id, :category)");
|
||||
}
|
||||
|
||||
$statement->bindParam("value_date", $entry['value_date']);
|
||||
$statement->bindParam("operation_date", $entry['operation_date'] == '' ? null : $entry['operation_date']);
|
||||
$statement->bindParam("label", $entry['label']);
|
||||
$statement->bindParam("value", $entry['value']);
|
||||
$statement->bindParam("account", $entry['account']);
|
||||
$statement->bindParam("account_id", $entry['account_id']);
|
||||
$statement->bindParam("id", $entry['id']);
|
||||
$statement->bindParam("category", $entry['category']);
|
||||
|
||||
|
@ -1,7 +1,158 @@
|
||||
/*
|
||||
Datepicker for Bootstrap
|
||||
Copyright 2012 Stefan Petre
|
||||
Licensed under the Apache License v2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
/*!
|
||||
* Datepicker for Bootstrap
|
||||
*
|
||||
* Original Idea: http://www.eyecon.ro/bootstrap-datepicker (Copyright 2012 Stefan Petre)
|
||||
* Updated by AymKdn (http://kodono.info - https://github.com/Aymkdn/Datepicker-for-Bootstrap)
|
||||
* Licensed under the Apache License v2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*/
|
||||
.datepicker { top: 0; left: 0; padding: 4px; margin-top: 1px; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; /*.dow { border-top: 1px solid #ddd !important; }*/ } .datepicker:before { content: ''; display: inline-block; border-left: 7px solid transparent; border-right: 7px solid transparent; border-bottom: 7px solid #ccc; border-bottom-color: rgba(0, 0, 0, 0.2); position: absolute; top: -7px; left: 6px; } .datepicker:after { content: ''; display: inline-block; border-left: 6px solid transparent; border-right: 6px solid transparent; border-bottom: 6px solid #ffffff; position: absolute; top: -6px; left: 7px; } .datepicker > div { display: none; } .datepicker table { width: 100%; margin: 0; } .datepicker td, .datepicker th { text-align: center; width: 20px; height: 20px; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .datepicker td.day:hover { background: #eeeeee; cursor: pointer; } .datepicker td.old, .datepicker td.new { color: #999999; } .datepicker td.active, .datepicker td.active:hover { background-color: #006dcc; background-image: -moz-linear-gradient(top, #0088cc, #0044cc); background-image: -ms-linear-gradient(top, #0088cc, #0044cc); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); background-image: -o-linear-gradient(top, #0088cc, #0044cc); background-image: linear-gradient(top, #0088cc, #0044cc); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); border-color: #0044cc #0044cc #002a80; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); color: #fff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .datepicker td.active:hover, .datepicker td.active:hover:hover, .datepicker td.active:active, .datepicker td.active:hover:active, .datepicker td.active.active, .datepicker td.active:hover.active, .datepicker td.active.disabled, .datepicker td.active:hover.disabled, .datepicker td.active[disabled], .datepicker td.active:hover[disabled] { background-color: #0044cc; } .datepicker td.active:active, .datepicker td.active:hover:active, .datepicker td.active.active, .datepicker td.active:hover.active { background-color: #003399 \9; } .datepicker td span { display: block; width: 47px; height: 54px; line-height: 54px; float: left; margin: 2px; cursor: pointer; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .datepicker td span:hover { background: #eeeeee; } .datepicker td span.active { background-color: #006dcc; background-image: -moz-linear-gradient(top, #0088cc, #0044cc); background-image: -ms-linear-gradient(top, #0088cc, #0044cc); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); background-image: -o-linear-gradient(top, #0088cc, #0044cc); background-image: linear-gradient(top, #0088cc, #0044cc); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); border-color: #0044cc #0044cc #002a80; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); color: #fff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .datepicker td span.active:hover, .datepicker td span.active:active, .datepicker td span.active.active, .datepicker td span.active.disabled, .datepicker td span.active[disabled] { background-color: #0044cc; } .datepicker td span.active:active, .datepicker td span.active.active { background-color: #003399 \9; } .datepicker td span.old { color: #999999; } .datepicker th.switch { width: 145px; } .datepicker th.next, .datepicker th.prev { font-size: 19.5px; } .datepicker thead tr:first-child th { cursor: pointer; } .datepicker thead tr:first-child th:hover { background: #eeeeee; } .input-append.date .add-on i, .input-prepend.date .add-on i { display: block; cursor: pointer; width: 16px; height: 16px; }
|
||||
.datepicker {
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 4px;
|
||||
margin-top: 1px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
/*.dow {
|
||||
border-top: 1px solid #ddd !important;
|
||||
}*/
|
||||
}
|
||||
.datepicker:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid #ccc;
|
||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
left: 6px;
|
||||
}
|
||||
.datepicker:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid #ffffff;
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
left: 7px;
|
||||
}
|
||||
.datepicker > div {
|
||||
display: none;
|
||||
}
|
||||
.datepicker table {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
.datepicker td, .datepicker th {
|
||||
text-align: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.datepicker td.day:hover {
|
||||
background: #eeeeee;
|
||||
cursor: pointer;
|
||||
}
|
||||
.datepicker td.old, .datepicker td.new {
|
||||
color: #999999;
|
||||
}
|
||||
.datepicker td.active, .datepicker td.active:hover {
|
||||
background-color: #006dcc;
|
||||
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
|
||||
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: linear-gradient(top, #0088cc, #0044cc);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
|
||||
border-color: #0044cc #0044cc #002a80;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.datepicker td.active:hover,
|
||||
.datepicker td.active:hover:hover,
|
||||
.datepicker td.active:active,
|
||||
.datepicker td.active:hover:active,
|
||||
.datepicker td.active.active,
|
||||
.datepicker td.active:hover.active,
|
||||
.datepicker td.active.disabled,
|
||||
.datepicker td.active:hover.disabled,
|
||||
.datepicker td.active[disabled],
|
||||
.datepicker td.active:hover[disabled] {
|
||||
background-color: #0044cc;
|
||||
}
|
||||
.datepicker td.active:active,
|
||||
.datepicker td.active:hover:active,
|
||||
.datepicker td.active.active,
|
||||
.datepicker td.active:hover.active {
|
||||
background-color: #003399 \9;
|
||||
}
|
||||
.datepicker td span {
|
||||
display: block;
|
||||
width: 47px;
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
float: left;
|
||||
margin: 2px;
|
||||
cursor: pointer;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.datepicker td span:hover {
|
||||
background: #eeeeee;
|
||||
}
|
||||
.datepicker td span.active {
|
||||
background-color: #006dcc;
|
||||
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
|
||||
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: linear-gradient(top, #0088cc, #0044cc);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
|
||||
border-color: #0044cc #0044cc #002a80;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.datepicker td span.active:hover,
|
||||
.datepicker td span.active:active,
|
||||
.datepicker td span.active.active,
|
||||
.datepicker td span.active.disabled,
|
||||
.datepicker td span.active[disabled] {
|
||||
background-color: #0044cc;
|
||||
}
|
||||
.datepicker td span.active:active, .datepicker td span.active.active {
|
||||
background-color: #003399 \9;
|
||||
}
|
||||
.datepicker td span.old {
|
||||
color: #999999;
|
||||
}
|
||||
.datepicker th.switch {
|
||||
width: 145px;
|
||||
}
|
||||
.datepicker thead tr:first-child th {
|
||||
cursor: pointer;
|
||||
}
|
||||
.datepicker thead tr:first-child th:hover {
|
||||
background: #eeeeee;
|
||||
}
|
||||
.input-append.date .add-on i, .input-prepend.date .add-on i {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.dropdown-menu.datepicker { max-width:220px }
|
205
src/html/datepicker/js/bootstrap-datepicker.js
vendored
205
src/html/datepicker/js/bootstrap-datepicker.js
vendored
@ -1,8 +1,8 @@
|
||||
/* =========================================================
|
||||
/*! =========================================================
|
||||
* bootstrap-datepicker.js
|
||||
* http://www.eyecon.ro/bootstrap-datepicker
|
||||
* Original Idea: http://www.eyecon.ro/bootstrap-datepicker (Copyright 2012 Stefan Petre)
|
||||
* Updated by AymKdn (http://kodono.info - https://github.com/Aymkdn/Datepicker-for-Bootstrap)
|
||||
* =========================================================
|
||||
* Copyright 2012 Stefan Petre
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -24,59 +24,31 @@
|
||||
var Datepicker = function(element, options){
|
||||
this.element = $(element);
|
||||
this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||'mm/dd/yyyy');
|
||||
this.picker = $(DPGlobal.template)
|
||||
.appendTo('body')
|
||||
.on({
|
||||
click: $.proxy(this.click, this),
|
||||
mousedown: $.proxy(this.mousedown, this)
|
||||
});
|
||||
this.isInput = this.element.is('input');
|
||||
this.picker = $(DPGlobal.template).appendTo('body').hide().on('mousedown.Datepicker',$.proxy(this.mousedown, this)).on('click.Datepicker',$.proxy(this.click, this));
|
||||
|
||||
this.isInput = this.element.is('input') || this.element.is('textarea');
|
||||
this.component = this.element.is('.date') ? this.element.find('.add-on') : false;
|
||||
|
||||
if (this.isInput) {
|
||||
this.element.on({
|
||||
focus: $.proxy(this.show, this),
|
||||
blur: $.proxy(this.hide, this),
|
||||
keyup: $.proxy(this.update, this)
|
||||
"focus.Datepicker": $.proxy(this.show, this),
|
||||
"click.Datepicker": $.proxy(this.show, this),
|
||||
"blur.Datepicker": $.proxy(this.blur, this),
|
||||
"keyup.Datepicker": $.proxy(this.update, this),
|
||||
"keydown.Datepicker": $.proxy(this.keydown, this)
|
||||
});
|
||||
} else {
|
||||
if (this.component){
|
||||
this.component.on('click', $.proxy(this.show, this));
|
||||
this.component.on('click.Datepicker', $.proxy(this.show, this));
|
||||
} else {
|
||||
this.element.on('click', $.proxy(this.show, this));
|
||||
this.element.on('click.Datepicker', $.proxy(this.show, this));
|
||||
}
|
||||
}
|
||||
this.minViewMode = options.minViewMode||this.element.data('date-minviewmode')||0;
|
||||
if (typeof this.minViewMode === 'string') {
|
||||
switch (this.minViewMode) {
|
||||
case 'months':
|
||||
this.minViewMode = 1;
|
||||
break;
|
||||
case 'years':
|
||||
this.minViewMode = 2;
|
||||
break;
|
||||
default:
|
||||
this.minViewMode = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.viewMode = options.viewMode||this.element.data('date-viewmode')||0;
|
||||
if (typeof this.viewMode === 'string') {
|
||||
switch (this.viewMode) {
|
||||
case 'months':
|
||||
this.viewMode = 1;
|
||||
break;
|
||||
case 'years':
|
||||
this.viewMode = 2;
|
||||
break;
|
||||
default:
|
||||
this.viewMode = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.startViewMode = this.viewMode;
|
||||
|
||||
this.viewMode = 0;
|
||||
this.weekStart = options.weekStart||this.element.data('date-weekstart')||0;
|
||||
this.weekEnd = this.weekStart === 0 ? 6 : this.weekStart - 1;
|
||||
this.scroll = (options.scroll != undefined ? options.scroll : true);
|
||||
this.weekEnd = this.weekStart == 0 ? 6 : this.weekStart - 1;
|
||||
this.fillDow();
|
||||
this.fillMonths();
|
||||
this.update();
|
||||
@ -87,39 +59,34 @@
|
||||
constructor: Datepicker,
|
||||
|
||||
show: function(e) {
|
||||
$('div.datepicker.dropdown-menu').hide(); //make sure to hide all other calendars
|
||||
this.picker.show();
|
||||
this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
|
||||
this.place();
|
||||
$(window).on('resize', $.proxy(this.place, this));
|
||||
if (e ) {
|
||||
$(window).on('resize.Datepicker', $.proxy(this.place, this));
|
||||
$('body').on('click.Datepicker', $.proxy(this.hide, this));
|
||||
if (e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
if (!this.isInput) {
|
||||
$(document).on('mousedown', $.proxy(this.hide, this));
|
||||
$(document).on('mousedown.Datepicker', $.proxy(this.hide, this));
|
||||
}
|
||||
this.element.trigger({
|
||||
type: 'show',
|
||||
date: this.date
|
||||
});
|
||||
// make sure we see the datepicker
|
||||
var elem = this.picker;
|
||||
var docScrollTop = $(document).scrollTop();
|
||||
var winHeight = $(window).height();
|
||||
var elemTop = elem.position().top;
|
||||
var elemHeight = elem.height();
|
||||
if (this.scroll && docScrollTop+winHeight<elemTop+elemHeight)
|
||||
$(document).scrollTop(elemTop-elemHeight);
|
||||
},
|
||||
|
||||
hide: function(){
|
||||
this.picker.hide();
|
||||
$(window).off('resize', this.place);
|
||||
this.viewMode = this.startViewMode;
|
||||
this.showMode();
|
||||
if (!this.isInput) {
|
||||
$(document).off('mousedown', this.hide);
|
||||
}
|
||||
this.set();
|
||||
this.element.trigger({
|
||||
type: 'hide',
|
||||
date: this.date
|
||||
});
|
||||
},
|
||||
|
||||
set: function() {
|
||||
setValue: function() {
|
||||
var formated = DPGlobal.formatDate(this.date, this.format);
|
||||
if (!this.isInput) {
|
||||
if (this.component){
|
||||
@ -131,17 +98,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
setValue: function(newDate) {
|
||||
if (typeof newDate === 'string') {
|
||||
this.date = DPGlobal.parseDate(newDate, this.format);
|
||||
} else {
|
||||
this.date = new Date(newDate);
|
||||
}
|
||||
this.set();
|
||||
this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
|
||||
this.fill();
|
||||
},
|
||||
|
||||
place: function(){
|
||||
var offset = this.component ? this.component.offset() : this.element.offset();
|
||||
this.picker.css({
|
||||
@ -150,12 +106,13 @@
|
||||
});
|
||||
},
|
||||
|
||||
update: function(newDate){
|
||||
update: function(){
|
||||
var date = this.element.val();
|
||||
this.date = DPGlobal.parseDate(
|
||||
typeof newDate === 'string' ? newDate : (this.isInput ? this.element.prop('value') : this.element.data('date')),
|
||||
date ? date : this.element.data('date'),
|
||||
this.format
|
||||
);
|
||||
this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
|
||||
this.viewDate = new Date(this.date);
|
||||
this.fill();
|
||||
},
|
||||
|
||||
@ -195,7 +152,7 @@
|
||||
html = [];
|
||||
var clsName;
|
||||
while(prevMonth.valueOf() < nextMonth) {
|
||||
if (prevMonth.getDay() === this.weekStart) {
|
||||
if (prevMonth.getDay() == this.weekStart) {
|
||||
html.push('<tr>');
|
||||
}
|
||||
clsName = '';
|
||||
@ -204,11 +161,11 @@
|
||||
} else if (prevMonth.getMonth() > month) {
|
||||
clsName += ' new';
|
||||
}
|
||||
if (prevMonth.valueOf() === currentDate) {
|
||||
if (prevMonth.valueOf() == currentDate) {
|
||||
clsName += ' active';
|
||||
}
|
||||
html.push('<td class="day'+clsName+'">'+prevMonth.getDate() + '</td>');
|
||||
if (prevMonth.getDay() === this.weekEnd) {
|
||||
if (prevMonth.getDay() == this.weekEnd) {
|
||||
html.push('</tr>');
|
||||
}
|
||||
prevMonth.setDate(prevMonth.getDate()+1);
|
||||
@ -221,7 +178,7 @@
|
||||
.text(year)
|
||||
.end()
|
||||
.find('span').removeClass('active');
|
||||
if (currentYear === year) {
|
||||
if (currentYear == year) {
|
||||
months.eq(this.date.getMonth()).addClass('active');
|
||||
}
|
||||
|
||||
@ -234,17 +191,34 @@
|
||||
.find('td');
|
||||
year -= 1;
|
||||
for (var i = -1; i < 11; i++) {
|
||||
html += '<span class="year'+(i === -1 || i === 10 ? ' old' : '')+(currentYear === year ? ' active' : '')+'">'+year+'</span>';
|
||||
html += '<span class="year'+(i == -1 || i == 10 ? ' old' : '')+(currentYear == year ? ' active' : '')+'">'+year+'</span>';
|
||||
year += 1;
|
||||
}
|
||||
yearCont.html(html);
|
||||
},
|
||||
|
||||
click: function(e) {
|
||||
blur:function(e) {
|
||||
},
|
||||
|
||||
hide: function(e){
|
||||
this.picker.hide();
|
||||
$(window).off('resize.Datepicker', this.place);
|
||||
this.viewMode = 0;
|
||||
this.showMode();
|
||||
if (!this.isInput) {
|
||||
$(document).off('mousedown.Datepicker', this.hide);
|
||||
}
|
||||
$('body').off('click.Datepicker',$.proxy(this.click, this));
|
||||
},
|
||||
click:function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
},
|
||||
mousedown: function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
var target = $(e.target).closest('span, td, th');
|
||||
if (target.length === 1) {
|
||||
if (target.length == 1) {
|
||||
switch(target[0].nodeName.toLowerCase()) {
|
||||
case 'th':
|
||||
switch(target[0].className) {
|
||||
@ -256,10 +230,9 @@
|
||||
this.viewDate['set'+DPGlobal.modes[this.viewMode].navFnc].call(
|
||||
this.viewDate,
|
||||
this.viewDate['get'+DPGlobal.modes[this.viewMode].navFnc].call(this.viewDate) +
|
||||
DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1)
|
||||
DPGlobal.modes[this.viewMode].navStep * (target[0].className == 'prev' ? -1 : 1)
|
||||
);
|
||||
this.fill();
|
||||
this.set();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -271,17 +244,8 @@
|
||||
var year = parseInt(target.text(), 10)||0;
|
||||
this.viewDate.setFullYear(year);
|
||||
}
|
||||
if (this.viewMode !== 0) {
|
||||
this.date = new Date(this.viewDate);
|
||||
this.element.trigger({
|
||||
type: 'changeDate',
|
||||
date: this.date,
|
||||
viewMode: DPGlobal.modes[this.viewMode].clsName
|
||||
});
|
||||
}
|
||||
this.showMode(-1);
|
||||
this.fill();
|
||||
this.set();
|
||||
break;
|
||||
case 'td':
|
||||
if (target.is('.day')){
|
||||
@ -294,42 +258,43 @@
|
||||
}
|
||||
var year = this.viewDate.getFullYear();
|
||||
this.date = new Date(year, month, day,0,0,0,0);
|
||||
this.viewDate = new Date(year, month, Math.min(28, day),0,0,0,0);
|
||||
this.viewDate = new Date(year, month, day,0,0,0,0);
|
||||
this.fill();
|
||||
this.set();
|
||||
this.setValue();
|
||||
this.element.trigger({
|
||||
type: 'changeDate',
|
||||
date: this.date,
|
||||
viewMode: DPGlobal.modes[this.viewMode].clsName
|
||||
date: this.date
|
||||
});
|
||||
this.hide();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mousedown: function(e){
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
},
|
||||
|
||||
keydown:function(e) {
|
||||
var keyCode = e.keyCode || e.which;
|
||||
if (keyCode == 9) this.hide(); // when hiting TAB, for accessibility
|
||||
},
|
||||
|
||||
showMode: function(dir) {
|
||||
if (dir) {
|
||||
this.viewMode = Math.max(this.minViewMode, Math.min(2, this.viewMode + dir));
|
||||
this.viewMode = Math.max(0, Math.min(2, this.viewMode + dir));
|
||||
}
|
||||
this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function() { this.element.removeData("datepicker").off(".Datepicker"); this.picker.remove() }
|
||||
};
|
||||
|
||||
$.fn.datepicker = function ( option, val ) {
|
||||
$.fn.datepicker = function ( option ) {
|
||||
return this.each(function () {
|
||||
var $this = $(this),
|
||||
data = $this.data('datepicker'),
|
||||
options = typeof option === 'object' && option;
|
||||
options = typeof option == 'object' && option;
|
||||
if (!data) {
|
||||
$this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.datepicker.defaults,options))));
|
||||
}
|
||||
if (typeof option === 'string') data[option](val);
|
||||
if (typeof option == 'string') data[option]();
|
||||
});
|
||||
};
|
||||
|
||||
@ -368,22 +333,20 @@
|
||||
return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
|
||||
},
|
||||
parseFormat: function(format){
|
||||
var separator = format.match(/[.\/\-\s].*?/),
|
||||
var separator = format.match(/[.\/-].*?/),
|
||||
parts = format.split(/\W+/);
|
||||
if (!separator || !parts || parts.length === 0){
|
||||
if (!separator || !parts || parts.length == 0){
|
||||
throw new Error("Invalid date format.");
|
||||
}
|
||||
return {separator: separator, parts: parts};
|
||||
},
|
||||
parseDate: function(date, format) {
|
||||
var today=new Date();
|
||||
if (!date) date="";
|
||||
var parts = date.split(format.separator),
|
||||
date = new Date(),
|
||||
date = new Date(today.getFullYear(),today.getMonth(),today.getDate(),0,0,0),
|
||||
val;
|
||||
date.setHours(0);
|
||||
date.setMinutes(0);
|
||||
date.setSeconds(0);
|
||||
date.setMilliseconds(0);
|
||||
if (parts.length === format.parts.length) {
|
||||
if (parts.length == format.parts.length) {
|
||||
for (var i=0, cnt = format.parts.length; i < cnt; i++) {
|
||||
val = parseInt(parts[i], 10)||1;
|
||||
switch(format.parts[i]) {
|
||||
@ -423,9 +386,9 @@
|
||||
},
|
||||
headTemplate: '<thead>'+
|
||||
'<tr>'+
|
||||
'<th class="prev">‹</th>'+
|
||||
'<th class="prev"><i class="icon-arrow-left"/></th>'+
|
||||
'<th colspan="5" class="switch"></th>'+
|
||||
'<th class="next">›</th>'+
|
||||
'<th class="next"><i class="icon-arrow-right"/></th>'+
|
||||
'</tr>'+
|
||||
'</thead>',
|
||||
contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>'
|
||||
|
@ -103,12 +103,12 @@
|
||||
|
||||
<script id="itemsTmpl" type="text/html">
|
||||
<tr data-bind="css: { 'error': sold() < 0 }">
|
||||
<td data-bind="date: value_date"></td>
|
||||
<td data-bind="date: operation_date"></td>
|
||||
<td data-bind="text: value_date"></td>
|
||||
<td data-bind="text: operation_date"></td>
|
||||
<td data-bind="text: label"></td>
|
||||
<td data-bind="text: value, css: {'text-error': value() < 0 }"></td>
|
||||
<td data-bind="text: sold, css: {'text-error': sold() < 0 }"></td>
|
||||
<td data-bind="text: pointedSold, css: {'text-error': pointedSold() < 0 }"></td>
|
||||
<td data-bind="text: operation_date() ? pointedsold : '', css: {'text-error': operation_date() && pointedsold() < 0 }"></td>
|
||||
<td data-bind="text: category"></td>
|
||||
<td class="buttons">
|
||||
<a class="btn btn-mini" data-bind="click: $root.edit" href="#" title="edit"><i class="icon-edit"></i></a>
|
||||
@ -119,12 +119,12 @@
|
||||
|
||||
<script id="editTmpl" type="text/html">
|
||||
<tr data-bind="css: { 'error': sold() < 0 }">
|
||||
<td><input type="text" class="input-small" data-bind="dateValue: value_date" data-date-format="yyyy-mm-dd" id="value_date"/></td>
|
||||
<td><div class="input-append"><input type="text" class="input-small" data-bind="dateValue: operation_date" data-date-format="yyyy-mm-dd" id="operation_date"/><button class="btn" type="button"><i class="icon-remove" id="operation_date_clear"></i></button></div></td>
|
||||
<td><div class="date"><input type="text" class="input-small" data-bind="value: value_date" data-date-format="yyyy-mm-dd" id="value_date"></input></div></td>
|
||||
<td><div class="input-append date"><input type="text" class="input-small" data-bind="value: operation_date" data-date-format="yyyy-mm-dd" id="operation_date"></input><button class="btn" type="button" data-bind="click: function(item) { item.operation_date(null)}"><i class="icon-remove"></i></button></div></td>
|
||||
<td><input type="text" class="input-xxlarge" data-bind="value: label"/></td>
|
||||
<td><input type="text" class="input-mini" data-bind="value: value"/></td>
|
||||
<td data-bind="text: sold"></td>
|
||||
<td data-bind="text: pointedSold"></td>
|
||||
<td data-bind="text: pointedsold"></td>
|
||||
<td><input type="text" class="input-small" data-bind="value: category"/></td>
|
||||
<td class="buttons">
|
||||
<a class="btn btn-mini btn-success" data-bind="click: $root.save" href="#" title="save"><i class="icon-ok"></i></a>
|
||||
@ -136,7 +136,10 @@
|
||||
<script type="text/javascript" src="jquery/jquery.js"></script>
|
||||
<script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="datepicker/js/bootstrap-datepicker.js"></script>
|
||||
|
||||
<script type="text/javascript" src="knockout/knockout.js"></script>
|
||||
<script type="text/javascript" src="knockout/knockout-mapping.min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="jqplot/jquery.jqplot.js"></script>
|
||||
<script type="text/javascript" src="jqplot/plugins/jqplot.dateAxisRenderer.js"></script>
|
||||
<script type="text/javascript" src="jqplot/plugins/jqplot.categoryAxisRenderer.min.js"></script>
|
||||
@ -147,6 +150,7 @@
|
||||
<script type="text/javascript" src="jqplot/plugins/jqplot.highlighter.min.js"></script>
|
||||
<script type="text/javascript" src="jqplot/plugins/jqplot.canvasOverlay.min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/date.js"></script>
|
||||
<script type="text/javascript" src="js/entries.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
69
src/html/js/date.js
Normal file
69
src/html/js/date.js
Normal file
@ -0,0 +1,69 @@
|
||||
// a global month names array
|
||||
var gsMonthNames = new Array(
|
||||
'January',
|
||||
'February',
|
||||
'March',
|
||||
'April',
|
||||
'May',
|
||||
'June',
|
||||
'July',
|
||||
'August',
|
||||
'September',
|
||||
'October',
|
||||
'November',
|
||||
'December'
|
||||
);
|
||||
// a global day names array
|
||||
var gsDayNames = new Array(
|
||||
'Sunday',
|
||||
'Monday',
|
||||
'Tuesday',
|
||||
'Wednesday',
|
||||
'Thursday',
|
||||
'Friday',
|
||||
'Saturday'
|
||||
);
|
||||
|
||||
// VB-like string replicator
|
||||
String.prototype.times = function(n)
|
||||
{
|
||||
var s = '';
|
||||
for (var i = 0; i < n; i++)
|
||||
s += this;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
// Zero-Padding
|
||||
String.prototype.zp = function(n) { return '0'.times(n - this.length) + this; }
|
||||
Number.prototype.zp = function(n) { thisStr = this.toString(); return '0'.times(n - thisStr.length) + thisStr; }
|
||||
|
||||
// the date format prototype
|
||||
Date.prototype.format = function(f)
|
||||
{
|
||||
if (!this.valueOf())
|
||||
return ' ';
|
||||
|
||||
var d = this;
|
||||
|
||||
return f.replace(/(yyyy|mmmm|mmm|mm|dddd|ddd|dd|hh|nn|ss|a\/p)/gi,
|
||||
function($1)
|
||||
{
|
||||
switch ($1.toLowerCase())
|
||||
{
|
||||
case 'yyyy': return d.getFullYear();
|
||||
case 'mmmm': return gsMonthNames[d.getMonth()];
|
||||
case 'mmm': return gsMonthNames[d.getMonth()].substr(0, 3);
|
||||
case 'mm': return (d.getMonth() + 1).zp(2);
|
||||
case 'dddd': return gsDayNames[d.getDay()];
|
||||
case 'ddd': return gsDayNames[d.getDay()].substr(0, 3);
|
||||
case 'dd': return d.getDate().zp(2);
|
||||
case 'hh': return ((h = d.getHours() % 12) ? h : 12).zp(2);
|
||||
case 'nn': return d.getMinutes().zp(2);
|
||||
case 'ss': return d.getSeconds().zp(2);
|
||||
case 'a/p': return d.getHours() < 12 ? 'a' : 'p';
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -5,9 +5,9 @@ function entry(data){
|
||||
this.operation_date=ko.observable(ko.utils.unwrapObservable(data.operation_date));
|
||||
this.label=ko.observable(ko.utils.unwrapObservable(data.label));
|
||||
this.value=ko.observable(ko.utils.unwrapObservable(data.value));
|
||||
this.account=ko.observable(ko.utils.unwrapObservable(data.account));
|
||||
this.account_id=ko.observable(ko.utils.unwrapObservable(data.account_id));
|
||||
this.sold=ko.observable(ko.utils.unwrapObservable(data.sold));
|
||||
this.pointedSold=ko.observable(ko.utils.unwrapObservable(data.pointedSold));
|
||||
this.pointedsold=ko.observable(ko.utils.unwrapObservable(data.pointedsold));
|
||||
this.category=ko.observable(ko.utils.unwrapObservable(data.category));
|
||||
}
|
||||
|
||||
@ -31,8 +31,10 @@ var ListViewModel = function() {
|
||||
// Entry store and selection
|
||||
self.entries = ko.observableArray([]);
|
||||
self.selectedItem = ko.observable();
|
||||
|
||||
// Placeholder for saved value to cancel entry edition
|
||||
self.savedItem = ko.observable();
|
||||
self.savedItem = null;
|
||||
|
||||
// Placeholder for entry to remove to be available in modal function "yes" click callback
|
||||
self.itemToRemove = ko.observable();
|
||||
|
||||
@ -125,22 +127,7 @@ var ListViewModel = function() {
|
||||
// Clean up selected entry.
|
||||
self.selectedItem(null);
|
||||
|
||||
var entries = [];
|
||||
$.each(data, function(index, element) {
|
||||
entries.push(new entry({
|
||||
id: element.id,
|
||||
value_date: new Date(element.value_date),
|
||||
operation_date: element.operation_date ? new Date(element.operation_date) : null,
|
||||
label: element.label,
|
||||
value: element.value,
|
||||
account: element.account_id,
|
||||
sold: element.sold,
|
||||
pointedSold: element.operation_date ? element.pointedsold : '',
|
||||
category: element.category
|
||||
}));
|
||||
});
|
||||
|
||||
self.entries(entries);
|
||||
self.entries(ko.utils.arrayMap(data, ko.mapping.fromJS));
|
||||
});
|
||||
};
|
||||
|
||||
@ -189,34 +176,32 @@ var ListViewModel = function() {
|
||||
};
|
||||
|
||||
self.edit = function(item) {
|
||||
if(self.savedItem() != null) {
|
||||
if(self.savedItem) {
|
||||
self.cancel();
|
||||
}
|
||||
|
||||
self.savedItem(new entry(item));
|
||||
self.savedItem=ko.toJS(item);
|
||||
self.selectedItem(item);
|
||||
|
||||
$("#value_date").datepicker({format: "yyyy-mm-dd"}).on('changeDate', function(ev){
|
||||
self.selectedItem().value_date(new Date(ev.date.valueOf()));
|
||||
console.debug(self.savedItem);
|
||||
|
||||
$("#value_date").datepicker().on('changeDate', function(ev){
|
||||
self.selectedItem().value_date(ev.date.format(ev.currentTarget.dataset.dateFormat));
|
||||
});
|
||||
|
||||
$("#operation_date").datepicker({format: "yyyy-mm-dd"}).on('changeDate', function(ev){
|
||||
self.selectedItem().operation_date(new Date(ev.date.valueOf()));
|
||||
});
|
||||
|
||||
$("#operation_date_clear").click(function(e){
|
||||
self.selectedItem().operation_date(null);
|
||||
$("#operation_date").datepicker().on('changeDate', function(ev){
|
||||
self.selectedItem().operation_date(ev.date.format(ev.currentTarget.dataset.dateFormat));
|
||||
});
|
||||
};
|
||||
|
||||
self.cancel = function() {
|
||||
if(self.selectedItem() && self.savedItem()) {
|
||||
self.selectedItem().id(self.savedItem().id());
|
||||
self.selectedItem().operation_date(self.savedItem().operation_date());
|
||||
self.selectedItem().value_date(self.savedItem().value_date());
|
||||
self.selectedItem().label(self.savedItem().label());
|
||||
self.selectedItem().value(self.savedItem().value());
|
||||
self.selectedItem().account(self.savedItem().account());
|
||||
if(self.selectedItem() && self.savedItem) {
|
||||
self.selectedItem().id(self.savedItem.id); // id should not change, but just in case...
|
||||
self.selectedItem().operation_date(self.savedItem.operation_date);
|
||||
self.selectedItem().value_date(self.savedItem.value_date);
|
||||
self.selectedItem().label(self.savedItem.label);
|
||||
self.selectedItem().value(self.savedItem.value);
|
||||
self.selectedItem().account_id(self.savedItem.account_id); // account_id should not change, but just in case...
|
||||
}
|
||||
|
||||
// This item was just added.
|
||||
@ -224,46 +209,23 @@ var ListViewModel = function() {
|
||||
self.entries.remove(self.selectedItem());
|
||||
}
|
||||
|
||||
self.savedItem(null);
|
||||
self.savedItem = null;
|
||||
self.selectedItem(null);
|
||||
};
|
||||
|
||||
self.add = function() {
|
||||
if(self.savedItem() != null) {
|
||||
self.cancel();
|
||||
}
|
||||
|
||||
var newEntry = new entry({
|
||||
account: self.account().id
|
||||
account_id: self.account().id
|
||||
});
|
||||
|
||||
self.entries.unshift(newEntry);
|
||||
self.selectedItem(newEntry);
|
||||
|
||||
$("#value_date").datepicker({format: "yyyy-mm-dd"}).on('changeDate', function(ev){
|
||||
self.selectedItem().value_date(new Date(ev.date.valueOf()));
|
||||
});
|
||||
|
||||
$("#operation_date").datepicker({format: "yyyy-mm-dd"}).on('changeDate', function(ev){
|
||||
self.selectedItem().operation_date(new Date(ev.date.valueOf()));
|
||||
});
|
||||
|
||||
$("#operation_date_clear").click(function(e){
|
||||
self.selectedItem().operation_date(null);
|
||||
});
|
||||
self.edit(newEntry);
|
||||
};
|
||||
|
||||
self.save = function() {
|
||||
var item = ko.toJS(self.selectedItem());
|
||||
|
||||
if(item.value_date) {
|
||||
item.value_date = dateToString(item.value_date);
|
||||
}
|
||||
|
||||
if(item.operation_date) {
|
||||
item.operation_date = dateToString(item.operation_date);
|
||||
}
|
||||
|
||||
$.post("api/entry.php", {action: "save_entry", entry:item}).success(function(data) {
|
||||
message("success", "Save", data.message);
|
||||
|
||||
@ -309,77 +271,6 @@ var ListViewModel = function() {
|
||||
};
|
||||
};
|
||||
|
||||
function dateToString(date) {
|
||||
if(date) {
|
||||
var year = date.getFullYear();
|
||||
var month = date.getMonth() + 1;
|
||||
var day = date.getDate();
|
||||
|
||||
var dateStr = year + "-" + (month < 10 ? '0' : '') + month + "-" + (day < 10 ? '0' : '') + day;
|
||||
|
||||
return dateStr;;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
ko.bindingHandlers.date = {
|
||||
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
|
||||
var unwrap = ko.utils.unwrapObservable;
|
||||
var dataSource = valueAccessor();
|
||||
|
||||
var value = dataSource ? unwrap(dataSource) : null;
|
||||
|
||||
if(value) {
|
||||
$(element).text(dateToString(value));
|
||||
} else {
|
||||
$(element).text('');
|
||||
}
|
||||
},
|
||||
|
||||
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
|
||||
var unwrap = ko.utils.unwrapObservable;
|
||||
var dataSource = valueAccessor();
|
||||
|
||||
var value = dataSource ? unwrap(dataSource) : null;
|
||||
|
||||
if(value) {
|
||||
$(element).text(dateToString(value));
|
||||
} else {
|
||||
$(element).text('');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ko.bindingHandlers.dateValue = {
|
||||
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
|
||||
var unwrap = ko.utils.unwrapObservable;
|
||||
var dataSource = valueAccessor();
|
||||
|
||||
var value = dataSource ? unwrap(dataSource) : null;
|
||||
|
||||
if(value) {
|
||||
$(element).val(dateToString(value));
|
||||
} else {
|
||||
$(element).val('');
|
||||
}
|
||||
},
|
||||
|
||||
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
|
||||
var unwrap = ko.utils.unwrapObservable;
|
||||
var dataSource = valueAccessor();
|
||||
|
||||
var value = dataSource ? unwrap(dataSource) : null;
|
||||
|
||||
if(value) {
|
||||
$(element).val(dateToString(value));
|
||||
} else {
|
||||
$(element).val('');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
drawChart = function(entries, element) {
|
||||
// clear previous chart
|
||||
$(element).html("");
|
||||
|
21
src/html/knockout/knockout-mapping.min.js
vendored
Normal file
21
src/html/knockout/knockout-mapping.min.js
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
/// Knockout Mapping plugin v2.3.5
|
||||
/// (c) 2012 Steven Sanderson, Roy Jacobs - http://knockoutjs.com/
|
||||
/// License: MIT (http://www.opensource.org/licenses/mit-license.php)
|
||||
(function(e){"function"===typeof require&&"object"===typeof exports&&"object"===typeof module?e(require("knockout"),exports):"function"===typeof define&&define.amd?define(["knockout","exports"],e):e(ko,ko.mapping={})})(function(e,f){function x(b,c){var a,d;for(d in c)if(c.hasOwnProperty(d)&&c[d])if(a=f.getType(b[d]),d&&b[d]&&"array"!==a&&"string"!==a)x(b[d],c[d]);else if("array"===f.getType(b[d])&&"array"===f.getType(c[d])){a=b;for(var e=d,k=b[d],m=c[d],s={},g=k.length-1;0<=g;--g)s[k[g]]=k[g];for(g=
|
||||
m.length-1;0<=g;--g)s[m[g]]=m[g];k=[];m=void 0;for(m in s)k.push(s[m]);a[e]=k}else b[d]=c[d]}function D(b,c){var a={};x(a,b);x(a,c);return a}function y(b,c){for(var a=D({},b),e=K.length-1;0<=e;e--){var f=K[e];a[f]&&(a[""]instanceof Object||(a[""]={}),a[""][f]=a[f],delete a[f])}c&&(a.ignore=h(c.ignore,a.ignore),a.include=h(c.include,a.include),a.copy=h(c.copy,a.copy),a.observe=h(c.observe,a.observe));a.ignore=h(a.ignore,i.ignore);a.include=h(a.include,i.include);a.copy=h(a.copy,i.copy);a.observe=h(a.observe,
|
||||
i.observe);a.mappedProperties=a.mappedProperties||{};a.copiedProperties=a.copiedProperties||{};return a}function h(b,c){"array"!==f.getType(b)&&(b="undefined"===f.getType(b)?[]:[b]);"array"!==f.getType(c)&&(c="undefined"===f.getType(c)?[]:[c]);return e.utils.arrayGetDistinctValues(b.concat(c))}function E(b,c,a,d,j,k,m){var s="array"===f.getType(e.utils.unwrapObservable(c)),k=k||"";if(f.isMapped(b))var g=e.utils.unwrapObservable(b)[n],a=D(g,a);var i=m||j,h=function(){return a[d]&&a[d].create instanceof
|
||||
Function},w=function(b){var f=F,g=e.dependentObservable;e.dependentObservable=function(a,b,c){c=c||{};a&&"object"==typeof a&&(c=a);var d=c.deferEvaluation,L=!1;c.deferEvaluation=!0;a=new G(a,b,c);if(!d){var g=a,d=e.dependentObservable;e.dependentObservable=G;a=e.isWriteableObservable(g);e.dependentObservable=d;a=G({read:function(){L||(e.utils.arrayRemoveItem(f,g),L=!0);return g.apply(g,arguments)},write:a&&function(a){return g(a)},deferEvaluation:!0});f.push(a)}return a};e.dependentObservable.fn=
|
||||
G.fn;e.computed=e.dependentObservable;b=e.utils.unwrapObservable(j)instanceof Array?a[d].create({data:b||c,parent:i,skip:M}):a[d].create({data:b||c,parent:i});e.dependentObservable=g;e.computed=e.dependentObservable;return b},t=function(){return a[d]&&a[d].update instanceof Function},u=function(b,f){var g={data:f||c,parent:i,target:e.utils.unwrapObservable(b)};e.isWriteableObservable(b)&&(g.observable=b);return a[d].update(g)};if(m=H.get(c))return m;d=d||"";if(s){var s=[],r=!1,l=function(a){return a};
|
||||
a[d]&&a[d].key&&(l=a[d].key,r=!0);e.isObservable(b)||(b=e.observableArray([]),b.mappedRemove=function(a){var c="function"==typeof a?a:function(b){return b===l(a)};return b.remove(function(a){return c(l(a))})},b.mappedRemoveAll=function(a){var c=B(a,l);return b.remove(function(a){return-1!=e.utils.arrayIndexOf(c,l(a))})},b.mappedDestroy=function(a){var c="function"==typeof a?a:function(b){return b===l(a)};return b.destroy(function(a){return c(l(a))})},b.mappedDestroyAll=function(a){var c=B(a,l);return b.destroy(function(a){return-1!=
|
||||
e.utils.arrayIndexOf(c,l(a))})},b.mappedIndexOf=function(a){var c=B(b(),l),a=l(a);return e.utils.arrayIndexOf(c,a)},b.mappedCreate=function(a){if(-1!==b.mappedIndexOf(a))throw Error("There already is an object with the key that you specified.");var c=h()?w(a):a;t()&&(a=u(c,a),e.isWriteableObservable(c)?c(a):c=a);b.push(c);return c});m=B(e.utils.unwrapObservable(b),l).sort();g=B(c,l);r&&g.sort();var r=e.utils.compareArrays(m,g),m={},I,z=e.utils.unwrapObservable(c),x={},y=!0,g=0;for(I=z.length;g<I;g++){var q=
|
||||
l(z[g]);if(void 0===q||q instanceof Object){y=!1;break}x[q]=z[g]}var z=[],A=0,g=0;for(I=r.length;g<I;g++){var q=r[g],p,v=k+"["+g+"]";switch(q.status){case "added":var C=y?x[q.value]:J(e.utils.unwrapObservable(c),q.value,l);p=E(void 0,C,a,d,b,v,j);h()||(p=e.utils.unwrapObservable(p));v=N(e.utils.unwrapObservable(c),C,m);p===M?A++:z[v-A]=p;m[v]=!0;break;case "retained":C=y?x[q.value]:J(e.utils.unwrapObservable(c),q.value,l);p=J(b,q.value,l);E(p,C,a,d,b,v,j);v=N(e.utils.unwrapObservable(c),C,m);z[v]=
|
||||
p;m[v]=!0;break;case "deleted":p=J(b,q.value,l)}s.push({event:q.status,item:p})}b(z);a[d]&&a[d].arrayChanged&&e.utils.arrayForEach(s,function(b){a[d].arrayChanged(b.event,b.item)})}else if(O(c)){b=e.utils.unwrapObservable(b);if(!b){if(h())return r=w(),t()&&(r=u(r)),r;if(t())return u(r);b={}}t()&&(b=u(b));H.save(c,b);if(t())return b;P(c,function(d){var f=k.length?k+"."+d:d;if(-1==e.utils.arrayIndexOf(a.ignore,f))if(-1!=e.utils.arrayIndexOf(a.copy,f))b[d]=c[d];else if("object"!=typeof c[d]&&"array"!=
|
||||
typeof c[d]&&0<a.observe.length&&-1==e.utils.arrayIndexOf(a.observe,f))b[d]=c[d],a.copiedProperties[f]=!0;else{var g=H.get(c[d]),j=E(b[d],c[d],a,d,b,f,b),g=g||j;if(0<a.observe.length&&-1==e.utils.arrayIndexOf(a.observe,f))b[d]=g(),a.copiedProperties[f]=!0;else{if(e.isWriteableObservable(b[d]))b[d](e.utils.unwrapObservable(g));else g=void 0===b[d]?g:e.utils.unwrapObservable(g),b[d]=g;a.mappedProperties[f]=!0}}})}else switch(f.getType(c)){case "function":t()?e.isWriteableObservable(c)?(c(u(c)),b=c):
|
||||
b=u(c):b=c;break;default:if(e.isWriteableObservable(b))return p=t()?u(b):e.utils.unwrapObservable(c),b(p),p;h()||t();b=h()?w():e.observable(e.utils.unwrapObservable(c));t()&&b(u(b))}return b}function N(b,c,a){for(var d=0,e=b.length;d<e;d++)if(!0!==a[d]&&b[d]===c)return d;return null}function Q(b,c){var a;c&&(a=c(b));"undefined"===f.getType(a)&&(a=b);return e.utils.unwrapObservable(a)}function J(b,c,a){for(var b=e.utils.unwrapObservable(b),d=0,f=b.length;d<f;d++){var k=b[d];if(Q(k,a)===c)return k}throw Error("When calling ko.update*, the key '"+
|
||||
c+"' was not found!");}function B(b,c){return e.utils.arrayMap(e.utils.unwrapObservable(b),function(a){return c?Q(a,c):a})}function P(b,c){if("array"===f.getType(b))for(var a=0;a<b.length;a++)c(a);else for(a in b)c(a)}function O(b){var c=f.getType(b);return("object"===c||"array"===c)&&null!==b}function S(){var b=[],c=[];this.save=function(a,d){var f=e.utils.arrayIndexOf(b,a);0<=f?c[f]=d:(b.push(a),c.push(d))};this.get=function(a){a=e.utils.arrayIndexOf(b,a);return 0<=a?c[a]:void 0}}function R(){var b=
|
||||
{},c=function(a){var c;try{c=a}catch(e){c="$$$"}a=b[c];void 0===a&&(a=new S,b[c]=a);return a};this.save=function(a,b){c(a).save(a,b)};this.get=function(a){return c(a).get(a)}}var n="__ko_mapping__",G=e.dependentObservable,A=0,F,H,K=["create","update","key","arrayChanged"],M={},w={include:["_destroy"],ignore:[],copy:[],observe:[]},i=w;f.isMapped=function(b){return(b=e.utils.unwrapObservable(b))&&b[n]};f.fromJS=function(b){if(0==arguments.length)throw Error("When calling ko.fromJS, pass the object you want to convert.");
|
||||
window.setTimeout(function(){A=0},0);A++||(F=[],H=new R);var c,a;2==arguments.length&&(arguments[1][n]?a=arguments[1]:c=arguments[1]);3==arguments.length&&(c=arguments[1],a=arguments[2]);a&&(c=D(c,a[n]));c=y(c);var d=E(a,b,c);a&&(d=a);--A||window.setTimeout(function(){for(;F.length;){var a=F.pop();a&&a()}},0);d[n]=D(d[n],c);return d};f.fromJSON=function(b){var c=e.utils.parseJson(b);arguments[0]=c;return f.fromJS.apply(this,arguments)};f.updateFromJS=function(){throw Error("ko.mapping.updateFromJS, use ko.mapping.fromJS instead. Please note that the order of parameters is different!");
|
||||
};f.updateFromJSON=function(){throw Error("ko.mapping.updateFromJSON, use ko.mapping.fromJSON instead. Please note that the order of parameters is different!");};f.toJS=function(b,c){i||f.resetDefaultOptions();if(0==arguments.length)throw Error("When calling ko.mapping.toJS, pass the object you want to convert.");if("array"!==f.getType(i.ignore))throw Error("ko.mapping.defaultOptions().ignore should be an array.");if("array"!==f.getType(i.include))throw Error("ko.mapping.defaultOptions().include should be an array.");
|
||||
if("array"!==f.getType(i.copy))throw Error("ko.mapping.defaultOptions().copy should be an array.");c=y(c,b[n]);return f.visitModel(b,function(a){return e.utils.unwrapObservable(a)},c)};f.toJSON=function(b,c){var a=f.toJS(b,c);return e.utils.stringifyJson(a)};f.defaultOptions=function(){if(0<arguments.length)i=arguments[0];else return i};f.resetDefaultOptions=function(){i={include:w.include.slice(0),ignore:w.ignore.slice(0),copy:w.copy.slice(0)}};f.getType=function(b){if(b&&"object"===typeof b){if(b.constructor==
|
||||
(new Date).constructor)return"date";if("[object Array]"===Object.prototype.toString.call(b))return"array"}return typeof b};f.visitModel=function(b,c,a){a=a||{};a.visitedObjects=a.visitedObjects||new R;var d,j=e.utils.unwrapObservable(b);if(O(j))a=y(a,j[n]),c(b,a.parentName),d="array"===f.getType(j)?[]:{};else return c(b,a.parentName);a.visitedObjects.save(b,d);var k=a.parentName;P(j,function(b){if(!(a.ignore&&-1!=e.utils.arrayIndexOf(a.ignore,b))){var i=j[b],g=a,h=k||"";"array"===f.getType(j)?k&&
|
||||
(h+="["+b+"]"):(k&&(h+="."),h+=b);g.parentName=h;if(!(-1===e.utils.arrayIndexOf(a.copy,b)&&-1===e.utils.arrayIndexOf(a.include,b)&&j[n]&&j[n].mappedProperties&&!j[n].mappedProperties[b]&&j[n].copiedProperties&&!j[n].copiedProperties[b]&&"array"!==f.getType(j)))switch(f.getType(e.utils.unwrapObservable(i))){case "object":case "array":case "undefined":g=a.visitedObjects.get(i);d[b]="undefined"!==f.getType(g)?g:f.visitModel(i,c,a);break;default:d[b]=c(i,a.parentName)}}});return d}});
|
Loading…
Reference in New Issue
Block a user