Class: Dommy::HTMLSelectElement
Overview
‘<select>` — exposes `value` (selected option’s value), ‘options`, `selectedIndex`, and dispatches change events. Minimal compared to happy-dom’s full HTMLSelectElement, but covers common test cases.
Constant Summary
collapse
- JS_METHOD_NAMES =
Own js_call methods, on top of Element’s.
%w[item add checkValidity reportValidity setCustomValidity].freeze
Constants inherited
from Element
Element::ATTRIBUTE_NODE, Element::CDATA_SECTION_NODE, Element::COMMENT_NODE, Element::DOCUMENT_FRAGMENT_NODE, Element::DOCUMENT_NODE, Element::DOCUMENT_POSITION_CONTAINED_BY, Element::DOCUMENT_POSITION_CONTAINS, Element::DOCUMENT_POSITION_DISCONNECTED, Element::DOCUMENT_POSITION_FOLLOWING, Element::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC, Element::DOCUMENT_POSITION_PRECEDING, Element::DOCUMENT_TYPE_NODE, Element::ELEMENT_NODE, Element::PROCESSING_INSTRUCTION_NODE, Element::SHADOW_HOST_TAGS, Element::TEXT_NODE
Constants included
from Node
Node::ATTRIBUTE_NODE, Node::CDATA_SECTION_NODE, Node::COMMENT_NODE, Node::DOCUMENT_FRAGMENT_NODE, Node::DOCUMENT_NODE, Node::DOCUMENT_POSITION_CONTAINED_BY, Node::DOCUMENT_POSITION_CONTAINS, Node::DOCUMENT_POSITION_DISCONNECTED, Node::DOCUMENT_POSITION_FOLLOWING, Node::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC, Node::DOCUMENT_POSITION_PRECEDING, Node::DOCUMENT_TYPE_NODE, Node::ELEMENT_NODE, Node::PROCESSING_INSTRUCTION_NODE, Node::TEXT_NODE
Instance Attribute Summary
Attributes inherited from Element
#document
Instance Method Summary
collapse
Methods inherited from HTMLElement
#case_sensitive_attribute_names?
Methods inherited from Element
#[], #[]=, #__dommy_backend_node__, #__internal_shadow_root__, #__test_scroll_log__, #after, #anchor_href, #animate, #append, #append_child, #at_xpath, #attach_shadow, #attributes, #base_uri, #before, #blur, #child_element_count, #child_nodes, #children, #class_list, #class_name, #class_name=, #click, #clone_node, #closest, #compare_document_position, #contains?, #dataset, #equal_node?, #first_child, #first_element_child, #focus, #get_animations, #get_attribute, #get_attribute_node, #get_elements_by_class_name, #get_elements_by_tag_name, #get_html, #get_inner_html, #has_attribute?, #has_attributes?, #has_child_nodes?, #id, #id=, #initialize, #inner_html, #inner_html=, #insert_adjacent_element, #insert_adjacent_html, #insert_adjacent_text, #insert_before, #is_connected?, #last_child, #last_element_child, #live_child_nodes, #local_name, #matches?, #namespace_uri, #next_element_sibling, #next_sibling, #normalize, #on, #outer_html, #outer_html=, #owner_document, #parent_element, #parent_node, #path, #prepend, #previous_element_sibling, #previous_sibling, #query_selector, #query_selector_all, #reflected_attr_name, #remove, #remove_attribute, #remove_attribute_node, #remove_child, #replace_child, #replace_children, #replace_with_nodes, #role, #role=, #root_node, #same_node?, #set_attribute, #set_attribute_node, #shadow_root, #slot, #slot=, #style, #tag_name, #text_content, #text_content=, #to_s, #toggle_attribute, #xpath
#__internal_deliver_event__, #add_event_listener, #dispatch_event, #invoke_listener, #remove_event_listener
Constructor Details
This class inherits a constructor from Dommy::Element
Instance Method Details
#__js_call__(method, args) ⇒ Object
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
|
# File 'lib/dommy/html_elements.rb', line 2383
def __js_call__(method, args)
case method
when "item"
item(args[0])
when "add"
add(args[0], args[1])
when "checkValidity"
check_validity
when "reportValidity"
report_validity
when "setCustomValidity"
set_custom_validity(args[0])
else
super
end
end
|
#__js_get__(key) ⇒ Object
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
|
# File 'lib/dommy/html_elements.rb', line 2335
def __js_get__(key)
case key
when "options"
options
when "length"
length
when "value"
value
when "name"
name
when "multiple"
multiple
when "size"
size
when "selectedIndex"
selected_index
when "form"
form
when "labels"
labels
when "type"
type
when "validity"
validity
when "willValidate"
will_validate
when "validationMessage"
validation_message
else
super
end
end
|
#__js_method_names__ ⇒ Object
2173
2174
2175
|
# File 'lib/dommy/html_elements.rb', line 2173
def __js_method_names__
super + JS_METHOD_NAMES
end
|
#__js_set__(key, val) ⇒ Object
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
|
# File 'lib/dommy/html_elements.rb', line 2368
def __js_set__(key, val)
case key
when "value"
self.value = val
when "name"
set_reflected_string("name", val)
when "multiple"
set_reflected_boolean("multiple", val)
when "selectedIndex"
self.selected_index = val
else
super
end
end
|
#add(option, before = nil) ⇒ Object
‘select.add(option, before)` — appends or inserts before `before`.
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
|
# File 'lib/dommy/html_elements.rb', line 2272
def add(option, before = nil)
return nil unless option.respond_to?(:__dommy_backend_node__)
if before.respond_to?(:__dommy_backend_node__)
insert_before(option, before)
else
append_child(option)
end
nil
end
|
#check_validity ⇒ Object
2320
2321
2322
2323
2324
|
# File 'lib/dommy/html_elements.rb', line 2320
def check_validity
ok = !will_validate || validity.valid
dispatch_event(Event.new("invalid", "bubbles" => false, "cancelable" => true)) unless ok
ok
end
|
2226
2227
2228
|
# File 'lib/dommy/html_elements.rb', line 2226
def form
closest("form")
end
|
#item(i) ⇒ Object
‘select.item(i)` — returns the option at index i.
2267
2268
2269
|
# File 'lib/dommy/html_elements.rb', line 2267
def item(i)
options[i.to_i]
end
|
#labels ⇒ Object
2292
2293
2294
2295
2296
|
# File 'lib/dommy/html_elements.rb', line 2292
def labels
return [] if id.empty?
@document.query_selector_all("label[for='#{id}']")
end
|
#length ⇒ Object
2222
2223
2224
|
# File 'lib/dommy/html_elements.rb', line 2222
def length
options.size
end
|
#multiple ⇒ Object
2185
2186
2187
|
# File 'lib/dommy/html_elements.rb', line 2185
def multiple
reflected_boolean("multiple")
end
|
#multiple=(v) ⇒ Object
2189
2190
2191
|
# File 'lib/dommy/html_elements.rb', line 2189
def multiple=(v)
set_reflected_boolean("multiple", v)
end
|
#name ⇒ Object
2177
2178
2179
|
# File 'lib/dommy/html_elements.rb', line 2177
def name
reflected_string("name")
end
|
#name=(v) ⇒ Object
2181
2182
2183
|
# File 'lib/dommy/html_elements.rb', line 2181
def name=(v)
set_reflected_string("name", v)
end
|
#options ⇒ Object
‘options` — all <option> descendants (including those inside <optgroup>). Live HTMLOptionsCollection (HTMLCollection + add/remove/selectedIndex/length= helpers).
2200
2201
2202
2203
2204
2205
|
# File 'lib/dommy/html_elements.rb', line 2200
def options
el = self
HTMLOptionsCollection.new(self) do
el.__dommy_backend_node__.css("option").map { |n| el.document.wrap_node(n) }.compact
end
end
|
#remove_option(i) ⇒ Object
‘select.remove(i)` — removes the option at index i. (Note: also inherits `remove()` from ChildNode for self-removal; spec lets both forms coexist via overloading.)
2287
2288
2289
2290
|
# File 'lib/dommy/html_elements.rb', line 2287
def remove_option(i)
target = options[i.to_i]
target&.remove
end
|
#report_validity ⇒ Object
2326
2327
2328
|
# File 'lib/dommy/html_elements.rb', line 2326
def report_validity
check_validity
end
|
#selected_index ⇒ Object
‘selectedIndex` — first option with `selected`, or 0 if none and not multiple, or -1 if multiple and none.
2232
2233
2234
2235
2236
2237
2238
|
# File 'lib/dommy/html_elements.rb', line 2232
def selected_index
opts = options
idx = opts.find_index { |o| o.__dommy_backend_node__.key?("selected") }
return idx if idx
multiple ? -1 : (opts.empty? ? -1 : 0)
end
|
#selected_index=(i) ⇒ Object
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
|
# File 'lib/dommy/html_elements.rb', line 2240
def selected_index=(i)
opts = options
opts.each_with_index do |o, idx|
if idx == i.to_i
o.set_attribute("selected", "")
elsif o.__dommy_backend_node__.key?("selected")
o.remove_attribute("selected")
end
end
end
|
#selected_options ⇒ Object
‘selectedOptions` — live collection of options with `selected` attribute. When nothing is explicitly selected, browsers fall back to the first option for non-multiple selects.
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
|
# File 'lib/dommy/html_elements.rb', line 2210
def selected_options
el = self
HTMLCollection.new do
opts = el.__dommy_backend_node__.css("option").map { |n| el.document.wrap_node(n) }.compact
chosen = opts.select { |o| o.__dommy_backend_node__.key?("selected") }
next chosen unless chosen.empty?
next [] if el.multiple
opts.first ? [opts.first] : []
end
end
|
#set_custom_validity(msg) ⇒ Object
2330
2331
2332
2333
|
# File 'lib/dommy/html_elements.rb', line 2330
def set_custom_validity(msg)
@custom_validity_message = msg.to_s
nil
end
|
#size ⇒ Object
2193
2194
2195
|
# File 'lib/dommy/html_elements.rb', line 2193
def size
@__node__["size"].to_s.to_i
end
|
#type ⇒ Object
2298
2299
2300
|
# File 'lib/dommy/html_elements.rb', line 2298
def type
multiple ? "select-multiple" : "select-one"
end
|
#validation_message ⇒ Object
2310
2311
2312
2313
2314
2315
2316
2317
2318
|
# File 'lib/dommy/html_elements.rb', line 2310
def validation_message
return "" unless will_validate
msg = (@custom_validity_message || "").to_s
return msg unless msg.empty?
return "Please select an item in the list." if validity.value_missing
""
end
|
#validity ⇒ Object
2302
2303
2304
|
# File 'lib/dommy/html_elements.rb', line 2302
def validity
@__validity ||= ValidityState.new(self)
end
|
#value ⇒ Object
‘value` of the select = value of the selected option, or “”.
2252
2253
2254
2255
2256
|
# File 'lib/dommy/html_elements.rb', line 2252
def value
opts = options
sel = opts.find { |o| o.__dommy_backend_node__.key?("selected") } || opts.first
sel ? (sel.__dommy_backend_node__["value"] || sel.text_content).to_s : ""
end
|
#value=(new_value) ⇒ Object
2258
2259
2260
2261
2262
2263
2264
|
# File 'lib/dommy/html_elements.rb', line 2258
def value=(new_value)
target = options.find { |o| (o.__dommy_backend_node__["value"] || o.text_content).to_s == new_value.to_s }
return unless target
options.each { |o| o.remove_attribute("selected") if o.__dommy_backend_node__.key?("selected") }
target.set_attribute("selected", "")
end
|
#will_validate ⇒ Object
2306
2307
2308
|
# File 'lib/dommy/html_elements.rb', line 2306
def will_validate
!reflected_boolean("disabled")
end
|