Velkommen til del II i opplæringsserien om å lage en quiz eller en undersøkelse webapplikasjon med jQuery Mobile og Ruby on Rails. I denne delen av opplæringen skal vi lage et mobilt, vennlig webgrensesnitt med jQuery Mobile, slik at vår undersøkelse lett kan tas med på en hvilken som helst HTML5-kompatibel smarttelefon. Dette kan gjøres veldig enkelt, ettersom jQuery Mobile kommer med forhåndsdefinerte CSS-maler som ser bra ut i mobile nettlesere i tillegg til å være et flott javascriptbibliotek som hjelper utviklere til å lage "app-like" -opplevelser for mobile nettsteder.
Før vi starter, har jeg tatt med en bonusrakeoppgave inne i prøvekoden for denne delen av opplæringen som genererer noen utvalgsspørsmål. For å kjøre dette, bare utfør dette på kommandolinjen inne i katalogen av Rails-appen:
rakeoppsett: undersøkelse
Kilden til denne oppgaven er plassert på lib / tasks / setup.rake
Vi starter med å generere en showhandling for våre spørsmålskontroller i app / kontrollere / questions_controller.rb.
def show @question = Question.find (params [: id]) @choices = @ question.choices avslutter
Vår show action her er veldig enkel. Vi laster et spørsmål fra databasen med sin ID. Vi lagrer valgene for spørsmålet i en instansvariabel for senere tilgang i vårt syn. Du vil legge merke til at siden vi oppretter et meget stort forhold mellom spørsmålene og valgene, får vi "automatisk" den enkleste metoden for å kunne hente alle valgene for et spørsmål ved å ringe "@ question.choices." Som standard vil Rails laste vår visning fra filen show.html.erb som vi vil opprette senere.
Deretter la vi opprette "svar" handlingen i våre spørsmålskontroller som vil ta en brukeres svar på et spørsmål og lagre det i databasen.
def answer @choice = Choice.find (: first,: conditions => : id => params [: id]) @answer = Answer.create (: question_id => @ choice.question_id,: choice_id => @choice .id) hvis Question.last == @ choice.question gjengi: action => "thanky" annet spørsmål = Question.find (: first,: conditions => : position => (@ choice.question.position + 1) ) redirect_to question_path (: id => question.id) slutten
Som vi forklarte før da vi opprettet bordet for å lagre svar, er et svar bare en kombinasjon av et spørsmåls ID og et valg-ID. Siden vi ikke har begrepet en bruker i dette systemet, skal vi bare lagre svar og se på resultatene en masse senere. La oss slå det ned:
@choice = Choice.find (: first,: conditions => : id => params [: id]) @answer = Answer.create (: question_id => @ choice.question_id,: choice_id => @ choice.id )
I ovennevnte kode finner vi valget i databasen med ID. Vi lager da et svarobjekt som består av question_id
og IDen vi får fra valgobjektet.
hvis Question.last == @ choice.question gjengir: action => "thanky" annet spørsmål = Question.find (: first,: conditions => : position => (q.position + 1)) redirect_to question_path (: id => question.id) slutten
Når en bruker besvarer et spørsmål, har vi en beslutning som bestemmer hva som skal vises for brukeren. Hvis brukeren har besvart det siste spørsmålet vi har lagret i databasen (som vi kan hente med "Question.last"), skal vi gjengi vår "takk for at du har fullført undersøkelsen". Hvis det ikke er det siste spørsmålet, kommer vi til å finne spørsmålet med en "posisjon" av det aktuelle spørsmåletes posisjon pluss 1. Deretter vil vi omdirigere til show-handlingen for det spørsmålet med RESTful-rails-hjelpemetoden for question_path
. For mer informasjon om hvordan du lager RESTful rails controllers, gjør et google-søk etter "RESTful Rails 3" og les noen av artiklene som folk har lagt ut.
I RESTful verden er det ikke noe som en svarhandling, så vi må legge til dette i vår config / routes.rb fil.
Bare erstatt denne linjen:
ressurser: spørsmål
med dette:
ressurser: spørsmål gjør samling får: svar på slutten
For øyeblikket, hvis en bruker treffer roten URL til vår server, vil de få en feil. For å forhindre dette skal vi legge til dette rotalternativet til vår config / routes.rb-fil også:
root: to => "spørsmål # index"
Denne linjen vil lede forespørselen til roten-nettadressen til indeksvirksomheten til spørsmålets kontroller. Selv om vi ikke har definert en faktisk indekshandling, vil Rails som standard laste inn index.html.erb-filen som visningen. Vi skal lage denne filen senere.
Nå som vårt Rails-arbeid er i hovedsak gjort, skal vi begynne å lage visninger som vil gjøre bruk av jQuery Mobile-rammen. Vi starter med å lage et globalt layout for vår mal på app / visninger / layouts / application.html.erb.
undersøkelse <%= csrf_meta_tag %><%= yield %>
I hovedenheten merker du at vi laster inn 2 jQuery Mobile-spesifikke filer fra jQuery-siden: 1 CSS-fil og 1 JS-fil. Dette er bra for utviklingsmodus, men hvis vi skulle presse dette inn i produksjonsmodus, vil vi gjerne bringe disse filene inn i vår app lokalt.
I kroppsdelen av vår mal oppretter vi vårt toppnivå DIV som vil inneholde all funksjonalitet for mobilnettstedet vårt:
<%= yield %>
Det er noen ting å påpeke i dette DIV. Først skal vi bruke en av de forhåndsdefinerte jQuery Mobile-temaene for dette nettstedet. Temaet vi har valgt heter "Tema B." Ved å plassere attributtdata-temaet = "b" i vårt toppnivå-DIV, tilordner vi elementet for å arve stilene for tema B. Hvis du vil se alle standardtemaalternativer for jQuery Mobile, kan du besøke følgende nettadresse: http : //jquerymobile.com/demos/1.0a4.1/#docs/api/themes.html
Toppnivåelementene i alle jQuery Mobile-apper kalles "sider". For å definere en side, angir vi attributtet data-role = "side"
på et element. I vår app skal vi definere bare én side og deretter laste alle påfølgende sider via Ajax-anrop. Men hvis vi hadde et hovedsakelig statisk nettsted, kunne vi definere flere elementer av data-role = "side"
alt på en gang. Vi kan da opprette enkle koblinger som vil navigere disse "sidene" og utføre flotte oversikter mellom dem. Den primære siden når nettleseren laster nettstedet skal ha en "aktiv" tilstand. I dette tilfellet, siden vi bare viser et enkelt sideelement, er dette ikke så viktig. Imidlertid forklarer vi klassen "Ui-side-aktiv"
å betegne at denne DIV er den som skal vises når nettleseren laster nettstedet.
Det neste trinnet er å skape våre synspunkter. Vi starter med index.html.erb-visning:
undersøkelse
<%= link_to "Begin Survey", question_path(Question.find(:first)), "data-role"=>"Knapp" %>Copyright 2011
Anatomien til en jQuery Mobile-side er ganske enkel. Hver side inneholder 3 hoveddeler: toppteksten, innholdet og bunnteksten. CSS-filene og javascript er utformet slik at du med svært enkel HTML kan opprette en dynamisk, opprinnelig opplevelse i et mobilnettsted. For vår overskrift, ved å bare angi data-rolle = "header"
attributt, vi har opprettet en fin heisknapp med en gradientbakgrunn som er temaspesifikk. Vi vil gå inn i flere alternativer på dette senere.
I vårt innholdsavsnitt har vi lagt til en standard HTML-kobling med Rails-hjelpemetoden til link til
. Vi har lagt til data-role = "button"
Tilordne å slå den vanlige lenken til en stilisert knapp. Nettadressen for lenken er en bane til det første spørsmålet i vår database som definert av den andre parameteren vi overfører til link til
metode.
Den interessante delen om å lage nettsteder med jQuery Mobile, er at den forsøker å etterligne oppføringer av native app-apper. I stedet for denne lenken omdirigerer nettleseren til helt ny side, som et typisk nettsted, vil jQuery Mobile-biblioteket faktisk konvertere det til en Ajax-kobling som vil trekke innhold inn fra serveren og vise det i et nylig opprettet «side» -element. Når den er lastet, kalles en tilbakeringingsfunksjon som viser en overgangsanimasjon til den nye siden. Som standard vil denne nye siden "glide" inn fra venstre. Igjen har jQuery Mobile oppnådd dette målet ved å la utvikleren lage denne innfødte opplevelsen uten spesiell markup eller avansert javascript-funksjonalitet.
Til slutt vil vi opprette et bunntekstelement av data-role = "footer"
å klemme bunnen av innholdsdelen vår.
Deretter skal vi opprette vår show.html.erb-visning for å vise vårt spørreskjema til brukeren:
undersøkelse
<%= @question.question %>
<% @choices.each_with_index do |c, i| %> <% i = i + 1 %>
- <%= link_to "#i. #c.choice", answer_questions_path(:id => c.id)%>
<% end %>Copyright 2011
Formatet på denne visningen er nesten identisk, som du kan se. I vårt "innhold" -element vil du legge merke til at vi har en uordnet liste med en data-rolle som "listevisning".
Når en uordnet liste er angitt til denne datarullen, blir det et slags navigasjonselement med høyre piler som standard. Dette er et ganske vanlig paradigme i mobilapper som det kan brukes til både nestede menyer, samt en slags lysbildefremvisning der hver skjerm er et annet kort i en stabel.
Innenfor vår uordnede liste vil du legge merke til at listeelementet har et datatemaattributt som er spesifisert:
Dette illustrerer hvordan jQuery Mobile's tema-motor lar oss endre element og tildele et nytt tema til det. I dette tilfellet ser blandingen av tema Bs overordnede element ut, men tema Cs liste-element ser veldig bra ut.
Innenfor listelementet bruker vi Rails hjelper-metoden for å lage en link igjen som effektivt vil svare på spørsmålet vi viser. Det er igjen interessant å merke seg at vi ikke gjør noen spesielle Javascript eller Ajax-samtaler her med denne linken. Som standard vil en enkel ankermerke laste URL-adressen som er angitt i href-attributtet til et nytt "side" -element via Ajax og deretter vise det til brukeren.
Til slutt skal vi lage en visning som har en takknemlig melding når brukeren har fullført undersøkelsen. Denne filen er plassert her: app / visninger / spørsmål / takk.html.erb.
HjemTakk skal du ha!
Takk for at du svarer på undersøkelsen! Ha en fin dag! :)
Denne utsikten er veldig lik de andre med ett unntak. Koblingen inne i "header" -elementet har et rel = "ekstern" attributt som effektivt blokkerer jQuery Mobile fra å endre standardkoblingen til en Ajax-loader. Sette rel = "ytre"
inne i et ankermerke vil tvinge lenken til å oppføre seg normalt og omdirigere nettleseren når den klikkes.
Du kan legge merke til i skjermbildene at når en bruker besvarer et spørsmål, blir de umiddelbart presentert med det neste spørsmålet. Som standard plasserer jQuery Mobile en tilbakeknapp inne i "header" -elementet som klemmer venstre side av skjermen. jQuery Mobile har en sofistikert metode for å bestemme brukerens sti eller historie gjennom appen. Ved å trykke på tilbakeknappen, flyttes brukeren tilbake til en ny "side" i appen som har blitt lastet dynamisk via Ajax-anropet.
Ved å plassere denne lenken inne i "header" -elementet, oppretter det en interessant funksjon overstyring. Lenker som er plassert til venstre for h1 tittel-taggen, erstatter tilbakeknappen. Siden vi er på slutten av undersøkelsen på denne skjermen, ønsker vi ikke at brukeren reiser bakover gjennom spørsmålene igjen. Denne hjemmekoblingen vil omdirigere nettleseren helt til startsiden, slik at brukeren kan svare på spørreskjemaene igjen.
Jeg oppfordrer alle til å ta en titt på demo- og dokumentasjonslenken på jQuery Mobile-nettstedet for å få mer informasjon om begreper som er dekket her: jQuery Mobile Documentation
Og der har vi det! Jeg håper du likte denne opplæringsserien om å lage en mobil webapplikasjon med Ruby on Rails og jQuery Mobile.