Browse Source

nitro 6.11.10

SunRiseGC 3 years ago
parent
commit
f01a7a6ab3
7 changed files with 47 additions and 62 deletions
  1. 2 2
      include/comboLookup.hrl
  2. 12 39
      lib/combo.ex
  3. 27 18
      lib/comboSearch.ex
  4. 1 1
      mix.exs
  5. 2 1
      priv/js/comboLookup.js
  6. 1 1
      src/nitro_pi.erl
  7. 2 0
      src/render/wf_event.erl

+ 2 - 2
include/comboLookup.hrl

@@ -5,10 +5,10 @@
 
 -record(comboKey,    { uid=[], value=[], dom=[], feed=[], delegate=[]}).
 -record(comboKeyup,  { value=[], dom=[], feed=[], delegate=[]}).
--record(comboSelect, { value=[], dom=[], feed=[], delegate=[] }).
+-record(comboSelect, { uid=[], value=[], dom=[], feed=[], delegate=[] }).
 -record(comboNext,   { pos=[],  count=[], feed=[]}).
 -record(comboScroll, { uid=[], dom=[], delegate=[] }).
--record(comboInsert, { dom=[], rows=[], chunks=[], status=[], delegate=[], feed=[] }).
+-record(comboInsert, { uid=[], dom=[], rows=[], chunks=[], status=[], delegate=[], feed=[] }).
 -record(comboLookup, { ?ELEMENT_BASE(element_comboLookup),
     value=[],
     disabled=false,

+ 12 - 39
lib/combo.ex

@@ -8,7 +8,7 @@ defmodule NITRO.Combo do
   def new(_name, obj, module, options) do
     dom = :proplists.get_value(:dom, options)
     feed = :proplists.get_value(:feed, options)
-    dropDown(obj, dom, module, feed)
+    dropDown([], obj, dom, module, feed)
   end
 
   def proto(NITRO.comboKey(value: "")), do: []
@@ -33,7 +33,7 @@ defmodule NITRO.Combo do
   def proto(NITRO.comboSelect(delegate: module) = msg) do
     case has_function(module, :select) do
       true -> module.select(msg)
-      false -> :skip
+      false -> select(msg)
     end
   end
 
@@ -44,58 +44,31 @@ defmodule NITRO.Combo do
     end
   end
 
+  def select(NITRO.comboSelect(uid: uid, dom: field)), do:
+    NITRO.Combo.Search.stop(uid, field)
+
   def comboInsert(NITRO.comboInsert(chunks: 0, dom: field, status: :finished)) do
     :nitro.wire("activeCombo = undefined; currentItem = undefined;")
     :nitro.hide(:nitro.atom([:comboContainer, :nitro.to_list(field)]))
     :nitro.wire("comboOpenFormById('#{:nitro.atom([:nitro.to_list(field), 'form'])}');")
   end
 
-  def comboInsert(NITRO.comboInsert(dom: field, rows: rows, delegate: module, feed: feed)) do
+  def comboInsert(NITRO.comboInsert(uid: uid, dom: field, rows: rows, delegate: module, feed: feed)) do
     :lists.foreach(fn row ->
       :nitro.insert_bottom(
         :nitro.atom([:comboContainer, :nitro.to_list(field)]),
-        :nitro.render(dropDown0(row, :nitro.to_list(field), module, feed))
+        :nitro.render(dropDown0(uid, row, :nitro.to_list(field), module, feed))
       )
     end, rows)
   end
 
-  def dropDownList0(filtered, field, module, feed) do
-    if has_function(module, :dropDownList) do
-      module.dropDownList(filtered, field, module, feed)
-    else
-      dropDownList(filtered, field, module, feed)
-    end
-  end
-
-  def dropDownList(filtered, field, module, feed) do
-    formId = :nitro.atom([field, "form"])
-
-    if filtered == [] do
-      :nitro.wire("activeCombo = undefined; currentItem = undefined;")
-      :nitro.hide(:nitro.atom([:comboContainer, field]))
-      :nitro.wire("comboOpenFormById('#{formId}');")
-    else
-      :nitro.display(:nitro.atom([:comboContainer, field]), :block)
-      :nitro.wire("comboCloseFormById('#{formId}');")
-    end
-
-    Enum.each(filtered, fn obj ->
-      form = dropDown0(obj, field, module, feed)
-
-      :nitro.insert_top(
-        :nitro.atom([:comboContainer, field]),
-        :nitro.render(form)
-      )
-    end)
-  end
-
-  def dropDown0(obj, dom0, module, feed) do
+  def dropDown0(uid, obj, dom0, module, feed) do
     case has_function(module, :dropDown) do
       true ->
-        module.dropDown(obj, dom0, feed)
+        module.dropDown(uid, obj, dom0, feed)
 
       false ->
-        dropDown(obj, dom0, module, feed)
+        dropDown(uid, obj, dom0, module, feed)
     end
   end
 
@@ -118,13 +91,13 @@ defmodule NITRO.Combo do
   def view_value(obj) when obj in ["", [], :undefined], do: []
   def view_value(obj), do: :nitro.jse(:erlang.iolist_to_binary(apply(:kvs,:field,[obj, hd(index([]))])))
 
-  def dropDown(obj, dom0, module, feed) do
+  def dropDown(uid, obj, dom0, module, feed) do
     view_value = view_value(obj, module, feed)
     dom = :nitro.to_list(dom0)
     id = :nitro.jse(:erlang.iolist_to_binary(:nitro.atom([dom, :erlang.element(2, obj)])))
     item = :nitro.to_list(item(obj, module))
     source = :erlang.iolist_to_binary(feed)
-    click = :nitro.jse("comboSelect('#{dom}', '#{view_value}', '#{source}', '#{module}', '#{id}')")
+    click = :nitro.jse("comboSelect('#{uid}', '#{dom}', '#{view_value}', '#{source}', '#{module}', '#{id}')")
     move = :nitro.jse("comboLookupMouseMove('#{dom}')")
 
     NITRO.panel(

+ 27 - 18
lib/comboSearch.ex

@@ -2,39 +2,35 @@ defmodule NITRO.Combo.Search do
   require NITRO
   require Record
 
-  Record.defrecord(:state, uid: [], pid: [], chunks: 0, value: [], reader: [], opts: [], feed: [])
+  Record.defrecord(:state, lastMsg: [], timer: [], uid: [], pid: [], chunks: 0, value: [], reader: [], opts: [], feed: [])
 
   def start(uid, value, field, feed, opts) do
-    Supervisor.start_link([], strategy: :one_for_one, name: NITRO.Combo.Search)
     state = state(uid: uid, pid: self(), value: value, reader: :erlang.apply(:kvs, :reader, [feed]), opts: opts, feed: feed)
     stop(uid, field)
     pi =
       NITRO.pi(
         module: NITRO.Combo.Search,
         table: :async,
-        sup: NITRO.Combo.Search,
         state: state,
-        name: "#{uid}#{field}",
+        name: "comboSearch#{uid}",
         timeout: :brutal_kill,
         restart: :temporary
       )
-    case :nitro_pi.start(pi) do
-      {pid,_} -> send(pid, {:filterComboValues, :init, value})
-      x -> x
-    end
+    pid = :erlang.spawn_link(:nitro_pi, :start_link, [pi])
+    :nitro_pi.cache(:async,{:async,"comboSearch#{uid}"},pid,:infinity)
   end
 
-  def stop(uid, field) do
-    case :nitro_pi.pid(:async, "#{uid}#{field}") do
+  def stop(uid, _field) do
+    case :nitro_pi.pid(:async, "comboSearch#{uid}") do
       [] -> :ok
       pid ->
         :erlang.exit(pid, :kill)
-         try do :nitro_pi.stop(:async, "#{uid}#{field}") catch _,_ -> :skip end
+        :nitro_pi.cache(:async, {:async, "comboSearch#{uid}"}, :undefined)
     end
   end
 
-  def comboScroll(NITRO.comboScroll(uid: uid, dom: field)) do
-    case :nitro_pi.pid(:async, "#{uid}#{field}") do
+  def comboScroll(NITRO.comboScroll(uid: uid)) do
+    case :nitro_pi.pid(:async, "comboSearch#{uid}") do
       [] -> []
       pid -> send(pid, {:filterComboValues, :append, []})
     end
@@ -63,7 +59,18 @@ defmodule NITRO.Combo.Search do
       "}"
     ])
 
-  def proc(:init, NITRO.pi() = pi), do: {:ok, pi}
+  def proc(:init, NITRO.pi(state: state(value: v) = st) = pi) do
+    send(self(), {:filterComboValues, :init, v})
+    {:ok, NITRO.pi(pi, state: state(st, lastMsg: :erlang.timestamp(), timer: ping(100)))}
+  end
+
+  def proc({:check}, NITRO.pi(state: state(timer: t, lastMsg: {_, sec, _}) = st) = pi) do
+    :erlang.cancel_timer(t)
+    case :erlang.timestamp() do
+      {_, x, _} when x - sec >= 60 -> {:stop, :normal, NITRO.pi(pi, state: state(st, timer: []))}
+      _ -> {:noreply, NITRO.pi(pi, state: state(st, timer: ping(10000)))}
+    end
+  end
 
   def proc({:filterComboValues, cmd, value0}, NITRO.pi(state: state(chunks: chunks) = st) = pi) do
     state(uid: uid, feed: feed, reader: r, value: prev, pid: pid, opts: opts) = st
@@ -73,7 +80,7 @@ defmodule NITRO.Combo.Search do
     r1 = :erlang.apply(:kvs, :take, [:erlang.apply(:kvs, :setfield, [r, :args, 10])])
     case :erlang.apply(:kvs, :field, [r1, :args]) do
       [] ->
-        send(pid, {:direct, NITRO.comboInsert(dom: field, delegate: m, chunks: chunks, status: :finished)})
+        send(pid, {:direct, NITRO.comboInsert(uid: uid, dom: field, delegate: m, chunks: chunks, status: :finished)})
         {:stop, :normal, NITRO.pi(pi, state: state(st, reader: :erlang.apply(:kvs, :setfield, [r1, :args, []])))}
       rows ->
         filtered =
@@ -83,15 +90,17 @@ defmodule NITRO.Combo.Search do
               :lists.filter(fn x -> :lists.any(&filter(value, x, &1), Keyword.get(opts, :index, [])) end, rows)
           end
         newChunks = chunks + length(filtered)
-        send(pid, {:direct, NITRO.comboInsert(dom: field, delegate: m, chunks: newChunks, feed: feed, rows: filtered)})
+        send(pid, {:direct, NITRO.comboInsert(uid: uid, dom: field, delegate: m, chunks: newChunks, feed: feed, rows: filtered)})
         chunks < 100 and
-          case :nitro_pi.pid(:async, "#{uid}#{field}") do [] -> []; pid -> send(pid, {:filterComboValues, cmd, value0}) end
-        {:noreply, NITRO.pi(pi, state: state(st, value: value, chunks: newChunks, reader: :erlang.apply(:kvs, :setfield, [r1, :args, []])))}
+          case :nitro_pi.pid(:async, "comboSearch#{uid}") do [] -> []; pid -> send(pid, {:filterComboValues, cmd, value0}) end
+        {:noreply, NITRO.pi(pi, state: state(st, lastMsg: :erlang.timestamp(), value: value, chunks: newChunks, reader: :erlang.apply(:kvs, :setfield, [r1, :args, []])))}
     end
   end
 
   def proc(_, pi), do: {:noreply, pi}
 
+  def ping(milliseconds), do: :erlang.send_after(milliseconds, self(), {:check})
+
   defp filter(val, obj, i) do
     fld =
       if is_function(i) do

+ 1 - 1
mix.exs

@@ -4,7 +4,7 @@ defmodule NITRO.Mixfile do
   def project do
     [
       app: :nitro,
-      version: "6.11.9",
+      version: "6.11.10",
       description: "NITRO Nitrogen Web Framework",
       package: package(),
       deps: deps()

+ 2 - 1
priv/js/comboLookup.js

@@ -41,7 +41,7 @@ function comboClear(dom) {
     activeCombo = undefined; currentItem = undefined;
 }
 
-function comboSelect(dom, row, feed, mod, id) {
+function comboSelect(uid, dom, row, feed, mod, id) {
     let elem = qi(dom);
     comboClear(dom);
     if (qi(id)) elem.setAttribute("data-bind", qi(id).getAttribute('data-bind'));
@@ -53,6 +53,7 @@ function comboSelect(dom, row, feed, mod, id) {
     dropdown.classList.add('dropdown-bind');
     let value = qi(id) ? dec(unbase64(qi(id).getAttribute('data-bind'))) : string(row);
     direct(tuple(atom('comboSelect'),
+                 bin(uid),
                  value,
                  string(dom),
                  string(feed),

+ 1 - 1
src/nitro_pi.erl

@@ -5,7 +5,7 @@
 -behaviour(gen_server).
 -export([start_link/1]).
 -export([init/1,handle_call/3,handle_cast/2,handle_info/2,terminate/2,code_change/3]).
--export([start/1,stop/2,send/2,send/3,cast/2,cast/3,pid/2,restart/2,uid/2]).
+-export([start/1,stop/2,send/2,send/3,cast/2,cast/3,pid/2,restart/2,uid/2,cache/4,cache/3]).
 
 start(#pi{table=Tab,name=Name,module=Module,sup=Sup,timeout=Timeout,restart=Restart} = Async) ->
     ChildSpec = {{Tab,Name},{?MODULE,start_link,[Async]},Restart,Timeout,worker,[Module]},

+ 2 - 0
src/render/wf_event.erl

@@ -1,4 +1,6 @@
 -module(wf_event).
+-author('Maxim Sokhatsky').
+-author('Andrey Martemyanov').
 -include_lib("nitro/include/cx.hrl").
 -include_lib("nitro/include/nitro.hrl").
 -export([target/1, new/2, new/6, new/7]).