Animacje i inne takie w JS

Moze (ba, raczej na pewno) ktos z Was juz czytal/interesowal sie tworzeniem animowanych, znikajacy i innych takich elementow stron. Zalozmy ze chce zrobic ladnie “wjezdrzajacy” formularz na strone gdy ktos kliknie “dodaj komentarz”. Poki co wszystko co czytalem o AJAXie dotyczylo httpxmlrequest (czy jak to sie tam nazywa), dlatego prosze o linki do przykladow (tutoriali) dotyczacych nie tylko samej komunikacji miedzy przegladarka a serwerem, ale tez i roznych “bajerow” na strony :slight_smile:

http://demo.script.aculo.us/
to demo i przykladowy kod zintegrowanej z Railsami biblioteki.
Uzywam jej i jest swietna.

http://prototype.conio.net/

Dzieki za linki.

Na poczatek wybralem sobie cos latwego do zrobienia. Postanowilem wykorzystac XMLHttpRequest w komentowaniu zdjec. Mam strone na ktorej pod zdjeciem pojawiaja sie komenarze a na samym dole formularz gdzie mozna dodac swoj komentarz. Kazdy komentarz jest wyswietlamy w osobnej tabelce, ktorej id jest na przyklad id=“comment23” gdzie 23 to id komentarza z bazy danych wziete.
Wszystko co dotyczy komentrzy jest renderowane z osobnego pliku

[code=ruby]


<%= render :partial => “photocomments” %>
[/code] Metody w kontrolerze na koncu renderuja tez plik _photocomments.rhtml. Na samym koncu w tym pliku mam jak wspomnialem formularz [code=ruby]<%= form_remote_tag(:update => "comments", :complete => "new Effect.Highlight()", :url => { :action => "photo_comment", :id => @photo }) %> ...[/code] No i teraz nie wiem co mam wpisac jako parametr w Effect.Highlight() tak aby podswietlic ostatnio dodany komentarz. Poza tym,usuwanie komentarzy wykorzystujace Effect.Puff('comment#{comment.id}') dziala, ale tylko dla komenarzy ktore byly juz wczesniej dodane, to znaczy ze gdy dodam nowy komentarz i go odrazu usune to owszem znika on z bazy ale nadal zostaje na stronie. Ma ktos jakies pomysly jak rozwiazac te problemy?

tak na ślepo, bez sprawdzania w dokumentacji: czy przypadkiem nie dać jako parametru id podświetlanego elementu?

a to drugie: czy dodany komentarz ma odpowiedni id?

generalnie to widzę trochę mentliku z tym AJAXem. wiele starych efektów, które robi się po prostu w DHTML teraz na siłe przenosi się częściowo na stronę serwera. zupełnie niepotrzebnie.

http://api.rubyonrails.com/classes/ActionView/Helpers/JavaScriptHelper.html

Zamiast :complete => “new Effect.Highlight()”,
zrob :complete => visual_effect( :highlight, “ID-elementu-np-comments”)

[quote=Adamh]Zamiast :complete => “new Effect.Highlight()”,
zrob :complete => visual_effect( :highlight, “ID-elementu-np-comments”)[/quote]

ale ja nie znam jeszcze tego id, bo dopiero gdy klikam przycisk submit to ten komentarz zostaje dodawany do bazy danych a potem wyswietlany na stronie. No ale zanim go nie dodam do bazy to nie moge wiedziec jakie ma id w bazie.

Moze istnieje jakies magiczne zaklecie (zgaduje): new, last or whatever? :wink:

BTW: mam takie cos

<%= content_tag("div", "Click here to show comments", :style => "font-size:1.0em; width:100px;", :onclick => visual_effect(:SlideDown, "comments")) %>
kod pieknie dziala, ale mam pytanie, jak zmienic to aby klikanie w ten element powodowalo na zmiane SlideDown i SlideUp (czyli de facto pokazywanie i ukrywanie warstwy div comments)? Nie bardzo mam pomysl jak to w RoR zapisac

a musisz używać id z bazy? możesz np. liczyć te komentarze i w momencie gdy dodajesz, to wiesz, że następny będzie miał id = liczba_komentarzy++.

