combo.ex 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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 -> select(msg)
  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 select(NITRO.comboSelect(uid: uid, dom: field)), do:
  40. NITRO.Combo.Search.stop(uid, field)
  41. def comboInsert(NITRO.comboInsert(chunks: 0, dom: field, status: :finished)) do
  42. :nitro.wire("activeCombo = undefined; currentItem = undefined;")
  43. :nitro.hide(:nitro.atom([:comboContainer, :nitro.to_list(field)]))
  44. :nitro.wire("comboOpenFormById('#{:nitro.atom([:nitro.to_list(field), 'form'])}');")
  45. end
  46. def comboInsert(NITRO.comboInsert(uid: uid, dom: field, rows: rows, delegate: module, feed: feed)) do
  47. :lists.foreach(fn row ->
  48. :nitro.insert_bottom(
  49. :nitro.atom([:comboContainer, :nitro.to_list(field)]),
  50. :nitro.render(dropDown0(uid, row, :nitro.to_list(field), module, feed))
  51. )
  52. end, rows)
  53. end
  54. def dropDown0(uid, obj, dom0, module, feed) do
  55. case has_function(module, :dropDown) do
  56. true ->
  57. module.dropDown(uid, obj, dom0, feed)
  58. false ->
  59. dropDown(uid, obj, dom0, module, feed)
  60. end
  61. end
  62. def view_value(obj, _, _) when obj in ["", [], :undefined], do: []
  63. def view_value(obj, module, feed) do
  64. case :erlang.function_exported(module, :view_value, 2) do
  65. true ->
  66. module.view_value(obj, feed)
  67. false ->
  68. if has_function(module, :view_value) do
  69. module.view_value(obj)
  70. else
  71. view_value(obj)
  72. end
  73. end
  74. end
  75. def view_value(obj) when obj in ["", [], :undefined], do: []
  76. def view_value(obj), do: :nitro.jse(:erlang.iolist_to_binary(apply(:kvs,:field,[obj, hd(index([]))])))
  77. def dropDown(uid, obj, dom0, module, feed) do
  78. view_value = view_value(obj, module, feed)
  79. dom = :nitro.to_list(dom0)
  80. id = :nitro.jse(:erlang.iolist_to_binary(:nitro.atom([dom, :erlang.element(2, obj)])))
  81. item = :nitro.to_list(item(obj, module))
  82. source = :erlang.iolist_to_binary(feed)
  83. click = :nitro.jse("comboSelect('#{uid}', '#{dom}', '#{view_value}', '#{source}', '#{module}', '#{id}')")
  84. move = :nitro.jse("comboLookupMouseMove('#{dom}')")
  85. NITRO.panel(
  86. id: id,
  87. class: ['dropdown-item'],
  88. bind: :base64.encode(:erlang.term_to_binary(obj)),
  89. onclick: click,
  90. onmousemove: move,
  91. body: [
  92. NITRO.p(body: item)
  93. ]
  94. )
  95. end
  96. def index([]), do: [:name, :id]
  97. def index(module) do
  98. case has_function(module, :index) do
  99. true -> module.index()
  100. false -> index([])
  101. end
  102. end
  103. def item(obj, []), do: view_value(obj)
  104. def item(obj, module) do
  105. case has_function(module, :item) do
  106. true -> module.item(obj)
  107. false -> item(obj, [])
  108. end
  109. end
  110. def update_comboVec(_parent, dom, feed, module, default, elem) do
  111. vector = view_value(default, module, feed)
  112. clear = "createSortable('##{dom}_list');"
  113. append = :lists.map(fn emp -> bind = emp |> :erlang.term_to_binary |> :base64.encode
  114. "appendItemFromBind('#{dom}_list','#{module.cn(emp)}','#{bind}');" end, vector)
  115. |> :erlang.iolist_to_binary
  116. render = :nitro.render elem
  117. command = "elem = qi('#{dom}'); elem.outerHTML = '#{render}';"
  118. :nitro.wire(command <> append <> clear) # reverse
  119. end
  120. def update_combo(id, feed, module), do: :nitro.update(:nitro.atom([:lookup, id]), NITRO.comboLookup(id: id, feed: feed, delegate: module))
  121. def update_combo_value(dom, value, feed, module) do
  122. view_value = view_value(value, module, feed)
  123. update_combo_value(dom, value, feed, module, view_value)
  124. end
  125. def update_combo_value(dom, value, feed, module, view_value) do
  126. bind = :base64.encode(:erlang.term_to_binary(value))
  127. update_combo(dom, feed, module)
  128. command = "elem = qi('#{dom}'); elem.setAttribute('data-bind', '#{bind}'); elem.value = '#{view_value}';"
  129. :nitro.wire(command)
  130. end
  131. def has_function(m, f) do
  132. functions = apply(m, :module_info, [:exports])
  133. isF = Keyword.get(functions, f, -1)
  134. isF != -1
  135. end
  136. end