diff --git a/README.md b/README.md index ccdf2bd..19bc05f 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,8 @@ Once you have SQLite3 working, you can set up your development environment with │   │   ├── main.css # our custom CSS │   │   └── normalize.css # a commonly used CSS library to aid in cross-browser compatibility │   └── js # folder to hold JavaScript script files -│   └── main.js # our main JavaScript script file, all the JS stuff goes here +│   └── jobs.js # script to manage behavior relating to job resources +│   └── skills.js # script to manage behavior relating to skills resources └── views # a folder to hold the HTML templates for our pages ├── layout.erb # this is the main template for our site ├── partials # a folder containing a bunch of partials (not listed, because there are a bunch of them) @@ -96,11 +97,12 @@ This is the first release with JavaScript and jQuery included. As a reference, h ### v[1.2.0] Asynchronously edit and delete jobs -- [ ] User can edit jobs on the résumé show page -- [ ] User can delete jobs on the résumé show page -- [ ] Editing and deleting jobs occurs asynchronously -- [ ] Edited jobs are updated on the page without refresh -- [ ] Deleted jobs are removed from the page without refresh +- [X] User can edit jobs on the résumé show page +- [X] User can delete jobs on the résumé show page +- [X] Editing jobs occurs asynchronously +- [X] Deleting jobs occurs asynchronously +- [X] Edited jobs are updated on the page without refresh +- [X] Deleted jobs are removed from the page without refresh ### v[1.4.0] Asynchronously edit and delete skills diff --git a/linkedout.rb b/linkedout.rb index b00e531..83027ab 100644 --- a/linkedout.rb +++ b/linkedout.rb @@ -48,7 +48,11 @@ def default_user job.save if request.xhr? - partial :'partials/job', :locals => { :job => job } + html = "
  • " + html += partial :'partials/job', :locals => { :job => job } + html += partial :'partials/job_edit', :locals => { :job => job, :hidden => true } + html += "
  • " + html else redirect "/" end @@ -62,7 +66,26 @@ def default_user job = Job.get(job_id) job.update(job_attrs) - redirect "/" + if request.xhr? + partial :'partials/job', :locals => { :job => job } + else + redirect "/" + end +end + +delete "/jobs" do + job_attrs = params[:job] + + job_id = job_attrs.delete("id") + + job = Job.get(job_id) + job.destroy + + if request.xhr? + job_id + else + redirect "/" + end end post "/skills" do diff --git a/public/css/main.css b/public/css/main.css index f57fce3..3513f39 100644 --- a/public/css/main.css +++ b/public/css/main.css @@ -108,6 +108,16 @@ form.mini input[type="submit"] { float: right; } padding: 0; } +.float_right { + float: right; + padding-left: 1em; +} + +.hidden { + display: none; + visibility: hidden; +} + /* * SECTION STYLING diff --git a/public/js/jobs.js b/public/js/jobs.js new file mode 100644 index 0000000..ed3ed93 --- /dev/null +++ b/public/js/jobs.js @@ -0,0 +1,121 @@ +// A utility function to log information to the console +var log = function(message) { + var timestamp = (new Date()).toTimeString(); + console.log('[' + timestamp + '] ' + message); +}; + +var createJobOnSubmit = function() { + $('.jobs').on('submit', 'form[name="new_job"]', function(evt) { + log("New job form submitted"); + + evt.preventDefault(); + + var $newJobForm = $(this); + var newJobFormData = $(this).serialize(); + + log("Sending POST request to /jobs"); + + $.post("/jobs", newJobFormData, function(jobHTML) { + log("Received response from POST request to /jobs"); + + log("Adding new job element to list"); + $newJobForm.parent('li').before(jobHTML); + + $newJobForm.get(0).reset(); + }); + }); +}; + +var showEditJobFormOnClick = function() { + $('.jobs').on('click', '.js_edit_job', function(evt) { + log("Show edit job form link clicked"); + + evt.preventDefault(); + + var $jobElem = $(this).parent('.job'); + var $editJobForm = $jobElem.siblings('form[name="edit_job"]'); + + log("Hiding job element and showing job form"); + $jobElem.addClass('hidden'); + $editJobForm.removeClass('hidden'); + }); +}; + +var updateJobOnSubmit = function() { + $('.jobs').on('submit', 'form[name="edit_job"]', function(evt) { + log("Edit job form submitted"); + + evt.preventDefault(); + + var $editJobForm = $(this); + var editJobFormData = $editJobForm.serialize(); + + // The job item to update is the the element of class + // 'job' in the same containing element (in this case,
  • ) + var $jobElem = $editJobForm.siblings('.job'); + + log("Sending PUT request to /jobs/edit"); + + // Send async PUT request to /jobs/edit + $.ajax({ + url: '/jobs/edit', + type: 'PUT', + data: editJobFormData + }).done(function(responseData) { + log("Received response from PUT request to /jobs/edit"); + // This function will execute when the response comes + // back from the server + // + // We expect to receive the updated job HTML + // (as a
    element with job info inside) + var newJobHTML = responseData; + + log("Hiding job form and showing job element"); + $jobElem.removeClass('hidden'); + $editJobForm.addClass('hidden'); + + log("Replacing old job info with updated info"); + $jobElem.replaceWith(newJobHTML); + }); + }); +}; + +var deleteJobOnSubmit = function() { + $('.jobs').on('submit', 'form[name="delete_job"]', function(evt) { + log("Edit job form submitted"); + + evt.preventDefault(); + + var $deleteJobForm = $(this); + var deleteJobFormData = $deleteJobForm.serialize(); + + // Grab the containing
  • element so that we can remove + // it when the delete request completes + var $jobContainerElem = $(this).closest('li'); + + log("Sending DELETE request to /jobs"); + + // Sending a DELETE request requires using the jQuery + // .ajax() function and configuring the url, type, + // data, and complete options + $.ajax({ + url: '/jobs', + type: 'DELETE', + data: deleteJobFormData + }).done(function() { + log("Received response from DELETE request to /jobs"); + + log("Removing deleted job element"); + $jobContainerElem.remove(); + }); + }); +}; + +$(document).ready(function() { + createJobOnSubmit(); + + showEditJobFormOnClick(); + updateJobOnSubmit(); + + deleteJobOnSubmit(); +}); diff --git a/public/js/main.js b/public/js/skills.js similarity index 78% rename from public/js/main.js rename to public/js/skills.js index 7392d33..e388e05 100644 --- a/public/js/main.js +++ b/public/js/skills.js @@ -47,35 +47,8 @@ var insertNewSkillIntoDOM = function(newSkillHTML) { $newSkillForm.get(0).reset(); }; - -var createNewJobsOnSubmit = function() { - var $newJobForm = getNewJobForm(); - - $newJobForm.submit(function (evt) { - evt.preventDefault(); - - var jobFormData = $(this).serialize(); - - $.post("/jobs", jobFormData, insertNewJobIntoDOM); - }); -}; - -var getNewJobForm = function() { - return $('form[name="new_job"]'); -}; - -var insertNewJobIntoDOM = function(newJobHTML) { - var $newJobForm = getNewJobForm(); - - $newJobForm.parent('li').before(newJobHTML); - - $newJobForm.get(0).reset(); -}; - - // Wait to execute all code until the document is ready // (i.e. all of the DOM nodes have been loaded) $(document).ready(function() { createNewSkillsOnSubmit(); - createNewJobsOnSubmit(); }); diff --git a/views/layout.erb b/views/layout.erb index 45dff07..4b24587 100644 --- a/views/layout.erb +++ b/views/layout.erb @@ -21,6 +21,7 @@ - + + diff --git a/views/partials/job.erb b/views/partials/job.erb index 0db8394..8e2ecd4 100644 --- a/views/partials/job.erb +++ b/views/partials/job.erb @@ -1,4 +1,10 @@ -
  • +
    +
    + + + +
    + Edit

    <%= job.job_title %> at <%= job.company_name %>

    <%= job.job_description %>

    -
  • + diff --git a/views/partials/job_edit.erb b/views/partials/job_edit.erb index 57bb66a..9b2ecd4 100644 --- a/views/partials/job_edit.erb +++ b/views/partials/job_edit.erb @@ -1,23 +1,19 @@ -<% - # When rendering a partial, the collection item takes the name - # of the file for the item, so the job object is assigned to - # the local variable `job_form` - job = job_edit -%> -
  • -
    - +<% if hidden %> + +<% else %> + +<% end %> + - + - at - -
    + at + +
    -
    - -
    +
    + +
    - -
    -
  • + + diff --git a/views/partials/job_new.erb b/views/partials/job_new.erb index 8d9a6a9..db2e235 100644 --- a/views/partials/job_new.erb +++ b/views/partials/job_new.erb @@ -1,13 +1,11 @@ -
  • -
    - at - -
    + + at + +
    -
    - -
    +
    + +
    - -
    -
  • + + diff --git a/views/resumes/edit.erb b/views/resumes/edit.erb index 83b0c37..d94594c 100644 --- a/views/resumes/edit.erb +++ b/views/resumes/edit.erb @@ -10,7 +10,11 @@

    Jobs

    diff --git a/views/resumes/show.erb b/views/resumes/show.erb index e98509a..7daf827 100644 --- a/views/resumes/show.erb +++ b/views/resumes/show.erb @@ -10,9 +10,16 @@

    Jobs