AJAX in Rails

ใน view ( จริงๆ ยัดเข้าไปใน view/layout/application.html.erb ได้ด้วย )

<%= javascript_include_tag :defaults %>
# include javascript [ Prototype and Scriptaculous ]

<script src="/javascripts/prototype.js?1223017864" type="text/javascript"></script>
<script src="/javascripts/effects.js?1223017864" type="text/javascript"></script>
<script src="/javascripts/dragdrop.js?1223017864" type="text/javascript"></script>
<script src="/javascripts/controls.js?1223017864" type="text/javascript"></script>
<script src="/javascripts/application.js?1223017864" type="text/javascript"></script>

Sample Prototype code

ใส่ลงไปใน public/javascripts/application.js ก็ได้

function serverSideAlert() {
new Ajax.Request( '/xhr_test/myresponse', {
method: 'get',
onSuccess: function( request ) {
alert( request.responseText );
}
})
}
<a href="#" onclick="serverSideAlert()">Server side alert()</a>

หรือ มันมี function ไว้ ส่ง XHR และ filling in a DOM element ให้เลยนะ ( .innerHTML )

new Ajax.Updater( 'HTMLid', '/xhr_test/myresponse', { method: 'get' })

หรือ ใส่ append แทนที่จะเซต .innerHTML

insertion: ‘bottom’

new Ajax.Updater( 'HTMLid', '/xhr_test/myresponse',
{ insertion: 'bottom', method: 'get' })

อีกตัวอย่างหนึ่ง

evalScripts:true

new Ajax.Request('/ajax_test/cityforzip', {method:'get', asynchronous:true, evalScripts:true, parameters:'zip='+$('postalcodeInput').value});

evalScripts คือ ให้ execute response เป็น script

Sample Rails code

link_to_remote คือ สร้าง a ไปเรียก ajax แทนที่จะ refresh page

# Ajax:Request()

<%= link_to_remote “Inline alert”, :url => { :action => :myresponse },
:success => “alert( request.responseText )” %>

# Ajax:Updater(), set innerHTML ของ HTMLid เป็น response

<%= link_to_remote “Inline alert”, :url => { :action => :myresponse },
:update => :HTMLid %>

<p id=”HTMLid”></p>

# append rather than .innerHTML

<%= link_to_remote “Inline alert”, :url => { :action => :myresponse },
:update => :HTMLid,
:position => ‘bottom’ %>

วิธีเขียน callback
:before, :complete (XHR state 4), :success, and :failure

<%= link_to_remote “Check time”, :url => { :action => :get_time },
:update => :current_time, :before =>”$(‘indicator’).show()“, :complete => “$(‘indicator’).hide()“, :success => “$(‘current_time’).visualEffect(‘highlight’);”, :failure => “alert(‘There was an error.’)” %>

NOTE .visualEffect คือ scriptaculous visual effect

<span id=”indicator” style=”display: none;”>Loading…</span>

<p id=”current_time“></p>

NOTE : XHR ย่อมาจาก XML HTTP request

rjs

เก็บไว้ที่ view/controllerName/actionName.rjs

page[:cityInput].value = ‘test’  แปลเป็น javascript ได้เป็น $(‘cityInput’).value = “test”

มันใช้ตัวแปรของ rails ได้ด้วย เหมือน view ทุกอย่าง

page[:cityInput].value = @zipcode.city

Ajax autocomplete

ลอง request ไป http://www.geonames.org

เราสามารถส่ง postalcode ไปยัง geonames.org เพื่อเอาค่ากลับมาได้ เช่น

http://ws.geonames.org/postalCodeLookupJSON?postalcode=12120&country=TH

ดู reference ได้ที่

http://www.geonames.org/export
1.

XMLHttpRequest -> only allows connections to original server

ถ้าจะเรียก ajax ข้ามเครื่อง ให้ใช้ JSONscriptRequest ของ Yahoo! นั่นเอง

( JSONscriptRequest add javascript tag to the DOM ไม่ได้ เรียก ajax ข้ามเครื่อง )

Download Levitt’s JSONscriptRequest class definition from http://developer.yahoo.com/javascript/samples/dynamic/jsr_class.js

2. Add <script> tags to import jsr_class.js and http://www.geonames.org/export/geonamesData.js

3. onblur = “postalCodeLookup”

// This function is called when the user leaves the postal code input field.
// It calls the geonames.org JSON Web service to fetch an array of places for
// the given postal code
function postalCodeLookup() {
var country = escape( $( ‘countrySelect’ ).value );
// Check if country is supported

## geonamesPostalCodeCountries เป็นตัวแปรอยู่ใน geonamesData.js

if (geonamesPostalCodeCountries.toString().search(country) == -1) {
alert(‘Sorry, geonames.org does not support lookups in country ‘ +
country + ‘.’);
return;
}
var postalcode = escape( $(‘postalcodeInput’).value );
// Display “loading” message in search status box
$( ‘searchStatusElement’ ).show;
$( ‘searchStatusElement’ ).innerHTML =
‘<small><i>searching for postal code ‘ + postalcode + ‘ in ‘ +
country + ‘…</i></small>’;
// Create a new script object
var request = ‘http://ws.geonames.org/postalCodeLookupJSON?postalcode=&#8217; +escape( postalcode ) + ‘&country=’ + escape( country ) +’&callback=extractLocation‘;

// callback ใช้โดย JSONscriptRequest

// มันจะเรียก extractLocation({“postalcodes”:[{“postalcode”:”12120″,”countryCode”:”TH”,”placeName”:”Khlong Luang”}]});
aObj = new JSONscriptRequest( request );
// Build the <script> tag point to that url

aObj.buildScriptTag();
// adds the new element to the DOM, the browser fetches the JavaScript code from the remote server and executes it.

aObj.addScriptTag();
}
////////////////////////////////////////////////////////////////////////////////////////////////

// This function will be called when the JSON response arrives from the
// server. The parameter jData will contain an array with postalcode
// objects.
function extractLocation( jData ) {
$( ‘searchStatusElement’ ).innerHTML = ”;
$( ‘searchStatusElement’ ).hide;
if (jData == null) {
alert( ‘There was a problem looking up your postal code.’ );
return;
}
if (jData.postalcodes.length >= 1) {
$(‘cityInput‘).value = jData.postalcodes[0].placeName;
$(‘stateInput‘).value = jData.postalcodes[0].adminName1;
} else {
$(‘cityInput’).value = ‘UNKNOWN’;
$(‘stateInput’).value = ‘UNKNOWN’;
}
}

Advertisements

One thought on “AJAX in Rails

  1. Its like you learn my mind! You seem to understand so much about this, like you wrote
    the e book in it or something. I believe that you just could do
    with some % to force the message house a little bit, but other than that, this is great blog.
    An excellent read. I’ll definitely be back.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s