#-- # Copyright (c) 2012+ Damjan Rems # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #++ module DrgcmsFormFields ########################################################################### # Implementation of text_autocomplete DRG CMS form field. # # ===Form options: # * +name:+ field name (required) # * +type:+ text_autocomplete (required) # * +table+ Collection (table) name. When defined search must contain field name # * +with_new+ Will add an icon for shortcut to add new document to related collection # * +with_edit+ Will add an icon for shortcut to edit (view) related document # * +is_id+ Field value represent value as id. If false, field will use entered value and not value selected with autocomplete. Default is true. # * +search:+ Search may consist of three parameters from which are separated either by dot (.) # * search_field_name; when table option is defined search must define field name which will be used for search query # * collection_name.search_field_name; Same as above except that table options must be ommited. # * collection_name.search_field_name.method_name; When searching is more complex custom search # method may be defined in CollectionName model which will provide result set for search. # # Form example: # 10: # name: user_id # type: text_autocomplete # search: dc_user.name # is_id: false # size: 30 # with_new: user # with_edit: user ########################################################################### class TextAutocomplete < DrgcmsField ########################################################################### # Render text_autocomplete field html code ########################################################################### def render # Return descriptive text and put it into input field # search field name if @yaml['search'].class == Hash table = @yaml['search']['table'] ret_name = @yaml['search']['field'] method = @yaml['search']['method'] elsif @yaml['search'].match(/\.|\,| /) table, ret_name, method = @yaml['search'].split(/\.|\,| /).map(&:strip) else ret_name = @yaml['search'] end # determine table name if @yaml['table'] table = if @yaml['table'].class == String @yaml['table'] elsif @yaml['table']['eval'] eval @yaml['table']['eval'] else Rails.logger.error "Field #{ @yaml['name'] }: Invalid table parameter!" nil end end return ro_standard 'Table or field keyword not defined!' unless (table && ret_name) # TODO check if table exists model_klass = table.classify.constantize # find record and return value of field value_send_as = 'p_' + @yaml['name'] value = if @parent.params[value_send_as] @parent.params[value_send_as] elsif @record && @record[@yaml['name']] @record[@yaml['name']] end not_id = @parent.dc_dont?(@yaml['is_id'], false) # Found value to be written in field. If field is not found write out value. value_displayed = value if value && !not_id if BSON::ObjectId.legal?(value) record = model_klass.find(value) value_displayed = record.send(ret_name) if record else value_displayed = model_klass.send(ret_name, method, @parent, value) end end return ro_standard(value_displayed) if @readonly # Add method back, so autocomplete will know that it must search for method inside class ret_name = "#{ret_name}.#{method}" if method @yaml['html'] ||= {} @yaml['html']['value'] = value_displayed @yaml['html']['placeholder'] ||= t('drgcms.search_placeholder') || nil _name = '_' + @yaml['name'] record = record_text_for(@yaml['name']) @html << '' + @parent.text_field(record, _name, @yaml['html']) + '' # with new icon if @yaml['with_new'] @html << ' ' + @parent.fa_icon('plus-square-o', class: 'in-edit-add', title: t('drgcms.new'), style: "vertical-align: top;", 'data-table' => @yaml['with_new'] ) end # with edit icon if @yaml['with_edit'] && @record && @record[@yaml['name']].present? @html << ' ' + @parent.fa_icon('edit-o', class: 'in-edit-add', title: t('drgcms.edit'), style: "vertical-align: top;", 'data-table' => @yaml['with_edit'], 'data-id' => @record[@yaml['name']] ) end @html << '' + @parent.hidden_field(record, @yaml['name'], value: value) # actual value will be in hidden field # JS stuff # allow unselected values on is_id: false option not_id_code = %( if (ui.item == null) { $("##{record}_#{@yaml['name']}").val($("##{record}__#{@yaml['name']}").val() ); return; } ) if not_id @js << <