0

I'm practicing making a web app in Sinatra and I'm trying update a page so that information from a database is displayed once a button is clicked (more specifically, I'm a using a student database with the students age, name, and campus location). I have a route with 5 buttons (one for each campus) and once a campus button is clicked, I want the page to update with all the students information (from that campus) on the same page.

This is what I have for the app.rb

require 'sinatra'
require 'sqlite3'
set :public_folder, File.dirname(__FILE__) + '/static'
db = SQLite3::Database.new("students.db")
db.results_as_hash = true

get '/' do
  @students = db.execute("SELECT * FROM students")
  erb :home
end

get '/students/new' do
  erb :new_student
end

get '/students/campus' do
  erb :campus
end

get '/students/campus/:campus' do
  erb :campus
  campus_data = db.execute("SELECT * FROM students WHERE campus=?", params[:campus])
  campus_data.to_s
  response = ""
  campus_data.each do |student|
    response << "ID: #{student['id']}<br>"
    response << "Name: #{student['name']}<br>"
    response << "Age: #{student['age']}<br>"
    response << "Campus: #{student['campus']}<br><br>"
  end
  response
end

post '/students' do
  db.execute("INSERT INTO students (name, campus, age) VALUES (?,?,?)", [params['name'], params['campus'], params['age'].to_i])
  redirect '/'
end

This is what I have for the campus.erb

<!DOCTYPE html>
<html>
<head>
  <title>Campus Cohorts</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Cohorts</h1>
<p>Click on a button to see all students from that location.</p>

  <a href="/students/campus/SF"><button type="button">San Francisco</button></a>
  <a href="/students/campus/NYC"><button type="button">New York City</button></a>
  <a href="/students/campus/SD"><button type="button">San Diego</button></a>
  <a href="/students/campus/CHI"><button type="button">Chicago</button></a>
  <a href="/students/campus/SEA"><button type="button">Seattle</button></a>


</body>
</html>

At the moment, if a button is clicked it will redirect you to a new page with the students information form that campus, how I can render the information on the same page?

1 Answers1

2

It sounds like you want to do an AJAX call. You will have to write some javascript to fetch the students view from your server and insert it into the current page.

Use a javascript library like jQuery: http://api.jquery.com/jquery.ajax/

The idea is that you would bind a click event on your campus buttons and fire an AJAX call to the URL given by the href of the campus button. The server will respond with the rendered view for that campus and return it to your javascript function. You can then insert it into the page.

For example:

You add a class to your buttons (to easily select them with jQuery):

<a class="campus" href="/students/campus/SF"><button type="button">San Francisco</button></a>

Now you write javascript. You will have to create a javascript file and include it into your app layout. Sinatra serves static assets like css and javascript files from the ./public directory of your app. Then, write <script src="you_file.js"></script> in the bottom of your app layout html file. You will also have to download the jQuery file and do the same just make sure the jQuery file is included in your app layout above your own javascript file i.e.

<script src="the-downloaded-jquery-file.js">
<script src="you-file.js">

Inside that javascript file you can define your jQuery functions to implement the AJAX call.

The click handler and AJAX call:

# When the document receives a click on a '.campus' element run this function
$(document).on('click', '.campus', function(){
  var path = this.href; # grab the route

  # jQuery provides this convenient AJAX method that will fetch the HTML
  # returned by calling the server at the path URL and insert it into 'body'
  $('body').load(path)
});

That's about it. The jQuery load function will fire an AJAX request to the clicked campus link's path. The server will receive the request at the get '/students/campus/:campus' do route and respond with the rendered results. jQuery will then replace the contents of the body tag with the results.

Disclaimer: you might have to fit this example to your use case but this should point you in the right direction. Some subjects covered by this answer are:

Happy coding!

Community
  • 1
  • 1
DiegoSalazar
  • 13,361
  • 2
  • 38
  • 55