that’s tricky idea :smiley:

Teraz kazdy ostatnio dodany komenarz ma id=comment0 ,zaczelo nawet dzialac Puff przy usuwaniu “świeżo” dodanych komentarzy.
jednak nadal nowo dodany komentarz nie chce sie w zaden sposob animowac (probowalem roznych efektow)

Sa 2 podejscia.
1.Jesli chcesz to robic JS to najlatwiej zrobic 2 linki (na jednym nie widze latwego rozwiazania - trzebabyloby podmieniac caly link na inny). Jeden opisac visual_effect(:slide_down, “comments”) a drugi (:slide_up, “comments”)

2.Moim zdaniem dobrze byloby to zrobic przez AJAX a nie sam javascript (nie ladujesz niepotrzebnie komentarzy).
Zakladajac, ze komentarze znajduja sie w div id=“comments” w tym divie robisz render(:partial => "without_comments")
W tym szablonie umieszczasz tylko link_to_remote, ktory zmienia div id=“comments” i wykonuje powiedzmy :action => “display_comments” - ta akcja sprawia, ze w @comments masz komentarze i po wykonaniu robi render(:partial => "comments", :collection => @comments)
W tym szablonie dajesz rowniez link_to_remote, ktory zmienia div id=“comments” z :action=> without_comments a ta metoda robi tylko render(:partial => “without_comments”).
W tym przypadku logiki jest troche duzo ale daje to duza elastycznosc gdy chcesz cos zmienic.

Mylisz pojecia AJAX czy bardziej XHR nie ma nic z efektami-animacjami wspolnego. Te efekty to tylko rzeczy wykonywane w czasie/przed/po wykonywania zadania na serwerze helpery RoR to umozliwiaja i bardzo ulatwiaja ale uzywac tego nie musisz.

Adamh dzieki za pomysl, zrobilem mniej wiecej tak jak napisales, zamieszcze troche kodu (bedzie dla potomnych)
gallery_controller.rb - fragment

[code=ruby]def show_photo
@photo = Photo.find(params[:id])
@gallery = @photo.gallery
end

def show_photo_comments
@photo = Photo.find(params[:id])
@gallery = @photo.gallery
@comments = PhotoComment.find(:all,
:conditions => [“photo_id = ?”, @photo.id],
:order => “id DESC”)
render(:partial => ‘photocomments’)
end[/code]
show_photo.rhtml - fragment dotyczacy komentarzy, wyzej wyswietlam zdjecie tylko

[code=ruby]

<%= image_tag("/images/indicator.gif",:id => ‘indicator2’, :style => ‘display:none’) %>
<%= link_to_remote(“SHOW COMMENTS”,
:update => “comments”,
:loading => “Element.show(‘indicator2’)”,
:complete => {visual_effect(:SlideDown, “comments”), “Element.hide(‘indicator2’)”},
:url => {:action => ‘show_photo_comments’, :id => @photo.id}) %>
<%= render :partial => "without_photocomments" %>
[/code] do tego mam jeszcze dwa pliki pomocnicze _photocomments.rhtml oraz _without_photocomments.rhtml (ten jest zupelnie pusty w srodku) :)

Wsio dziala, tylko nadal nie mam ukrywania i pokazywania pod jednym przyciskiem. Z tego co wyczytalem jest cos takiego jak Element.toggle() ktore na zmiane ukrywa i pokazuje element, ale w tedy nie mamy efektow animacji.

a jeszcze chcialem zwrocic uwage na linijke

:complete => {visual_effect(:SlideDown, "comments"), "Element.hide('indicator2')"},

dzieki ktorej komentarze wyjezdaja na dol strony, a dopiero potem znika animowany gif symbolizujacy jakies tam dzialanie na stronie - bajera jest :stuck_out_tongue:
O wlasnie na cos wpadlem, w tej linijce jeszcze mozna dodac ukrywanie linka “SHOW COMMENTS” po tym jak zostana pokazane komentarze, a w _photocomments.rhtml dodac na samej gorze link z opcja Element.hide(this). dzieki czemu uztkownik w tym samym miejscu ekranu bedzie mial raz przycisk do pokazywania, a raz do ukrywania komentarzy (a tak na prawde to beda dwa rozne linki)

