0

So part of my system is I have to submit expense reports, but I can't submit them line by line. The user needs an option to add a new expense so as to be submitted under the same trip. I have part of it working, where a user can add a new expense and this duplicates the original form. However, I'm not sure how I'd go about sending more than 1 form to my database and have it saved as one. Also not sure if the duplicate form will mess with my original based on how it's generated

Original form:

JSFiddle of expenses form

Then here is my PHP to insert the values of the form inputs into the database:

    if(isset($_POST['submit'])) {
    try {
        $sql = "INSERT INTO expenses (userid, submitted_date, receiptid, description, categoryid, clientid, billable, paymentid, currencyid) VALUES (:userid, :submitted_date, :receiptid, :description, :categoryid, :clientid, :billable, :paymentid, :currencyid)";

        $statement = $connection->prepare($sql);

        $userID = filter_input(INPUT_POST, 'userid');
        $statement->bindValue(':userid', $userID, PDO::PARAM_STR);

        $subDate = filter_input(INPUT_POST, 'submitted_date');
        $statement->bindValue(':submitted_date', $subDate, PDO::PARAM_STR);

        $receipt = filter_input(INPUT_POST, 'receiptid');
        $statement->bindValue(':receiptid', $receipt, PDO::PARAM_STR);

        $description = filter_input(INPUT_POST, 'description');
        $statement->bindValue(':description', $description, PDO::PARAM_STR);

        $category = filter_input(INPUT_POST, 'categoryid');
        $statement->bindValue(':categoryid', $category, PDO::PARAM_STR);

        $client = filter_input(INPUT_POST, 'clientid');
        $statement->bindValue(':clientid', $client, PDO::PARAM_STR);

        $billable = filter_input(INPUT_POST, 'billable');
        $statement->bindValue(':billable', $billable, PDO::PARAM_STR);

        $paymenttype = filter_input(INPUT_POST, 'paymentid');
        $statement->bindValue(':paymentid', $paymenttype, PDO::PARAM_STR);

        $currencyid = filter_input(INPUT_POST, 'currencyid');
        $statement->bindValue(':currencyid', $currencyid, PDO::PARAM_STR);

        print_r($sql);
        $statement->execute();
        $connection = null;

        echo '<script language="javascript">';
        echo 'alert("Expense has been added to the database.");';
        echo 'window.location.href = "submit.php";';
        echo '</script>';
      } catch (PDOException $e) {
        // for dev
        print "We had an error: " . $e->getMessage() . "<br>";
        die();
    }
?>
<?php } else { ?>
<!DOCTYPE html>

Thanks in advance!

Barodian
  • 13
  • 4
Cymatik
  • 13
  • 4
  • 1
    Please click [edit](https://stackoverflow.com/posts/55497790/edit) then `[<>]` snippet editor and paste RENDERED HTML and JS into the panes. The last code you can leave. We cannot test your code unless we have a [mcve] – mplungjan Apr 03 '19 at 14:39
  • Add `[]` to the input fields on your form which will return them to PHP as arrays which you may then loop over to do what you need to with them. – Dave Apr 03 '19 at 14:41
  • @mplungjan Is that any better? Sorry, I'm still quite new to asking questions on here so was unaware of the rendering panes – Cymatik Apr 03 '19 at 14:54
  • Please use the view-source to give us pure HTML in the html pane and click TIDY before saving – mplungjan Apr 03 '19 at 14:56
  • @mplungjan I was having issues with the code snippet editor when adding the pure HTML, so I've just added it to a JSFiddle instead and tidied it if that helps – Cymatik Apr 03 '19 at 15:11
  • Looks like your php that receives the expenses needs to loop – mplungjan Apr 03 '19 at 15:57
  • @mplungjan any idea how I'd do that? I've been trying to figure out how to integrate a foreach loop, but not entirely sure how to go about it. – Cymatik Apr 03 '19 at 16:16
  • @Cymatik Please see my answer – mplungjan Apr 03 '19 at 20:17

1 Answers1

0

Here is the answer to part 1

How to submit multiple expenses to the PHP

I gave the submit button an ID and commented out the code to actually send it to the server

The second question is how to receive them and for that you can search

parse json with PHP

Here is one answer

How do I extract data from JSON with PHP?

$(".nav-tabs").on("click", "a", function(e) {
    e.preventDefault();
    if (!$(this).hasClass('addNew')) {
      $(this).tab('show');
    }
  })
  .on("click", "span", function() {
    var anchor = $(this).parent('a');
    $(this).parent().parent().remove();
    $(".nav-tabs li").children('a').first().click();
  });

var defaultValues = $('#expense_1>.card-body').html()

$('.addNew').click(function(e) {
  e.preventDefault();
  var id = $(".nav-tabs").children().length; //think about it ;)
  var tabId = 'expense_' + id;
  $(this).closest('li').before('<li class="nav-item"><a class="nav-link" data-toggle="tab" href="#expense_' + id + '">Expense #' + id + ' <span>x</span></a></li>');
  $('.tab-content').append('<div class="tab-pane fade" id="' + tabId + '"><div class="card-header">Expense #' + id + '</div><div class="card-body">' + defaultValues + '</div></div>');
  $('.nav-tabs li:nth-child(' + id + ') a').click();
});

$("#Submit").on("click",function(e) { // clicking the submit link
  e.preventDefault(); // stop the link from actually running
  var expenses = []; // create an array
  $(".card-header").each(function(){ // we have one header per expense
    var expense = {}
    var title = this.textContent; // it has a title
    expense[title] = {}
    $(this).next().find("[name]").each(function() { // the next div has named fields (IDs need to be unique so I ignore them
      expense[title][this.name]=this.value || ""; // save the name and value if any
    })
    expenses.push(expense); // add to array
  })
  console.log(expenses); // remove this when you are happy and uncomment next 3 lines of code
  // here you AJAX the expenses to the server
  // $post("submit.php",{ data: expenses },function(res) {
  //   console.log(res); // you want to show this somewhere 
  // });
});
body {
  background: #464646;
  color: #ddd;
  margin-bottom: 25px;
}

.navbar {
  background-color: #4a7aae;
  font-size: 20px;
}

.my-shadow {
  box-shadow: 0 8px 6px -6px #000000;
}

.navbar .navbar-brand {
  color: #ddd;
}

.navbar .navbar-brand:hover,
.navbar .navbar-brand:focus {
  color: #ddd;
}

.navbar .navbar-text {
  color: #ddd;
}

.navbar .navbar-text a {
  color: #ddd;
}

.navbar .navbar-text a:hover,
.navbar .navbar-text a:focus {
  color: #ddd;
}

.navbar .navbar-nav .nav-link {
  color: #ddd;
  border-radius: .25rem;
  margin: 0 0.25em;
}

.navbar .navbar-nav .nav-link:not(.disabled):hover,
.navbar .navbar-nav .nav-link:not(.disabled):focus {
  color: #ddd;
}

.navbar .navbar-nav .dropdown-menu {
  background-color: #222;
  border-color: #000;
}

.navbar .navbar-nav .dropdown-menu .dropdown-item {
  color: #ddd;
}

.navbar .navbar-nav .dropdown-menu .dropdown-item:hover,
.navbar .navbar-nav .dropdown-menu .dropdown-item:focus,
.navbar .navbar-nav .dropdown-menu .dropdown-item.active {
  color: #ddd;
  background-color: #4a7aae;
}

.navbar .navbar-nav .dropdown-menu .dropdown-divider {
  border-top-color: #4a7aae;
}

.navbar .navbar-nav .nav-item.active .nav-link,
.navbar .navbar-nav .nav-item.active .nav-link:hover,
.navbar .navbar-nav .nav-item.active .nav-link:focus,
.navbar .navbar-nav .nav-item.show .nav-link,
.navbar .navbar-nav .nav-item.show .nav-link:hover,
.navbar .navbar-nav .nav-item.show .nav-link:focus {
  color: #ddd;
  background-color: #4a7aae;
}

.navbar .navbar-toggle {
  border-color: #6195cc;
}

.navbar .navbar-toggle:hover,
.navbar .navbar-toggle:focus {
  background-color: #6195cc;
}

.navbar .navbar-toggler {
  border-color: rgba(0, 0, 0, 0.5);
}

.navbar-toggler-icon {
  background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

.navbar .navbar-collapse,
.navbar .navbar-form {
  border-color: #ddd;
}

.navbar .navbar-link {
  color: #ddd;
}

.navbar .navbar-link:hover {
  color: #ddd;
}

.nav-tabs a {
  color: #ddd;
}

.nav-tabs .nav-link.active,
.nav-tabs .nav-item-show .nav-link {
  color: #ddd;
  background-color: #343a40;
  border-color: #9ea0a3;
}

input[type="checkbox"] {
  cursor: pointer;
  -webkit-appearance: none;
  background-color: #fff;
  appearance: none;
  border-radius: 1px;
  box-sizing: border-box;
  position: relative;
  box-sizing: content-box;
  width: 25px;
  height: 25px;
  border-width: 0;
  transition: all 0.1s linear;
}

input[type="checkbox"]:checked {
  background-color: #2ecc71;
}

input[type="checkbox"]:focus {
  outline: 0 none;
  box-shadow: none;
}

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
  /* display: none; <- Crashes Chrome on hover */
  -webkit-appearance: none;
  margin: 0;
  /* <-- Apparently some margin are still there even though it's hidden */
}

input[type="number"] {
  -moz-appearance: textfield;
}

hr {
  background-color: #ddd;
}

@media (max-width: 575px) {
  .navbar-expand-sm .navbar-nav .show .dropdown-menu .dropdown-item {
    color: #ddd;
  }
  .navbar-expand-sm .navbar-nav .show .dropdown-menu .dropdown-item:hover,
  .navbar-expand-sm .navbar-nav .show .dropdown-menu .dropdown-item:focus {
    color: #ddd;
  }
  .navbar-expand-sm .navbar-nav .show .dropdown-menu .dropdown-item.active {
    color: #ddd;
    background-color: #4a7aae;
  }
}

@media (max-width: 767px) {
  .navbar-expand-md .navbar-nav .show .dropdown-menu .dropdown-item {
    color: #ddd;
  }
  .navbar-expand-md .navbar-nav .show .dropdown-menu .dropdown-item:hover,
  .navbar-expand-md .navbar-nav .show .dropdown-menu .dropdown-item:focus {
    color: #ddd;
  }
  .navbar-expand-md .navbar-nav .show .dropdown-menu .dropdown-item.active {
    color: #ddd;
    background-color: #4a7aae;
  }
}

@media (max-width: 991px) {
  .navbar-expand-lg .navbar-nav .show .dropdown-menu .dropdown-item {
    color: #ddd;
  }
  .navbar-expand-lg .navbar-nav .show .dropdown-menu .dropdown-item:hover,
  .navbar-expand-lg .navbar-nav .show .dropdown-menu .dropdown-item:focus {
    color: #ddd;
  }
  .navbar-expand-lg .navbar-nav .show .dropdown-menu .dropdown-item.active {
    color: #ddd;
    background-color: #4a7aae;
  }
}

@media (max-width: 1199px) {
  .navbar-expand-xl .navbar-nav .show .dropdown-menu .dropdown-item {
    color: #ddd;
  }
  .navbar-expand-xl .navbar-nav .show .dropdown-menu .dropdown-item:hover,
  .navbar-expand-xl .navbar-nav .show .dropdown-menu .dropdown-item:focus {
    color: #ddd;
  }
  .navbar-expand-xl .navbar-nav .show .dropdown-menu .dropdown-item.active {
    color: #ddd;
    background-color: #4a7aae;
  }
}

.navbar-expand .navbar-nav .show .dropdown-menu .dropdown-item {
  color: #ddd;
}

.navbar-expand .navbar-nav .show .dropdown-menu .dropdown-item:hover,
.navbar-expand .navbar-nav .show .dropdown-menu .dropdown-item:focus {
  color: #ddd;
}

.navbar-expand .navbar-nav .show .dropdown-menu .dropdown-item.active {
  color: #ddd;
  background-color: #4a7aae;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <title>Saggezza Expenses</title>
  <!-- Bootstrap Default CSS -->
  <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
  <!-- Font Awesome library -->
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>

</head>

<body>
  <nav class="navbar navbar-expand-lg my-shadow">
    <!-- <div class="container"> -->
    <a href="home.php" class="navbar-brand">
      <img src="images/saggezza.png" width="141px" height="56px" title="Saggezza Logo" alt="saggezza-logo">
    </a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
   </button>

    <div class="collapse navbar-collapse justify-content-end" id="navbarSupportedContent">
      <ul class="navbar-nav">
        <li class="nav-item active">
          <a href="home.php" class="nav-link">Expenses <span class="sr-only">(current)</span></a>
        </li>
        <li class="nav-item">
          <a href="submit.php" id="Submit" class="nav-link">Submit</a>
        </li>
        <li class="nav-item dropdown">
          <a href="#" class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Account</a>
          <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
            <a href="settings.php" class="dropdown-item">Account Settings</a>
            <a href="contact.php" class="dropdown-item">Contact Admin</a>
            <a href="logout.php" class="dropdown-item">Logout</a>
          </div>
        </li>
      </ul>
    </div>
    <!-- </div> -->
  </nav>
  <br>
  <div class="container">
    <h1 class="text-white">Submit an Expense Report</h1>
    <hr>
    <ul class="nav nav-tabs" role="tablist">
      <li class="nav-item"><a href="#expense_1" class="nav-link active" data-toggle="tab">Expense #1</a></li>
      <li class="nav-item"><a href="#" class="addNew nav-link">+ Add Expense</a></li>
    </ul>
    <div class="card bg-dark mb-6 tab-content" id="myTabContent">
      <div class="tab-pane active show fade" id="expense_1">
        <div class="card-header">Expense #1</div>
        <div class="card-body">
          <form enctype="multipart/form-data" autocomplete="off" action="/submit.php" method="post">
            <div class="form-group row">
              <label for="userid" class="col-sm-2 col-form-label">User ID</label>
              <div class="col-sm-10">
                <input type="text" class="form-control" id="userid" name="userid" style="max-width: 55px;" required>
              </div>
            </div>
            <div class="form-group row">
              <label for="submitted_date" class="col-sm-2 col-form-label">Date</label>
              <div class="col-sm-10">
                <input type="date" class="form-control" id="submitted_date" name="submitted_date" style="max-width: 165px;" required>
              </div>
            </div>
            <div class="form-group row">
              <label for="receiptid" class="col-sm-2 col-form-label">Receipt</label>
              <div class="col-sm-10">
                <select name="receiptid" id="receiptid" class="form-control" required>
                  <option value="selectOne">Choose Option</option>
                  <option value="1">
                    Yes - Soft Copy </option>
                  <option value="2">
                    Yes - Hard Copy </option>
                  <option value="3">
                    No - No Receipt </option>
                </select>
              </div>
            </div>
            <div class="form-group row">
              <label for="description" class="col-sm-2 col-form-label">Description</label>
              <div class="col-sm-10">
                <textarea class="form-control" name="description" id="description" rows="3" required></textarea>
              </div>
            </div>
            <div class="form-group row">
              <label for="categoryid" class="col-sm-2 col-form-label">Category</label>
              <div class="col-sm-10">
                <select name="categoryid" id="categoryid" class="form-control" required>
                  <option value="selectTwo">Choose Option</option>
                  <option value="1">Employee Rewards </option>
                  <option value="2">Consumables </option>
                  <option value="3">General Office Expenses </option>
                  <option value="4">General Travel: Accommodation </option>
                  <option value="5">General Travel: Travel </option>
                  <option value="6">General Travel: Substinence </option>
                  <option value="7">Sales Travel: Accommodation </option>
                  <option value="8">Sales Travel: Travel </option>
                  <option value="9">Sales Travel: Subsistence </option>
                  <option value="10">Sales Entertaining </option>
                  <option value="11">Staff Entertaining </option>
                  <option value="12">Recruitment Fees </option>
                  <option value="13">Visa & Immigration </option>
                  <option value="14">Software and IT </option>
                  <option value="15">Staff Training </option>
                  <option value="16">Stationery & Office Supplies </option>
                  <option value="17">Telephone & Conference </option>
                  <option value="18">Other </option>
                </select>
              </div>
            </div>
            <div class="form-group row">
              <label for="clientid" class="col-sm-2 col-form-label">Client Name</label>
              <div class="col-sm-10">
                <select name="clientid" id="clientid" class="form-control" required>
                  <option value="selectThree">Choose Option</option>
                  <option value="1"> Saggezza - UK </option>
                  <option value="2"> Saggezza - US </option>
                  <option value="3"> Client... </option>
                </select>
              </div>
            </div>
            <div class="form-group row">
              <label for="clientproject" class="col-sm-2 col-form-label">Client Project</label>
              <div class="col-sm-10">
                <input type="text" class="form-control" disabled readonly id="clientproject" value="To be edited by admin">
              </div>
            </div>
            <div class="form-group row">
              <label for="billable" class="col-sm-2 col-form-label">Billable to Client?</label>
              <div class="col-sm-10">
                <div class="form-check">
                  <input type="checkbox" class="form-check-input" id="billable">
                </div>
              </div>
            </div>
            <div class="form-group row">
              <label for="paymentid" class="col-sm-2 col-form-label">Payment Method</label>
              <div class="col-sm-10">
                <select name="paymentid" id="paymentid" class="form-control">
                  <option value="selectFour">Choose Option</option>
                  <option value="1"> Own Card </option>
                  <option value="2"> Corporate Card </option>
                </select>
              </div>
            </div>
            <div class="form-group row">
              <label for="currencyid" class="col-sm-2 col-form-label">Currency</label>
              <div class="col-sm-10">
                <select name="currencyid" id="currencyid" class="form-control">
                  <option value="selectFour">Choose Option</option>
                  <option value="1"> GBP </option>
                  <option value="2"> USD </option>
                  <option value="3"> EUR </option>
                </select>
              </div>
            </div>
            <div class="form-group row">
              <label for="amountnum" class="col-sm-2 col-form-label">Amount</label>
              <div class="col-sm-10">
                <input type="number" value="0" min="0" name="amountid" id="amountid" class="form-control">
              </div>
            </div>
          </form>
        </div>
      </div>
      <div class="tab-pane" id="expense_1"></div>
    </div>
  </div>




</body>

</html>
mplungjan
  • 169,008
  • 28
  • 173
  • 236