Problemy z observe_field()

Mam pole combobox (<select…>) i mam podpięty kod z observe_field() który po zmiane wartości selecta odpala coś tam na serwerze (oczywiście ajax). Wszystko działa z jednym wyjątkiem. Jak z poziomu JavaScritpt zmienię wartość tego comboboxa (np. $(‘select_id’).value = ‘blah’:wink: to pole zmienia wartość ale akcja z observe_field() jest kompletnie ignorowana. Może to jakiś bug w funkcji observe_field()?

Nie mam nawet jak podejrzeć jaki kod JavaScript został wygenerowany dla tego railsowego helpera observer_field() bo ten kod jest generowany ajaxem i innej akcji a plugin FireBug (zresztą genialny) z Firefoxa w ogóle mi nic nie wyświetla w tym miejscu. Tzn. widzę wszystko co wygenerowane zostało ajaxem z wyjątkiem observe_field(). Ale to działa, mimo że plugin go nie widzi.

Pierwsza rzecz to jak masz ustawiony observe_field? jesli bez :frequency to moze byc takie zachowanie.

Dziwne, ze nie widzisz Java Scriptu wygenerowanego jesli ten element zostal AJAXowo wrzucony to mozesz sprobowac zaznaczyc tego selecta lacznie z polem nizej i zrobic “pokaz zrodlo zaznaczenia” wtedy powinno byc ok.

[quote=Adamh]Pierwsza rzecz to jak masz ustawiony observe_field? jesli bez :frequency to moze byc takie zachowanie.

Dziwne, ze nie widzisz Java Scriptu wygenerowanego jesli ten element zostal AJAXowo wrzucony to mozesz sprobowac zaznaczyc tego selecta lacznie z polem nizej i zrobic “pokaz zrodlo zaznaczenia” wtedy powinno byc ok.[/quote]
Może wyjaśnię na przykładzie. Mam kilka comboboxów z podpiętym observer_field(). Jak wybierą coś w pierwszym to chce aby mi się tak samo ustawiły pozostałe z tej grupy. Teraz trudniejsza część. Jak napisałem każdy combobox ma podpięty observe_field(). Ta metoda wywołuje ajaxem metodę która na podstawie wartości w tym comboboxie tworzy inny, po prawej.

Czyli jak zmienię coś w pierwszym, to chcę aby zmieniły się na tą samą wartość pozostałe w grupie i aby każda ich zmiana odpaliła przypisane im ajaksowe triggery który obok im stworzą dodatkowe comboboxy obok każdego z nich. Jak dodam frequency: to te triggery się odpalają. Ale z kolei pojawia się inny problem. Nie mam jak zmienić tych comboboxów z tej pierwszej grupy, bo frequency: zaingeruje szybciej niż ja kliknę i automatycznie je ustawi na wartość tego pierwszego.

Co do źródła, to nic nie pomaga. Po prostu nic nie widać i już. Tak jakby observe_field() było jakimś duchem.

[code=html]

//<![CDATA[ new Form.Element.Observer('modelsearch', 1, function(element, value) {new Ajax.Request('/online/knowledge_base/search_model', {asynchronous:true, evalScripts:true, parameters:'search=' + escape(value)})}) //]]> </script> <div id="model-search-results"></div>[/code] tak to powinno mniej wiecej wygladac. <p><a href="http://api.rubyonrails.com/classes/ActionView/Helpers/PrototypeHelper.html#M000421" class="onebox" target="_blank">http://api.rubyonrails.com/classes/ActionView/Helpers/PrototypeHelper.html#M000421</a><br> Pokombinuje z polem :on to powinno rozwiazac ten problem… Tylko szczerze mowiac nie wiem co mozna tam podac- wartoscia domyslna jest “changed” wiec powinno byc ok.</p>

Fragment mego szablonu wygląda tak:

<% field_id = "room[#{destination[:destination_id]}][#{datestr}]" info_id = "room_info[#{destination[:destination_id]}][#{datestr}]" %> <%= select_tag(field_id, options_for_select([''] + night[:suppliers])) %> <%= observe_field(field_id, :with => "'destination_id=#{destination[:destination_id]}&supplier_id='+$F('#{field_id}')+'&date=#{datestr}'", :url => { :action => :accommodation }) %> %>
I to działa, ale jak w/w pole select zmienię z poziomu JS, to observe_field() nic nie odpala. Mój fragment RJS (który odpowiada odpalanej akcji acccommodation) wygląda:

page << " /* cut */ var Holiday = { fill: function(ids, destination_id, supplier_id, datestr, url, nights) { /* cut */ if (action && $F(first)) { ids.each(function(id) { $(id).value = $F(first); params = 'destination_id='+destination_id+'&supplier_id='+supplier_id+'&date='+datestr; new Ajax.Request(url, {parameters: params, onSuccess: handlerFunc, onFailure: errFunc, evalScripts: true}); }); } } }; " end page.holiday.fill(ids, @destination_id, @supplier_id, @datestr, url_for(:action => :accommodation), ids.size)
Jak widać, pod koniec odpala się zmiana comboboxa

$(id).value = $F(first);

Ona powinna automatycznie odpalić dowiązane observe_field(), ale tego nie czyni. Więc postanowiłem bezpośrednio wywołać funkcję na serwerze. I stąd jest:

params = 'destination_id='+destination_id+'&supplier_id='+supplier_id+'&date='+datestr; new Ajax.Request(url, {parameters: params, onSuccess: handlerFunc, onFailure: errFunc, evalScripts: true});
Niestety, wyskakuje mi okienko z kodem JavaScript. Chyba muszę to przemielić. Dodałem evalScript: true, ale nic nie pomaga…

Ufff, niby się dało. Coś te helpery są mało wiarygodne. Wymieniłem

<%= observe_field(field_id, :with => "'destination_id=#{destination[:destination_id]}&supplier_id='+$F('#{field_id}')+'&date=#{datestr}'", :url => { :action => :accommodation }) %>
na

[code=JavaScript]<% options = “‘destination_id=#{destination[:destination_id]}&supplier_id=’+$F(’#{field_id}’)+’&date=#{datestr}’” %>

[/code]

i jakoś działa. Nie do końca idealnie, bo po wybraniu 1 pola trzeba poczekać parę sekund zanim reszta się wykona. Nie wiem dlaczego…

[quote=jzabiello]…
i jakoś działa. Nie do końca idealnie, bo po wybraniu 1 pola trzeba poczekać parę sekund zanim reszta się wykona. Nie wiem dlaczego…[/quote]
Z ciekawości zapytam dlaczego używasz observe_field a nie onChange ?
Robiłem kiedyś takie dynamiczne podmienianie drop-down’ów i używałem onChange żeby odpalić zapytanie ajaxem do serwera i podmienić zawartość innego drop-down. Observe_field to typowy observer pattern wiec stąd chyba to kilkusekundowe opóźnienie ???