hmm no zorbilem tak, niestety mam problem bo nie moge wiecej niz dwa argumenty do :complete wyslac i zostaje mi animowany gif na ekranie bo nie mam jak go ukryc.

dobra rozwiazalem i ten problem, troche na okolo, ale dziala:
sam poczatek _showcomments.rhtml

<%= content_tag("div", "Hide comments", :style => "font-size:1.0em; width:100px;", :onmouseover => "Element.hide(indicator2)", :onclick => {visual_effect(:SlideUp, "comments"), "Element.show('show_comments_button')"}) %>
Chodzi oczywiscie o OnMouseOver()

Prototype formie graficznej (nadaje sie na wallpaper :slight_smile: ) http://www.snook.ca/archives/000531.php

Godna zaint. biblioteka js jest Behaviour http://bennolan.com/behaviour.

Inne oparte na prototype:
Rico http://openrico.org
moo.fx http://moofx.mad4milk.net + moo.ajax http://www.mad4milk.net/entry/moo.ajax - gdy prototype + aculo.us wydaje sie overkill (~13kb vs ~140kb)

Oczywiscie powyzsze trzeba integrowac z RoR na wlasna reke (helpery itd).

Dodatkowo aby zmniejszyc rozmiar bibliotek mozna zastosowac ShrinkSafe.

BTW. Sprytna technika wykorzystania tablic asocjacyjnych do symulacji klas. Na poczatku nie moglem sie zorient. o co chodzi :slight_smile:

na szczescie js sa “keszowane”. a to czy uzywac okrojonych bibliotek chyba zalezy od rozmiarow projektu: im wiekszy (w sensie ilosci odwiedzin) tym bardziej trzeba zwaracac uwage na wielkosc, dla 100 uzytkownikow dziennie 13kb czy 140kb dodatkowo nie robi roznicy IMHO, wiec szkoda czasu na samodzielne implementowanie innych bibiotek skoro Prototype jest w RoR.

zrobilem piekne animacje i tak dalej, dalem kumplowi linka, on wlacza i… IE sie wykrzacza zupelnie na SlideDown. U mnie tez sie wykrzaczylo, ja mam XPSP2. Wiec w sumie kicha!!!

Moze zle opisales CSS? Wszystkie efekty jakich uzywalem dzialaja na Firefoxie, IE i Operze poki co.

IE 5.5 nalezy sobie darowac. Co do nieszczesnego IE6 to sprawa css. Elementowi nalezy dac jakis layout np. height: 1px.
Z wiki aculo (http://wiki.script.aculo.us/scriptaculous/show/Effect.Appear)
“Microsoft Internet Explorer can only set opacity on elements that have a ‘layout’. To let an element have a layout, you must set some CSS positional properties, like ‘width’ or ‘height’.”

Tutaj jest kilka informacji odn. ie6, SlideUp/Down i pozycjonowania absolutnego: http://wiki.script.aculo.us/scriptaculous/show/Effect.SlideDown

Mozna tez uzyc efektu BlindUp/Down.

W rails jest jakas archiwalna wersja aculo. Najlepiej zaktualizowac do 1.5.3

Mylisz pojecia AJAX czy bardziej XHR nie ma nic z efektami-animacjami wspolnego. Te efekty to tylko rzeczy wykonywane w czasie/przed/po wykonywania zadania na serwerze helpery RoR to umozliwiaja i bardzo ulatwiaja ale uzywac tego nie musisz.[/quote]
nie mylę, dobrze wiem jak jest różnica. zobacz taki przykład:

masz formularz oceniania produktu. i tam masz pole tekstowe na swoją recenzję i jego ocenę w formie gwiazdek. i to jest zrobione fajnie, jak w amazonie, że mozesz po prostu kliknać w 4 gwiazdke i ocena jest 4 gwiazdki. tylko że teraz takie rzeczy b. często robi się używając, moim zdaniem niepotrzebnie AJAXA i natychmiast zapisując ocenę na serwerze. a przecież równie dobrze można to zrobić w momencie wysyłania formularza.