diff --git a/Gemfile b/Gemfile
index 7cf43305..0f5ca329 100644
--- a/Gemfile
+++ b/Gemfile
@@ -21,6 +21,7 @@ group :assets do
gem 'therubyracer', :platforms => :ruby
gem 'uglifier', '>= 1.0.3'
+ gem 'mustache' #, :require => 'mustache/railtie'
end
gem 'jquery-rails'
@@ -44,7 +45,8 @@ gem 'kaminari-bootstrap'
# To use Jbuilder templates for JSON
# gem 'jbuilder'
group :development do
- gem 'pry'
+ gem 'pry'
+ gem 'pry-remote'
gem 'rspec-rails'
gem 'thin'
end
diff --git a/Gemfile.lock b/Gemfile.lock
index 3263f1b0..dd89859c 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -50,7 +50,7 @@ GEM
arel (3.0.2)
bcrypt-ruby (3.0.1)
builder (3.0.4)
- capybara (2.0.0)
+ capybara (2.0.1)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
@@ -97,7 +97,7 @@ GEM
factory_girl_rails (4.1.0)
factory_girl (~> 4.1.0)
railties (>= 3.0.0)
- ffi (1.1.5)
+ ffi (1.2.0)
fssm (0.2.9)
haml (3.1.7)
haml-rails (0.3.5)
@@ -124,7 +124,7 @@ GEM
actionpack (>= 3.1)
less (~> 2.2.0)
libv8 (3.3.10.4)
- libwebsocket (0.1.6)
+ libwebsocket (0.1.6.1)
websocket
mail (2.4.4)
i18n (>= 0.4.0)
@@ -135,6 +135,7 @@ GEM
mini_magick (3.4)
subexec (~> 0.2.1)
multi_json (1.3.7)
+ mustache (0.99.4)
nokogiri (1.5.5)
orm_adapter (0.0.7)
polyglot (0.3.3)
@@ -142,6 +143,9 @@ GEM
coderay (~> 1.0.5)
method_source (~> 0.8)
slop (~> 3.3.1)
+ pry-remote (0.1.6)
+ pry (~> 0.9)
+ slop (~> 3.0)
rack (1.4.1)
rack-cache (1.2)
rack (>= 0.4)
@@ -233,7 +237,7 @@ GEM
multi_json (~> 1.0, >= 1.0.2)
warden (1.1.1)
rack (>= 1.0)
- websocket (1.0.3)
+ websocket (1.0.4)
xpath (1.0.0)
nokogiri (~> 1.3)
@@ -253,7 +257,9 @@ DEPENDENCIES
kaminari-bootstrap
less-rails
mini_magick
+ mustache
pry
+ pry-remote
rack-cors
rails (= 3.2.9)
rqrcode
diff --git a/app/assets/javascripts/user/application.js.erb b/app/assets/javascripts/user/application.js.erb
index 9f38e5ff..0bbcd65e 100644
--- a/app/assets/javascripts/user/application.js.erb
+++ b/app/assets/javascripts/user/application.js.erb
@@ -27,6 +27,7 @@
//= require twitter/bootstrap/bootstrap-typeahead
//= require twitter/bootstrap/bootstrap-affix
//= require qwaiter
+//= require mustache
//= require_directory .
//= require_self
var path_mapping = {
@@ -176,9 +177,20 @@ $(function(){
container.show();
}
$('[data-t]').each(function(){$(this).text(t($(this).attr('data-t')))})
+ setTranslations();
});
function setLocale(locale){
QMobile.setLocale(locale);
$locale = locale;
- $('[data-t]').each(function(){$(this).text(t($(this).attr('data-t')))})
+ setTranslations();
+}
+function Qupdate(selector){
+ setTranslations(selector);
+}
+function setTranslations(selector){
+ if(selector){
+ $(selector).find('[data-t]').each(function(){$(this).text(t($(this).attr('data-t')))})
+ }else{
+ $('[data-t]').each(function(){$(this).text(t($(this).attr('data-t')))})
+ }
}
diff --git a/app/assets/javascripts/user/quser.js.coffee b/app/assets/javascripts/user/quser.js.coffee
index 83f20d68..c4d29bbc 100644
--- a/app/assets/javascripts/user/quser.js.coffee
+++ b/app/assets/javascripts/user/quser.js.coffee
@@ -175,31 +175,35 @@ window.Quser=
link.attr('href', root_url + src + '?'+authentication_string+'&page='+i)
li.append(link)
list.append(li)
+ mustache: (selector, locals)->
+ locs = $.extend(locals,
+ currency: ->
+ (val)->
+ currency(Mustache.render(val, this))
+ )
+ Mustache.to_html($(selector).html(), locs)
build_list_table: (body, foot, res) ->
body.find('tr').remove()
foot.find('tr').remove()
if !res.orders && !res.orders.length
alert('No orders in list')
return
- for order in res.orders
+ m_obj = res
+ for order in m_obj.orders
order_txts = []
- row = $('
').appendTo(body)
- row.addClass(order.state)
- #if(order.state == 'placed') row.addClass('info');
- #if(order.state == 'delivered') row.addClass('success');
- row.addClass('error') if order.state == 'cancelled'
for product in order.products
order_txts.push(product.name + ' (' + product['number'] + ')')
- row.append($(' | ').text(order_txts.join(', ')))
- row.append($(' | ').html(currency(order.total_amount)))
- foot.append(' | '+currency(res.total_amount)+' |
')
+ order.products_display = order_txts.join(', ')
+ body.append @mustache('#active-list-orders-template', m_obj)
+ foot.append @mustache('#active-list-orders-footer-template', m_obj)
+
order_selected_products: ()->
return if $.isEmptyObject(window.active_products_list)
h = {}
match = window.document.URL.toString().match('table_id=([0-9a-zA-Z]+)')
h['table_id'] = match[1] if match
- for product_id, info of window.active_products_list
- h['products['+product_id+']'] = info.number
+ for product_id, number of window.active_products_list
+ h['products['+product_id+']'] = number
$.post(data_host + '/user/order_selected_products', $.extend(h, authentication_object), ((res) -> Quser.handle_response(res)), 'json')
handle_response: (res) ->
if(typeof(res) == 'string')
@@ -215,21 +219,17 @@ window.Quser=
else
redirect_to res.location || 'list_products' if res['ok']
build_product_list: ->
- table = $('#active-order-table')
- tbody = table.find('tbody')
- tbody = $('').appendTo(table) unless tbody.length
- tbody.find('tr').remove()
total = 0.0
- for product_id, info of window.active_products_list
- total += info.product.price * info.number
- row = $('
').attr('id', 'active-order-row-'+product_id).appendTo(tbody)
- row.append(''+info.product.name+' | ')
- row.append(''+info.number+' | ')
- row.append(''+currency(info.product.price * info.number)+' | ')
- x_btn = $('').click(-> delete(window.active_products_list[product_id]) && Quser.build_product_list() )
- row.append($(' | ').append(x_btn))
- $('#active-order-total').html(currency(total))
- table.show()
+ h = {products: []}
+ for product_id, number of window.active_products_list
+ product = window.products[product_id]
+ product.number = number
+ product.product_total = product.price * number
+ h.products.push product
+ total += product.price * number
+ h.total = total
+ $('#active-order-container').html @mustache('#active-order-template', h)
+ Qupdate('#active-order-container')
load_active_list_products: ->
Quser.populate_products_table('/user/list_products.json?'+authentication_string)
@@ -256,40 +256,39 @@ window.Quser=
if res.supplier_name
$('.supplier-name').text(res.supplier_name)
delete(res['supplier_name'])
+ window.products = {}
body.find('tr').remove()
+ script_id = if include_order_buttons then '#products-category-for-order-template' else '#products-category-template'
for category, products of res
- body.append(''+category+' |
')
+ body.append Quser.mustache(script_id,
+ category: category,
+ products: products,
+ include_order_buttons: include_order_buttons
+ )
for product in products
- row = $('
')
- row.append(''+product.name+' | ')
- if include_order_buttons
- button = $('')
- callback = ((prod) ->
- ->
- product_count_holder = $('#order-product-count-'+prod._id)
- count = parseInt(product_count_holder.text())
- product_count_holder.text(1)
- Quser.add_product(prod, count)
- )(product)
- button.click(callback)
- order_product_count = $('1')
- order_count_minus = $('-')
- order_count_minus.click(->
- val_holder = $(this).siblings('.order-product-count')
- val = parseInt(val_holder.text())
- val_holder.text(val - 1) if val > 1
- )
- order_count_plus = $('+')
- order_count_plus.click(->
- val_holder = $(this).siblings('.order-product-count')
- val = parseInt(val_holder.text())
- val_holder.text(val + 1)
- )
- row.append($(' | ').append(order_count_minus).append(' ').append(order_product_count).append(' ').append(order_count_plus))
- row.append(''+currency(product.price)+' | ')
- row.append($(' | ').append(button)) if include_order_buttons
- body.append(row)
+ window.products[product._id] = product
)
+ increment_products_counter: (product_id)->
+ product_count_holder = $('#order-product-count-'+product_id)
+ count = parseInt(product_count_holder.text())
+ product_count_holder.text(count + 1)
+ false
+ lower_products_counter: (product_id)->
+ product_count_holder = $('#order-product-count-'+product_id)
+ count = parseInt(product_count_holder.text())
+ product_count_holder.text(count - 1)
+ false
+ add_product_to_order: (product_id, context) ->
+ product_count_holder = $('#order-product-count-'+product_id)
+ count = parseInt(product_count_holder.text())
+ count ||= 1
+ product_count_holder.text(1)
+ window.active_products_list ||= {}
+ window.active_products_list[product_id] ||= 0
+ window.active_products_list[product_id] += count
+ delete(window.active_products_list[product_id]) if window.active_products_list[product_id] < 1
+ Quser.build_product_list()
+ false
actions_for_table: (table)->
table = JSON.parse(table) if typeof(table) == 'string'
$.getJSON(data_host + '/user/table_info.json?'+authentication_string+'&table_id='+table.table_id, (res)->
@@ -357,11 +356,11 @@ window.Quser=
else
redirect_to 'user_root', {message: 'join_request_rejected'}
)
- add_product: (product, count) ->
+ add_product: (product_id, count) ->
count ||= 1
- window.active_products_list = {} unless window.active_products_list
- window.active_products_list[product._id] = {product: product, number: 0} unless window.active_products_list[product._id]
- window.active_products_list[product._id].number += count
+ window.active_products_list ||= {}
+ window.active_products_list[product_id] ||= 0
+ window.active_products_list[product_id] += count
Quser.build_product_list()
clear_selected_products: ->
window.active_products_list = {}
diff --git a/app/templates/user/_active_list_orders.mustache b/app/templates/user/_active_list_orders.mustache
new file mode 100644
index 00000000..8e2d7a2a
--- /dev/null
+++ b/app/templates/user/_active_list_orders.mustache
@@ -0,0 +1,6 @@
+{{#orders}}
+
+ | {{products_display}} |
+ {{#currency}}{{total_amount}}{{/currency}} |
+
+{{/orders}}
diff --git a/app/templates/user/_active_list_orders_footer.mustache b/app/templates/user/_active_list_orders_footer.mustache
new file mode 100644
index 00000000..403b0f47
--- /dev/null
+++ b/app/templates/user/_active_list_orders_footer.mustache
@@ -0,0 +1 @@
+ | {{#currency}}{{total_amount}}{{/currency}} |
diff --git a/app/templates/user/_active_order.mustache b/app/templates/user/_active_order.mustache
new file mode 100644
index 00000000..5eb0a618
--- /dev/null
+++ b/app/templates/user/_active_order.mustache
@@ -0,0 +1,29 @@
+
+
+
+ |
+ # |
+ |
+ |
+
+
+
+ {{#products}}
+
+ | {{name}} |
+ {{number}} |
+ {{#currency}}{{product_total}}{{/currency}} |
+
+ {{/products}}
+
+
+
+ |
+
+
+ |
+ {{#currency}}{{total}}{{/currency}} |
+ |
+
+
+
diff --git a/app/templates/user/_products_category.mustache b/app/templates/user/_products_category.mustache
new file mode 100644
index 00000000..87543de1
--- /dev/null
+++ b/app/templates/user/_products_category.mustache
@@ -0,0 +1,7 @@
+{{category}} |
+{{#products}}
+
+ | {{name}} |
+ {{#currency}}{{price}}{{/currency}} |
+
+{{/products}}
diff --git a/app/templates/user/_products_category_for_order.mustache b/app/templates/user/_products_category_for_order.mustache
new file mode 100644
index 00000000..eddbf7c6
--- /dev/null
+++ b/app/templates/user/_products_category_for_order.mustache
@@ -0,0 +1,13 @@
+{{category}} |
+{{#products}}
+
+ | {{name}} |
+
+ -
+ 1
+ +
+ |
+ {{#currency}}{{price}}{{/currency}} |
+ |
+
+{{/products}}
diff --git a/app/views/layouts/phone.html.slim b/app/views/layouts/phone.html.slim
index 0a915209..3f964ad1 100644
--- a/app/views/layouts/phone.html.slim
+++ b/app/views/layouts/phone.html.slim
@@ -17,7 +17,7 @@ html lang="en"
link href="/images/apple-touch-icon.png" rel="apple-touch-icon-precomposed"
link href="/favicon.ico" rel="shortcut icon"
javascript:
- var data_host = '#{Rails.env == 'development' ? 'http://localhost:3000' : 'http://data.qwaiter.com' }';
+ var data_host = '#{Rails.env == 'development' ? 'http://qwaiter.dev' : 'http://data.qwaiter.com' }';
//var data_host = 'http://localhost:3000';
//data_host = 'http://192.168.1.148:3000';
var $locale = 'en';
diff --git a/app/views/user/active_list.html.slim b/app/views/user/active_list.html.slim
index 9d3a98e3..56972a35 100644
--- a/app/views/user/active_list.html.slim
+++ b/app/views/user/active_list.html.slim
@@ -16,6 +16,8 @@
tr
td colspan=2 = slider_image
tfoot
+script#active-list-orders-template[type="text/html"]= render 'active_list_orders.mustache'
+script#active-list-orders-footer-template[type="text/html"]= render 'active_list_orders_footer.mustache'
- content_for :footer do
javascript:
jQuery(function(){
diff --git a/app/views/user/list_products.html.slim b/app/views/user/list_products.html.slim
index 9affe714..dee36534 100644
--- a/app/views/user/list_products.html.slim
+++ b/app/views/user/list_products.html.slim
@@ -11,23 +11,10 @@
tbody
tr
td= slider_image
- table#active-order-table.table.hide
- thead
- tr
- th data-t="models.product"= Product.model_name.human
- th #
- th.currency data-t="basket.total"= t('user.basket.total')
- th
- tbody
- tfoot
- tr
- td colspan=2
- button class="btn btn-primary" onClick="Quser.handle_active_list(function(){Quser.order_selected_products()})" data-t="selected_products.order"= t('selected_products.order')
- |
- button class="btn btn btn-warning" onClick="Quser.clear_selected_products()" data-t="selected_products.clear"= t('selected_products.clear')
- td.currency
- strong#active-order-total
- td
+ #active-order-container
+script#products-category-template[type="text/html"]= render 'products_category.mustache'
+script#products-category-for-order-template[type="text/html"]= render 'products_category_for_order.mustache'
+script#active-order-template[type="text/html"]= render 'active_order.mustache'
- content_for :footer do
javascript:
jQuery(function(){
diff --git a/app/views/user/list_products_for_table.html.slim b/app/views/user/list_products_for_table.html.slim
index 57ead7e0..ceb3852b 100644
--- a/app/views/user/list_products_for_table.html.slim
+++ b/app/views/user/list_products_for_table.html.slim
@@ -24,6 +24,8 @@
td.currency
strong#active-order-total
td
+script#products-category-template[type="text/html"]= render 'products_category.mustache'
+script#products-category-for-order-template[type="text/html"]= render 'products_category_for_order.mustache'
- content_for :footer do
javascript:
jQuery(function(){
diff --git a/config/initializers/mustache_template_handler.rb b/config/initializers/mustache_template_handler.rb
new file mode 100644
index 00000000..2eb3f77f
--- /dev/null
+++ b/config/initializers/mustache_template_handler.rb
@@ -0,0 +1,11 @@
+module MustacheTemplateHandler
+ def self.call(template)
+ if template.locals.include? :locals
+ "Mustache.render(#{template.source.inspect}, locals).html_safe"
+ else
+ "#{template.source.inspect}.html_safe"
+ end
+ end
+end
+ActionView::Template.register_template_handler(:mustache, MustacheTemplateHandler)
+ActionController::Base.view_paths << Rails.root.join('app', 'templates')
diff --git a/vendor/assets/javascripts/mustache.js b/vendor/assets/javascripts/mustache.js
new file mode 100644
index 00000000..0148d29d
--- /dev/null
+++ b/vendor/assets/javascripts/mustache.js
@@ -0,0 +1,625 @@
+/*!
+ * mustache.js - Logic-less {{mustache}} templates with JavaScript
+ * http://github.com/janl/mustache.js
+ */
+
+/*global define: false*/
+
+var Mustache;
+
+(function (exports) {
+ if (typeof module !== "undefined" && module.exports) {
+ module.exports = exports; // CommonJS
+ } else if (typeof define === "function") {
+ define(exports); // AMD
+ } else {
+ Mustache = exports; //