Changing a bill (bill_data) now works, as does cancelling cleanly - this is now functional. I have renamed/improved the left-hand-side fields, right-hand-side next - to improve consistency between html and db and bill_data and bill_type

This commit is contained in:
2025-08-14 15:32:09 +10:00
parent 0c0745fe68
commit b02e03339e
6 changed files with 242 additions and 53 deletions

View File

@@ -21,50 +21,47 @@
<div class="containerfluid row">
<h3 align="center">Bill Details (go to <a href="/">Finance Tracker</a>)</h3>
<div class="col-6">
<div class="row align-items-center">
<button id="new-bill" class="px-0 offset-6 col-2 btn btn-success" onCLick="$('.bills').removeClass('d-none');$('#new-bill').addClass('d-none');$('#name').focus()"><span class="bi bi-plus-lg"> New Bill</span></button>
<div class="bills px-0 col-2 d-none"> <select id="name" class="form-select text-end float-end border border-primary">
<button id="new-bill-data-button" class="px-0 offset-6 col-2 btn btn-success" onCLick="StartNewBillData()"><span class="bi bi-plus-lg"> New Bill</span></button>
<div class="bills px-0 col-2 d-none"> <select id="new-bill-data-type" class="form-select text-end float-end border border-primary">
{% for el in bill_types %}
<option value={{el.id}}>{{el.name}}</option>
{% endfor %}
</select>
</div>
<div class="bills px-0 col-2 d-none"> <input type="date" class="form-control text-end float-end border border-primary" id="bill-date"> </div>
<div class="bills px-0 col-2 d-none"> <input type="number" class="form-control text-end float-end border border-primary" id="amt"> </div>
<button id="save-bill" class="bills px-0 col-1 btn btn-success d-none" onClick="
$.ajax( { type: 'POST', url: '/newbill',
contentType: 'application/json', data: JSON.stringify( { 'name': $('#name').val(), 'amt': $('#amt').val(), 'bill_date': $('#bill-date').val() } ),
success: function() { window.location='bills' } } )"
">
<div class="bills px-0 col-2 d-none"> <input type="date" class="form-control text-end float-end border border-primary" id="new-bill-data-date"> </div>
<div class="bills px-0 col-2 d-none"> <input type="number" class="form-control text-end float-end border border-primary" id="new-bill-data-amount"> </div>
<button id="save-bill" class="bills px-0 col-1 btn btn-success d-none" onClick="NewBill()">
<span class="bi bi-floppy"></span> Save </button>
<button class="bills px-0 col-1 btn btn-danger d-none" onClick="$('.bills').addClass('d-none');$('#new-bill').removeClass('d-none')"><span class="bi bi-trash3"> Cancel</span> </button>
<button class="bills px-0 col-1 btn btn-danger d-none" onClick="CancelNewBill()" ><span class="bi bi-trash3"> Cancel</span> </button>
</div>
<div class="row">
<div class="px-0 col-2"> <label class="form-control text-center border-0">Name</ > </div>
<div class="px-0 col-2"> <label class="form-control text-center border-0">Date</ > </div>
<div class="px-0 col-2"> <label class="form-control text-center border-0">Amount</ > </div>
</div>
{% for el in bill_data %}
<div class="row">
<div class="px-0 col-2"> <input type="text" class="form-control text-center bg-white" id="n-{{el.id}}" name="n-{{el.id}}" value="{{ el.name }}" disabled> </div>
<div class="px-0 col-2"> <input type="date" class="form-control text-center bg-white" id="d-{{el.id}}" name="d-{{el.id}}" value="{{ el.bill_date }}" disabled> </div>
<div class="px-0 col-2"> <input type="number" class="form-control text-center bg-white" id="a-{{el.id}}" name="a-{{el.id}}" value="{{ el.amount }}" disabled> </div>
<button class="px-0 col-1 btn btn-success" onClick="" disabled>Change</button>
<button class="px-0 col-1 btn btn-danger" onClick="
$.ajax( { type: 'POST', url: '/delbill', contentType: 'application/json',
data: JSON.stringify( { 'id': '{{el.id}}' } ), success: function() { window.location='bills' } } )">
<span class="bi bi-trash3"> Delete
</button>
<div class="px-0 col-2"> <label class="form-control text-center border-0">Name</ > </div>
<div class="px-0 col-2"> <label class="form-control text-center border-0">Date</ > </div>
<div class="px-0 col-2"> <label class="form-control text-center border-0">Amount</ > </div>
</div>
{% endfor %}
{% for el in bill_data %}
<div class="row">
<div class="px-0 col-2"> <input type="text" class="form-control text-center bg-white" id="n-{{el.id}}" name="n-{{el.id}}" value="{{ el.name }}" disabled> </div>
<div class="px-0 col-2"> <input type="date" class="form-control text-center bg-white" id="d-{{el.id}}" name="d-{{el.id}}" value="{{ el.bill_date }}" disabled> </div>
<div class="px-0 col-2"> <input type="number" class="form-control text-center bg-white" id="a-{{el.id}}" name="a-{{el.id}}" value="{{ el.amount }}" disabled> </div>
<button id="bill-chg-{{el.id}}" class="px-0 col-1 btn btn-success" onClick="StartUpdateBill( {{el.id}} )">Change</button>
<button id="bill-del-{{el.id}}" class="px-0 col-1 btn btn-danger" onClick="DeleteBill( {{el.id }} )"><span class="bi bi-trash3"> Delete
<button id="bill-save-{{el.id}}" class="px-0 col-1 btn btn-success d-none" onClick="UpdateBill( {{el.id}} )">Save</button>
<button id="bill-canc-{{el.id}}" class="px-0 col-1 btn btn-danger d-none"
onClick="CancelUpdateBill({{el.id}}, '{{el.name}}', '{{el.bill_date}}', '{{el.amount}}')"> <span class="bi bi-trash3"> Cancel</button>
</button>
</div>
{% endfor %}
</div>
<!-- right-hand-side, bill types (e.g. gas, phone, etc.) -->
<div class="col-6">
<div class="row align-items-center">
<button id="new-bill-type" class="px-0 offset-2 col-2 btn btn-success" onCLick="StartNewBillType()"><span class="bi bi-plus-lg"> New Bill Type</span></button>
<button id="new-bill-type-button" class="px-0 offset-2 col-2 btn btn-success" onCLick="StartNewBillType()"><span class="bi bi-plus-lg"> New Bill Type</span></button>
<div class="bill-type px-0 col-2 d-none"> <input type="text" class="form-control text-end float-end border border-primary" id="bill-type"></div>
<button id="save-bill-type" class="bill-type px-0 col-1 btn btn-success d-none" onClick="NewBillType()"><span class="bi bi-floppy"></span> Save</button>
<button id="canc-bill-type" class="bill-type px-0 col-1 btn btn-danger d-none" onClick="CancelNewBillType()"><span class="bi bi-trash3"> Cancel</span></button>
@@ -81,7 +78,7 @@
<script>$("#bill-type-name-{{el.id}}").keyup(function(event){ if(event.which == 13){ $('#bill-type-save-{{el.id}}').click(); } event.preventDefault(); });</script>
<div class="px-0 col-2"><input type="text" class="bill-type-{{el.id}} form-control text-center bg-white" id="bill-type-freq-{{el.id}}" value="not yet" disabled> </div>
<div class="px-0 col-2"><input type="text" class="bill-type-{{el.id}} form-control text-center bg-white" id="bill-type-grow-{{el.id}}" value="not yet" disabled> </div>
<button id="bill-type-chg-{{el.id}}" class="px-0 col-1 btn btn-success" onClick="AllowUpdateBillType( {{el.id}} )">Change</button>
<button id="bill-type-chg-{{el.id}}" class="px-0 col-1 btn btn-success" onClick="StartUpdateBillType( {{el.id}} )">Change</button>
<button id="bill-type-del-{{el.id}}" class="px-0 col-1 btn btn-danger" onClick="DelBillType({{el.id}})"><span class="bi bi-trash3"> Delete</button>
<button id="bill-type-save-{{el.id}}" class="px-0 col-1 btn btn-success d-none" onClick="UpdateBillType( {{el.id}} )">Save</button>
<button id="bill-type-canc-{{el.id}}" class="px-0 col-1 btn btn-danger d-none" onClick="CancelUpdateBillType({{el.id}}, '{{el.name}}')"><span class="bi bi-trash3"> Cancel</button>
@@ -89,8 +86,84 @@
{% endfor %}
</div>
<script>
function StartNewBillType()
function StartNewBillData()
{
$('.bills').removeClass('d-none')
$('#new-bill-data-button').addClass('d-none')
$('#new-bill-data-type').focus()
}
function NewBill()
{
$.ajax( { type: 'POST', url: '/newbill',
contentType: 'application/json', data: JSON.stringify( { 'name': $('#new-bill-data-type').val(), 'amount': $('#new-bill-data-amount').val(), 'bill_date': $('#new-bill-data-date').val() } ),
success: function() { window.location='bills' } } )
}
function CancelNewBill()
{
$('.bills').addClass('d-none')
$('#new-bill-data-button').removeClass('d-none')
// reset select to first option
$('#new-bill-data-type').val( $('#new-bill-data-type option:first').attr('value') )
// clear out date and amount
$('#new-bill-data-date').val('')
$('#new-bill-data-amount').val('')
}
function StartUpdateBill( id )
{
val=$('#a-'+id).val()
// enable date and amount fields
$('#n-'+id).removeClass('bg-white')
$('#d-'+id).prop('disabled', false )
$('#a-'+id).prop('disabled', false )
// "enable" name for edits
$('#a-'+id).prop('disabled', false).focus()
// move cursor to the end after 'focus()' above
$('#a-'+id).val('').val( val )
// alter change/delete buttons to be save/cancel
$('#bill-chg-'+id).addClass('d-none')
$('#bill-del-'+id).addClass('d-none')
$('#bill-save-'+id).removeClass('d-none')
$('#bill-canc-'+id).removeClass('d-none')
}
function UpdateBill(id)
{
$.ajax( { type: 'POST', url: '/updatebill',
contentType: 'application/json', data: JSON.stringify( { 'id': id, 'name': $('#n-'+id).val(), 'bill_date' : $('#d-'+id).val(), 'amount': $('#a-'+id).val() } ),
success: function() { window.location='bills' } } )
}
function CancelUpdateBill( id, bill_type, bill_date, amount )
{
// fix-up type, date and amount fields
$('#n-'+id).addClass('bg-white')
$('#d-'+id).prop('disabled', true )
$('#a-'+id).prop('disabled', true )
// alter change/delete buttons to be save/cancel
$('#bill-chg-'+id).removeClass('d-none')
$('#bill-del-'+id).removeClass('d-none')
$('#bill-save-'+id).addClass('d-none')
$('#bill-canc-'+id).addClass('d-none')
// finally we might have modified the string, and then clicked cancel, so rest bill values to orig
$('#n-'+id).val(bill_type)
$('#d-'+id).val(bill_date)
$('#a-'+id).val(amount)
}
function DeleteBill( id )
{
$.ajax( { type: 'POST', url: '/delbill', contentType: 'application/json',
data: JSON.stringify( { 'id': id } ), success: function() { window.location='bills' } } )
}
function StartNewBillType()
{
$('.bill-type').removeClass('d-none')
$('#new-bill-type').addClass('d-none')
$('#bill-type').focus()
@@ -100,16 +173,18 @@
{
$('.bill-type').addClass('d-none')
$('#new-bill-type').removeClass('d-none')
$('#bill-type').val('')
}
function NewBillType() {
function NewBillType()
{
$.ajax( { type: 'POST', url: '/newbilltype',
contentType: 'application/json', data: JSON.stringify( { 'bill_type': $('#bill-type').val() } ),
success: function() { window.location='bills' } } )
}
function AllowUpdateBillType( id )
{
function StartUpdateBillType( id )
{
val=$('#bill-type-name-'+id).val()
// "disable" the freq & growth
@@ -128,7 +203,8 @@
$('#bill-type-canc-'+id).removeClass('d-none')
}
function UpdateBillType(id) {
function UpdateBillType(id)
{
$.ajax( { type: 'POST', url: '/updatebilltype',
contentType: 'application/json', data: JSON.stringify( { 'id': id, 'bill_type': $('#bill-type-name-'+id).val() } ),
success: function() { window.location='bills' } } )
@@ -138,7 +214,7 @@
{
// "re-enable" the freq & growth
$('.bill-type-'+id).removeClass('bg-light text-secondary').addClass('bg-white')
// "enable" name for edits
// "disable" name for edits
$('#bill-type-name-'+id).prop('disabled', true)
// alter change/delete buttons to be save/cancel
$('#bill-type-chg-'+id).removeClass('d-none')
@@ -150,14 +226,14 @@
}
function DelBillType( id )
{
{
$.ajax( { type: 'POST', url: '/delbilltype', contentType: 'application/json',
data: JSON.stringify( { 'id': id } ), success: function() { window.location='bills' } } )
}
$(document).ready(function () {
// if amount has enter key in it then save, but dont do this for other fields in new bill
$("#amt").keyup(function(event){ if(event.which == 13){ $("#save-bill").click(); } event.preventDefault(); });
$("#new-bill-data-amount").keyup(function(event){ if(event.which == 13){ $("#save-bill").click(); } event.preventDefault(); });
// if we hit enter in new bill type name field, save it
$("#bill-type").keyup(function(event){ if(event.which == 13){ $("#save-bill-type").click(); } event.preventDefault(); });

View File

@@ -18,7 +18,7 @@
</head>
<body>
<div class="containerfluid">
<h3 align="center">Finance Tracker</h3>
<h3 align="center">Finance Tracker (go to <a href="bills">Bills</a>)</h3>
<form id="vals_form" class="ms-3 mt-3" action="/update" method="POST">
{% for r in DISP %}