module Ecoportal module API class V2 class Page class Component class SelectionField < Page::Component passthrough :multiple, :flat passthrough :other, :other_desc #class_resolver :selection_option_class, "Ecoportal::API::V2::Page::Component::SelectionOption" embeds_multiple :options, klass: "Ecoportal::API::V2::Page::Component::SelectionOption", order_key: :weight def select(value) opt = options.find {|opt| opt.value == value} sel = selected return true if !multiple && opt == sel sel.selected = false if !multiple && sel opt.selected = true unless !opt end def selected if multiple options.select {|opt| opt.selected} else options.find {|opt| opt.selected} end end def value if multiple selected.map {|opt| opt.value} else selected&.value end end def add_option(name:, value:, pos: NOT_USED, before: NOT_USED, after: NOT_USED) opt_doc = Ecoportal::API::V2::Page::Component::SelectionOption.new_doc options.upsert!(opt_doc, pos: pos, before: before, after: after) do |option| option.name = name option.value = value if prev = previous_option(option) option.weight = prev.weight end yield(option) if block_given? fix_option_weights! end end def ordered_options options.each_with_index.sort_by do |option, index| (option.weight >= 9999) ? [index, index] : [option.weight, index] end.map(&:first) end private def fix_option_weights! ordered_options.each_with_index do |option, index| option.weight = index end end def previous_option(value) opts = ordered_options pos = opts.index(value) - 1 return if pos < 0 opts[pos] end end end end end end end require 'ecoportal/api/v2/page/component/selection_option'