AJAX_ify StockArticle manipulation; Introduce publish/subscribe pattern for DOM updates
This commit is contained in:
parent
e99752e483
commit
dd08e277c7
22 changed files with 313 additions and 107 deletions
|
@ -5,29 +5,61 @@ class StockitController < ApplicationController
|
||||||
order('suppliers.name, article_categories.name, articles.name')
|
order('suppliers.name, article_categories.name, articles.name')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def index_on_stock_article_create # See publish/subscribe design pattern in /doc.
|
||||||
|
@stock_article = StockArticle.find(params[:id])
|
||||||
|
|
||||||
|
render :layout => false
|
||||||
|
end
|
||||||
|
|
||||||
|
def index_on_stock_article_update # See publish/subscribe design pattern in /doc.
|
||||||
|
@stock_article = StockArticle.find(params[:id])
|
||||||
|
|
||||||
|
render :layout => false
|
||||||
|
end
|
||||||
|
|
||||||
|
# three possibilites to fill a new_stock_article form
|
||||||
|
# (1) start from blank or use params
|
||||||
def new
|
def new
|
||||||
@stock_article = StockArticle.new
|
@stock_article = StockArticle.new(params[:stock_article])
|
||||||
|
|
||||||
|
render :layout => false
|
||||||
|
end
|
||||||
|
|
||||||
|
# (2) StockArticle as template
|
||||||
|
def copy
|
||||||
|
@stock_article = StockArticle.find(params[:stock_article_id]).dup
|
||||||
|
|
||||||
|
render :layout => false
|
||||||
|
end
|
||||||
|
|
||||||
|
# (3) non-stock Article as template
|
||||||
|
def derive
|
||||||
|
@stock_article = Article.find(params[:old_article_id]).becomes(StockArticle).dup
|
||||||
|
|
||||||
|
render :layout => false
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@stock_article = StockArticle.new(params[:stock_article])
|
@stock_article = StockArticle.new(params[:stock_article])
|
||||||
if @stock_article.save
|
if @stock_article.valid? and @stock_article.save
|
||||||
redirect_to stock_articles_path, :notice => I18n.t('stockit.stock_create.notice')
|
render :layout => false
|
||||||
else
|
else
|
||||||
render :action => 'new'
|
render :action => 'new', :layout => false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
@stock_article = StockArticle.find(params[:id])
|
@stock_article = StockArticle.find(params[:id])
|
||||||
|
|
||||||
|
render :layout => false
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@stock_article = StockArticle.find(params[:id])
|
@stock_article = StockArticle.find(params[:id])
|
||||||
if @stock_article.update_attributes(params[:stock_article])
|
if @stock_article.update_attributes(params[:stock_article])
|
||||||
redirect_to stock_articles_path, :notice => I18n.t('stockit.stock_update.notice')
|
render :layout => false
|
||||||
else
|
else
|
||||||
render :action => 'edit'
|
render :action => 'edit', :layout => false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -36,9 +68,15 @@ class StockitController < ApplicationController
|
||||||
@stock_changes = @stock_article.stock_changes.order('stock_changes.created_at DESC')
|
@stock_changes = @stock_article.stock_changes.order('stock_changes.created_at DESC')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def show_on_stock_article_update # See publish/subscribe design pattern in /doc.
|
||||||
|
@stock_article = StockArticle.find(params[:id])
|
||||||
|
|
||||||
|
render :layout => false
|
||||||
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@article = StockArticle.find(params[:id])
|
@stock_article = StockArticle.find(params[:id])
|
||||||
@article.mark_as_deleted
|
@stock_article.mark_as_deleted
|
||||||
render :layout => false
|
render :layout => false
|
||||||
rescue => error
|
rescue => error
|
||||||
render :partial => "destroy_fail", :layout => false,
|
render :partial => "destroy_fail", :layout => false,
|
||||||
|
|
|
@ -14,4 +14,13 @@ module StockitHelper
|
||||||
link_to t('.stock_taking'), stock_taking_path(stock_change.stock_taking)
|
link_to t('.stock_taking'), stock_taking_path(stock_change.stock_taking)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def stock_article_price_hint(stock_article)
|
||||||
|
t('simple_form.hints.stock_article.edit_stock_article.price',
|
||||||
|
:stock_article_copy_link => link_to(t('.copy_stock_article'),
|
||||||
|
stock_article_copy_path(stock_article),
|
||||||
|
:remote => true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
= simple_form_for stock_article, :validate => true do |f|
|
= simple_form_for stock_article, remote: true, :validate => true do |f|
|
||||||
|
.modal-header
|
||||||
|
= link_to t('ui.marks.close').html_safe, '#', class: 'close', data: {dismiss: 'modal'}
|
||||||
|
%h3= title
|
||||||
|
.modal-body
|
||||||
= f.association :supplier
|
= f.association :supplier
|
||||||
= f.input :name
|
= f.input :name
|
||||||
= f.input :unit
|
= f.input :unit
|
||||||
= f.input :note
|
= f.input :note
|
||||||
|
|
||||||
- if stock_article.new_record?
|
- if stock_article.new_record?
|
||||||
= f.input :price
|
= f.input :price
|
||||||
= f.input :tax, :wrapper => :append do
|
= f.input :tax, :wrapper => :append do
|
||||||
|
@ -11,8 +14,8 @@
|
||||||
%span.add-on %
|
%span.add-on %
|
||||||
= f.input :deposit
|
= f.input :deposit
|
||||||
- else
|
- else
|
||||||
= f.input :price, :input_html => {:disabled => 'disabled'}, :hint => t('.price_hint')
|
= f.input :price, :input_html => {:disabled => 'disabled'}, :hint => stock_article_price_hint(stock_article).html_safe
|
||||||
= f.association :article_category
|
= f.association :article_category
|
||||||
.form-actions
|
.modal-footer
|
||||||
= f.submit class: 'btn'
|
= link_to t('ui.close'), '#', class: 'btn', data: {dismiss: 'modal'}
|
||||||
= link_to t('ui.or_cancel'), stock_articles_path
|
= f.submit :class => 'btn btn-primary', 'data-disable-with' => t('ui.please_wait')
|
||||||
|
|
14
app/views/stockit/_stock_article.html.haml
Normal file
14
app/views/stockit/_stock_article.html.haml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
%tr{:class => stock_article_classes(stock_article), :id => "stockArticle-#{stock_article.id}"}
|
||||||
|
%td= link_to stock_article.name, stock_article
|
||||||
|
%td= stock_article.quantity
|
||||||
|
%td= stock_article.quantity - stock_article.quantity_available
|
||||||
|
%th= stock_article.quantity_available
|
||||||
|
%td= stock_article.unit
|
||||||
|
%td= stock_article.price
|
||||||
|
%td= number_to_percentage stock_article.tax
|
||||||
|
%td= link_to stock_article.supplier.name, stock_article.supplier
|
||||||
|
%td= stock_article.article_category.name
|
||||||
|
%td
|
||||||
|
= link_to t('ui.edit'), edit_stock_article_path(stock_article), remote: true, class: 'btn btn-mini'
|
||||||
|
= link_to t('ui.delete'), stock_article, :method => :delete, :confirm => t('.confirm_delete', :name => stock_article.name),
|
||||||
|
class: 'btn btn-mini btn-danger', :remote => true
|
26
app/views/stockit/_stock_article_details.html.haml
Normal file
26
app/views/stockit/_stock_article_details.html.haml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#stockArticleDetails
|
||||||
|
%dl.dl-horizontal
|
||||||
|
%dt= heading_helper(StockArticle, :supplier)
|
||||||
|
%dd= link_to stock_article.supplier.name, stock_article.supplier
|
||||||
|
%dt= heading_helper(StockArticle, :name)
|
||||||
|
%dd= stock_article.name
|
||||||
|
%dt= heading_helper(StockArticle, :unit)
|
||||||
|
%dd= stock_article.unit
|
||||||
|
%dt= heading_helper(StockArticle, :price)
|
||||||
|
%dd= number_to_currency stock_article.price
|
||||||
|
%dt= heading_helper(StockArticle, :tax)
|
||||||
|
%dd= number_to_percentage stock_article.tax
|
||||||
|
%dt= heading_helper(StockArticle, :deposit)
|
||||||
|
%dd= number_to_currency stock_article.deposit
|
||||||
|
%dt= heading_helper(StockArticle, :fc_price)
|
||||||
|
%dd= number_to_currency stock_article.fc_price
|
||||||
|
%dt= heading_helper(StockArticle, :article_category)
|
||||||
|
%dd= stock_article.article_category.name
|
||||||
|
%dt= heading_helper(StockArticle, :note)
|
||||||
|
%dd= stock_article.note
|
||||||
|
%dt= heading_helper(StockArticle, :quantity)
|
||||||
|
%dd= stock_article.quantity
|
||||||
|
%dt= heading_helper(StockArticle, :quantity_available)
|
||||||
|
%dd= stock_article.quantity_available
|
||||||
|
.form-actions
|
||||||
|
= link_to t('ui.edit'), edit_stock_article_path(stock_article), remote: true, class: 'btn'
|
9
app/views/stockit/copy.js.erb
Normal file
9
app/views/stockit/copy.js.erb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
$('#modalContainer').html('<%= j(render(
|
||||||
|
:partial => "form",
|
||||||
|
:locals => {
|
||||||
|
:title => t('.title'),
|
||||||
|
:stock_article => @stock_article
|
||||||
|
}
|
||||||
|
)) %>');
|
||||||
|
|
||||||
|
$('#modalContainer').modal();
|
15
app/views/stockit/create.js.erb
Normal file
15
app/views/stockit/create.js.erb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
$('div.container-fluid').prepend('<%= j(render(
|
||||||
|
:partial => 'shared/alert_success',
|
||||||
|
:locals => {
|
||||||
|
:alert_message => t('.notice', :name => @stock_article.name)
|
||||||
|
}
|
||||||
|
)) %>');
|
||||||
|
|
||||||
|
// Publish database changes.
|
||||||
|
// See publish/subscribe design pattern in /doc.
|
||||||
|
$(document).trigger({
|
||||||
|
type: 'StockArticle#create',
|
||||||
|
stock_article_id: <%= @stock_article.id %>
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#modalContainer').modal('hide');
|
13
app/views/stockit/destroy.js.erb
Normal file
13
app/views/stockit/destroy.js.erb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
$('div.container-fluid').prepend('<%= j(render(
|
||||||
|
:partial => 'shared/alert_success',
|
||||||
|
:locals => {
|
||||||
|
:alert_message => t('.notice', :name => @stock_article.name)
|
||||||
|
}
|
||||||
|
)) %>');
|
||||||
|
|
||||||
|
// Publish database changes.
|
||||||
|
// See publish/subscribe design pattern in /doc.
|
||||||
|
$(document).trigger({
|
||||||
|
type: 'StockArticle#destroy',
|
||||||
|
stock_article_id: <%= @stock_article.id %>
|
||||||
|
});
|
|
@ -1,8 +0,0 @@
|
||||||
-# please polish the following line if you know how, same in partial _destroy_fail
|
|
||||||
var successDiv = $('<div class="alert fade in alert-success"><a class="close" data-dismiss="alert" href="#">#{escape_javascript(t('ui.marks.close').html_safe)}</a></div>');
|
|
||||||
|
|
||||||
successDiv.append(document.createTextNode('#{escape_javascript(t('.notice', name: @article.name))}'));
|
|
||||||
$('div.container-fluid').prepend(successDiv);
|
|
||||||
|
|
||||||
$('#stockArticle-#{@article.id}').remove();
|
|
||||||
-# WARNING: Do not use a simple .fadeOut() above, because it conflicts with the show/hide function of unavailable articles.
|
|
|
@ -1,3 +0,0 @@
|
||||||
- title t('.title')
|
|
||||||
|
|
||||||
= render :partial => 'form', :locals => {:stock_article => @stock_article}
|
|
9
app/views/stockit/edit.js.erb
Normal file
9
app/views/stockit/edit.js.erb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
$('#modalContainer').html('<%= j(render(
|
||||||
|
:partial => "form",
|
||||||
|
:locals => {
|
||||||
|
:title => t('.title'),
|
||||||
|
:stock_article => @stock_article
|
||||||
|
}
|
||||||
|
)) %>');
|
||||||
|
|
||||||
|
$('#modalContainer').modal();
|
|
@ -3,6 +3,30 @@
|
||||||
:javascript
|
:javascript
|
||||||
$(function() {
|
$(function() {
|
||||||
$('tr.unavailable').hide();
|
$('tr.unavailable').hide();
|
||||||
|
|
||||||
|
// Subscribe to database changes.
|
||||||
|
// See publish/subscribe design pattern in /doc.
|
||||||
|
$(document).on('StockArticle#create', function(e) {
|
||||||
|
$.ajax({
|
||||||
|
url: '#{index_on_stock_article_create_stock_articles_path}',
|
||||||
|
type: 'get',
|
||||||
|
data: {id: e.stock_article_id},
|
||||||
|
contentType: 'application/json; charset=UTF-8'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('StockArticle#destroy', function(e) {
|
||||||
|
$('#stockArticle-' + e.stock_article_id).remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('StockArticle#update', function(e) {
|
||||||
|
$.ajax({
|
||||||
|
url: '#{index_on_stock_article_update_stock_articles_path}',
|
||||||
|
type: 'get',
|
||||||
|
data: {id: e.stock_article_id},
|
||||||
|
contentType: 'application/json; charset=UTF-8'
|
||||||
|
});
|
||||||
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
.well.well-small
|
.well.well-small
|
||||||
|
@ -17,7 +41,7 @@
|
||||||
.btn-group
|
.btn-group
|
||||||
= link_to_if @current_user.role_orders?, t('.order_online'), new_order_path(supplier_id: 0),
|
= link_to_if @current_user.role_orders?, t('.order_online'), new_order_path(supplier_id: 0),
|
||||||
class: 'btn', class: 'btn btn-primary'
|
class: 'btn', class: 'btn btn-primary'
|
||||||
= link_to t('.new_stock_article'), new_stock_article_path, class: 'btn'
|
= link_to t('.new_stock_article'), new_stock_article_path, remote: true, class: 'btn'
|
||||||
= link_to t('.new_stock_taking'), new_stock_taking_path, class: 'btn'
|
= link_to t('.new_stock_taking'), new_stock_taking_path, class: 'btn'
|
||||||
= link_to t('.show_stock_takings'), stock_takings_path, class: 'btn'
|
= link_to t('.show_stock_takings'), stock_takings_path, class: 'btn'
|
||||||
|
|
||||||
|
@ -42,22 +66,9 @@
|
||||||
%th= t '.article.supplier'
|
%th= t '.article.supplier'
|
||||||
%th= t '.article.category'
|
%th= t '.article.category'
|
||||||
%th
|
%th
|
||||||
%tbody
|
%tbody#articles-tbody
|
||||||
- for article in @stock_articles
|
- for stock_article in @stock_articles
|
||||||
%tr{:class => stock_article_classes(article), :id => "stockArticle-#{article.id}"}
|
= render :partial => 'stock_article', :locals => {:stock_article => stock_article}
|
||||||
%td= link_to article.name, article
|
|
||||||
%td= article.quantity
|
|
||||||
%td= article.quantity - article.quantity_available
|
|
||||||
%th= article.quantity_available
|
|
||||||
%td= article.unit
|
|
||||||
%td= article.price
|
|
||||||
%td= number_to_percentage article.tax
|
|
||||||
%td= link_to article.supplier.name, article.supplier
|
|
||||||
%td= article.article_category.name
|
|
||||||
%td
|
|
||||||
= link_to t('ui.edit'), edit_stock_article_path(article), class: 'btn btn-mini'
|
|
||||||
= link_to t('ui.delete'), article, :method => :delete, :confirm => t('.confirm_delete'),
|
|
||||||
class: 'btn btn-mini btn-danger', :remote => true
|
|
||||||
%p
|
%p
|
||||||
= t '.stock_worth'
|
= t '.stock_worth'
|
||||||
= number_to_currency StockArticle.stock_value
|
= number_to_currency StockArticle.stock_value
|
||||||
|
|
12
app/views/stockit/index_on_stock_article_create.js.erb
Normal file
12
app/views/stockit/index_on_stock_article_create.js.erb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// Handle more advanced DOM update after AJAX database manipulation.
|
||||||
|
// See publish/subscribe design pattern in /doc.
|
||||||
|
(function() {
|
||||||
|
var stock_article_row = $('<%= j(render(
|
||||||
|
:partial => 'stock_article',
|
||||||
|
:locals => {
|
||||||
|
:stock_article => @stock_article
|
||||||
|
}
|
||||||
|
)) %>');
|
||||||
|
|
||||||
|
$('#articles-tbody').prepend(stock_article_row);
|
||||||
|
})();
|
12
app/views/stockit/index_on_stock_article_update.js.erb
Normal file
12
app/views/stockit/index_on_stock_article_update.js.erb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// Handle more advanced DOM update after AJAX database manipulation.
|
||||||
|
// See publish/subscribe design pattern in /doc.
|
||||||
|
(function() {
|
||||||
|
var stock_article_row = $('<%= j(render(
|
||||||
|
:partial => 'stock_article',
|
||||||
|
:locals => {
|
||||||
|
:stock_article => @stock_article
|
||||||
|
}
|
||||||
|
)) %>');
|
||||||
|
|
||||||
|
$('#stockArticle-<%= @stock_article.id %>').replaceWith(stock_article_row);
|
||||||
|
})();
|
|
@ -1,22 +0,0 @@
|
||||||
- title t('.title')
|
|
||||||
|
|
||||||
- content_for :head do
|
|
||||||
:javascript
|
|
||||||
$(function() {
|
|
||||||
$('#article_search').autocomplete({
|
|
||||||
source: '#{articles_search_stock_articles_path}',
|
|
||||||
select: function(e, ui) {
|
|
||||||
alert(ui.item.value);
|
|
||||||
//location.href = '#{nil}' + ui.item.value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
/
|
|
||||||
TODO: Fix this
|
|
||||||
%p
|
|
||||||
= t '.search_text'
|
|
||||||
= text_field_tag 'article_search'
|
|
||||||
#stock_article_form
|
|
||||||
= render :partial => 'form', :locals => {:stock_article => @stock_article}
|
|
9
app/views/stockit/new.js.erb
Normal file
9
app/views/stockit/new.js.erb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
$('#modalContainer').html('<%= j(render(
|
||||||
|
:partial => "form",
|
||||||
|
:locals => {
|
||||||
|
:title => t('.title'),
|
||||||
|
:stock_article => @stock_article
|
||||||
|
}
|
||||||
|
)) %>');
|
||||||
|
|
||||||
|
$('#modalContainer').modal();
|
|
@ -1,32 +1,22 @@
|
||||||
- title @stock_article.name
|
- title @stock_article.name
|
||||||
|
- content_for :javascript do
|
||||||
|
:javascript
|
||||||
|
$(function() {
|
||||||
|
// Subscribe to database changes.
|
||||||
|
// See publish/subscribe design pattern in /doc.
|
||||||
|
$(document).on('StockArticle#update', function(e) {
|
||||||
|
$.ajax({
|
||||||
|
url: '#{show_on_stock_article_update_stock_articles_path}',
|
||||||
|
type: 'get',
|
||||||
|
data: {id: e.stock_article_id},
|
||||||
|
contentType: 'application/json; charset=UTF-8'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
.row-fluid
|
.row-fluid
|
||||||
.span6
|
.span6
|
||||||
%dl.dl-horizontal
|
= render :partial => 'stock_article_details', :locals => {:stock_article => @stock_article}
|
||||||
%dt= StockArticle.human_attribute_name 'supplier'
|
|
||||||
%dd= link_to @stock_article.supplier.name, @stock_article.supplier
|
|
||||||
%dt= StockArticle.human_attribute_name 'name'
|
|
||||||
%dd= @stock_article.name
|
|
||||||
%dt= StockArticle.human_attribute_name 'unit'
|
|
||||||
%dd= @stock_article.unit
|
|
||||||
%dt= StockArticle.human_attribute_name 'price'
|
|
||||||
%dd= number_to_currency @stock_article.price
|
|
||||||
%dt= StockArticle.human_attribute_name 'tax'
|
|
||||||
%dd= number_to_percentage @stock_article.tax
|
|
||||||
%dt= StockArticle.human_attribute_name 'deposit'
|
|
||||||
%dd= number_to_currency @stock_article.deposit
|
|
||||||
%dt= StockArticle.human_attribute_name 'fc_price'
|
|
||||||
%dd= number_to_currency @stock_article.fc_price
|
|
||||||
%dt= StockArticle.human_attribute_name 'article_category'
|
|
||||||
%dd= @stock_article.article_category.name
|
|
||||||
%dt= StockArticle.human_attribute_name 'note'
|
|
||||||
%dd= @stock_article.note
|
|
||||||
%dt= StockArticle.human_attribute_name 'quantity'
|
|
||||||
%dd= @stock_article.quantity
|
|
||||||
%dt= StockArticle.human_attribute_name 'quantity_available'
|
|
||||||
%dd= @stock_article.quantity_available
|
|
||||||
.form-actions
|
|
||||||
= link_to t('ui.edit'), edit_stock_article_path(@stock_article), class: 'btn'
|
|
||||||
|
|
||||||
.span6
|
.span6
|
||||||
%h2= t('.stock_changes')
|
%h2= t('.stock_changes')
|
||||||
|
|
13
app/views/stockit/show_on_stock_article_update.js.erb
Normal file
13
app/views/stockit/show_on_stock_article_update.js.erb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// Handle more advanced DOM update after AJAX database manipulation.
|
||||||
|
// See publish/subscribe design pattern in /doc.
|
||||||
|
(function() {
|
||||||
|
var stock_article_details = $('<%= j(render(
|
||||||
|
:partial => 'stock_article_details',
|
||||||
|
:locals => {
|
||||||
|
:stock_article => @stock_article
|
||||||
|
}
|
||||||
|
)) %>');
|
||||||
|
|
||||||
|
$('#stockArticleDetails').replaceWith(stock_article_details);
|
||||||
|
$('h1').first().text('<%= j(@stock_article.name) %>');
|
||||||
|
})();
|
15
app/views/stockit/update.js.erb
Normal file
15
app/views/stockit/update.js.erb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
$('div.container-fluid').prepend('<%= j(render(
|
||||||
|
:partial => 'shared/alert_success',
|
||||||
|
:locals => {
|
||||||
|
:alert_message => t('.notice', :name => @stock_article.name)
|
||||||
|
}
|
||||||
|
)) %>');
|
||||||
|
|
||||||
|
// Publish database changes.
|
||||||
|
// See publish/subscribe design pattern in /doc.
|
||||||
|
$(document).trigger({
|
||||||
|
type: 'StockArticle#update',
|
||||||
|
stock_article_id: <%= @stock_article.id %>
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#modalContainer').modal('hide');
|
|
@ -1348,7 +1348,7 @@ en:
|
||||||
units_to_order: If you change the total amount of delivered units, you also have to change individual group amounts by clicking on the article name. They will not be automatically recalculated and so ordergroups may be accounted for articles that were not delivered!
|
units_to_order: If you change the total amount of delivered units, you also have to change individual group amounts by clicking on the article name. They will not be automatically recalculated and so ordergroups may be accounted for articles that were not delivered!
|
||||||
update_current_price: Also update the price of the current order
|
update_current_price: Also update the price of the current order
|
||||||
stock_article:
|
stock_article:
|
||||||
copy_stock_article:
|
copy:
|
||||||
name: Please modify
|
name: Please modify
|
||||||
edit_stock_article:
|
edit_stock_article:
|
||||||
price: <ul><li>Price changes are forbidden.</li><li>If necessary, %{stock_article_copy_link}.</li></ul>
|
price: <ul><li>Price changes are forbidden.</li><li>If necessary, %{stock_article_copy_link}.</li></ul>
|
||||||
|
@ -1421,8 +1421,10 @@ en:
|
||||||
stockit:
|
stockit:
|
||||||
check:
|
check:
|
||||||
not_empty: ! '%{name} could not be deleted, the inventory is not zero.'
|
not_empty: ! '%{name} could not be deleted, the inventory is not zero.'
|
||||||
|
create:
|
||||||
|
notice: New stock article »%{name}« was created.
|
||||||
destroy:
|
destroy:
|
||||||
notice: Article %{name} was deleted.
|
notice: Article »%{name}« was deleted.
|
||||||
edit:
|
edit:
|
||||||
title: Edit stock articles
|
title: Edit stock articles
|
||||||
form:
|
form:
|
||||||
|
@ -1461,10 +1463,10 @@ en:
|
||||||
reason: Reason
|
reason: Reason
|
||||||
stock_changes: Stock quantity changes
|
stock_changes: Stock quantity changes
|
||||||
stock_taking: Inventory
|
stock_taking: Inventory
|
||||||
stock_create:
|
stock_article:
|
||||||
notice: Stock article was created.
|
confirm_delete: Are you sure you want to delete the stock article »%{name}«?
|
||||||
stock_update:
|
update:
|
||||||
notice: Stock article was saved.
|
notice: Stock article »%{name}« was saved.
|
||||||
suppliers:
|
suppliers:
|
||||||
create:
|
create:
|
||||||
notice: Supplier was created
|
notice: Supplier was created
|
||||||
|
|
|
@ -86,9 +86,15 @@ Foodsoft::Application.routes.draw do
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :stock_articles, :to => 'stockit' do
|
resources :stock_articles, :to => 'stockit' do
|
||||||
|
get :copy
|
||||||
collection do
|
collection do
|
||||||
get :articles_search
|
get :articles_search
|
||||||
get :fill_new_stock_article_form
|
get :fill_new_stock_article_form
|
||||||
|
|
||||||
|
get :index_on_stock_article_create
|
||||||
|
get :index_on_stock_article_update
|
||||||
|
|
||||||
|
get :show_on_stock_article_update
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
33
doc/design_patterns/publish_subscribe.md
Normal file
33
doc/design_patterns/publish_subscribe.md
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# Publish/subscribe pattern
|
||||||
|
## Handling DOM updates after AJAX database manipulation
|
||||||
|
|
||||||
|
As an example, let us consider the manipulation (create, update...) of `StockArticles`. This can be done in different views, e.g., `stock_articles/index`, `stock_articles/show` and `deliveries/_form` through modals using AJAX requests. As an advantage of the AJAX technique, the user does not need to reload the entire page. However, (after the update of the `StockArticle` in the database) it is generally required to update the DOM in the current view such that the page properly reacts to the asynchronous actions.
|
||||||
|
|
||||||
|
The process can be divided in two steps: **1.** AJAX database manipulation and **2.** DOM updates for the particular view. The crucial point is the coupling of the two steps since the controller for the first step offers the same functionality to all views and does not need to know anything about the current view.
|
||||||
|
|
||||||
|
1. AJAX database manipulation
|
||||||
|
1. Example: current view `deliveries/_form` offers a link for the AJAX action `StockArticle#new`. This opens a modal filled with `stock_articles/_form`.
|
||||||
|
2. AJAX form post addresses the `StockArticle#create` action which handles the database manipulation.
|
||||||
|
3. The database manipulation is finished by the rendering of, e.g., `stock_articles/create.js.erb`. The key task there is to **publish** the database changes by calling `trigger`, i.e.,
|
||||||
|
$(document).trigger({
|
||||||
|
type: 'StockArticle#create',
|
||||||
|
stock_article_id: <%= @stock_article.id %>
|
||||||
|
});
|
||||||
|
2. DOM updates for the particular view
|
||||||
|
1. Each view has the opportunity to **subscribe** to particular events of the previous step. A very simple example is the update of the `stock_articles/index` view after `StockArticle#destroy`:
|
||||||
|
$(document).on('StockArticle#destroy', function(e) {
|
||||||
|
$('#stockArticle-' + e.stock_article_id).remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
However, in most of the situations you will like to use the full power of the MVC framework in order to read new data from the database and render some partial. Let us consider this slightly more advanced case in the following.
|
||||||
|
|
||||||
|
The view `stock_articles/index` could listen (amongst others) to `StockArticle#create` like this:
|
||||||
|
$(document).on('StockArticle#create', function(e) {
|
||||||
|
$.ajax({
|
||||||
|
url: '#{index_on_stock_article_create_stock_articles_path}',
|
||||||
|
type: 'get',
|
||||||
|
data: {id: e.stock_article_id},
|
||||||
|
contentType: 'application/json; charset=UTF-8'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
2. The action `StockArticles#index_on_stock_article_create` is a special helper action to handle DOM updates of the `stock_articles/index` view after the creation of a new `StockArticle` with the given `id`.
|
Loading…
Reference in a new issue