Skip to content

Commit

Permalink
Merge pull request #2 from ltfschoen/feature/csv-ajax-filter
Browse files Browse the repository at this point in the history
Feature / Search and Filter Data Uploaded from CSV with Pagination
  • Loading branch information
ltfschoen authored Mar 7, 2017
2 parents 3905bd2 + b2f3c77 commit 5dde4fa
Show file tree
Hide file tree
Showing 21 changed files with 371 additions and 43 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,7 @@ bower.json
# Additional Custom Modifications by Luke Schoen

# Ignore Jetbrains IDEA files
.idea/
.idea/

# Ignore .DS_Store
.DS_Store
7 changes: 6 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ gem 'pg', '~> 0.18'
# Use Puma as the app server
gem 'puma', '~> 3.0'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
gem 'sass-rails', '~> 5.0.6'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views
Expand All @@ -21,6 +21,11 @@ gem 'coffee-rails', '~> 4.2'

# Use jquery as the JavaScript library
gem 'jquery-rails'
gem 'jquery-ui-rails', '~> 6.0.1'

# Pagination
gem 'will_paginate', '~> 3.1.0'

# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
Expand Down
7 changes: 6 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ GEM
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
jquery-ui-rails (6.0.1)
railties (>= 3.2.16)
listen (3.0.8)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
Expand Down Expand Up @@ -171,6 +173,7 @@ GEM
websocket-driver (0.6.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2)
will_paginate (3.1.5)

PLATFORMS
ruby
Expand All @@ -180,19 +183,21 @@ DEPENDENCIES
coffee-rails (~> 4.2)
jbuilder (~> 2.5)
jquery-rails
jquery-ui-rails (~> 6.0.1)
listen (~> 3.0.5)
pg (~> 0.18)
puma (~> 3.0)
rails (~> 5.0.0, >= 5.0.0.1)
rails-controller-testing (~> 1.0.1)
rspec-rails (~> 3.5.2)
sass-rails (~> 5.0)
sass-rails (~> 5.0.6)
spring
spring-watcher-listen (~> 2.0.0)
turbolinks (~> 5)
tzinfo-data
uglifier (>= 1.3.0)
web-console
will_paginate (~> 3.1.0)

