diff --git a/app/views/line_items/_issue_form.html.erb b/app/views/line_items/_issue_form.html.erb index 27a0a03..72d85c8 100644 --- a/app/views/line_items/_issue_form.html.erb +++ b/app/views/line_items/_issue_form.html.erb @@ -6,14 +6,15 @@ data-nested-form data-wrapper-selector=".line-item"> -
<%= t :label_line_items %>
+ <%= t :label_line_items %>| <%= t :label_description %> | -<%= t :label_qty %> | -<%= t :label_price %> | +<%= t :label_description %> | +<%= t :label_qty %> | +<%= t :label_price %> | +<%= t :label_total %> | <% unless readonly %><% end %> @@ -29,6 +30,11 @@ |
|---|
+ <%= t :label_total %>: + 0.00 +
+ <% unless readonly %> <%= f.fields_for :line_items, LineItem.new, child_index: "NEW_RECORD" do |item_form| %> diff --git a/app/views/line_items/_issue_line_items.html.erb b/app/views/line_items/_issue_line_items.html.erb index 691beef..c651298 100644 --- a/app/views/line_items/_issue_line_items.html.erb +++ b/app/views/line_items/_issue_line_items.html.erb @@ -6,10 +6,10 @@| <%= t :label_description %> | -<%= t :label_qty %> | -<%= t :label_price %> | -<%= t :label_total %> | +<%= t :label_description %> | +<%= t :label_qty %> | +<%= t :label_price %> | +<%= t :label_total %> | + | <%= f.text_field :description, - size: 50, placeholder: l(:label_description), no_label: true, disabled: readonly %> | -+ | <%= f.number_field :quantity, step: 1, min: 0, - style: "width:90px;", + class: "qty-field", no_label: true, disabled: readonly %> | -+ | <%= f.number_field :unit_price, step: 0.01, - style: "width:120px;", + class: "price-field", no_label: true, disabled: readonly %> | ++ 0.00 + | + <% unless readonly %> -+ | diff --git a/assets/javascripts/line_items.js b/assets/javascripts/line_items.js new file mode 100644 index 0000000..e5a015b --- /dev/null +++ b/assets/javascripts/line_items.js @@ -0,0 +1,40 @@ +function updateLineItemTotals() { + + let grandTotal = 0; + + document.querySelectorAll(".line-item").forEach(function(row){ + + let qty = parseFloat(row.querySelector(".qty-field")?.value || 0); + let price = parseFloat(row.querySelector(".price-field")?.value || 0); + + let total = qty * price; + + row.querySelector(".line-total").textContent = + total.toLocaleString(undefined,{minimumFractionDigits:2,maximumFractionDigits:2}); + + grandTotal += total; + + }); + + let grand = document.getElementById("line-items-grand-total"); + + if(grand){ + grand.textContent = + grandTotal.toLocaleString(undefined,{minimumFractionDigits:2,maximumFractionDigits:2}); + } +} + +document.addEventListener("input", function(e){ + + if(e.target.classList.contains("qty-field") || + e.target.classList.contains("price-field")){ + + updateLineItemTotals(); + + } + +}); + +document.addEventListener("DOMContentLoaded", function(){ + updateLineItemTotals(); +}); \ No newline at end of file diff --git a/assets/stylesheets/line_items.css b/assets/stylesheets/line_items.css new file mode 100644 index 0000000..3977961 --- /dev/null +++ b/assets/stylesheets/line_items.css @@ -0,0 +1,58 @@ +.line-items-table { + width: 100%; +} + +.line-items-table input { + width: 100%; + box-sizing: border-box; +} + +.qty-field { + max-width: 90px; +} + +.price-field { + max-width: 120px; +} + +/* MOBILE MODE */ +@media screen and (max-width: 700px) { + + .line-items-table thead { + display: none; + } + + .line-items-table, + .line-items-table tbody, + .line-items-table tr, + .line-items-table td { + display: block; + width: 100%; + } + + .line-items-table tr { + border: 1px solid #ddd; + border-radius: 6px; + padding: 10px; + margin-bottom: 10px; + background: #fff; + } + + .line-items-table td { + display: flex; + justify-content: space-between; + align-items: center; + padding: 6px 0; + } + + .line-items-table td::before { + content: attr(data-label); + font-weight: bold; + margin-right: 10px; + } + + .line-items-table td.actions { + justify-content: flex-end; + } + +} \ No newline at end of file diff --git a/lib/redmine_qbo_line_items/hooks/view_hook_listener.rb b/lib/redmine_qbo_line_items/hooks/view_hook_listener.rb index 4ced57e..c02f95c 100644 --- a/lib/redmine_qbo_line_items/hooks/view_hook_listener.rb +++ b/lib/redmine_qbo_line_items/hooks/view_hook_listener.rb @@ -16,7 +16,9 @@ module RedmineQboLineItems # Load the javascript to support the autocomplete forms def view_layouts_base_html_head(context = {}) safe_join([ - javascript_include_tag( 'nested_form_controller.js', plugin: :redmine_qbo_lineitems) + javascript_include_tag( 'nested_form_controller.js', plugin: :redmine_qbo_lineitems), + javascript_include_tag("line_items", plugin: :redmine_qbo_lineitems), + stylesheet_link_tag("line_items", plugin: :redmine_qbo_lineitems) ]) end |
|---|