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 @@
-
+
+