This is a simple PHP based income and expense calculator without the use of the database.
Are you looking for interesting budget calculator with PHP?
Today, we are going to build an amazing income and expense calculator with PHP only. It’s just for real-time fun, no need to store anywhere.
But If you want then this might be an assignment for you. Isn’t it?
One bonus point is that we also going to learn some interesting jQuery here. Why jQuery?
jQuery helps us to add some extra fun Like add more field, remove field etc.
So, let’s roll-out,
let’s dive into it,
We are going to add the following files:
The header file is to link external CSS and Js. Footer file is to link and trigger Js.
You can read about the best position of Js file in HTML document, here.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <!-- Add page icon --> <link rel="icon" href="assets/icon/sb.png" type="image/png" sizes="16x16" /> <title>Income & Expense calculator</title> <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" /> <!-- Latest compiled and minified JavaScript --> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> <!-- Add external css --> <link rel="stylesheet" href="assets/css/theme.css" /> </head> <body>
<script src="./assets/js/main.js"></script> </body> </html>
In this file, we will get all the added incomes and expenses. Then calculate the final balance and balance may be positive or negative.
We will also count max records to process max rows of the table, talk about it later.
<?php $total_income = $total_exp = $balance = $count_inc = $count_exp = $row_length = 0; if(isset($_POST['inc'])){ $count_inc = count($_POST['inc']); foreach($_POST['inc_amt'] as $amt) { $total_income += intval($amt); } } if(isset($_POST['exp'])){ $count_exp = count($_POST['exp']); foreach($_POST['exp_amt'] as $amt) { $total_exp += intval($amt); } } $row_length = $count_inc > $count_exp ? $count_inc : $count_exp ; $balance = $total_income - $total_exp;
This file helps us to connect all the other files like layout and budget calculator file.
Let’s look at the code,
<?php include_once('layout/header.php'); include_once('budget_calculator.php'); ?> <div class="container"> <div class="page-header"> <h1>Income & Expenses <small>Calculator</small></h1> </div> <div class="row"> <div class="col-md-12"> <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post"> <table class="table table-bordered"> <thead> <tr> <th colspan="2">Receipients</th> <th colspan="2">Expenditures</th> </tr> <tr> <th>Item</th> <th>Amount</th> <th>Item</th> <th>Amount</th> </tr> </thead> <tbody> <tr class="head-inputs"> <td> <i class="glyphicon glyphicon-plus i-btn add-income-btn"></i> <input class="inpt" name="income" type="text"> </td> <td> <i class="glyphicon glyphicon-piggy-bank i-btn inc-amt"></i> <input class="inpt" name="income_amt" type="text"> </td> <td> <i class="glyphicon glyphicon-plus i-btn add-expense-btn"></i> <input class="inpt" name="expense" type="text"> </td> <td> <i class="glyphicon glyphicon-piggy-bank i-btn exp-amt"></i> <input class="inpt" name="expense_amt" type="text"> </td> </tr> <?php for ($i = 0; $i < $row_length; $i++) { ?> <tr> <td><?php echo isset($_POST['inc'][$i]) ? "<i class='glyphicon glyphicon-minus i-btn remove-income-btn'></i> <input type='text' class='td-inpt' readonly name='inc[]' value='".$_POST['inc'][$i]."' />" : ''; ?></td> <td><?php echo isset($_POST['inc_amt'][$i]) ? "<input type='text' class='td-inpt' readonly name='inc_amt[]' value='".$_POST['inc_amt'][$i]."' />" : ''; ?></td> <td><?php echo isset($_POST['exp'][$i]) ? "<i class='glyphicon glyphicon-minus i-btn remove-expense-btn'></i> <input type='text' class='td-inpt' readonly name='exp[]' value='".$_POST['exp'][$i]."' />" : ''; ?></td> <td><?php echo isset($_POST['exp_amt'][$i]) ? "<input type='text' class='td-inpt' readonly name='exp_amt[]' value='".$_POST['exp_amt'][$i]."' />" : ''; ?></td> </tr> <?php } ?> </tbody> </table> <div class="well"> <button type="submit" class="btn btn-success">Calculate</button> <hr /> <p><strong>Income : </strong> <?= $total_income; ?></p> <p><strong>Expenses : </strong> <?= $total_exp; ?></p> <p><strong>Balance : </strong> <?= $balance; ?></p> </div> </form> </div> </div> </div> <?php include_once('layout/footer.php'); ?>
This is the bonus point here, we are using some jQuery which will help us to build add a record and remove record system for income and expenses in the table.
We will also use the recursive function concept. Read about recursive function here.
$(document).ready(()=>{ $('.add-expense-btn').click(()=>{ add_new_record('expense'); }) $('.add-income-btn').click(()=>{ add_new_record('income'); }) $(document).on('click', '.remove-income-btn', function(){ remove_record(this, 'input[name="exp[]"]', [0, 1]); }) $(document).on('click', '.remove-expense-btn', function(){ remove_record(this, 'input[name="inc[]"]', [2, 3]); }) }) function remove_parent_row(element) { element.remove(); } function empty_parent_row(element, inx) { element.children().map((i, el)=>{ if(i == inx[0] || i == inx[1]) { $(el).html(''); } }) } function remove_record(element, search_input, indexes) { var parent_row = $(element).closest('tr'); parent_row.find(search_input).length > 0 ? empty_parent_row(parent_row, indexes) : remove_parent_row(parent_row); } function add_new_record(type) { var short_form = type === 'income' ? 'inc' : 'exp'; var inx = type === 'income' ? [0, 1] : [2, 3]; var item = $('input[name="'+type+'"]').val(); var item_amt = $('input[name="'+type+'_amt"]').val(); if(item.length > 0 && item_amt.length > 0 && /^[0-9]*$/.test(item_amt)) { var last_row = $('tbody tr:not(.head-inputs)').last(); var row = last_row.length > 0 ? find_child(last_row, short_form) ? false : check_prev(last_row, short_form) : false; var remove_btn = '<i class="glyphicon glyphicon-minus i-btn remove-'+type+'-btn"></i>'; if(!row) { var tr = "<tr><td></td><td></td><td></td><td></td></tr>"; $('tbody').append(tr); row = $('tbody tr').last(); } var itm = "<input type='text' class='td-inpt' readonly name='"+short_form+"[]' value=' "+item+" '> "; var itm_amt = "<input type='text' class='td-inpt' readonly name='"+short_form+"_amt[]' value=' "+item_amt+" '> "; row.children().map((i, el)=>{ if(i == inx[0]) { $(el).html(remove_btn+itm); } else if(i == inx[1]) { $(el).html(itm_amt); } }) $('input[name="'+type+'"]').val(''); $('input[name="'+type+'_amt"]').val(''); } else { alert('Please enter the valid '+type+' source and amount'); } } function check_prev(element, input_name) { var prev_input = $(element).prev().not('.head-inputs'); if (prev_input.length > 0) { if (!find_child(prev_input, input_name)) { return check_prev(prev_input, input_name); } } return element; } function find_child(element, name) { return element.children().find("input[name='"+name+"[]']").length > 0; }
Here is your assignment, add edit record feature in this project. If you face any kind of issue then please write in the comment section below.
What will learn from the above project?
Done!
Click on the below button to clone code from git-hub repository.
Today we are going to learn about managing multiple PHP versions on ubuntu with xampp.…
Let's understand about how to use coding to improve your website's SEO. In today’s computerized…
Let's understand the most important linux commands for web developers. Linux, as an open-source and…
Today we are going to discuss top 75+ Laravel interview questions asked by top MNCs.Laravel,…
Today we will discuss about the Mailtrap integration with laravel 10 .Sending and receiving emails…
Today we are going to integrate FCM (Firebase Cloud Messaging) push notifications with ionic application.Firebase…
View Comments
Awesome post! Keep up the great work! :)
Thanks