combo.ex 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. defmodule NITRO.Combo do
  2. require NITRO
  3. require Record
  4. def to_list(fld) when is_atom(fld), do: fld
  5. def to_list(fld), do: :unicode.characters_to_list(fld, :unicode)
  6. def new(_name, obj, module, options) do
  7. dom = :proplists.get_value(:dom, options)
  8. feed = :proplists.get_value(:feed, options)
  9. dropDown(obj, dom, module, feed)
  10. end
  11. def proto(NITRO.comboKey(value: "")), do: []
  12. def proto(NITRO.comboKey(delegate: []) = msg), do: NITRO.Combo.Search.keyUp(msg)
  13. def proto(NITRO.comboScroll(delegate: []) = msg), do: NITRO.Combo.Search.comboScroll(msg)
  14. def proto(NITRO.comboInsert(delegate: []) = msg), do: comboInsert(msg)
  15. def proto(NITRO.comboKey(delegate: module) = msg) do
  16. case has_function(module, :keyUp) do
  17. true -> module.keyUp(msg)
  18. false -> NITRO.Combo.Search.keyUp(msg)
  19. end
  20. end
  21. def proto(NITRO.comboScroll(delegate: module) = msg) do
  22. case has_function(module, :comboScroll) do
  23. true -> module.comboScroll(msg)
  24. false -> NITRO.Combo.Search.comboScroll(msg)
  25. end
  26. end
  27. def proto(NITRO.comboSelect(delegate: module) = msg) do
  28. case has_function(module, :select) do
  29. true -> module.select(msg)
  30. false -> :skip
  31. end
  32. end
  33. def proto(NITRO.comboInsert(delegate: module) = msg) do
  34. case has_function(module, :comboInsert) do
  35. true -> module.comboInsert(msg)
  36. false -> comboInsert(msg)
  37. end
  38. end
  39. def comboInsert(NITRO.comboInsert(chunks: 0, dom: field, status: :finished)) do
  40. :nitro.wire("activeCombo = undefined; currentItem = undefined;")
  41. :nitro.hide(:nitro.atom([:comboContainer, :nitro.to_list(field)]))
  42. :nitro.wire("comboOpenFormById('#{:nitro.atom([:nitro.to_list(field), 'form'])}');")
  43. end
  44. def comboInsert(NITRO.comboInsert(dom: field, rows: rows, delegate: module, feed: feed)) do
  45. :lists.foreach(fn row ->
  46. :nitro.insert_bottom(
  47. :nitro.atom([:comboContainer, :nitro.to_list(field)]),
  48. :nitro.render(dropDown0(row, :nitro.to_list(field), module, feed))
  49. )
  50. end, rows)
  51. end
  52. def dropDownList0(filtered, field, module, feed) do
  53. if has_function(module, :dropDownList) do
  54. module.dropDownList(filtered, field, module, feed)
  55. else
  56. dropDownList(filtered, field, module, feed)
  57. end
  58. end
  59. def dropDownList(filtered, field, module, feed) do
  60. formId = :nitro.atom([field, "form"])
  61. if filtered == [] do
  62. :nitro.wire("activeCombo = undefined; currentItem = undefined;")
  63. :nitro.hide(:nitro.atom([:comboContainer, field]))
  64. :nitro.wire("comboOpenFormById('#{formId}');")
  65. else
  66. :nitro.display(:nitro.atom([:comboContainer, field]), :block)
  67. :nitro.wire("comboCloseFormById('#{formId}');")
  68. end
  69. Enum.each(filtered, fn obj ->
  70. form = dropDown0(obj, field, module, feed)
  71. :nitro.insert_top(
  72. :nitro.atom([:comboContainer, field]),
  73. :nitro.render(form)
  74. )
  75. end)
  76. end
  77. def dropDown0(obj, dom0, module, feed) do
  78. case has_function(module, :dropDown) do
  79. true ->
  80. module.dropDown(obj, dom0, feed)
  81. false ->
  82. dropDown(obj, dom0, module, feed)
  83. end
  84. end
  85. def view_value(obj, _, _) when obj in ["", [], :undefined], do: []
  86. def view_value(obj, module, feed) do
  87. case :erlang.function_exported(module, :view_value, 2) do
  88. true ->
  89. module.view_value(obj, feed)
  90. false ->
  91. if has_function(module, :view_value) do
  92. module.view_value(obj)
  93. else
  94. view_value(obj)
  95. end
  96. end
  97. end
  98. def view_value(obj) when obj in ["", [], :undefined], do: []
  99. def view_value(obj), do: :nitro.jse(:erlang.iolist_to_binary(apply(:kvs,:field,[obj, hd(index([]))])))
  100. def dropDown(obj, dom0, module, feed) do
  101. view_value = view_value(obj, module, feed)
  102. dom = :nitro.to_list(dom0)
  103. id = :nitro.jse(:erlang.iolist_to_binary(:nitro.atom([dom, :erlang.element(2, obj)])))
  104. item = :nitro.to_list(item(obj, module))
  105. source = :erlang.iolist_to_binary(feed)
  106. click = :nitro.jse("comboSelect('#{dom}', '#{view_value}', '#{source}', '#{module}', '#{id}')")
  107. move = :nitro.jse("comboLookupMouseMove('#{dom}')")
  108. NITRO.panel(
  109. id: id,
  110. class: ['dropdown-item'],
  111. bind: :base64.encode(:erlang.term_to_binary(obj)),
  112. onclick: click,
  113. onmousemove: move,
  114. body: [
  115. NITRO.p(body: item)
  116. ]
  117. )
  118. end
  119. def index([]), do: [:name, :id]
  120. def index(module) do
  121. case has_function(module, :index) do
  122. true -> module.index()
  123. false -> index([])
  124. end
  125. end
  126. def item(obj, []), do: view_value(obj)
  127. def item(obj, module) do
  128. case has_function(module, :item) do
  129. true -> module.item(obj)
  130. false -> item(obj, [])
  131. end
  132. end
  133. def update_comboVec(_parent, dom, feed, module, default, elem) do
  134. vector = view_value(default, module, feed)
  135. clear = "createSortable('##{dom}_list');"
  136. append = :lists.map(fn emp -> bind = emp |> :erlang.term_to_binary |> :base64.encode
  137. "appendItemFromBind('#{dom}_list','#{module.cn(emp)}','#{bind}');" end, vector)
  138. |> :erlang.iolist_to_binary
  139. render = :nitro.render elem
  140. command = "elem = qi('#{dom}'); elem.outerHTML = '#{render}';"
  141. :nitro.wire(command <> append <> clear) # reverse
  142. end
  143. def update_combo(id, feed, module), do: :nitro.update(:nitro.atom([:lookup, id]), NITRO.comboLookup(id: id, feed: feed, delegate: module))
  144. def update_combo_value(dom, value, feed, module) do
  145. view_value = view_value(value, module, feed)
  146. update_combo_value(dom, value, feed, module, view_value)
  147. end
  148. def update_combo_value(dom, value, feed, module, view_value) do
  149. bind = :base64.encode(:erlang.term_to_binary(value))
  150. update_combo(dom, feed, module)
  151. command = "elem = qi('#{dom}'); elem.setAttribute('data-bind', '#{bind}'); elem.value = '#{view_value}';"
  152. :nitro.wire(command)
  153. end
  154. def has_function(m, f) do
  155. functions = apply(m, :module_info, [:exports])
  156. isF = Keyword.get(functions, f, -1)
  157. isF != -1
  158. end
  159. end