If you’ve got a field such that onBlur causes other fields to get populated, here’s how to set that up and to test it.
Use case:
- fill in the phone field and tab out (blur)
- other address fields get populated.
Ajax Setup
var $phone = $("#phone")
$phone.blur(function(evt) {
var url = "/get_address_for_phone";
var phoneValue = $phone.val().trim();
$.ajax({
url: url,
type: "GET",
data: { phone: phoneValue },
dataType : "json"
}).done(function(json) {
$("#street").val(json.street);
}).fail(function( xhr, status, errorThrown ) {
var msg = "Phone '" + phoneValue + "' does not exist.";
alert(msg);
$phone.focus();
});
Controller Setup
def address_for_phone
phone = params[:phone].try(:strip)
address_record = Addresses.where(phone: phone).first
respond_to do |format|
if address_record
format.json do
address = {
street: address_record.street,
city: address_record.city,
state: address_record.state,
zip: address_record.zip
}
render json: address, status: :ok
end
else
format.json do
render json: { error: "Address with phone '#{phone}' does not exist" }, status: 404
end
end
end
Testing with Capybara
How to trigger the loss of focus
# Trigger focus on another field
page.execute_script("$('#street').trigger('focus')")
How to check that some field has a value (reference)
expect(page).to have_field('Street', with: '123 Main Street')
Here’s the test code to fill in the field and see that that a field was updated by the ajax call
fill_in "Phone", with: phone
# next line auto-fills the address fields
page.execute_script("$('#street').trigger('focus')")
expect(page).to have_field('Street', with: '123 Main Street')
Controller Spec
require 'spec_helper'
describe AddressController do
let(:phone) { "808-555-3344" }
# Important to use let! so that record is created!
let!(:address) { FactoryGirl.create :address, phone: phone }
let(:user) { FactoryGirl.create :user }
context 'address for phone' do
before do
sign_in user
end
it 'should get address for phone that exists' do
get :address_for_phone, phone: phone, format: :json
expect(response).to be_success
expect(JSON.parse(response.body)).to eq({
"street" => address.street,
"city" => address.city,
"state" => address.state,
"zip" => address.zip
})
end
it 'should get error for phone that does not exist' do
get :address_for_phone, phone: phone, format: :json
expect(response).not_to be_success
expect(response.response_code).to eq(404)
expect(JSON.parse(response.body)["error"]).to match /#{phone} does not exist/
end
end
context "not logged in" do
it "should get a 401" do
get :address_for_phone, phone: phone, format: :json
expect(response).not_to be_success
expect(response.response_code).to eq(401)
end
end
end