Class: AspaceFormHelper::FormContext
- Inherits:
-
Object
- Object
- AspaceFormHelper::FormContext
- Defined in:
- frontend/app/helpers/aspace_form_helper.rb
Direct Known Subclasses
Defined Under Namespace
Classes: BaseDefinition, JSONModelDefinition, ReadOnlyContext
Constant Summary collapse
- PROPERTIES_TO_EXCLUDE_FROM_READ_ONLY_VIEW =
["jsonmodel_type", "lock_version", "_resolved", "uri", "ref", "create_time", "system_mtime", "user_mtime", "created_by", "last_modified_by", "sort_name_auto_generate", "suppressed", "display_string", "file_uri", "agent_person_id", "agent_software_id", "agent_family_id", "agent_corporate_entity_id", "id"]
Instance Method Summary collapse
-
#[](key) ⇒ Object
-
#add_tooltip_options(tooltip, options) ⇒ Object
-
#allowable_types_for(name) ⇒ Object
-
#array_for_textarea(values) ⇒ Object
-
#checkbox(name, opts = {}, default = true, force_checked = false) ⇒ Object
-
#checkboxes_for_oai_sets(set_json, value_list) ⇒ Object
takes a JSON representation of the current options selected and the list of archival_record_level enums returns HTML for a set of checkboxes representing current selected and deselected sets for OAI export.
-
#clean_mixed_content(content, root_url) ⇒ Object
-
#combobox(name, options, opts = {}) ⇒ Object
-
#current_context ⇒ Object
-
#current_id ⇒ Object
-
#custom_report_template_limit_options ⇒ Object
-
#default_for(name) ⇒ Object
-
#define_template(name, definition = nil, &block) ⇒ Object
we expect the template to be defined in a view context that will have the @required_fields object if applicable.
-
#emit_template(name, *args) ⇒ Object
-
#error_params(exceptions) ⇒ Object
-
#exceptions_for_js(exceptions) ⇒ Object
-
#fields_for(object, context_name, &block) ⇒ Object
renders a single template containing form elements.
-
#form_context(name, values_from = {}, &body) ⇒ Object
-
#form_top ⇒ Object
-
#h(str) ⇒ Object
-
#help_path_for(name) ⇒ Object
-
#hidden_input(name, value = nil, field_opts = {}) ⇒ Object
-
#i18n_for(name, ignore_form_context = false) ⇒ Object
ignore_form_context will return a translation divorced from the active template or form in which it appears.
-
#id ⇒ Object
-
#id_for(name, qualify = true) ⇒ Object
-
#id_for_javascript(name) ⇒ Object
-
#initialize(name, values_from, parent) ⇒ FormContext
constructor
A new instance of FormContext.
-
#jsonmodel_definition(type, root = nil) ⇒ Object
-
#label(name, opts = {}, classes = []) ⇒ Object
-
#label_and_boolean(name, opts = {}, default = false, force_checked = false) ⇒ Object
-
#label_and_date(name, opts = {}) ⇒ Object
-
#label_and_disabled_checkbox(name) ⇒ Object
-
#label_and_fourpartid ⇒ Object
-
#label_and_merge_select(name, default = "", opts = {}) ⇒ Object
-
#label_and_password(name, opts = {}) ⇒ Object
-
#label_and_readonly(name, default = "", opts = {}) ⇒ Object
-
#label_and_select(name, options, opts = {}) ⇒ Object
-
#label_and_textarea(name, opts = {}) ⇒ Object
-
#label_and_textfield(name, opts = {}) ⇒ Object
-
#label_with_field(name, field_html, opts = {}) ⇒ Object
-
#list_for(objects, context_name, &block) ⇒ Object
renders a list of form element sets from a template.
-
#merge_checkbox(name, opts = {}, default = false, force_checked = false) ⇒ Object
-
#merge_select(name, value, opts) ⇒ Object
ANW-429: Modified this method so that a disable_replace can be passed in, which will skip the creation of the “replace” checkboxes.
-
#merge_victim_view(hash, opts = {}) ⇒ Object
-
#name_to_json_path(name) ⇒ Object
Turn a name like my[nested][object][0][title] into the equivalent JSON path (my/nested/object/0/title).
-
#notes_preview(notes_index = "notes", content_index = "content") ⇒ Object
ANW-429 Generates HTML for a very stripped down summary of a note for use in the agents merge preview.
-
#notes_preview_single(obj) ⇒ Object
Same as above, but intended for use with an agents top level notes record instead of a subrecord, in the merge selector form.
-
#oai_config_repo_set_codes_field(set_json, repositories) ⇒ Object
-
#oai_config_sponsor_set_names_field(set_json, opts = {}) ⇒ Object
-
#obj ⇒ Object
-
#parent_context ⇒ Object
-
#password(name = nil, value = "", opts = {}) ⇒ Object
-
#path(name = nil) ⇒ Object
-
#possible_options_for(name, add_empty_options = false, opts = {}) ⇒ Object
-
#preserve_newlines(string) ⇒ Object
-
#push(name, values_from = {}) {|_self| ... } ⇒ Object
-
#radio(name, value, opts = {}) ⇒ Object
-
#read_only_view(hash, opts = {}) ⇒ Object
-
#readonly? ⇒ Boolean
-
#readonly_context(name, values_from = {}, &body) ⇒ Object
-
#record_level_merge_controls(form, name = "undefined", controls = true, replace = true, append = true) ⇒ Object
ANW-429 outputs HTML for checkboxes for record-level add and replace for agents merge.
-
#required?(name) ⇒ Boolean
-
#select(name, options, opts = {}) ⇒ Object
-
#set_index(template, idx) ⇒ Object
-
#slug_url_field(name, repo_slug = nil, generate_url_with_repo_slug = nil) ⇒ Object
ANW-617: TODO: Ideally, this method should generate a full URL, with the value from AppConfig[:public_url], so the link is fully actionable.
-
#templates ⇒ Object
-
#templates_for_js(jsonmodel_type = nil) ⇒ Object
-
#textarea(name = nil, value = "", opts = {}) ⇒ Object
-
#textarea_ro(name = nil, value = "", opts = {}) ⇒ Object
-
#textfield(name = nil, value = nil, opts = {}) ⇒ Object
-
#tooltip(name, prefix = '') ⇒ Object
-
#update_monitor_params(record) ⇒ Object
Constructor Details
#initialize(name, values_from, parent) ⇒ FormContext
Returns a new instance of FormContext.
16 17 18 19 20 21 22 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 16 def initialize(name, values_from, parent) values = values_from.is_a?(JSONModelType) ? values_from.to_hash(:raw) : values_from @forms = FormHelpers.new @parent = parent @context = [[name, values]] end |
Instance Method Details
#[](key) ⇒ Object
218 219 220 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 218 def [](key) obj[key] end |
#add_tooltip_options(tooltip, options) ⇒ Object
544 545 546 547 548 549 550 551 552 553 554 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 544 def (tooltip, ) [:title] = tooltip ['data-placement'] = 'bottom' ['data-html'] = true ['data-delay'] = 500 ['data-trigger'] = 'manual' ['data-template'] = '<div class="tooltip archivesspace-help"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>' [:class] ||= '' [:class] += ' has-tooltip' end |
#allowable_types_for(name) ⇒ Object
701 702 703 704 705 706 707 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 701 def allowable_types_for(name) if @active_template && @parent.templates[@active_template] @parent.templates[@active_template][:definition].allowable_types_for(name) else [] end end |
#array_for_textarea(values) ⇒ Object
1337 1338 1339 1340 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 1337 def array_for_textarea(values) return values unless values.is_a?(Array) values.join("\n") end |
#checkbox(name, opts = {}, default = true, force_checked = false) ⇒ Object
560 561 562 563 564 565 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 560 def checkbox(name, opts = {}, default = true, force_checked = false) = {:id => "#{id_for(name)}", :type => "checkbox", :name => path(name), :value => 1} [:checked] = "checked" if force_checked or (obj[name] === true) or (obj[name].is_a? String and obj[name].start_with?("true")) or (obj[name] === "1") or (obj[name].nil? and default) @forms.tag("input", .merge(opts), false, false) end |
#checkboxes_for_oai_sets(set_json, value_list) ⇒ Object
takes a JSON representation of the current options selected and the list of archival_record_level enums returns HTML for a set of checkboxes representing current selected and deselected sets for OAI export
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 569 def checkboxes_for_oai_sets(set_json, value_list) return "" if value_list == nil # when called by #new, set_json will be nil. if set_json set_arry = JSON::parse(set_json) else set_arry = [] end html = "" html << "<div class='form-group'>" html << label("oai_sets_available", {}, ["control-label", "col-sm-2"]) html << "<div class='col-sm-9'>" html << "<ul class='checkbox-list'>" value_list['enumeration_values'].each do |v| # if we have an empty list of checkboxes, assume all sets are enabled. # otherwise, a checkbox is on if it's the in the list we get from the backend. checked = set_arry.include?(v['id'].to_s) || set_arry.length == 0 html << "<li class='list-group-item'>" html << "<div class='checkbox'>" html << "<label>" html << "<input id=\"#{v['id']}\" name=\"sets[#{v['id']}]\" type=\"checkbox\" " if checked html << "checked=\"checked\" " end if readonly? html << "disabled />" else html << "/>" end # of checkbox tag html << "#{v['value']}" html << "</label>" html << "</div>" html << "</li>" end html << "</ul>" html << "</div>" #col-sm-9 html << "</div>" #form-group return html.html_safe end |
#clean_mixed_content(content, root_url) ⇒ Object
30 31 32 33 34 35 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 30 def clean_mixed_content(content, root_url) content = content.to_s return content if content.blank? MixedContentParser::parse(content, root_url, { :wrap_blocks => false } ).to_s.html_safe end |
#combobox(name, options, opts = {}) ⇒ Object
405 406 407 408 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 405 def combobox(name, , opts = {}) select(name, , opts.merge({ :"data-combobox" => true, :id => id_for(name) })) end |
#current_context ⇒ Object
208 209 210 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 208 def current_context @context.last end |
#current_id ⇒ Object
262 263 264 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 262 def current_id path(nil).gsub(/[\[\]]/, '_') end |
#custom_report_template_limit_options ⇒ Object
1333 1334 1335 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 1333 def [100, 500, 1000, 5000, 10000, 50000] end |
#default_for(name) ⇒ Object
692 693 694 695 696 697 698 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 692 def default_for(name) if @active_template && @parent.templates[@active_template] @parent.templates[@active_template][:definition].default_for(name) else nil end end |
#define_template(name, definition = nil, &block) ⇒ Object
we expect the template to be defined in a view context that will have the @required_fields object if applicable. We add it to the template hash because the object will be out of scope when the JS templates are emitted.
1174 1175 1176 1177 1178 1179 1180 1181 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 1174 def define_template(name, definition = nil, &block) @templates ||= {} @templates[name] = { :block => block, :definition => (definition || BaseDefinition.new), :requirements => @required_fields } end |
#emit_template(name, *args) ⇒ Object
502 503 504 505 506 507 508 509 510 511 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 502 def emit_template(name, *args) if !@parent.templates[name] raise "No such template: #{name.inspect}" end old = @active_template @active_template = name @parent.templates[name][:block].call(self, *args) @active_template = old end |
#error_params(exceptions) ⇒ Object
1327 1328 1329 1330 1331 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 1327 def error_params(exceptions) { :"data-form-errors" => (exceptions && exceptions.keys[0]) } end |
#exceptions_for_js(exceptions) ⇒ Object
242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 242 def exceptions_for_js(exceptions) result = {} [:errors, :warnings].each do |condition| if exceptions[condition] result[condition] = exceptions[condition].keys.map {|property| id_for_javascript(property) } end end result.to_json.html_safe end |
#fields_for(object, context_name, &block) ⇒ Object
renders a single template containing form elements.
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 141 def fields_for(object, context_name, &block) result = "" push(context_name, object) do result << hidden_input("lock_version", object["lock_version"]) if object result << @parent.capture(object, &block) end extra_classes = "" # ANW-429: Add class to top level div so element can be switched out by JS based on user form input # TODO: refactor extra_classes += "sdl-subrecord-form" if context_name == "structured_date_range" || context_name == "structured_date_single" ("<div data-name-path=\"#{set_index(self.path(context_name), '${index}')}\" " + " data-id-path=\"#{id_for(set_index(self.path(context_name), '${index}'), false)}\" " + " class=\"subrecord-form-fields-for #{extra_classes}\">#{result}</div>").html_safe end |
#form_context(name, values_from = {}, &body) ⇒ Object
990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 990 def form_context(name, values_from = {}, &body) context = FormContext.new(name, values_from, self) env = self.request.env env['form_context_depth'] ||= 0 context.instance_variable_set(:@form_context_depth, env['form_context_depth']) # Only fetch required values at the top-level if env['form_context_depth'] == 0 begin required_fields = RequiredFields.get(values_from.jsonmodel_type) context.instance_variable_set(:@required_fields, required_fields) rescue end end s = "<div class=\"form-context\" id=\"form_#{name}\">".html_safe s << context.hidden_input("lock_version", values_from["lock_version"]) env['form_context_depth'] += 1 s << capture(context, &body) env['form_context_depth'] -= 1 if env['form_context_depth'] == 0 # Only emit the JS templates at the top-level s << templates_for_js(values_from["jsonmodel_type"]) end s << "</div>".html_safe s rescue Rails.logger.error("Failure generating templates for JS: #{$!}") Rails.logger.error("Stacktrace:\n%s" % [$@.join("\n")]) raise $! end |
#form_top ⇒ Object
162 163 164 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 162 def form_top @context[0].first end |
#h(str) ⇒ Object
25 26 27 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 25 def h(str) ERB::Util.html_escape(str) end |
#help_path_for(name) ⇒ Object
196 197 198 199 200 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 196 def help_path_for(name) names = @context.map(&:first) return "#{names[-1].to_s.gsub(/\[.*\]/, "").singularize}_#{name}" if names.length > 0 name end |
#hidden_input(name, value = nil, field_opts = {}) ⇒ Object
488 489 490 491 492 493 494 495 496 497 498 499 500 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 488 def hidden_input(name, value = nil, field_opts = {}) value = obj[name] if value.nil? full_name = path(name) if value && value.is_a?(Hash) && value.has_key?('ref') full_name += '[ref]' value = value['ref'] end @forms.tag("input", {:id => id_for(name), :type => "hidden", :value => h(value), :name => full_name}.merge(field_opts), false, false) end |
#i18n_for(name, ignore_form_context = false) ⇒ Object
ignore_form_context will return a translation divorced from the active template or form in which it appears.
233 234 235 236 237 238 239 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 233 def i18n_for(name, ignore_form_context = false) if ignore_form_context "#{name.to_s.gsub(/\[\]$/, "")}" else "#{@active_template or form_top}.#{name.to_s.gsub(/\[\]$/, "")}" end end |
#id ⇒ Object
167 168 169 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 167 def id "form_#{form_top}" end |
#id_for(name, qualify = true) ⇒ Object
266 267 268 269 270 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 266 def id_for(name, qualify = true) name = path(name) if qualify name.gsub(/[\[\]]/, '_') end |
#id_for_javascript(name) ⇒ Object
256 257 258 259 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 256 def id_for_javascript(name) path = name.split("/").collect {|a| "[#{a}]"}.join "#{form_top}#{path}".gsub(/[\[\]\/]/, "_") end |
#jsonmodel_definition(type, root = nil) ⇒ Object
1044 1045 1046 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 1044 def jsonmodel_definition(type, root = nil) JSONModelDefinition.new(JSONModel(type), root) end |
#label(name, opts = {}, classes = []) ⇒ Object
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 523 def label(name, opts = {}, classes = []) prefix = '' prefix << "#{opts[:contextual]}." if opts[:contextual] prefix << 'plugins.' if opts[:plugin] classes << 'control-label' = {:class => classes.join(' '), :for => id_for(name)} unless (tooltip = tooltip(name, prefix)).empty? (tooltip, ) end attr_string = .merge(opts || {}) .map {|k, v| '%s="%s"' % [CGI::escapeHTML(k.to_s), CGI::escapeHTML(v.to_s)]} .join(' ') content = CGI::escapeHTML(I18n.t(prefix + i18n_for(name, opts[:ignore_form_context]))) "<label #{attr_string}>#{content}</label>".html_safe end |
#label_and_boolean(name, opts = {}, default = false, force_checked = false) ⇒ Object
333 334 335 336 337 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 333 def label_and_boolean(name, opts = {}, default = false, force_checked = false) opts[:col_size] = 1 opts[:controls_class] = "checkbox" label_with_field(name, checkbox(name, opts, default, force_checked), opts) end |
#label_and_date(name, opts = {}) ⇒ Object
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 276 def label_and_date(name, opts = {}) field_opts = (opts[:field_opts] || {}).merge({ :class => "date-field form-control", :"data-format" => "yyyy-mm-dd", :"data-date" => Date.today.strftime('%Y-%m-%d'), :"data-autoclose" => true, :"data-force-parse" => false, :"data-label" => I18n.t("actions.date_picker_toggle") }) if obj[name].blank? && opts[:default] value = opts[:default] else value = obj[name] end opts[:col_size] = 4 date_input = textfield(name, value, field_opts) label_with_field(name, date_input, opts) end |
#label_and_disabled_checkbox(name) ⇒ Object
299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 299 def label_and_disabled_checkbox(name) html = "" html << "<div class='form-group'>" html << "<label class='col-sm-2 control-label'>#{name}</label>" html << "<div class='col-sm-1'>" html << "<input type='checkbox' name='disabled' disabled>" html << "</div>" html << "</div>" return html.html_safe end |
#label_and_fourpartid ⇒ Object
513 514 515 516 517 518 519 520 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 513 def label_and_fourpartid field_html = textfield("id_0", obj["id_0"], :class => "id_0 form-control", :size => 10) field_html << textfield("id_1", obj["id_1"], :class => "id_1 form-control", :size => 10, :disabled => obj["id_0"].blank? && obj["id_1"].blank?, :'aria-label' => "id_1") field_html << textfield("id_2", obj["id_2"], :class => "id_2 form-control", :size => 10, :disabled => obj["id_1"].blank? && obj["id_2"].blank?, :'aria-label' => "id_2") field_html << textfield("id_3", obj["id_3"], :class => "id_3 form-control", :size => 10, :disabled => obj["id_2"].blank? && obj["id_3"].blank?, :'aria-label' => "id_3") @forms.content_tag(:div, (I18n.t(i18n_for("id_0")) + field_html).html_safe, :class=> "identifier-fields") label_with_field("id_0", field_html, :control_class => "identifier-fields") end |
#label_and_merge_select(name, default = "", opts = {}) ⇒ Object
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 365 def label_and_merge_select(name, default = "", opts = {}) value = obj[name] begin jsonmodel_type = obj["jsonmodel_type"] prefix = opts[:plugin] ? 'plugins.' : '' schema = JSONModel(jsonmodel_type).schema if (schema["properties"][name].has_key?('dynamic_enum')) value = I18n.t({:enumeration => schema["properties"][name]["dynamic_enum"], :value => value}, :default => value) elsif schema["properties"][name].has_key?("enum") value = I18n.t("#{prefix}#{jsonmodel_type.to_s}.#{property}_#{value}", :default => value) end rescue end if opts.has_key? :controls_class opts[:controls_class] << " label-only" else opts[:controls_class] = " label-only" end if value.blank? label_with_field(name, value.blank? ? default : value , opts) else label_with_field(name, merge_select(name, value, opts), opts) end end |
#label_and_password(name, opts = {}) ⇒ Object
328 329 330 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 328 def label_and_password(name, opts = {}) label_with_field(name, password(name, obj[name], opts[:field_opts] || {}), opts) end |
#label_and_readonly(name, default = "", opts = {}) ⇒ Object
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 339 def label_and_readonly(name, default = "", opts = {}) value = obj[name] if !(value.is_a? String) value = value.to_s end begin jsonmodel_type = obj["jsonmodel_type"] prefix = opts[:plugin] ? 'plugins.' : '' schema = JSONModel(jsonmodel_type).schema if (schema["properties"][name].has_key?('dynamic_enum')) value = I18n.t({:enumeration => schema["properties"][name]["dynamic_enum"], :value => value}, :default => value) elsif schema["properties"][name].has_key?("enum") value = I18n.t("#{prefix}#{jsonmodel_type.to_s}.#{property}_#{value}", :default => value) end rescue end if opts.has_key? :controls_class opts[:controls_class] << " label-only" else opts[:controls_class] = " label-only" end label_with_field(name, value.blank? ? default : value , opts) end |
#label_and_select(name, options, opts = {}) ⇒ Object
318 319 320 321 322 323 324 325 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 318 def label_and_select(name, , opts = {}) = ([""] + ) if opts[:nodefault] opts[:field_opts] ||= {} opts[:col_size] = 9 = .length < COMBOBOX_MIN_LIMIT ? select(name, , opts[:field_opts] || {}) : combobox(name, , opts[:field_opts] || {}) label_with_field(name, , opts) end |
#label_and_textarea(name, opts = {}) ⇒ Object
313 314 315 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 313 def label_and_textarea(name, opts = {}) label_with_field(name, textarea(name, obj[name] || opts[:default], opts[:field_opts] || {}), opts) end |
#label_and_textfield(name, opts = {}) ⇒ Object
272 273 274 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 272 def label_and_textfield(name, opts = {}) label_with_field(name, textfield(name, obj[name], opts[:field_opts] || {}), opts) end |
#label_with_field(name, field_html, opts = {}) ⇒ Object
719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 719 def label_with_field(name, field_html, opts = {}) opts[:label_opts] ||= {} opts[:label_opts][:plugin] = opts[:plugin] opts[:col_size] ||= 9 control_group_classes, label_classes, controls_classes = %w(form-group), [], [] unless opts[:layout] && opts[:layout] == 'stacked' label_classes << "col-sm-#{opts[:label_opts].fetch(:col_size, 2)}" controls_classes << "col-sm-#{opts[:col_size]}" end # There must be a better way to say this... # The value of the 'required' option wins out if set to either true or false # if not specified, we take the value of required? required = [:required, 'required'].map {|r| opts[r]}.compact.first if required.nil? required = required?(name) end # additional admin-defined requirements unless required || @required_fields.nil? type = @record_type || @context.last[1]["jsonmodel_type"] # ideally we would send along the property as well, # and be really sure that this field is required on # this type of record in such and such context. A possible # refactor would be to have all or some of the marking up # of required fields happen on demand (in JavaScript). required = @required_fields.required?(nil, type, name) end control_group_classes << "required" if required == true control_group_classes << "conditionally-required" if required == :conditionally control_group_classes << "#{opts[:control_class]}" if opts.has_key? :control_class #TODO: refactor this. We don't need a separate method for each extra special class to be added below. Probably the thing to is to use the opts param. # ANW-617: add JS classes to slug fields control_group_classes << "js-slug_textfield" if name == "slug" control_group_classes << "js-slug_auto_checkbox" if name == "is_slug_auto" # ANW-429: add JS classes to structured date fields control_group_classes << "js-structured_date_select" if name == "date_type_structured" controls_classes << "#{opts[:controls_class]}" if opts.has_key? :controls_class control_group = "<div class=\"#{control_group_classes.join(' ')}\">" control_group << label(name, opts[:label_opts], label_classes) control_group << "<div class=\"#{controls_classes.join(' ')}\">" control_group << field_html control_group << "</div>" control_group << "</div>" # ANW-429 # TODO: Refactor to the JS files, ideally so this is run when the "Add Date" button is clicked. This is a tricky one since the select field this JS needs to be run on doesn't exist until the callbacks that run after the button is clicked run. Putting it here means that it runs as part of the html, and is always included in the right context. control_group << "<script>selectStructuredDateSubform();</script>" if name == "date_type_structured" control_group.html_safe end |
#list_for(objects, context_name, &block) ⇒ Object
renders a list of form element sets from a template. Each item will be re-orderable. Objects should be an array.
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 121 def list_for(objects, context_name, &block) objects ||= [] result = "" objects.each_with_index do |object, idx| push(set_index(context_name, idx), object) do result << "<li id=\"#{current_id}\" class=\"subrecord-form-wrapper\" data-index=\"#{idx}\" data-object-name=\"#{context_name.gsub(/\[\]/, "").singularize}\">" result << hidden_input("lock_version") if obj.respond_to?(:has_key?) && obj.has_key?("lock_version") result << @parent.capture(object, idx, &block) result << "</li>" end end ("<ul data-name-path=\"#{set_index(self.path(context_name), '${index}')}\" " + " data-id-path=\"#{id_for(set_index(self.path(context_name), '${index}'), false)}\" " + " class=\"subrecord-form-list\">#{result}</ul>").html_safe end |
#merge_checkbox(name, opts = {}, default = false, force_checked = false) ⇒ Object
668 669 670 671 672 673 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 668 def merge_checkbox(name, opts = {}, default = false, force_checked = false) = {:id => "#{id_for(name)}", :type => "checkbox", :name => path(name), :value => "REPLACE"} [:checked] = "checked" if force_checked or (obj[name] === true) or (obj[name].is_a? String and obj[name].start_with?("true")) or (obj[name] === "REPLACE") or (obj[name].nil? and default) @forms.tag("input", .merge(opts), false, false) end |
#merge_select(name, value, opts) ⇒ Object
ANW-429: Modified this method so that a disable_replace can be passed in, which will skip the creation of the “replace” checkboxes. This can be used to not render them in case a replace in inappropriate, e.g., the target record has nothing to replace with.
392 393 394 395 396 397 398 399 400 401 402 403 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 392 def merge_select(name, value, opts) unless opts[:disable_replace] == true value += "<label class='subreplace-control'>".html_safe value += merge_checkbox("#{name}", { :class => "merge-toggle"}, false, false) value += " <small>".html_safe value += I18n.t("actions.merge_replace") value += "</small></label>".html_safe else value += "" end end |
#merge_victim_view(hash, opts = {}) ⇒ Object
887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 887 def merge_victim_view(hash, opts = {}) jsonmodel_type = hash["jsonmodel_type"] schema = JSONModel(jsonmodel_type).schema prefix = opts[:plugin] ? 'plugins.' : '' html = "<div class='form-horizontal'>" hash.reject {|k, v| PROPERTIES_TO_EXCLUDE_FROM_READ_ONLY_VIEW.include?(k)}.each do |property, value| if schema and schema["properties"].has_key?(property) if (schema["properties"][property].has_key?('dynamic_enum')) value = I18n.t({:enumeration => schema["properties"][property]["dynamic_enum"], :value => value}, :default => value) elsif schema["properties"][property].has_key?("enum") value = I18n.t("#{prefix}#{jsonmodel_type.to_s}.#{property}_#{value}", :default => value) elsif schema["properties"][property]["type"] === "boolean" value = value === true ? "True" : "False" elsif schema["properties"][property]["type"] === "date" value = value.blank? ? "" : Date.strptime(value, "%Y-%m-%d") elsif schema["properties"][property]["type"] === "array" # this view doesn't support arrays next elsif value.is_a? Hash # can't display an object either next end end html << "<div class='form-group'>" html << "<div class='control-label col-sm-2'>" html << I18n.t("#{prefix}#{jsonmodel_type.to_s}.#{property}") html << "</div>" html << "<div class='label-only col-sm-8'>#{value}</div>" html << "</div>" end html << "</div>" html.html_safe end |
#name_to_json_path(name) ⇒ Object
Turn a name like my[nested][object][0][title] into the equivalent JSON path (my/nested/object/0/title)
174 175 176 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 174 def name_to_json_path(name) name.gsub(/[\[\]]+/, "/").gsub(/\/+$/, "").gsub(/^\/+/, "") end |
#notes_preview(notes_index = "notes", content_index = "content") ⇒ Object
ANW-429 Generates HTML for a very stripped down summary of a note for use in the agents merge preview. TODO: Eventually we’ll want to use the notes partials in place of this code. This code was created because the current notes show takes up a lot of space, and work needs to be done to figure out the exact setup/context needed to get those views to render properly. T
785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 785 def notes_preview(notes_index = "notes", content_index = "content") content_label = I18n.t("note._frontend.preview.content") html = "" if obj[notes_index] && obj[notes_index].length > 0 html << "<div class='subrecord-form-container'>" html << "<h4 class='subrecord-form-heading'>#{I18n.t("subsections.notes")}</h4>" obj[notes_index].each_with_index do |o, i| notes_heading = I18n.t("note.#{o['jsonmodel_type'].to_s}") if o[content_index].is_a?(Array) notes_content = o[content_index].join(" : ") else notes_content = o[content_index] end html << "<section>" html << "<h5>#{notes_heading}</h5>" html << "<div class='panel panel-default'>" html << "<div class=\"form-group\">" html << "<label class='control-label col-sm-2'>#{content_label}</label>" html << "<div class='col-sm-9 label-only'>" html << "#{notes_content}" html << "</div>" html << "</div>" html << "</div>" html << "</section>" end html << "</div>" html.html_safe end end |
#notes_preview_single(obj) ⇒ Object
Same as above, but intended for use with an agents top level notes record instead of a subrecord, in the merge selector form. Needed because emitting templates as usual breaks the merge selector interface
825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 825 def notes_preview_single(obj) content_label = I18n.t("note._frontend.preview.content") html = "" notes_content = "" obj['subnotes'].each do |subnote| if subnote['jsonmodel_type'] == "note_text" notes_content << subnote["content"] if subnote["content"] end end html << "<br />" html << "<section>" html << "<div class='panel panel-default'>" html << "<div class=\"form-group\">" html << "<label class='control-label col-sm-2'>#{content_label}</label>" html << "<div class='col-sm-9 label-only'>" html << "#{notes_content}" html << "</div>" html << "</div>" html << "</div>" html << "</section>" html.html_safe end |
#oai_config_repo_set_codes_field(set_json, repositories) ⇒ Object
615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 615 def oai_config_repo_set_codes_field(set_json, repositories) #label_and_textfield(name, opts) set_arry = JSON::parse(set_json) html = "" html << "<div class='form-group'>" html << label("repo_set_section", {}, ["control-label", "col-sm-2"]) html << "<div class='col-sm-9'>" html << "<ul class='checkbox-list'>" repositories.each do |r| # a checkbox is on if it's the in the list we get from the backend. checked = set_arry.include?(r['repo_code'].to_s) html << "<li class='list-group-item'>" html << "<div class='checkbox'>" html << "<label>" html << "<input id=\"#{r['repo_code']}\" name=\"repo_set_codes[#{r['repo_code']}]\" type=\"checkbox\" " if checked html << "checked=\"checked\" " end html << "/>" html << "#{r['repo_code']}" html << "</label>" html << "</div>" html << "</li>" end html << "</ul>" html << "</div>" #col-sm-9 html << "</div>" #form-group return html.html_safe end |
#oai_config_sponsor_set_names_field(set_json, opts = {}) ⇒ Object
651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 651 def oai_config_sponsor_set_names_field(set_json, opts = {}) # turn array from DB into a comma delimited list for UI set_arry = JSON::parse(set_json) value = set_arry.join("|") html = "" html << "<div class='form-group'>" html << label("sponsor_set_names", {}, ["control-label", "col-sm-2"]) html << "<div class='col-sm-9'>" html << "<input id='oai_config_sponsor_set_names_' type='text' value='#{value}' name='oai_config[sponsor_set_names]' class='form-control js-taggable' datarole='tagsinput'>" html << "</div>" html << "</div>" return html.html_safe end |
#obj ⇒ Object
213 214 215 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 213 def obj @context.last.second end |
#parent_context ⇒ Object
203 204 205 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 203 def parent_context form_top end |
#password(name = nil, value = "", opts = {}) ⇒ Object
483 484 485 486 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 483 def password(name = nil, value = "", opts = {}) @forms.tag("input", {:id => id_for(name), :type => "password", :value => h(value), :name => path(name)}.merge(opts), false, false) end |
#path(name = nil) ⇒ Object
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 179 def path(name = nil) names = @context.map(&:first) tail = names.drop(1) tail += [name] if name path = tail.map {|e| if e =~ /(.*?)\[([0-9]+)?\]$/ "[#{$1}][#{$2}]" else "[#{e}]" end }.join("") "#{names.first}#{path}" end |
#possible_options_for(name, add_empty_options = false, opts = {}) ⇒ Object
710 711 712 713 714 715 716 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 710 def (name, = false, opts = {}) if @active_template && @parent.templates[@active_template] @parent.templates[@active_template][:definition].(self, name, , opts) else [] end end |
#preserve_newlines(string) ⇒ Object
1311 1312 1313 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 1311 def preserve_newlines(string) string.gsub(/\n/, '<br>') end |
#push(name, values_from = {}) {|_self| ... } ⇒ Object
223 224 225 226 227 228 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 223 def push(name, values_from = {}) path(name) # populate the i18n mapping @context.push([name, values_from]) yield(self) @context.pop end |
#radio(name, value, opts = {}) ⇒ Object
675 676 677 678 679 680 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 675 def radio(name, value, opts = {}) = {:id => "#{id_for(name)}", :type => "radio", :name => path(name), :value => value} [:checked] = "checked" if obj[name] == value @forms.tag("input", .merge(opts), false, false) end |
#read_only_view(hash, opts = {}) ⇒ Object
1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 1261 def read_only_view(hash, opts = {}) jsonmodel_type = hash["jsonmodel_type"] schema = JSONModel(jsonmodel_type).schema prefix = opts[:plugin] ? 'plugins.' : '' html = "<div class='form-horizontal'>" # in some cases, we want to not display certain fields for some records, but not for others. # e.g., we don't want to display published for subjects (they are always published), but we do for other records types. if opts[:exclude] props_to_exclude = PROPERTIES_TO_EXCLUDE_FROM_READ_ONLY_VIEW + opts[:exclude] else props_to_exclude = PROPERTIES_TO_EXCLUDE_FROM_READ_ONLY_VIEW end hash.reject {|k, v| props_to_exclude.include?(k)}.each do |property, value| if schema and schema["properties"].has_key?(property) if (schema["properties"][property].has_key?('dynamic_enum')) value = I18n.t({:enumeration => schema["properties"][property]["dynamic_enum"], :value => value}, :default => value) elsif schema["properties"][property].has_key?("enum") value = I18n.t("#{prefix}#{jsonmodel_type.to_s}.#{property}_#{value}", :default => value) elsif schema["properties"][property]["type"] === "boolean" value = value === true ? I18n.t('boolean.true') : I18n.t('boolean.false') elsif schema["properties"][property]["type"] === "date" value = value.blank? ? "" : Date.strptime(value, "%Y-%m-%d") elsif schema["properties"][property]["type"] === "integer" value = value.blank? ? "" : value.to_s elsif schema["properties"][property]["type"] === "array" # this view doesn't support arrays next elsif value.is_a? Hash # can't display an object either next end end html << "<div class='form-group'>" html << "<div class='control-label col-sm-2'>" html << I18n.t("#{prefix}#{jsonmodel_type.to_s}.#{property}") html << "</div>" html << "<div class='label-only col-sm-8'>#{value}</div>" html << "</div>" end html << "</div>" html.html_safe end |
#readonly? ⇒ Boolean
38 39 40 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 38 def readonly? false end |
#readonly_context(name, values_from = {}, &body) ⇒ Object
1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 1244 def readonly_context(name, values_from = {}, &body) context = ReadOnlyContext.new(name, values_from, self) # Not feeling great about this, but we render the form twice: the first pass # sets up the mapping from form input names to i18n keys, while the second # actually uses that map to set the labels correctly. capture(context, &body) s = "<div class=\"readonly-context form-horizontal\">".html_safe s << capture(context, &body) s << "</div>".html_safe s end |
#record_level_merge_controls(form, name = "undefined", controls = true, replace = true, append = true) ⇒ Object
ANW-429 outputs HTML for checkboxes for record-level add and replace for agents merge
854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 854 def record_level_merge_controls(form, name = "undefined", controls = true, replace = true, append = true) html = "" html << '<h4 class="subrecord-form-heading">' html << I18n.t("#{name}._singular").to_s if controls if replace html << '<label class="replace-control">' html << form.merge_checkbox('replace') html << '<small>' html << I18n.t("actions.merge_replace").to_s html << '</small>' html << '</label>' end if append html << '<label class="append-control">' html << form.merge_checkbox('append') html << '<small>' html << I18n.t("actions.merge_add").to_s html << '</small>' html << '</label>' end end html << '</h4>' return html.html_safe end |
#required?(name) ⇒ Boolean
683 684 685 686 687 688 689 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 683 def required?(name) if @active_template && @parent.templates[@active_template] @parent.templates[@active_template][:definition].required?(name) else false end end |
#select(name, options, opts = {}) ⇒ Object
411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 411 def select(name, , opts = {}) if opts.has_key? :class opts[:class] << " form-control" else opts[:class] = "form-control" end if opts.has_key? :"data-combobox" opts[:role] = "listbox" opts[:"aria-label"] = I18n.t(i18n_for(name)) end selection = obj[name] selection = selection[0...-4] if selection.is_a? String and selection.end_with?("_REQ") @forms.select_tag(path(name), @forms.(, selection || default_for(name) || opts[:default]), {:id => id_for(name)}.merge!(opts)) end def textarea(name = nil, value = "", opts = {}) value = value[0...-4] if value.is_a? String and value.end_with?("_REQ") value = nil if value === "REQ" = {:id => id_for(name), :rows => 3} placeholder = I18n.t("#{i18n_for(name)}_placeholder", :default => '') [:placeholder] = placeholder if not placeholder.empty? [:class] = "form-control" @forms.text_area_tag(path(name), h(value), .merge(opts)) end def textarea_ro(name = nil, value = "", opts = {}) return "" if value.blank? opts[:escape] = true unless opts[:escape] == false opts[:base_url] ||= "/" value = clean_mixed_content(value, opts[:base_url]) if opts[:clean] == true value = @parent.preserve_newlines(value) if opts[:clean] == true value = CGI::escapeHTML(value) if opts[:escape] value.html_safe end def textfield(name = nil, value = nil, opts = {}) value ||= obj[name] if !name.nil? value = value[0...-4] if value.is_a? String and value.end_with?("_REQ") value = nil if value === "REQ" = {:id => id_for(name), :type => "text", :value => h(value), :name => path(name)} placeholder = I18n.t("#{i18n_for(name)}_placeholder", :default => '') [:placeholder] = placeholder if not placeholder.empty? [:class] = "form-control" value = @forms.tag("input", .merge(opts), false, false) if opts[:automatable] by_default = default_for("#{name}_auto_generate") || false value << "<label>".html_safe value << checkbox("#{name}_auto_generate", { :class => "automate-field-toggle", :display_text_when_checked => I18n.t("states.auto_generated") }, by_default, false) value << " <small>".html_safe value << I18n.t("actions.automate") value << "</small></label>".html_safe end inline_help = I18n.t("#{i18n_for(name)}_inline_help", :default => '') if !inline_help.empty? value << "<span class=\"help-inline\">#{inline_help}</span>".html_safe end value end def password(name = nil, value = "", opts = {}) @forms.tag("input", {:id => id_for(name), :type => "password", :value => h(value), :name => path(name)}.merge(opts), false, false) end def hidden_input(name, value = nil, field_opts = {}) value = obj[name] if value.nil? full_name = path(name) if value && value.is_a?(Hash) && value.has_key?('ref') full_name += '[ref]' value = value['ref'] end @forms.tag("input", {:id => id_for(name), :type => "hidden", :value => h(value), :name => full_name}.merge(field_opts), false, false) end def emit_template(name, *args) if !@parent.templates[name] raise "No such template: #{name.inspect}" end old = @active_template @active_template = name @parent.templates[name][:block].call(self, *args) @active_template = old end def label_and_fourpartid field_html = textfield("id_0", obj["id_0"], :class => "id_0 form-control", :size => 10) field_html << textfield("id_1", obj["id_1"], :class => "id_1 form-control", :size => 10, :disabled => obj["id_0"].blank? && obj["id_1"].blank?, :'aria-label' => "id_1") field_html << textfield("id_2", obj["id_2"], :class => "id_2 form-control", :size => 10, :disabled => obj["id_1"].blank? && obj["id_2"].blank?, :'aria-label' => "id_2") field_html << textfield("id_3", obj["id_3"], :class => "id_3 form-control", :size => 10, :disabled => obj["id_2"].blank? && obj["id_3"].blank?, :'aria-label' => "id_3") @forms.content_tag(:div, (I18n.t(i18n_for("id_0")) + field_html).html_safe, :class=> "identifier-fields") label_with_field("id_0", field_html, :control_class => "identifier-fields") end def label(name, opts = {}, classes = []) prefix = '' prefix << "#{opts[:contextual]}." if opts[:contextual] prefix << 'plugins.' if opts[:plugin] classes << 'control-label' = {:class => classes.join(' '), :for => id_for(name)} unless (tooltip = tooltip(name, prefix)).empty? (tooltip, ) end attr_string = .merge(opts || {}) .map {|k, v| '%s="%s"' % [CGI::escapeHTML(k.to_s), CGI::escapeHTML(v.to_s)]} .join(' ') content = CGI::escapeHTML(I18n.t(prefix + i18n_for(name, opts[:ignore_form_context]))) "<label #{attr_string}>#{content}</label>".html_safe end def (tooltip, ) [:title] = tooltip ['data-placement'] = 'bottom' ['data-html'] = true ['data-delay'] = 500 ['data-trigger'] = 'manual' ['data-template'] = '<div class="tooltip archivesspace-help"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>' [:class] ||= '' [:class] += ' has-tooltip' end def tooltip(name, prefix = '') I18n.t_raw("#{prefix}#{i18n_for(name)}_tooltip", :default => '') end def checkbox(name, opts = {}, default = true, force_checked = false) = {:id => "#{id_for(name)}", :type => "checkbox", :name => path(name), :value => 1} [:checked] = "checked" if force_checked or (obj[name] === true) or (obj[name].is_a? String and obj[name].start_with?("true")) or (obj[name] === "1") or (obj[name].nil? and default) @forms.tag("input", .merge(opts), false, false) end # takes a JSON representation of the current options selected and the list of archival_record_level enums # returns HTML for a set of checkboxes representing current selected and deselected sets for OAI export def checkboxes_for_oai_sets(set_json, value_list) return "" if value_list == nil # when called by #new, set_json will be nil. if set_json set_arry = JSON::parse(set_json) else set_arry = [] end html = "" html << "<div class='form-group'>" html << label("oai_sets_available", {}, ["control-label", "col-sm-2"]) html << "<div class='col-sm-9'>" html << "<ul class='checkbox-list'>" value_list['enumeration_values'].each do |v| # if we have an empty list of checkboxes, assume all sets are enabled. # otherwise, a checkbox is on if it's the in the list we get from the backend. checked = set_arry.include?(v['id'].to_s) || set_arry.length == 0 html << "<li class='list-group-item'>" html << "<div class='checkbox'>" html << "<label>" html << "<input id=\"#{v['id']}\" name=\"sets[#{v['id']}]\" type=\"checkbox\" " if checked html << "checked=\"checked\" " end if readonly? html << "disabled />" else html << "/>" end # of checkbox tag html << "#{v['value']}" html << "</label>" html << "</div>" html << "</li>" end html << "</ul>" html << "</div>" #col-sm-9 html << "</div>" #form-group return html.html_safe end def oai_config_repo_set_codes_field(set_json, repositories) #label_and_textfield(name, opts) set_arry = JSON::parse(set_json) html = "" html << "<div class='form-group'>" html << label("repo_set_section", {}, ["control-label", "col-sm-2"]) html << "<div class='col-sm-9'>" html << "<ul class='checkbox-list'>" repositories.each do |r| # a checkbox is on if it's the in the list we get from the backend. checked = set_arry.include?(r['repo_code'].to_s) html << "<li class='list-group-item'>" html << "<div class='checkbox'>" html << "<label>" html << "<input id=\"#{r['repo_code']}\" name=\"repo_set_codes[#{r['repo_code']}]\" type=\"checkbox\" " if checked html << "checked=\"checked\" " end html << "/>" html << "#{r['repo_code']}" html << "</label>" html << "</div>" html << "</li>" end html << "</ul>" html << "</div>" #col-sm-9 html << "</div>" #form-group return html.html_safe end def oai_config_sponsor_set_names_field(set_json, opts = {}) # turn array from DB into a comma delimited list for UI set_arry = JSON::parse(set_json) value = set_arry.join("|") html = "" html << "<div class='form-group'>" html << label("sponsor_set_names", {}, ["control-label", "col-sm-2"]) html << "<div class='col-sm-9'>" html << "<input id='oai_config_sponsor_set_names_' type='text' value='#{value}' name='oai_config[sponsor_set_names]' class='form-control js-taggable' datarole='tagsinput'>" html << "</div>" html << "</div>" return html.html_safe end def merge_checkbox(name, opts = {}, default = false, force_checked = false) = {:id => "#{id_for(name)}", :type => "checkbox", :name => path(name), :value => "REPLACE"} [:checked] = "checked" if force_checked or (obj[name] === true) or (obj[name].is_a? String and obj[name].start_with?("true")) or (obj[name] === "REPLACE") or (obj[name].nil? and default) @forms.tag("input", .merge(opts), false, false) end def radio(name, value, opts = {}) = {:id => "#{id_for(name)}", :type => "radio", :name => path(name), :value => value} [:checked] = "checked" if obj[name] == value @forms.tag("input", .merge(opts), false, false) end def required?(name) if @active_template && @parent.templates[@active_template] @parent.templates[@active_template][:definition].required?(name) else false end end def default_for(name) if @active_template && @parent.templates[@active_template] @parent.templates[@active_template][:definition].default_for(name) else nil end end def allowable_types_for(name) if @active_template && @parent.templates[@active_template] @parent.templates[@active_template][:definition].allowable_types_for(name) else [] end end def (name, = false, opts = {}) if @active_template && @parent.templates[@active_template] @parent.templates[@active_template][:definition].(self, name, , opts) else [] end end def label_with_field(name, field_html, opts = {}) opts[:label_opts] ||= {} opts[:label_opts][:plugin] = opts[:plugin] opts[:col_size] ||= 9 control_group_classes, label_classes, controls_classes = %w(form-group), [], [] unless opts[:layout] && opts[:layout] == 'stacked' label_classes << "col-sm-#{opts[:label_opts].fetch(:col_size, 2)}" controls_classes << "col-sm-#{opts[:col_size]}" end # There must be a better way to say this... # The value of the 'required' option wins out if set to either true or false # if not specified, we take the value of required? required = [:required, 'required'].map {|r| opts[r]}.compact.first if required.nil? required = required?(name) end # additional admin-defined requirements unless required || @required_fields.nil? type = @record_type || @context.last[1]["jsonmodel_type"] # ideally we would send along the property as well, # and be really sure that this field is required on # this type of record in such and such context. A possible # refactor would be to have all or some of the marking up # of required fields happen on demand (in JavaScript). required = @required_fields.required?(nil, type, name) end control_group_classes << "required" if required == true control_group_classes << "conditionally-required" if required == :conditionally control_group_classes << "#{opts[:control_class]}" if opts.has_key? :control_class #TODO: refactor this. We don't need a separate method for each extra special class to be added below. Probably the thing to is to use the opts param. # ANW-617: add JS classes to slug fields control_group_classes << "js-slug_textfield" if name == "slug" control_group_classes << "js-slug_auto_checkbox" if name == "is_slug_auto" # ANW-429: add JS classes to structured date fields control_group_classes << "js-structured_date_select" if name == "date_type_structured" controls_classes << "#{opts[:controls_class]}" if opts.has_key? :controls_class control_group = "<div class=\"#{control_group_classes.join(' ')}\">" control_group << label(name, opts[:label_opts], label_classes) control_group << "<div class=\"#{controls_classes.join(' ')}\">" control_group << field_html control_group << "</div>" control_group << "</div>" # ANW-429 # TODO: Refactor to the JS files, ideally so this is run when the "Add Date" button is clicked. This is a tricky one since the select field this JS needs to be run on doesn't exist until the callbacks that run after the button is clicked run. Putting it here means that it runs as part of the html, and is always included in the right context. control_group << "<script>selectStructuredDateSubform();</script>" if name == "date_type_structured" control_group.html_safe end # ANW-429 # Generates HTML for a very stripped down summary of a note for use in the agents merge preview. # TODO: Eventually we'll want to use the notes partials in place of this code. This code was created because the current notes show takes up a lot of space, and work needs to be done to figure out the exact setup/context needed to get those views to render properly. # T def notes_preview(notes_index = "notes", content_index = "content") content_label = I18n.t("note._frontend.preview.content") html = "" if obj[notes_index] && obj[notes_index].length > 0 html << "<div class='subrecord-form-container'>" html << "<h4 class='subrecord-form-heading'>#{I18n.t("subsections.notes")}</h4>" obj[notes_index].each_with_index do |o, i| notes_heading = I18n.t("note.#{o['jsonmodel_type'].to_s}") if o[content_index].is_a?(Array) notes_content = o[content_index].join(" : ") else notes_content = o[content_index] end html << "<section>" html << "<h5>#{notes_heading}</h5>" html << "<div class='panel panel-default'>" html << "<div class=\"form-group\">" html << "<label class='control-label col-sm-2'>#{content_label}</label>" html << "<div class='col-sm-9 label-only'>" html << "#{notes_content}" html << "</div>" html << "</div>" html << "</div>" html << "</section>" end html << "</div>" html.html_safe end end # Same as above, but intended for use with an agents top level notes record instead of a subrecord, in the merge selector form. # Needed because emitting templates as usual breaks the merge selector interface def notes_preview_single(obj) content_label = I18n.t("note._frontend.preview.content") html = "" notes_content = "" obj['subnotes'].each do |subnote| if subnote['jsonmodel_type'] == "note_text" notes_content << subnote["content"] if subnote["content"] end end html << "<br />" html << "<section>" html << "<div class='panel panel-default'>" html << "<div class=\"form-group\">" html << "<label class='control-label col-sm-2'>#{content_label}</label>" html << "<div class='col-sm-9 label-only'>" html << "#{notes_content}" html << "</div>" html << "</div>" html << "</div>" html << "</section>" html.html_safe end # ANW-429 # outputs HTML for checkboxes for record-level add and replace for agents merge def record_level_merge_controls(form, name = "undefined", controls = true, replace = true, append = true) html = "" html << '<h4 class="subrecord-form-heading">' html << I18n.t("#{name}._singular").to_s if controls if replace html << '<label class="replace-control">' html << form.merge_checkbox('replace') html << '<small>' html << I18n.t("actions.merge_replace").to_s html << '</small>' html << '</label>' end if append html << '<label class="append-control">' html << form.merge_checkbox('append') html << '<small>' html << I18n.t("actions.merge_add").to_s html << '</small>' html << '</label>' end end html << '</h4>' return html.html_safe end end |
#set_index(template, idx) ⇒ Object
43 44 45 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 43 def set_index(template, idx) template.gsub(/\[\]$/, "[#{idx}]") end |
#slug_url_field(name, repo_slug = nil, generate_url_with_repo_slug = nil) ⇒ Object
ANW-617: TODO: Ideally, this method should generate a full URL, with the value from AppConfig[:public_url], so the link is fully actionable. Ran into a a bug (with AS? or deeper?) where the value of AppConfig[:public_url] was being changed at runtime simply by getting it’s value, with code like base_url = AppConfig[:public_url]. For now, this method generates a relative URL, like ‘\resources\Resource A’ to avoid this.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 51 def slug_url_field(name, repo_slug = nil, generate_url_with_repo_slug = nil) url = "" html = "" case obj['jsonmodel_type'] when 'resource' scope = :repo route = "resources" when 'accession' scope = :repo route = "accessions" when 'classification' scope = :repo route = "classifications" when 'classification_term' scope = :repo route = "classification_terms" when 'digital_object' scope = :repo route = "digital_objects" when 'repository' scope = :global route = "repositories" when 'agent_person' scope = :global route = "agents" when 'agent_family' scope = :global route = "agents" when 'agent_software' scope = :global route = "agents" when 'agent_corporate_entity' scope = :global route = "agents" when 'subject' scope = :global route = "subjects" when 'archival_object' scope = :repo route = "archival_objects" when 'digital_object_component' scope = :repo route = "digital_object_components" end # For repo scoped objects, # if we have access to the repo slug in the session and the repo scoped URLs are enabled # generate link with repo slug if !obj['slug'].nil? && !obj['slug'].empty? && AppConfig[:use_human_readable_urls] if scope == :repo if generate_url_with_repo_slug && repo_slug url << "/" + "repositories" + "/" url << repo_slug end end url << "/" + route + "/" + obj['slug'] else url = obj['uri'] end url.to_s end |
#templates ⇒ Object
1027 1028 1029 1030 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 1027 def templates @templates ||= {} @templates end |
#templates_for_js(jsonmodel_type = nil) ⇒ Object
1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 1184 def templates_for_js(jsonmodel_type = nil) @delivering_js_templates = true result = "" return result if @templates.blank? obj = {} obj['jsonmodel_type'] = jsonmodel_type if jsonmodel_type templates_to_process = @templates.clone templates_processed = [] # As processing a template may register further templates that hadn't been # registered previously, keep looping until we have no more templates to # process. # # Because infinite loops are terrifying and a pain to debug, let us reign # in the fear with a 100-loop-count-get-out-of-here-alive limit. i = 0 while (true) templates_to_process.each do |name, template| context = FormContext.new("${path}", obj, self) def context.id_for(name, qualify = true) name = path(name) if qualify name.gsub(/[\[\]]/, '_').gsub('${path}', '${id_path}') end context.instance_eval do @active_template = name @record_type = template[:definition].record_type @required_fields = template[:requirements] end result << "<div id=\"template_#{name}\"><!--" result << capture(context, &template[:block]) result << "--></div>" templates_processed << name end if templates_processed.length < @templates.length # some new templates were defined while outputing the js templates templates_to_process = @templates.reject {|name, _| templates_processed.include?(name)} else # we've got them all break end i += 1 if i > 100 Rails.logger.error("templates_for_js has looped out more that 100 times") break end end result.html_safe end |
#textarea(name = nil, value = "", opts = {}) ⇒ Object
426 427 428 429 430 431 432 433 434 435 436 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 426 def textarea(name = nil, value = "", opts = {}) value = value[0...-4] if value.is_a? String and value.end_with?("_REQ") value = nil if value === "REQ" = {:id => id_for(name), :rows => 3} placeholder = I18n.t("#{i18n_for(name)}_placeholder", :default => '') [:placeholder] = placeholder if not placeholder.empty? [:class] = "form-control" @forms.text_area_tag(path(name), h(value), .merge(opts)) end |
#textarea_ro(name = nil, value = "", opts = {}) ⇒ Object
438 439 440 441 442 443 444 445 446 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 438 def textarea_ro(name = nil, value = "", opts = {}) return "" if value.blank? opts[:escape] = true unless opts[:escape] == false opts[:base_url] ||= "/" value = clean_mixed_content(value, opts[:base_url]) if opts[:clean] == true value = @parent.preserve_newlines(value) if opts[:clean] == true value = CGI::escapeHTML(value) if opts[:escape] value.html_safe end |
#textfield(name = nil, value = nil, opts = {}) ⇒ Object
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 448 def textfield(name = nil, value = nil, opts = {}) value ||= obj[name] if !name.nil? value = value[0...-4] if value.is_a? String and value.end_with?("_REQ") value = nil if value === "REQ" = {:id => id_for(name), :type => "text", :value => h(value), :name => path(name)} placeholder = I18n.t("#{i18n_for(name)}_placeholder", :default => '') [:placeholder] = placeholder if not placeholder.empty? [:class] = "form-control" value = @forms.tag("input", .merge(opts), false, false) if opts[:automatable] by_default = default_for("#{name}_auto_generate") || false value << "<label>".html_safe value << checkbox("#{name}_auto_generate", { :class => "automate-field-toggle", :display_text_when_checked => I18n.t("states.auto_generated") }, by_default, false) value << " <small>".html_safe value << I18n.t("actions.automate") value << "</small></label>".html_safe end inline_help = I18n.t("#{i18n_for(name)}_inline_help", :default => '') if !inline_help.empty? value << "<span class=\"help-inline\">#{inline_help}</span>".html_safe end value end |
#tooltip(name, prefix = '') ⇒ Object
556 557 558 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 556 def tooltip(name, prefix = '') I18n.t_raw("#{prefix}#{i18n_for(name)}_tooltip", :default => '') end |
#update_monitor_params(record) ⇒ Object
1316 1317 1318 1319 1320 1321 1322 1323 1324 |
# File 'frontend/app/helpers/aspace_form_helper.rb', line 1316 def update_monitor_params(record) { :"data-update-monitor" => true, :"data-update-monitor-url" => url_for(:controller => :update_monitor, :action => :poll), :"data-update-monitor-record-uri" => record.uri, :"data-update-monitor-record-is-stale" => !!@record_is_stale, :"data-update-monitor-lock_version" => record.lock_version } end |