RUBY VERSION
ruby 2.4.0p0
Expand Down
131 changes: 129 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,35 @@
* [Setup - Replace Unit Test with RSpec](#part-3000)
* [Setup - Git Repo](#part-4000)
* [Setup - Git Releases and Tags](#part-5000)
* [Feature - CSV Upload and Display](#part-6000)
* [Feature - Search and Filter Data Uploaded from CSV with Pagination](#part-6000)

---

## Instructions

* Install System Requirements
* Install Gems
* Run PostgreSQL
* Run Rails Server
* Go to http://localhost:3000
* Click "Choose File" (to upload a CSV)
* Select the [products.csv](https://github.com/ltfschoen/rails_csv_app/blob/master/products.csv) file located in the root directory
* Click "Import CSV"
* Click the "1", "2", "Next" or "Previous" to change Page using Pagination
* Click the column Labels (i.e. "Id", "Name", "Price", "Quantity", "Released") to filter ordering ascending/descending
* Enter a value in the input field (case sensitive). Click "Search" to filter list.

## Goals

* [X] - Import pre-populated CSV into database from web form.
* [X] - Present populated data from database in table view
* [ ] - Use AJAX and apply basic filters on table so data updated without refreshing whole page.
* [X] - Use AJAX and apply basic filters on table so data updated without refreshing whole page.
* [ ] - Use `div`'s instead of `table`
* [ ] - Use Sass instead of CSS
* [ ] - Add Bootstrap or Foundation styling for buttons and tables
* [ ] - Switch front-end to React.js or Angular.js instead of jQuery
* [ ] - Add more Unit Tests

## System Requirements and Info<a id="part-1000"></a>
* Show System Setup
Expand Down Expand Up @@ -166,4 +187,110 @@
## Setup - Git Release and Tags <a id="part-5000"></a>
* Create New Release https://github.com/ltfschoen/rails_csv_app/releases/new
* Pre-Release (non-production) i.e. v0.1
* Pre-Release (non-production) i.e. v0.1
## Feature - CSV Upload and Display <a id="part-6000"></a>
### CSV Setup
* Create new Git branch
```
git checkout -b feature/csv
```
* Generate Model
```
rails g model Product name:string quantity:integer price:decimal comments:string
```
* Modify the migration file as follows:
`t.decimal :price, precision: 12, scale: 2`
* Migrate
`rake db:migrate RAILS_ENV=development`
* Generate Controller with index and import Actions
`rails g controller Products index import`
* Modify Routes as follows:
```
resources :products do
collection { post :import }
end
root to: "products#index"
```
* Update Product Model import function to accept CSV and process each row by
comparing with Product table of database, and either updating or creating new entry
* Update Product Controller's index action to fetch all Products to be available in view
as @products. Also update its import action to call the Product Model's import function
passing a given file parameter as argument, and then redirecting user to the root url
* Update Product's index View to display list of products, including form allowing user to
upload the CSV by submitting form
* Create a CSV file called products.csv
* Run server and upload the CSV file, then check it exists in database. Drop database and re-migrate to further test
```
rails dbconsole
select * from products;
rake db:drop
rake db:create db:migrate RAILS_ENV=development
```
* Add Unit Tests by adding the following gem to allow use of `assigns` in Controller tests
`gem 'rails-controller-testing', '~> 1.0.1'`
* Modify Unit Tests for Product Controller and Model
* Reference: http://stackoverflow.com/questions/15175970/undefined-method-when-running-rspec-test-using-a-stub
* Create New Release https://github.com/ltfschoen/rails_csv_app/releases/new
* Feature Release (non-production) i.e. v0.2
## Feature - Search and Filter Data Uploaded from CSV with Pagination <a id="part-7000"></a>
* References
* http://stackoverflow.com/questions/28603881/how-to-create-a-ajax-filter-in-the-index-page
* http://railscasts.com/episodes/240-search-sort-paginate-with-ajax
* Update to jQuery v3 and install jQuery UI Rails
* https://github.com/rails/jquery-rails
* Updating app/assets/javascripts/application.js with:
```
//= require jquery3
//= require jquery_ujs
```
* Install jquery-ui-rails Gem
* https://github.com/jquery-ui-rails/jquery-ui-rails
* Add Willpaginate Gem
* https://github.com/mislav/will_paginate
* Since using latest version of Rails 5.0.2 and Ruby 2.4.0 it was
necessary to make the following key changes to the RailsCast #240 code that was
written for Rails 3 back in 2010, to make it run without error:
* Replaced `scope` with `where(nil)` in app/models/product.rb
* Replaced `params.merge` with `request.parameters` in app/helpers/application_helper.rb
* Replaced `sort_column` with `self.sort_column`, and `sort_direction` with `self.sort_direction` in app/helpers/application_helper.rb
* Added `include ApplicationHelper` in app/controllers/products_controller.rb
* Whitelisted parameters in app/controllers/products_controller.rb with the following and by accessing parameters with `product_params[:search]` instead of just `params[:search]`:
```
def product_params
params.permit(:id, :name, :price, :released_at, :search, :page, :sort, :utf8, :direction, :_)
end
```
* In app/assets/javascripts/application.js, change jQuery `.live`(deprecated) to `.on`
* In app/views/products/index.html.erb had to change code to dynamically display title of page by using `<% content_for :title, "Products" %>` instead of just `<% title "Products" %>`
* Add Sass Rails Gem
* http://stackoverflow.com/questions/15257555/how-to-reference-images-in-css-within-rails-4
Binary file added app/assets/images/down_arrow.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/assets/images/up_arrow.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 13 additions & 1 deletion app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,19 @@
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery3
//= require jquery_ujs
//= require jquery-ui
//= require turbolinks
//= require_tree .

$(function() {
$("#products th a, #products .pagination a").on("click", function() {
$.getScript(this.href);
return false;
});
$("#products_search input").keyup(function() {
$.get($("#products_search").attr("action"), $("#products_search").serialize(), null, "script");
return false;
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
* files in this directory. Styles in this file should be added after the last require_* statement.
* It is generally better to create a new file per style scope.
*
*= require jquery-ui
*= require_tree .
*= require_self
*/

@import "products";
104 changes: 104 additions & 0 deletions app/assets/stylesheets/products.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,107 @@
// Place all the styles related to the Products controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

body {
background-color: #000000;
font-family: Verdana, Helvetica, Arial;
font-size: 14px;
}

a img {
border: none;
}

a {
color: #0000FF;
}

.clear {
clear: both;
height: 0;
overflow: hidden;
}

#container {
width: 75%;
margin: 0 auto;
background-color: #FFF;
padding: 20px 40px;
border: solid 1px black;
margin-top: 20px;
}

#flash_notice, #flash_error, #flash_alert {
padding: 5px 8px;
margin: 10px 0;
}

#flash_notice {
background-color: #CFC;
border: solid 1px #6C6;
}

#flash_error, #flash_alert {
background-color: #FCC;
border: solid 1px #C66;
}

.fieldWithErrors {
display: inline;
}

.error_messages {
width: 400px;
border: 2px solid #CF0000;
padding: 0px;
padding-bottom: 12px;
margin-bottom: 20px;
background-color: #f0f0f0;
font-size: 12px;
}

.error_messages h2 {
text-align: left;
font-weight: bold;
padding: 5px 10px;
font-size: 12px;
margin: 0;
background-color: #c00;
color: #fff;
}

.error_messages p {
margin: 8px 10px;
}

.error_messages ul {
margin: 0;
}

table.pretty {
border-collapse: collapse;
margin-bottom: 10px;
}

.pretty td, .pretty th {
padding: 4px 10px;
border: solid 1px #AAA;
}

.pretty .price {
text-align: right;
}

.pretty th .current {
padding-right: 12px;
background-repeat: no-repeat;
background-position: right center;
}

.pretty th .asc {
background-image: asset-data-url("up_arrow.gif");
}

.pretty th .desc {
background-image: asset-data-url("down_arrow.gif");
}
Loading

0 comments on commit 5dde4fa

Please sign in to comment.