diff --git a/app/assets/javascripts/jquery.ui.datepicker.monthyearpicker.js b/app/assets/javascripts/jquery.ui.datepicker.monthyearpicker.js new file mode 100644 index 0000000..4311ac6 --- /dev/null +++ b/app/assets/javascripts/jquery.ui.datepicker.monthyearpicker.js @@ -0,0 +1,400 @@ +/* +Month and Year picker for jQuery UI Datepicker 1.8.21 + +Written by Anton Ludescher (silverskater{at}gmail.com). +Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and +MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. */ + +if (datepicker == undefined){ + var datepicker_fn = $.fn.datepicker + var datepicker = $.datepicker +} +(function($, undefined ) { + + //overriding functions meant to be private (starting with an underscore) + $.ui_datepicker = datepicker + $.fn.ui_datepicker = datepicker_fn + $.ui_datepicker._updateDatepicker_MonthYearPicker = $.ui_datepicker._updateDatepicker; + $.ui_datepicker._showDatepicker_MonthYearPicker = $.ui_datepicker._showDatepicker; + $.ui_datepicker._doKeyDown_MonthYearPicker = $.ui_datepicker._doKeyDown; + + $.extend($.ui_datepicker, { + _doKeyDown: function(event) { + var inst = $.ui_datepicker._getInst(event.target); + var handled = true; + //var isRTL = inst.dpDiv.is('.ui-datepicker-rtl'); + inst._keyEvent = true; + if ($.ui_datepicker._datepickerShowing) { + switch (event.keyCode) { + case 27: + if($('.ui-datepicker-select-month').is(':visible')) { + $.ui_datepicker._updateDatepicker(inst); + } + else if($('.ui-datepicker-select-year').is(':visible')) { + $.ui_datepicker._toggleDisplay_MonthYearPicker(inst, 2, this); + } + else { + $.ui_datepicker._hideDatepicker(); + } + break; // hide on escape + //TODO prev/next month/year on month/year picker screens + default: + //call the original function + $.ui_datepicker._doKeyDown_MonthYearPicker(event); + } + } + else { + //call the original function + $.ui_datepicker._doKeyDown_MonthYearPicker(event); + } + }, + + _updateDatepicker: function(inst) { + //call the original function + if (this._get(inst, 'show_view') == 'year' && !$('.ui-datepicker-select-year').is(':visible')){ + var current_format = this._get(inst, 'dateFormat') + var regex = /\W/, indice = 0; + var result = current_format.split(/\W/) + for (var i=0;i').append(this.dpDiv.clone()).html()); + + var uidptitle = inst.dpDiv.find('.ui-datepicker-title'); + var uidptitle_link = uidptitle.wrapInner(''); + uidptitle_link.click(function(){$.ui_datepicker.select_month = false;$.ui_datepicker._toggleDisplay_MonthYearPicker('#' + inst.id, 2); return false;}); + inst.dpDiv.children('table.ui-datepicker-calendar').after(this._generateExtraHTML_MonthYearPicker(inst)); + if (!$('.ui-datepicker-select-year').is(':visible') && !$('.ui-datepicker-select-month').is(':visible')){ + if (this._get(inst, 'show_view') == 'month') + { + this._toggleDisplay_MonthYearPicker('#' + inst.id,2) + }else if (this._get(inst, 'show_view') == 'year'){ + this._toggleDisplay_MonthYearPicker('#' + inst.id,3) + } + } + this._reposition_MonthYearPicker(inst); + }, + + //focus the date input field + _instInputFocus_MYP: function(inst) { + //code copied from datePicker's _updateDatepicker() + if (inst == $.ui_datepicker._curInst && $.ui_datepicker._datepickerShowing && inst.input && + // #6694 - don't focus the input if it's already focused + // this breaks the change event in IE + inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement) + inst.input.focus(); + + }, + + _generateMonthPickerHTML_MonthYearPicker: function(inst, minDate, maxDate, drawMonth, inMinYear, inMaxYear) { + //TODO RTL? + var monthNamesShort = this._get(inst, 'monthNamesShort'); + + var monthPicker = ''; + + var unselectable = false; + for (var month = 0; month < 12; ) { + unselectable = (inMinYear && month < minDate.getMonth()) || + (inMaxYear && month > maxDate.getMonth()); + monthPicker += ''; // display selectable date + + if(++month % 4 === 0) { + monthPicker += ''; + if(month != 12) { + monthPicker += ''; + } + } + } + monthPicker += '
' + // actions + ((unselectable ? '' + monthNamesShort[month] + '' : '' + monthNamesShort[month] + '')) + '
'; + + return monthPicker; + }, + + _generateExtraHTML_MonthYearPicker: function(inst,show_view) { + if (show_view != 'year'){ + var minDate = this._getMinMaxDate(inst, 'min'); + var maxDate = this._getMinMaxDate(inst, 'max'); + var drawYear = inst.drawYear; + var drawMonth = inst.drawMonth; + var inMinYear = (minDate && minDate.getFullYear() == drawYear); + var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); + var monthPicker = this._generateMonthPickerHTML_MonthYearPicker(inst, minDate, maxDate, drawMonth, inMinYear, inMaxYear); + if (show_view != 'month'){ + return '' + + ''; //yearPicker gets filled dinamically + } + else{ + return '
' + monthPicker + '
' + + ''; + } + } + else{ + return '' + + '
'; + } + }, + + _pickMonthYear_MonthYearPicker: function(id, valueMY, period) { + var dummySelect = $('" + field_html = " + + #{multi_lang_tag} + #{require_ask_tag} + #{field_select_tag}
+ #{multi_lang_prompt_tag} + #{time_setting_block(k,v)} + #{tmp} + #{key} + + + #{create_delete_button('delete_field_func')} + + " + end + def create_delete_button(func_name) + "" + end def page_for_askquestion(askquestion) ann_page = nil pages = Page.where(:module=>'ask') diff --git a/app/models/ask_question.rb b/app/models/ask_question.rb index 82b71b0..2f8356d 100644 --- a/app/models/ask_question.rb +++ b/app/models/ask_question.rb @@ -21,7 +21,7 @@ class AskQuestion field :situation, type: String, default: "is_waiting" #預設待處理 field :send_email, type: Boolean, default: false field :email_id - + field :custom_values, type: Hash,default: {} # validates_presence_of :name, :identity, :mail, :title, :content def email diff --git a/app/models/ask_setting.rb b/app/models/ask_setting.rb new file mode 100644 index 0000000..81f7677 --- /dev/null +++ b/app/models/ask_setting.rb @@ -0,0 +1,19 @@ +class AskSetting + include Mongoid::Document + include Mongoid::Timestamps + after_initialize do + if default_setting.class != Hash + default_setting = {} + end + if custom_fields.class != Hash + custom_fields = {} + end + self.save + end + def custom_fields + tmp = super + tmp.select{|k,v| v['delete'] != true} + end + field :default_setting, type: Hash,default: {ask_category_id: true,name: true,sex: false,mail: true,phone: false,appointment: false,recaptcha: false} + field :custom_fields, type: Hash,default: {} +end diff --git a/app/models/ask_setting_index.rb b/app/models/ask_setting_index.rb new file mode 100644 index 0000000..039f7d9 --- /dev/null +++ b/app/models/ask_setting_index.rb @@ -0,0 +1,5 @@ +class AskSettingIndex + include Mongoid::Document + include Mongoid::Timestamps + field :key,type: Integer,default: 0 +end diff --git a/app/views/admin/asks/_form.html.erb b/app/views/admin/asks/_form.html.erb index 5ce06b7..9129026 100644 --- a/app/views/admin/asks/_form.html.erb +++ b/app/views/admin/asks/_form.html.erb @@ -1,11 +1,36 @@ +<% + ask_setting = AskSetting.first + set_input_name('ask_question') +%> <% content_for :page_specific_css do %> <%= stylesheet_link_tag "lib/main-forms" %> <%= stylesheet_link_tag "lib/main-list" %> <% end %> -<% content_for :page_specific_javascript do %> - <%= javascript_include_tag "lib/module-area" %> -<% end %> - +<%# javascript_include_tag "lib/bootstrap-datetimepicker.js" %> +<%# javascript_include_tag "//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"%> +<%= javascript_include_tag "/assets/lib/jquery-ui-1.12.1/jquery-ui.min" %> +<%# javascript_include_tag "lib/module-area" %> +<%= javascript_include_tag "jquery.ui.datepicker.monthyearpicker" %> +<%# javascript_include_tag "lib/bootstrap-datetimepicker" %> +
@@ -21,7 +46,7 @@ - + @@ -55,6 +80,15 @@
<%= AskQuestion.human_attribute_name(:appointment) %>:<%= @ask_question.appointment.strftime("%Y-%m-%d %H:%M") %><%= AskQuestion.human_attribute_name(:appointment) %>:<%= @ask_question.appointment.strftime("%Y-%m-%d %H:%M") rescue nil %>
+ <%= ask_setting.custom_fields.collect do |k,v| + required_pattern = v['required']=='true' ? '*' : '' + "
+ +
+ #{show_on_front(k,v,@ask_question.custom_values[k])} +
+
" + end.join.html_safe %>
diff --git a/app/views/admin/asks/_index.html.erb b/app/views/admin/asks/_index.html.erb index 10f8a41..c75c7b0 100644 --- a/app/views/admin/asks/_index.html.erb +++ b/app/views/admin/asks/_index.html.erb @@ -42,7 +42,7 @@ <%= b.phone %> - <%= b.appointment.strftime("%Y-%m-%d %H:%M") %> + <%= b.appointment.strftime("%Y-%m-%d %H:%M") rescue nil %> <% end %> diff --git a/app/views/admin/asks/setting.html.erb b/app/views/admin/asks/setting.html.erb new file mode 100644 index 0000000..a255762 --- /dev/null +++ b/app/views/admin/asks/setting.html.erb @@ -0,0 +1,145 @@ +<% + set_input_name('ask_setting[custom_fields]') +%> + + +<%= form_for @ask_setting,method: 'post',url: @url,html: { class: 'form-horizontal main-forms previewable' } do |f| %> +
+ + + + + + + + + <% @ask_setting.default_setting.each do |k,v| %> + + + + + <% end %> + <% @ask_setting.custom_fields.each do |k,v| %> + <%= custom_field_block(k,v).html_safe %> + <% end %> + + + + + + + +
+ <%= t('ask.field') %> + + <%= t('ask.whether_open') %> +
+ <%= t("mongoid.attributes.ask_question.#{k}") %> + + <%= f.select "default_setting[#{k}]",[[t('yes'),'true'],[t('no'),false]] ,selected: v %> +
+ +
+ <%= hidden_field_tag :delete_field, nil,{'class'=> 'delete_field' } %> + <%= f.hidden_field :id, value: @ask_setting.id %> + +
+
+<% end %> \ No newline at end of file diff --git a/app/views/asks/index.html.erb b/app/views/asks/index.html.erb index 8515066..e2a72e9 100644 --- a/app/views/asks/index.html.erb +++ b/app/views/asks/index.html.erb @@ -3,6 +3,9 @@ @categories = data["categories"] @tags = data["tags"] @module_app = data["module_app"] + ask_setting = AskSetting.first + ask_setting = AskSetting.create() if ask_setting.nil? + set_input_name('ask_question') %> <%= stylesheet_link_tag "basic/bootstrap-datetimepicker" %> @@ -10,48 +13,122 @@ .default_picker label{ display: none; } + .ask-question .control-group{ + flex-wrap: wrap; + display: inline-flex; + width: 100%; + align-items: center; + } + .ask-question .controls > *{ + display: block; + } + .ask-question .controls > script{ + display: none; + } + .ask-question .form-horizontal .control-label{ + width: 24%; + max-width: 15em; + min-width: 14em; + padding: 0; + text-align: center; + } + .ask-question .form-horizontal .control-group .controls{ + margin: 0; + display: inline-flex; + align-items: center; + overflow: hidden; + position: relative; + min-width: 10em; + max-width: 20em; + padding-left: 0; + width: 70%; + padding: 0.5em; + justify-content: center; + } + .ask-question .form-horizontal input[type="text"],.ask-question .form-horizontal select{ + width: 97%; + max-width: 13.75em; + } + .ask-question .form-horizontal .form-actions{ + position: relative; + padding: 1em 0 0 0; + text-align: center; + } + .time_selector{ + display: inline-flex; + } + @media (max-width: 768px){ + .ask-question .control-group{ + justify-content: center; + } + .time_selector{ + display: inline-flex; + } + .datetime_selector{ + flex-direction: column; + } + } - +<%= javascript_include_tag "/assets/lib/jquery-ui-1.12.1/jquery-ui.min" %> +<%= stylesheet_link_tag "/assets/lib/jquery-ui-1.12.1/jquery-ui.min" %> + <%= javascript_include_tag "lib/bootstrap-datetimepicker" %> -<%= javascript_include_tag "lib/datetimepicker/datetimepicker.js" %> - - +<%= javascript_include_tag "jquery.ui.datepicker.monthyearpicker" %> <%= javascript_include_tag 'validator' %>
<%= form_for @ask_question, url: asks_path, html: {class: 'form-horizontal'} do |f| %> -
- <%= f.label :ask_category_id, class: 'control-label required' %> -
- <%= f.select :category_id, @categories.collect{|t| [ t.title, t.id ]} %> + <% if ask_setting.default_setting['ask_category_id'] %> +
+ <%= f.label :ask_category_id, class: 'control-label required' %> +
+ <% if @categories.count > 1 %> + <%= f.select :category_id, @categories.collect{|t| [ t.title, t.id ]} %> + <% else %> + + <%= @categories[0].title rescue '' %> + + <%= f.hidden_field :category_id, :value => (@categories[0].id.to_s rescue nil) %> + <% end %> +
-
+ <% elsif @categories.count == 1 %> + <%= f.hidden_field :category_id, :value => (@categories[0].id.to_s rescue nil) %> + <% end %> -
- <%= f.label :name, class: 'control-label required' %> -
- <%= f.text_field :name, data: {"fv-validation" => "required;", "fv-messages" => "必填欄位;"} %> + <% if ask_setting.default_setting['name'] %> +
+ <%= f.label :name, class: 'control-label required' %> +
+ <%= f.text_field :name, data: {"fv-validation" => "required;", "fv-messages" => "必填欄位;"} %> +
-
+ <% end %> -
- <%= f.label :sex, class: 'control-label required' %> -
- - + <% if ask_setting.default_setting['sex'] %> +
+ <%= f.label :sex, class: 'control-label required' %> +
+ + +
-
+ <% end %> @@ -62,49 +139,63 @@
-
- <%= f.label :phone, class: 'control-label' %> -
- <%= f.text_field :phone %> + <% if ask_setting.default_setting['phone'] %> +
+ <%= f.label :phone, class: 'control-label' %> +
+ <%= f.text_field :phone %> +
-
+ <% end %> -
- <%= f.label :appointment, class: 'control-label' %> -
- <%= f.datetime_picker :appointment %> + <% if ask_setting.default_setting['appointment'] %> +
+ <%= f.label :appointment, class: 'control-label' %> +
+ <%= f.datetime_picker :appointment %> +
-
+ <% end %> -
- <%= f.label :recaptcha, class: 'control-label' %> -
- <%= gotcha_error %> - <%= gotcha %> + <%= ask_setting.custom_fields.collect do |k,v| + required_pattern = v['required']=='true' ? '*' : '' + "
+ +
+ #{show_on_front(k,v)} +
+
" + end.join.html_safe %> + <% if ask_setting.default_setting['recaptcha'] %> +
+ <%= f.label :recaptcha, class: 'control-label' %> +
+ <%= gotcha_error %> + <%= gotcha %> +
-
- + <% end %>
"> <%= f.submit t('submit'), class: 'btn btn-primary', :id => 'button-mail' %> diff --git a/app/views/layouts/back_end_with_jquery_first.html.erb b/app/views/layouts/back_end_with_jquery_first.html.erb new file mode 100644 index 0000000..d492eeb --- /dev/null +++ b/app/views/layouts/back_end_with_jquery_first.html.erb @@ -0,0 +1,8 @@ +<%= javascript_include_tag "//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"%> +<%= javascript_include_tag "/assets/lib/jquery-ui-1.12.1/jquery-ui.min" %> + +<%= render :template => 'layouts/back_end' %> \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index b1294df..ce9988b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -5,6 +5,19 @@ en: is_referral: Rreferral sex: Sex ask: + 'yes': 'Yes' + 'no': 'No' + required: Required + datepicker: Select a Date + enable_range_setting: Enable Time Range Setting + format: Format + add_new_options: Add new options + field: Field + prompt_word: Prompt Word + option_name: Option Name + field_name: Field Name + whether_open: Whether to open it + setting: Setting ask: Ask all_articles: All exports: Export @@ -26,7 +39,21 @@ en: mongoid: attributes: ask_question: + ask_category_id: Ask Category + recaptcha: Recaptcha + sex: Sex + name: Name + identity: Identity + mail: Email + phone: Phone male: Man female: Woman - ask_category_id: Ask Category - identity: Identity \ No newline at end of file + appointment: Appointment time + fax: Fax + title: Title + reply: Reply + created_at: Time + content: Content + comment: Comment + status: Status + send_email: Whether to reply email \ No newline at end of file diff --git a/config/locales/zh_tw.yml b/config/locales/zh_tw.yml index c53e619..54a2692 100644 --- a/config/locales/zh_tw.yml +++ b/config/locales/zh_tw.yml @@ -11,6 +11,19 @@ zh_tw: errors: verification_failed: 驗證碼錯誤 ask: + 'yes': 是 + 'no': 否 + required: 必填 + datepicker: 選擇日期 + enable_range_setting: 啟用時間區段設定 + format: 格式 + add_new_options: 新增選項 + field: 欄位 + prompt_word: 提示文字 + option_name: 選項名稱 + field_name: 欄位名稱 + whether_open: 是否開啟 + setting: 設定 name: 預約客戶 appointment: 預約時間 created_at: 發問時間 @@ -44,7 +57,7 @@ zh_tw: sex: 性別 name: 姓名 identity: 身份 - mail: Email + mail: 電子信箱 phone: 聯絡電話 male: 男 female: 女 diff --git a/config/routes.rb b/config/routes.rb index ab02daa..2989470 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -6,6 +6,9 @@ Rails.application.routes.draw do resources :asks do collection do get 'export' + get 'setting' + post 'setting_save' + post 'get_new_setting_index' post 'export', to: 'asks#do_export' end end diff --git a/lib/ask/engine.rb b/lib/ask/engine.rb index 78622da..bf5c7cd 100644 --- a/lib/ask/engine.rb +++ b/lib/ask/engine.rb @@ -1,6 +1,18 @@ module Ask class Engine < ::Rails::Engine initializer "ask" do + begin + require File.expand_path('../../../app/models/ask_setting', __FILE__) + require File.expand_path('../../../app/models/ask_setting_index', __FILE__) + if defined? AskSetting && AskSetting.first.nil? + AskSetting.create() + end + if defined? AskSettingIndex && AskSettingIndex.first.nil? + AskSettingIndex.create() + end + rescue => e + puts ['AskSetting not found',e] + end OrbitApp.registration "Ask", :type => "ModuleApp" do module_label "ask.ask" base_url File.expand_path File.dirname(__FILE__) @@ -23,6 +35,11 @@ module Ask :priority=>1, :active_for_action=>{'admin/asks'=>'index'}, :available_for => 'users' + context_link 'ask.setting', + :link_path=>"setting_admin_asks_path" , + :priority=>5, + :active_for_action=>{'admin/asks'=>'setting'}, + :available_for => 'managers' context_link 'categories', :link_path=>"admin_module_app_categories_path" , :link_arg=>"{:module_app_id=>ModuleApp.find_by(:key=>'ask').id}",