mirror of
https://github.com/simonmichael/hledger.git
synced 2024-12-25 19:31:44 +03:00
234 lines
7.5 KiB
JavaScript
234 lines
7.5 KiB
JavaScript
/* hledger web ui javascript */
|
|
|
|
//----------------------------------------------------------------------
|
|
// STARTUP
|
|
|
|
$(document).ready(function() {
|
|
|
|
// add form helpers XXX move to addForm ?
|
|
|
|
// date picker
|
|
// http://bootstrap-datepicker.readthedocs.io/en/latest/options.html
|
|
var dateEl = $('#dateWrap').datepicker({
|
|
showOnFocus: false,
|
|
autoclose: true,
|
|
format: 'yyyy-mm-dd',
|
|
todayHighlight: true,
|
|
weekStart: 1 // Monday
|
|
});;
|
|
|
|
// focus and pre-fill the add form whenever it is shown
|
|
$('#addmodal')
|
|
.on('shown.bs.modal', function() {
|
|
addformFocus();
|
|
})
|
|
.on('hidden.bs.modal', function() {
|
|
// close the date picker if open
|
|
dateEl.datepicker('hide');
|
|
});
|
|
|
|
// ensure that the keypress listener on the final amount input is always active
|
|
$('#addform')
|
|
.on('focus', '.amount-input:last', function() {
|
|
addformLastAmountBindKey();
|
|
});
|
|
|
|
// keyboard shortcuts
|
|
// 'body' seems to hold focus better than document in FF
|
|
$('body').bind('keydown', 'h', function(){ $('#helpmodal').modal('toggle'); return false; });
|
|
$('body').bind('keydown', 'shift+/', function(){ $('#helpmodal').modal('toggle'); return false; });
|
|
$('body').bind('keydown', 'j', function(){ location.href = document.hledgerWebBaseurl+'/journal'; return false; });
|
|
$('body').bind('keydown', 's', function(){ sidebarToggle(); return false; });
|
|
$('body').bind('keydown', 'e', function(){ emptyAccountsToggle(); return false; });
|
|
$('body').bind('keydown', 'a', function(){ addformShow(); return false; });
|
|
$('body').bind('keydown', 'n', function(){ addformShow(); return false; });
|
|
$('body').bind('keydown', 'f', function(){ $('#searchform input').focus(); return false; });
|
|
|
|
// highlight the entry from the url hash
|
|
if (window.location.hash && $(window.location.hash)[0]) {
|
|
$(window.location.hash).addClass('highlighted');
|
|
}
|
|
$(window).on('hashchange', function() {
|
|
$('.highlighted').removeClass('highlighted');
|
|
$(window.location.hash).addClass('highlighted');
|
|
});
|
|
$('[data-toggle="offcanvas"]').click(function () {
|
|
$('.row-offcanvas').toggleClass('active');
|
|
});
|
|
});
|
|
|
|
//----------------------------------------------------------------------
|
|
// REGISTER CHART
|
|
|
|
//eslint-disable-next-line no-unused-vars
|
|
function registerChart($container, series) {
|
|
// https://github.com/flot/flot/blob/master/API.md
|
|
return $container.plot(
|
|
series,
|
|
{ /* general chart options */
|
|
xaxis: {
|
|
mode: "time",
|
|
timeformat: "%Y/%m/%d",
|
|
},
|
|
selection: {
|
|
mode: "x"
|
|
},
|
|
legend: {
|
|
position: 'sw'
|
|
},
|
|
grid: {
|
|
markings: function () {
|
|
var now = Date.now();
|
|
return [
|
|
{
|
|
xaxis: { to: now }, // past
|
|
yaxis: { to: 0 }, // <0
|
|
color: '#ffdddd',
|
|
},
|
|
{
|
|
xaxis: { from: now }, // future
|
|
yaxis: { from: 0 }, // >0
|
|
color: '#e0e0e0',
|
|
},
|
|
{
|
|
xaxis: { from: now }, // future
|
|
yaxis: { to: 0 }, // <0
|
|
color: '#e8c8c8',
|
|
},
|
|
{
|
|
yaxis: { from: 0, to: 0 }, // =0
|
|
color: '#bb0000',
|
|
lineWidth:1
|
|
},
|
|
];
|
|
},
|
|
hoverable: true,
|
|
autoHighlight: true,
|
|
clickable: true,
|
|
},
|
|
/* https://github.com/krzysu/flot.tooltip */
|
|
tooltip: true,
|
|
tooltipOpts: {
|
|
xDateFormat: "%Y/%m/%d",
|
|
content:
|
|
function(label, x, y, flotitem) {
|
|
var data = flotitem.series.data[flotitem.dataIndex];
|
|
return data[3]+" balance on %x after "+data[2]+" posted by transaction:<pre>"+data[4]+"</pre>";
|
|
},
|
|
onHover: function(flotitem, $tooltipel) {
|
|
$tooltipel.css('border-color',flotitem.series.color);
|
|
},
|
|
},
|
|
}
|
|
).data("plot");
|
|
}
|
|
|
|
function registerChartClick(ev, pos, item) {
|
|
if (!item) {
|
|
return;
|
|
}
|
|
var targetselector = '#' + item.series.data[item.dataIndex][5];
|
|
var $target = $(targetselector);
|
|
if ($target.length) {
|
|
window.location.hash = targetselector;
|
|
$('html, body').animate({
|
|
scrollTop: $target.offset().top
|
|
}, 1000);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// ADD FORM
|
|
|
|
function addformShow(showmsg) {
|
|
showmsg = typeof showmsg !== 'undefined' ? showmsg : false;
|
|
addformReset(showmsg);
|
|
$('#addmodal').modal('show');
|
|
}
|
|
|
|
// Make sure the add form is empty and clean and has the default number of rows.
|
|
function addformReset(showmsg) {
|
|
showmsg = typeof showmsg !== 'undefined' ? showmsg : false;
|
|
if ($('form#addform').length > 0) {
|
|
if (!showmsg) $('div#message').html('');
|
|
$('#addform .account-group.added-row').remove();
|
|
addformLastAmountBindKey();
|
|
$('#addform')[0].reset();
|
|
// reset typehead state (though not fetched completions)
|
|
$('.typeahead').typeahead('val', '');
|
|
$('.tt-dropdown-menu').hide();
|
|
}
|
|
}
|
|
|
|
// Set the add-new-row-on-keypress handler on the add form's current last amount field, only.
|
|
// (NB: removes all other keypress handlers from all amount fields).
|
|
function addformLastAmountBindKey() {
|
|
$('.amount-input').off('keypress');
|
|
$('.amount-input:last').keypress(addformAddPosting);
|
|
}
|
|
|
|
// Pre-fill today's date and focus the description field in the add form.
|
|
function addformFocus() {
|
|
$('#addform input[name=date]').val(isoDate());
|
|
focus($('#addform input[name=description]'));
|
|
}
|
|
|
|
function isoDate() {
|
|
return new Date().toLocaleDateString("sv"); // https://stackoverflow.com/a/58633651/84401
|
|
}
|
|
|
|
// Focus a jquery-wrapped element, working around http://stackoverflow.com/a/7046837.
|
|
function focus($el) {
|
|
setTimeout(function (){
|
|
$el.focus();
|
|
}, 0);
|
|
}
|
|
|
|
// Insert another posting row in the add form.
|
|
function addformAddPosting() {
|
|
if (!$('#addform').is(':visible')) {
|
|
return;
|
|
}
|
|
// Clone the old last row to make a new last row
|
|
$('#addform .account-postings').append( $('#addform .account-group:last').clone().addClass('added-row') );
|
|
// renumber and clear the new last account and amount fields
|
|
var n = $('#addform .account-group').length;
|
|
$('.account-input:last').prop('placeholder', 'Account '+n).val('');
|
|
$('.amount-input:last').prop('placeholder','Amount '+n).val(''); // XXX Enable typehead on dynamically created inputs
|
|
// and move the keypress handler to the new last amount field
|
|
addformLastAmountBindKey();
|
|
}
|
|
|
|
// Remove the add form's last posting row, if empty, keeping at least two.
|
|
function addformDeletePosting() {
|
|
if ($('#addform .account-group').length <= 2) {
|
|
return;
|
|
}
|
|
// remember if the last row's field or button had focus
|
|
var focuslost =
|
|
$('.account-input:last').is(':focus')
|
|
|| $('.amount-input:last').is(':focus');
|
|
// delete last row
|
|
$('#addform .account-group:last').remove();
|
|
if (focuslost) {
|
|
focus($('.account-input:last'));
|
|
}
|
|
// move the keypress handler to the new last amount field
|
|
addformLastAmountBindKey();
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// SIDEBAR
|
|
|
|
function sidebarToggle() {
|
|
$('#sidebar-menu').toggleClass('col-md-4 col-sm-4 col-any-0');
|
|
$('#main-content').toggleClass('col-md-8 col-sm-8 col-md-12 col-sm-12');
|
|
$('#spacer').toggleClass('col-md-4 col-sm-4 col-any-0');
|
|
$.cookie('showsidebar', $('#sidebar-menu').hasClass('col-any-0') ? '0' : '1');
|
|
}
|
|
|
|
function emptyAccountsToggle() {
|
|
$('.acct.empty').parent().toggleClass('hide');
|
|
$.cookie('hideemptyaccts', $.cookie('hideemptyaccts') === '1' ? '0' : '1')
|
|
}
|