Represents an action on a model in response to a web request.
Methods
Public Class
Public Instance
- association_class_link
- association_link
- association_link_list
- association_links
- base_url_for
- column_label_for
- column_options_for
- csv
- edit_page
- form_attributes
- form_opts
- h
- handle
- handle_association_links
- handle_autocomplete
- handle_browse
- handle_create
- handle_delete
- handle_destroy
- handle_edit
- handle_mtm_edit
- handle_mtm_update
- handle_new
- handle_search
- handle_show
- handle_update
- humanize
- inline_mtm_edit_forms
- list_page
- model
- model_params
- mtm_edit_remove
- new_page
- normalized_type
- output_filename
- output_type
- page
- params_association
- redirect
- request
- show_page
- subtype
- supported?
- tab_name
- table_page
- table_pager
- tabs
- title
- type
- url_for
Constants
ALL_SUPPORTED_ACTIONS | = | %w'new create show edit update delete destroy browse search mtm_edit mtm_update association_links autocomplete'.freeze |
Array of strings for all action types currently supported |
|
NON_IDEMPOTENT_TYPES | = | NORMALIZED_ACTION_MAP = {:create=>:new, :update=>:edit, :destroy=>:delete, :mtm_update=>:mtm_edit} |
Map of regular type symbols to normalized type symbols |
|
TITLE_MAP | = | {:new=>'New', :show=>'Show', :edit=>'Edit', :delete=>'Delete', :browse=>'Browse', :search=>'Search', :mtm_edit=>'Many To Many Edit'} |
Map of type symbols to HTML titles |
Attributes
model | [R] |
The |
normalized_type | [R] |
The normalized type symbol related to the current action, so that paired actions such as new and create both use :new. |
output_filename | [R] |
The filename to use for file output |
output_type | [R] |
The type of output, currently nil for normal output, and ‘csv’ for csv output |
params_association | [R] |
An association symbol for the current related association. |
request | [R] |
The |
title | [R] |
An string suitable for use as the HTML title on the displayed page |
type | [R] |
The type symbols related to the current action (e.g. :new, :create). |
Public Class methods
Creates a new action for the model and request. This action is not usable unless supported? is called first and it returns true.
# File lib/autoforme/action.rb 44 def initialize(model, request) 45 @model = model 46 @request = request 47 end
Public Instance methods
If the framework contains the associated model class and that supports browsing, return a link to the associated browse page, otherwise, just return the name.
# File lib/autoforme/action.rb 640 def association_class_link(mc, assoc) 641 assoc_name = humanize(assoc) 642 if mc && mc.supported_action?(:browse, request) 643 "<a href=\"#{base_url_for("#{mc.link}/browse")}\">#{assoc_name}</a>" 644 else 645 assoc_name 646 end 647 end
For the given associated object, if the framework contains the associated model class, and that supports the type of action we are doing, return a link to the associated action page.
# File lib/autoforme/action.rb 652 def association_link(mc, assoc_obj) 653 if mc 654 t = h(mc.object_display_name(:association, request, assoc_obj)) 655 if mc.supported_action?(type, request) 656 t = "<a href=\"#{base_url_for("#{mc.link}/#{type}/#{mc.primary_key_value(assoc_obj)}")}\">#{t}</a>" 657 end 658 t 659 else 660 h(model.default_object_display_name(assoc_obj)) 661 end 662 end
HTML fragment for the list of association links, allowing quick access to associated models and objects.
# File lib/autoforme/action.rb 586 def association_link_list(obj) 587 assocs = model.association_links_for(type, request) 588 return if assocs.empty? 589 read_only = type == :show 590 t = String.new 591 t << '<h3 class="associated_records_header">Associated Records</h3>' 592 t << "<ul class='association_links'>\n" 593 assocs.each do |assoc| 594 mc = model.associated_model_class(assoc) 595 t << "<li>" 596 t << association_class_link(mc, assoc) 597 t << "\n " 598 599 case model.association_type(assoc) 600 when :one 601 if assoc_obj = obj.send(assoc) 602 t << " - " 603 t << association_link(mc, assoc_obj) 604 end 605 assoc_objs = [] 606 when :edit 607 if !read_only && model.supported_mtm_edit?(assoc.to_s, request) 608 t << "(<a href=\"#{url_for("mtm_edit/#{model.primary_key_value(obj)}?association=#{assoc}")}\">associate</a>)" 609 end 610 assoc_objs = obj.send(assoc) 611 when :new 612 if !read_only && mc && mc.supported_action?(:new, request) 613 params = model.associated_new_column_values(obj, assoc).map do |col, value| 614 "#{mc.link}%5b#{col}%5d=#{value}" 615 end 616 t << "(<a href=\"#{base_url_for("#{mc.link}/new?#{params.join('&')}")}\">create</a>)" 617 end 618 assoc_objs = obj.send(assoc) 619 else 620 assoc_objs = [] 621 end 622 623 unless assoc_objs.empty? 624 t << "<ul>\n" 625 assoc_objs.each do |assoc_obj1| 626 t << "<li>" 627 t << association_link(mc, assoc_obj1) 628 t << "</li>" 629 end 630 t << "</ul>" 631 end 632 633 t << "</li>" 634 end 635 t << "</ul>" 636 end
HTML fragment containing the association links for the given object, or a link to lazily load them if configured. Also contains the inline mtm_edit forms when editing.
# File lib/autoforme/action.rb 575 def association_links(obj) 576 if model.lazy_load_association_links?(type, request) && normalized_type != :association_links && request.params['associations'] != 'show' 577 "<div id='lazy_load_association_links' data-object='#{model.primary_key_value(obj)}' data-type='#{type}'><a href=\"#{url_for("#{type}/#{model.primary_key_value(obj)}?associations=show")}\">Show Associations</a></div>" 578 elsif type == :show 579 association_link_list(obj).to_s 580 else 581 "#{inline_mtm_edit_forms(obj)}#{association_link_list(obj)}" 582 end 583 end
A path for the given page tied to the framework, but not the current model. Used for linking to other models in the same framework.
# File lib/autoforme/action.rb 109 def base_url_for(page) 110 "#{request.path}#{model.framework.prefix}/#{page}" 111 end
The label to use for the given column.
# File lib/autoforme/action.rb 171 def column_label_for(type, request, model, column) 172 unless label = model.column_options_for(type, request, column)[:label] 173 label = humanize(column) 174 end 175 label 176 end
The options to use for the given column, which will be passed to Forme::Form#input.
# File lib/autoforme/action.rb 158 def column_options_for(type, request, obj, column) 159 opts = model.column_options_for(type, request, column) 160 if opts[:class] == 'autoforme_autocomplete' 161 if type == :show 162 opts[:value] = model.column_value(type, request, obj, column) 163 elsif key = obj.send(model.association_key(column)) 164 opts[:value] = "#{key} - #{model.column_value(type, request, obj, column)}" 165 end 166 end 167 opts 168 end
Return a string in CSV format with the results
# File lib/autoforme/action.rb 179 def csv(meth) 180 @output_type = 'csv' 181 @output_filename = "#{model.link.downcase}_#{normalized_type}.csv" 182 columns = model.columns_for(type, request) 183 headers = columns.map{|column| column_label_for(type, request, model, column)} 184 EnumCSV.csv(model.send(meth, normalized_type, request, :all_results=>true), :headers=>headers) do |obj| 185 columns.map{|column| model.column_value(type, request, obj, column)} 186 end 187 end
The page to use when editing the object.
# File lib/autoforme/action.rb 345 def edit_page(obj) 346 page do 347 t = String.new 348 form_attr = form_attributes(:action=>url_for("update/#{model.primary_key_value(obj)}")) 349 t << Forme.form(obj, form_attr, form_opts(form_attr[:action])) do |f| 350 model.columns_for(:edit, request).each do |column| 351 col_opts = column_options_for(:edit, request, obj, column) 352 if html = model.edit_html_for(obj, column, :edit, request) 353 col_opts = col_opts.merge(:html=>html) 354 end 355 f.input(column, col_opts) 356 end 357 f.button(:value=>'Update', :class=>'btn btn-primary') 358 end 359 if model.supported_action?(:delete, request) 360 t << Forme.form(form_attributes(:action=>url_for("delete/#{model.primary_key_value(obj)}")), form_opts) do |f| 361 f.button(:value=>'Delete', :class=>'btn btn-danger') 362 end 363 end 364 t << association_links(obj) 365 end 366 end
Merge the model’s form attributes into the given form attributes, yielding the attributes to use for the form.
# File lib/autoforme/action.rb 241 def form_attributes(attrs) 242 attrs.merge(model.form_attributes_for(type, request)) 243 end
Options to use for the form. If the form uses POST, automatically adds the CSRF token.
# File lib/autoforme/action.rb 225 def form_opts(action=nil) 226 opts = model.form_options_for(type, request).dup 227 228 opts[:_before_post] = lambda do |form| 229 if csrf_hash = request.csrf_token_hash(action) 230 csrf_hash.each do |name, value| 231 form.tag(:input, :type=>:hidden, :name=>name, :value=>value) 232 end 233 end 234 end 235 236 opts 237 end
Convert input to a string adn HTML escape it.
# File lib/autoforme/action.rb 97 def h(s) 98 Rack::Utils.escape_html(s.to_s) 99 end
Handle the current action, returning an HTML string containing the page content, or redirecting.
# File lib/autoforme/action.rb 146 def handle 147 model.before_action_hook(type, request) 148 send("handle_#{type}") 149 end
Handle association_links
action by returning an HTML fragment of association links.
# File lib/autoforme/action.rb 558 def handle_association_links 559 @type = @normalized_type = @subtype 560 obj = model.with_pk(@type, request, request.id) 561 association_links(obj) 562 end
Handle autocomplete action by returning a string with one line per model object.
# File lib/autoforme/action.rb 565 def handle_autocomplete 566 if (query = request.params['q'].to_s).empty? 567 '' 568 else 569 model.autocomplete(:type=>@subtype, :request=>request, :association=>params_association, :query=>query, :exclude=>request.params['exclude']).join("\n") 570 end 571 end
Handle browse action by showing a table containing model objects.
# File lib/autoforme/action.rb 462 def handle_browse 463 if request.id == 'csv' 464 csv(:browse) 465 else 466 table_page(*model.browse(type, request)) 467 end 468 end
Handle the create action by creating a new model object.
# File lib/autoforme/action.rb 270 def handle_create 271 obj = model.new(nil, request) 272 model.set_fields(obj, :new, request, model_params) 273 model.hook(:before_create, request, obj) 274 if model.save(obj) 275 model.hook(:after_create, request, obj) 276 request.set_flash_notice("Created #{model.class_name}") 277 redirect(:new, obj) 278 else 279 request.set_flash_now_error("Error Creating #{model.class_name}") 280 new_page(obj) 281 end 282 end
Handle the edit action by showing a list page if there is no model object selected, or a confirmation screen if there is one.
# File lib/autoforme/action.rb 395 def handle_delete 396 if request.id 397 handle_show 398 else 399 list_page(:delete, :form=>{:action=>url_for('delete')}) 400 end 401 end
Handle the destroy action by destroying the model object.
# File lib/autoforme/action.rb 404 def handle_destroy 405 obj = model.with_pk(normalized_type, request, request.id) 406 model.hook(:before_destroy, request, obj) 407 model.destroy(obj) 408 model.hook(:after_destroy, request, obj) 409 request.set_flash_notice("Deleted #{model.class_name}") 410 redirect(:delete, obj) 411 end
Handle the edit action by showing a list page if there is no model object selected, or the edit page if there is one.
# File lib/autoforme/action.rb 369 def handle_edit 370 if request.id 371 obj = model.with_pk(normalized_type, request, request.id) 372 model.hook(:before_edit, request, obj) 373 edit_page(obj) 374 else 375 list_page(:edit) 376 end 377 end
Handle the mtm_edit action by showing a list page if there is no model object selected, a list of associations for that model if there is a model object but no association selected, or a mtm_edit form if there is a model object and association selected.
# File lib/autoforme/action.rb 495 def handle_mtm_edit 496 if request.id 497 obj = model.with_pk(:edit, request, request.id) 498 unless assoc = params_association 499 options = model.mtm_association_select_options(request) 500 if options.length == 1 501 assoc = options.first 502 end 503 end 504 if assoc 505 page do 506 t = String.new 507 t << "<h2>Edit #{humanize(assoc)} for #{h model.object_display_name(type, request, obj)}</h2>" 508 form_attr = form_attributes(:action=>url_for("mtm_update/#{model.primary_key_value(obj)}?association=#{assoc}")) 509 t << Forme.form(obj, form_attr, form_opts(form_attr[:action])) do |f| 510 opts = model.column_options_for(:mtm_edit, request, assoc) 511 add_opts = opts[:add] ? opts.merge(opts.delete(:add)) : opts 512 remove_opts = opts[:remove] ? opts.merge(opts.delete(:remove)) : opts 513 add_opts = {:name=>'add[]', :id=>'add', :label=>'Associate With'}.merge!(add_opts) 514 if model.association_autocomplete?(assoc, request) 515 f.input(assoc, {:type=>'text', :class=>'autoforme_autocomplete', :attr=>{'data-type'=>'association', 'data-column'=>assoc, 'data-exclude'=>model.primary_key_value(obj)}, :value=>''}.merge!(add_opts)) 516 else 517 f.input(assoc, {:dataset=>model.unassociated_mtm_objects(request, assoc, obj), :size=>10}.merge!(add_opts)) 518 end 519 f.input(assoc, {:name=>'remove[]', :id=>'remove', :label=>'Disassociate From', :dataset=>model.associated_mtm_objects(request, assoc, obj), :value=>[], :size=>10}.merge!(remove_opts)) 520 f.button(:value=>'Update', :class=>'btn btn-primary') 521 end 522 end 523 else 524 page do 525 Forme.form(form_attributes(:action=>"mtm_edit/#{model.primary_key_value(obj)}"), form_opts) do |f| 526 f.input(:select, :options=>options, :name=>'association', :id=>'association', :label=>'Association', :add_blank=>true) 527 f.button(:value=>'Edit', :class=>'btn btn-primary') 528 end 529 end 530 end 531 else 532 list_page(:edit, :form=>{}) 533 end 534 end
Handle mtm_update action by updating the related many to many association. For ajax requests, return an HTML fragment to update the page, otherwise redirect to the appropriate form.
# File lib/autoforme/action.rb 538 def handle_mtm_update 539 obj = model.with_pk(:edit, request, request.id) 540 assoc = params_association 541 assoc_obj = model.mtm_update(request, assoc, obj, request.params['add'], request.params['remove']) 542 request.set_flash_notice("Updated #{assoc} association for #{model.class_name}") unless request.xhr? 543 if request.xhr? 544 if request.params['add'] 545 @type = :edit 546 mtm_edit_remove(assoc, model.associated_model_class(assoc), obj, assoc_obj) 547 else 548 "<option value=\"#{model.primary_key_value(assoc_obj)}\">#{model.associated_object_display_name(assoc, request, assoc_obj)}</option>" 549 end 550 elsif request.params['redir'] == 'edit' 551 redirect(:edit, obj) 552 else 553 redirect(:mtm_edit, obj) 554 end 555 end
Handle the new action by always showing the new form.
# File lib/autoforme/action.rb 263 def handle_new 264 obj = model.new(request.params[model.link], request) 265 model.hook(:before_new, request, obj) 266 new_page(obj) 267 end
Handle browse action by showing a search form if no page is selected, or the correct page of search results if there is a page selected.
# File lib/autoforme/action.rb 472 def handle_search 473 if request.id == 'csv' 474 csv(:search_results) 475 elsif request.id 476 table_page(*model.search_results(normalized_type, request)) 477 else 478 page do 479 Forme.form(model.new(nil, request), form_attributes(:action=>url_for("search/1"), :method=>:get), form_opts) do |f| 480 model.columns_for(:search_form, request).each do |column| 481 col_opts = column_options_for(:search_form, request, f.obj, column).merge(:name=>column, :id=>column) 482 if html = model.edit_html_for(f.obj, column, :search_form, request) 483 col_opts[:html] = html 484 end 485 f.input(column, col_opts) 486 end 487 f.button(:value=>'Search', :class=>'btn btn-primary') 488 end 489 end 490 end 491 end
Handle the show action by showing a list page if there is no model object selected, or the show page if there is one.
# File lib/autoforme/action.rb 336 def handle_show 337 if request.id 338 show_page(model.with_pk(normalized_type, request, request.id)) 339 else 340 list_page(:show) 341 end 342 end
Handle the update action by updating the current model object.
# File lib/autoforme/action.rb 380 def handle_update 381 obj = model.with_pk(normalized_type, request, request.id) 382 model.set_fields(obj, :edit, request, model_params) 383 model.hook(:before_update, request, obj) 384 if model.save(obj) 385 model.hook(:after_update, request, obj) 386 request.set_flash_notice("Updated #{model.class_name}") 387 redirect(:edit, obj) 388 else 389 request.set_flash_now_error("Error Updating #{model.class_name}") 390 edit_page(obj) 391 end 392 end
Convert the given object into a suitable human readable string.
# File lib/autoforme/action.rb 152 def humanize(string) 153 string = string.to_s 154 string.respond_to?(:humanize) ? string.humanize : string.gsub(/_/, " ").capitalize 155 end
HTML fragment used for the inline mtm_edit forms on the edit page.
# File lib/autoforme/action.rb 665 def inline_mtm_edit_forms(obj) 666 assocs = model.inline_mtm_assocs(request) 667 return if assocs.empty? 668 669 t = String.new 670 t << "<div class='inline_mtm_add_associations'>" 671 assocs.each do |assoc| 672 form_attr = form_attributes(:action=>url_for("mtm_update/#{model.primary_key_value(obj)}?association=#{assoc}&redir=edit"), :class => 'mtm_add_associations', 'data-remove' => "##{assoc}_remove_list") 673 t << Forme.form(obj, form_attr, form_opts(form_attr[:action])) do |f| 674 opts = model.column_options_for(:mtm_edit, request, assoc) 675 add_opts = opts[:add] ? opts.merge(opts.delete(:add)) : opts.dup 676 add_opts = {:name=>'add[]', :id=>"add_#{assoc}"}.merge!(add_opts) 677 if model.association_autocomplete?(assoc, request) 678 f.input(assoc, {:type=>'text', :class=>'autoforme_autocomplete', :attr=>{'data-type'=>'association', 'data-column'=>assoc, 'data-exclude'=>model.primary_key_value(obj)}, :value=>''}.merge!(add_opts)) 679 else 680 f.input(assoc, {:dataset=>model.unassociated_mtm_objects(request, assoc, obj), :multiple=>false, :add_blank=>true}.merge!(add_opts)) 681 end 682 f.button(:value=>'Add', :class=>'btn btn-xs btn-primary') 683 end 684 end 685 t << "</div>" 686 t << "<div class='inline_mtm_remove_associations'><ul>" 687 assocs.each do |assoc| 688 mc = model.associated_model_class(assoc) 689 t << "<li>" 690 t << association_class_link(mc, assoc) 691 t << "<ul id='#{assoc}_remove_list'>" 692 obj.send(assoc).each do |assoc_obj| 693 t << mtm_edit_remove(assoc, mc, obj, assoc_obj) 694 end 695 t << "</ul></li>" 696 end 697 t << "</ul></div>" 698 end
Shared page used by show, edit, and delete actions that shows a list of available model objects (or an autocompleting box), and allows the user to choose one to act on.
# File lib/autoforme/action.rb 286 def list_page(type, opts={}) 287 page do 288 form_attr = form_attributes(opts[:form] || {:action=>url_for(type)}) 289 Forme.form(form_attr, form_opts) do |f| 290 input_opts = {:name=>'id', :id=>'id', :label=>model.class_name} 291 if model.autocomplete_options_for(type, request) 292 input_type = :text 293 input_opts.merge!(:class=>'autoforme_autocomplete', :attr=>{'data-type'=>type}) 294 else 295 input_type = :select 296 input_opts.merge!(:options=>model.select_options(type, request), :add_blank=>true) 297 end 298 f.input(input_type, input_opts) 299 f.button(:value=>type.to_s.capitalize, :class=>"btn btn-#{type == :delete ? 'danger' : 'primary'}") 300 end 301 end 302 end
Get request parameters for the model. Used when retrieving form values that use namespacing.
# File lib/autoforme/action.rb 103 def model_params 104 request.params[model.params_name] 105 end
Line item containing form to remove the currently associated object.
# File lib/autoforme/action.rb 701 def mtm_edit_remove(assoc, mc, obj, assoc_obj) 702 t = String.new 703 t << "<li>" 704 t << association_link(mc, assoc_obj) 705 form_attr = form_attributes(:action=>url_for("mtm_update/#{model.primary_key_value(obj)}?association=#{assoc}&remove%5b%5d=#{model.primary_key_value(assoc_obj)}&redir=edit"), :method=>'post', :class => 'mtm_remove_associations', 'data-add'=>"#add_#{assoc}") 706 t << Forme.form(form_attr, form_opts(form_attr[:action])) do |f| 707 f.button(:value=>'Remove', :class=>'btn btn-xs btn-danger') 708 end 709 t << "</li>" 710 end
HTML content used for the new action
# File lib/autoforme/action.rb 246 def new_page(obj, opts={}) 247 page do 248 form_attr = form_attributes(:action=>url_for("create")) 249 Forme.form(obj, form_attr, form_opts(form_attr[:action])) do |f| 250 model.columns_for(:new, request).each do |column| 251 col_opts = column_options_for(:new, request, obj, column) 252 if html = model.edit_html_for(obj, column, :new, request) 253 col_opts = col_opts.merge(:html=>html) 254 end 255 f.input(column, col_opts) 256 end 257 f.button(:value=>'Create', :class=>'btn btn-primary') 258 end 259 end 260 end
Yields and wraps the returned data in a header and footer for the page.
# File lib/autoforme/action.rb 214 def page 215 html = String.new 216 html << (model.page_header_for(type, request) || tabs) 217 html << "<div id='autoforme_content' data-url='#{url_for('')}'>" 218 html << yield.to_s 219 html << "</div>" 220 html << model.page_footer_for(type, request).to_s 221 html 222 end
Redirect to a page based on the type of action and the given object.
# File lib/autoforme/action.rb 124 def redirect(type, obj) 125 if redir = model.redirect_for 126 path = redir.call(obj, type, request) 127 end 128 129 unless path 130 path = case type 131 when :new, :delete 132 type.to_s 133 when :edit 134 "edit/#{model.primary_key_value(obj)}" 135 else # when :mtm_edit 136 "mtm_edit/#{model.primary_key_value(obj)}?association=#{params_association}" 137 end 138 path = url_for(path) 139 end 140 141 request.redirect(path) 142 end
The page to use when displaying an object, always used as a confirmation screen when deleting an object.
# File lib/autoforme/action.rb 305 def show_page(obj) 306 page do 307 t = String.new 308 f = Forme::Form.new(obj, :formatter=>:readonly, :wrapper=>:trtd, :labeler=>:explicit) 309 t << "<table class=\"#{model.table_class_for(:show, request)}\">" 310 model.columns_for(type, request).each do |column| 311 col_opts = column_options_for(type, request, obj, column) 312 if html = model.show_html_for(obj, column, type, request) 313 col_opts = col_opts.merge(:html=>html) 314 end 315 t << f.input(column, col_opts) 316 end 317 t << '</table>' 318 if type == :show && model.supported_action?(:edit, request) 319 t << Forme.form(form_attributes(:action=>url_for("edit/#{model.primary_key_value(obj)}")), form_opts) do |f1| 320 f1.button(:value=>'Edit', :class=>'btn btn-primary') 321 end 322 end 323 if type == :delete 324 form_attr = form_attributes(:action=>url_for("destroy/#{model.primary_key_value(obj)}"), :method=>:post) 325 t << Forme.form(form_attr, form_opts(form_attr[:action])) do |f1| 326 f1.button(:value=>'Delete', :class=>'btn btn-danger') 327 end 328 else 329 t << association_links(obj) 330 end 331 t 332 end 333 end
The subtype of request, used for association_links
and autocomplete actions.
# File lib/autoforme/action.rb 119 def subtype 120 ((t = request.params['type']) && ALL_SUPPORTED_ACTIONS.include?(t) && t.to_sym) || :edit 121 end
Return true if the action is supported, and false otherwise. An action may not be supported if the type is not one of the supported types, or if an non-idemponent request is issued with get instead of post, or potentionally other reasons.
As a side-effect, this sets up additional state related to the request.
# File lib/autoforme/action.rb 55 def supported? 56 return false unless ALL_SUPPORTED_ACTIONS.include?(request.action_type) 57 type = @type = request.action_type.to_sym 58 @normalized_type = NORMALIZED_ACTION_MAP.fetch(type, type) 59 return false if NON_IDEMPOTENT_TYPES[type] && !request.post? 60 61 case type 62 when :mtm_edit 63 return false unless model.supported_action?(type, request) 64 if request.id && (assoc = request.params['association']) 65 return false unless model.supported_mtm_edit?(assoc, request) 66 @params_association = assoc.to_sym 67 end 68 69 @title = "#{model.class_name} - #{TITLE_MAP[type]}" 70 when :mtm_update 71 return false unless request.id && (assoc = request.params['association']) && model.supported_mtm_update?(assoc, request) 72 @params_association = assoc.to_sym 73 when :association_links 74 @subtype = subtype 75 return false unless model.supported_action?(@subtype, request) 76 when :autocomplete 77 if assoc = request.id 78 return false unless model.association?(assoc) 79 @params_association = assoc.to_sym 80 @subtype = :association 81 return false unless associated_class = model.associated_model_class(@params_association) 82 return false unless associated_class.autocomplete_options_for(@subtype, request) 83 else 84 @subtype = subtype 85 return false unless model.autocomplete_options_for(@subtype, request) 86 end 87 else 88 return false unless model.supported_action?(normalized_type, request) 89 90 @title = "#{model.class_name} - #{TITLE_MAP[@normalized_type]}" 91 end 92 93 true 94 end
The name to give the tab for the given type.
# File lib/autoforme/action.rb 202 def tab_name(type) 203 case type 204 when :browse 205 model.class_name 206 when :mtm_edit 207 'MTM' 208 else 209 type.to_s.capitalize 210 end 211 end
Show page used for browse/search pages.
# File lib/autoforme/action.rb 455 def table_page(next_page, objs) 456 page do 457 Table.new(self, objs).to_s << table_pager(normalized_type, next_page) 458 end 459 end
HTML fragment for the table pager, showing links to next page or previous page for browse/search forms.
# File lib/autoforme/action.rb 414 def table_pager(type, next_page) 415 html = String.new 416 html << '<ul class="pager">' 417 qs = next_qs = h request.query_string 418 419 if next_page.is_a?(Array) 420 # Filter pagination, next_page contains the values for the last record of current page 421 no_previous = true 422 if next_page.empty? 423 next_page = nil 424 else 425 next_qs = qs.dup 426 params = request.params.dup 427 next_page = next_page.map(&:to_s) 428 next_page = next_page[0] if next_page.length == 1 429 params["_after"] = next_page 430 next_qs = h Rack::Utils.build_nested_query(params) 431 following = prev = "0" 432 end 433 else 434 # Offset pagination, request id contains current page 435 page = request.id.to_i 436 page = 1 if page < 1 437 no_previous = page <= 1 438 prev = page-1 439 following = page+1 440 end 441 442 unless no_previous 443 html << "<li><a href=\"#{url_for("#{type}/#{prev}?#{qs}")}\">Previous</a></li>" 444 end 445 446 if next_page 447 html << "<li><a href=\"#{url_for("#{type}/#{following}?#{next_qs}")}\">Next</a></li>" 448 end 449 450 html << "</ul>" 451 html << "<p><a href=\"#{url_for("#{type}/csv?#{qs}")}\">CSV Format</a></p>" 452 end
HTML fragment for the default page header, which uses tabs for each supported action.
# File lib/autoforme/action.rb 190 def tabs 191 content = String.new 192 content << '<ul class="nav nav-tabs">' 193 Model::DEFAULT_SUPPORTED_ACTIONS.each do |action_type| 194 if model.supported_action?(action_type, request) 195 content << "<li class=\"nav-item #{'active' if type == action_type}\"><a class=\"nav-link\" href=\"#{url_for(action_type)}\">#{tab_name(action_type)}</a></li>" 196 end 197 end 198 content << '</ul>' 199 end
A path for the given page for the same model.
# File lib/autoforme/action.rb 114 def url_for(page) 115 base_url_for("#{model.link}/#{page}") 116 end