From 67944e435b8602c3349520ae9fd0e8f706e7c9c5 Mon Sep 17 00:00:00 2001 From: Shashank Bansal Date: Fri, 26 Jul 2019 19:26:08 +0530 Subject: [PATCH 01/18] initial push for development branch --- Gemfile | 2 +- Gemfile.lock | 19 +++++ app/assets/javascripts/application.js | 11 ++- app/assets/javascripts/custom.js | 94 +++++++++++++++++++++++++ app/assets/stylesheets/application.scss | 2 - app/assets/stylesheets/tasklist.scss | 1 + app/controllers/tasklists_controller.rb | 12 +++- app/controllers/tasks_controller.rb | 14 ++-- app/models/task.rb | 2 +- app/views/tasklists/_task.html.haml | 21 ++++++ app/views/tasklists/index1.html.haml | 23 ++++++ config/routes.rb | 14 ++-- 12 files changed, 198 insertions(+), 17 deletions(-) create mode 100644 app/assets/javascripts/custom.js create mode 100644 app/views/tasklists/_task.html.haml create mode 100644 app/views/tasklists/index1.html.haml diff --git a/Gemfile b/Gemfile index 6148ff8..490eae7 100644 --- a/Gemfile +++ b/Gemfile @@ -44,7 +44,7 @@ gem 'font-awesome-sass' gem 'haml-rails', '~> 2.0', '>= 2.0.1' gem 'hirb' gem 'jquery-rails' - +gem 'rubocop-rails', '~> 2.2', '>= 2.2.1' group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: %i[mri mingw x64_mingw] diff --git a/Gemfile.lock b/Gemfile.lock index 09fec99..93c6f17 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -61,6 +61,7 @@ GEM archive-zip (0.12.0) io-like (~> 0.3.0) arel (9.0.0) + ast (2.4.0) autoprefixer-rails (9.6.1) execjs babel-source (5.8.35) @@ -142,6 +143,7 @@ GEM railties (>= 4.2, < 5.3) responders io-like (0.3.0) + jaro_winkler (1.5.3) jbuilder (2.9.1) activesupport (>= 4.2.0) jquery-rails (4.3.5) @@ -181,6 +183,9 @@ GEM nokogiri (1.10.3) mini_portile2 (~> 2.4.0) orm_adapter (0.5.0) + parallel (1.17.0) + parser (2.6.3.0) + ast (~> 2.4.0) popper_js (1.14.5) public_suffix (3.1.1) puma (3.12.1) @@ -211,6 +216,7 @@ GEM method_source rake (>= 0.8.7) thor (>= 0.19.0, < 2.0) + rainbow (3.0.0) rake (12.3.2) ransack (2.1.1) actionpack (>= 5.0) @@ -224,6 +230,17 @@ GEM responders (3.0.0) actionpack (>= 5.0) railties (>= 5.0) + rubocop (0.73.0) + jaro_winkler (~> 1.5.1) + parallel (~> 1.10) + parser (>= 2.6) + rainbow (>= 2.2.2, < 4.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 1.7) + rubocop-rails (2.2.1) + rack (>= 1.1) + rubocop (>= 0.72.0) + ruby-progressbar (1.10.1) ruby_dep (1.5.0) ruby_parser (3.13.1) sexp_processor (~> 4.9) @@ -279,6 +296,7 @@ GEM thread_safe (~> 0.1) uglifier (4.1.20) execjs (>= 0.3.0, < 3) + unicode-display_width (1.6.0) warden (1.2.8) rack (>= 2.0.6) web-console (3.7.0) @@ -312,6 +330,7 @@ DEPENDENCIES listen (>= 3.0.5, < 3.2) puma (~> 3.11) rails (~> 5.2.3) + rubocop-rails (~> 2.2, >= 2.2.1) sass-rails (~> 5.0) selenium-webdriver spring diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index cd1a3e7..f6845df 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -10,11 +10,18 @@ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details // about supported directives. // +//= require custom.js //= require rails-ujs //= require activestorage //= require turbolinks -//= require_tree . //= require jquery +//= require popper +//= require bootstrap + function ajaxcall(tasklist_id,id){ - $.ajax({url: location.origin+"/updatecheck/"+tasklist_id+"/"+id,success: function(result){console.log(result);}}) + Rails.ajax({ + type: "PATCH", + url: location.origin+"/tasklists/"+tasklist_id+"/tasks/"+id+"/checkbox_update", + success: function(result){console.log(result);} + }) } diff --git a/app/assets/javascripts/custom.js b/app/assets/javascripts/custom.js new file mode 100644 index 0000000..2b26c29 --- /dev/null +++ b/app/assets/javascripts/custom.js @@ -0,0 +1,94 @@ +function inputForTask(tasklistId) { + return "
" + + "
"; +} + +function inputForTasklist(){ +return "



" +} + +function addTasklist(){ + $('#newtasklist').html(inputForTasklist()); +} + +function addTask(tasklistId) { + if ($("#task0").length == 0) { + var input = inputForTask(tasklistId) + $("#tasks").html($("#tasks").html() + input); + } +} + +function renderTask(tasklistId) { + $.ajax({ + url: "/tasklists/" + tasklistId + "/render_tasks", + success: function(result) { + $("#tasks").html(result); + } + }); +} + +function renderUpdate(tasklistId, taskId) { + if ( + $("#task" + taskId).prop("tagName") == "SPAN" && + $("#task" + taskId).find($("#inputTask" + taskId)).length == 0 + ) { + var text = $("#task" + taskId).text(); + $("#task" + taskId).html( + " " + + "
"; + + "Add Task"; +} + +var taskNamePartial=[]; +function restoreTask(taskId){ + $('#task'+taskId).html(taskNamePartial[taskId]); +console.log($('#task'+taskId).html() + taskId); + } function inputForTasklist(){ @@ -13,27 +20,29 @@ function addTasklist(){ } function addTask(tasklistId) { - if ($("#task0").length == 0) { + if ($("#newtask").length == 0) { var input = inputForTask(tasklistId) $("#tasks").html($("#tasks").html() + input); } } -function renderTask(tasklistId) { +function renderTask(tasklistId,tasklistCount) { $.ajax({ url: "/tasklists/" + tasklistId + "/render_tasks", success: function(result) { $("#tasks").html(result); } }); + setSelectedTasklist(tasklistCount); } function renderUpdate(tasklistId, taskId) { if ( - $("#task" + taskId).prop("tagName") == "SPAN" && + $("#task" + taskId).prop("tagName") == "DIV" && $("#task" + taskId).find($("#inputTask" + taskId)).length == 0 ) { var text = $("#task" + taskId).text(); + taskNamePartial[taskId] = text; $("#task" + taskId).html( "" ); } } @@ -55,7 +65,19 @@ function createTasklist(){ data: "name=" + $("#tasklistnew").val(), success: function(data) { console.log(data); - console.log($("#task" + inputCounter).val()); + console.log($("#newTask").val()); + } + }); +} + +function updateTasklist(tasklistId){ + Rails.ajax({ + type: "put", + url: "/tasklists/"+tasklistId+"/", + data: "name="+$("#updateTasklistInput"+tasklistId).val(), + success: function(data) { + console.log(data); + console.log($("#newTask").val()); } }); } @@ -63,10 +85,10 @@ function createTask(tasklistId) { Rails.ajax({ type: "post", url: "tasklists/" + tasklistId + "/tasks/", - data: "name=" + $("#task" + inputCounter).val(), + data: "name=" + $("#newTask").val(), success: function(data) { console.log(data); - console.log($("#task" + inputCounter).val()); + console.log($("#newTask").val()); } }); } @@ -78,7 +100,6 @@ function updateTask(tasklistId, taskId) { data: "name=" + $("#inputTask" + taskId).val(), success: function(data) { console.log(data); - console.log($("#task" + inputCounter).val()); } }); } @@ -92,3 +113,39 @@ function deleteTask(tasklistId,taskId){ } }); } + +function setSelectedTasklist(selectedTasklist){ +localStorage.setItem("selectedTasklistCount",selectedTasklist); +} + +function defaultSelectedTasklist(){ + $(document).ready(function(){ + if(typeof (localStorage.getItem("selectedTasklistCount")) == 'undefine'){ + $(document).find(".tasklist_list")[0].click(); + }else + $(document).find(".tasklist_list")[localStorage.getItem("selectedTasklistCount")].click(); + }); +} +defaultSelectedTasklist(); + +function inputForUpdateTasklist(tasklistId){ +return "
"+ +""+ +"
"+ +"
"+ +"
"+ +"
"+ +"
" +} + + +function restoreTasklist(tasklistId){ + $('#tasklist'+tasklistId).html(tasklistNamePartial[tasklistId]); +} +var tasklistNamePartial=[]; +function renderUpdateTasklist(tasklistId){ +tasklistNamePartial[tasklistId] = $('#tasklist'+tasklistId).text(); +$('#tasklist'+tasklistId).html(inputForUpdateTasklist(tasklistId)); +} \ No newline at end of file diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index fb25cf5..c77eaf1 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -14,3 +14,4 @@ @import "bootstrap"; @import "font-awesome-sprockets"; @import "font-awesome"; + @import "tasklist"; diff --git a/app/assets/stylesheets/tasklist.scss b/app/assets/stylesheets/tasklist.scss index 581abe2..08c5161 100644 --- a/app/assets/stylesheets/tasklist.scss +++ b/app/assets/stylesheets/tasklist.scss @@ -1,4 +1,20 @@ // Place all the styles related to the tasklist controller here. // They will automatically be included in application.css. // You can use Sass (SCSS) here: http://sass-lang.com/ -@import 'bootstrap' \ No newline at end of file +@import 'bootstrap'; + +.tasklist_list:hover{ +cursor: pointer; + +} + +#update +{ + visibility: visible; +} + +#delete +{ + visibility: visible; +} + diff --git a/app/controllers/tasklists_controller.rb b/app/controllers/tasklists_controller.rb index 738997b..2eeed89 100644 --- a/app/controllers/tasklists_controller.rb +++ b/app/controllers/tasklists_controller.rb @@ -19,7 +19,7 @@ def new def create @tasklist = current_user.tasklists.build(tasklist_params) if @tasklist.save - redirect_to tasklists_path + redirect_to root_path else render 'new' end @@ -29,11 +29,25 @@ def show @tasklist = current_user.tasklists.find(params[:id]) end + def update + tasklist = current_user.tasklists.find(params[:id]) + if tasklist.update(tasklist_params) + redirect_to root_path + else + render plain: tasklist.errors.full_messages + end + end + def render_tasks @tasks = Tasklist.find(params[:id]).tasks render partial: 'task' end + def destroy + Tasklist.find(params[:id]).delete + redirect_to root_path + end + private def tasklist_params diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb index 5be0638..a9e3cbd 100644 --- a/app/controllers/tasks_controller.rb +++ b/app/controllers/tasks_controller.rb @@ -32,7 +32,7 @@ def edit def update @tasks = @tasklist.tasks.find(params[:id]) if @tasks.update(tasklist_params) - redirect_to tasklist_tasks_path(@tasks.tasklist_id) + redirect_to root_path else render 'edit' end diff --git a/app/views/tasklists/_task.html.haml b/app/views/tasklists/_task.html.haml index d675c51..a2f4e7e 100644 --- a/app/views/tasklists/_task.html.haml +++ b/app/views/tasklists/_task.html.haml @@ -1,21 +1,18 @@ .tab-content - -if !@tasks.first.nil? - .tab-pane.fade{id:"tasklist#{@tasks.first.tasklist.id}"} - -@tasks.each do |task| - .row - .card.col-sm-10 - .row - .col-sm-8.align-self-center - %span{id:"task#{task.id}",onClick:"renderUpdate(#{@tasks.first.tasklist.id},#{task.id})"} - =task.name - .col-sm-2 - %button.float-right.card-body.btn.btn.danger.far.fa-trash-alt{onClick:"deleteTask(#{@tasks.first.tasklist.id},#{task.id})"} - %br - %br + .tab-pane.fade{id:"tasklist#{params[:id]}"} + -@tasks.each do |task| .row - %br - %button{onClick:"addTask(#{@tasks.first.tasklist.id})",class: "btn btn-primary"} Add Task - -else - .row - %br - %button{onClick:"addTask()",class: "btn btn-primary"} Add Task + .card.col-sm-10 + .row + .col-sm-8.align-self-center + %div{id:"task#{task.id}",onClick:"renderUpdate(#{params[:id]},#{task.id})"} + =task.name + .col-sm-2 + %button.float.right.card-body.btn.fa.fa-edit{onclick: "renderUpdate(#{params[:id]},#{task.id})"} + .col-sm-2 + %button.float-left.card-body.btn.far.fa-trash-alt{onClick:"deleteTask(#{params[:id]},#{task.id})"} + %br + %br + .row + %br + %button{onClick:"addTask(#{params[:id]})",class: "btn btn-primary"} Add Task diff --git a/app/views/tasklists/index1.html.haml b/app/views/tasklists/index1.html.haml index 67ac39a..699f96e 100644 --- a/app/views/tasklists/index1.html.haml +++ b/app/views/tasklists/index1.html.haml @@ -14,8 +14,16 @@ %a.float-right.fa.fa-plus{onClick: 'addTasklist()'} %hr #newtasklist + - tasklistCount = 0 -@tasklists.each do |tasklist| - %a{onClick: "renderTask(#{tasklist.id})"} #{tasklist.name} + .row.align-middle + .col-sm-6 + .tasklist_list{onClick: "renderTask(#{tasklist.id},#{tasklistCount})", id:"tasklist#{tasklist.id}"} #{tasklist.name} + .co-sm-1 + %a.fa.fa-edit.float-right{onclick: "renderUpdateTasklist(#{tasklist.id})"} + .col-sm-1 + =link_to '', tasklist_path(tasklist.id),method: 'delete', class: "float-right fa fa-trash-alt" ,id: "delete" + - tasklistCount += 1 %br .col-sm-1 .col-sm-8 From bf122e1c7594a01b525306e81524bb3373f285e5 Mon Sep 17 00:00:00 2001 From: Shashank Bansal Date: Tue, 30 Jul 2019 23:47:07 +0530 Subject: [PATCH 03/18] update task fixed and other fixes let intermediary commit --- app/assets/javascripts/custom.js | 130 ++++++++++++++---------- app/assets/stylesheets/tasklist.scss | 24 ++++- app/controllers/tasklists_controller.rb | 23 +---- app/controllers/tasks_controller.rb | 27 +---- app/models/tasklist.rb | 2 +- app/views/tasklists/_task.html.haml | 18 ---- app/views/tasklists/_tasklist.html.haml | 7 ++ app/views/tasklists/_tasks.html.haml | 19 ++++ app/views/tasklists/index.html.haml | 44 +++++--- app/views/tasklists/index1.html.haml | 31 ------ app/views/tasklists/new.html.haml | 8 -- app/views/tasklists/show.html.haml | 0 app/views/tasks/_task.html.haml | 12 +++ app/views/tasks/edit.html.haml | 15 --- app/views/tasks/index.html.haml | 27 ----- app/views/tasks/new.html.haml | 18 ---- app/views/tasks/show.html.haml | 9 -- config/routes.rb | 2 +- 18 files changed, 175 insertions(+), 241 deletions(-) delete mode 100644 app/views/tasklists/_task.html.haml create mode 100644 app/views/tasklists/_tasklist.html.haml create mode 100644 app/views/tasklists/_tasks.html.haml delete mode 100644 app/views/tasklists/index1.html.haml delete mode 100644 app/views/tasklists/new.html.haml delete mode 100644 app/views/tasklists/show.html.haml create mode 100644 app/views/tasks/_task.html.haml delete mode 100644 app/views/tasks/edit.html.haml delete mode 100644 app/views/tasks/index.html.haml delete mode 100644 app/views/tasks/new.html.haml delete mode 100644 app/views/tasks/show.html.haml diff --git a/app/assets/javascripts/custom.js b/app/assets/javascripts/custom.js index 037c76a..c125dbb 100644 --- a/app/assets/javascripts/custom.js +++ b/app/assets/javascripts/custom.js @@ -1,32 +1,36 @@ function inputForTask(tasklistId) { - return "" - + ""; + return ( + "
" + + "


" + ); } -var taskNamePartial=[]; -function restoreTask(taskId){ - $('#task'+taskId).html(taskNamePartial[taskId]); -console.log($('#task'+taskId).html() + taskId); - +var taskNamePartial = []; +function restoreTask(taskId) { + $("#task" + taskId).html(taskNamePartial[taskId]); + console.log($("#task" + taskId).html() + taskId); } -function inputForTasklist(){ -return "



" +function inputForTasklist() { + $('#newtasklist').show(); + return "



"; } -function addTasklist(){ - $('#newtasklist').html(inputForTasklist()); +function addTasklist() { + $("#newtasklist").html(inputForTasklist()); } function addTask(tasklistId) { - if ($("#newtask").length == 0) { - var input = inputForTask(tasklistId) - $("#tasks").html($("#tasks").html() + input); + if ($("#newTask").length == 0) { + var input = inputForTask(tasklistId); + $("#newtasks").append(input); } } -function renderTask(tasklistId,tasklistCount) { +function renderTask(tasklistId, tasklistCount) { $.ajax({ url: "/tasklists/" + tasklistId + "/render_tasks", success: function(result) { @@ -53,28 +57,31 @@ function renderUpdate(tasklistId, taskId) { tasklistId + "," + taskId + - ")>Update"+ - "" + + "

" + ")'>Save"+ + "
Cancel
" ); } var taskNamePartial = []; -function restoreTask(taskId) { - $("#task" + taskId).html(taskNamePartial[taskId]); - console.log($("#task" + taskId).html() + taskId); +var taskChecked =[]; +function restoreTask(tasklistId,taskId) { + console.log("i am calling"); + $("#card" + taskId).empty(); + $("#card" + taskId).append(restoreTaskView(tasklistId,taskId)); +} + +function restoreTaskView(tasklistId,taskId){ + return "
"+ + ""+ + "
"+ + "
"+ + "
"+taskNamePartial[taskId]+"
"+ + "
"+ + "
"+ + ""+ + "
"+ + "
"+ + ""+ + "
" } function inputForTasklist() { - $('#newtasklist').show(); - return "



"; + return "
"+ + "
"+ + "
"+ + "
"+ + "
"+ + "
"+ + "
"+ + ""+ + "Create"+ + ""+ + "
"+ + "
"+ + "Cancel
"; } function addTasklist() { - $("#newtasklist").html(inputForTasklist()); + $("#newtasklist").html(inputForTasklist()).append("
"); } function addTask(tasklistId) { if ($("#newTask").length == 0) { var input = inputForTask(tasklistId); $('#newtasks').show(); - console.log("iam here"); + $("#newtasks").addClass("card"); $("#newtasks").append(input); } } @@ -49,20 +79,24 @@ function renderUpdate(tasklistId, taskId) { ) { var text = $("#task" + taskId).text(); taskNamePartial[taskId] = text; - $("#task" + taskId).html( - ""+ + " " + - "
"+ + "
" + + "" + - "
" + + "
"+ + "Cancel
" ); } } @@ -73,8 +107,9 @@ function createTasklist() { data: "name=" + $("#tasklistnew").val(), success: function(data) { $("#tasklists").append($(data).find('DIV')[0]).append("
"); - $('#newtasklist').hide(); + $('#newtasklist').empty(); $('#tasklistnew').val(""); + $('#tasklists').find('.tasklist_list').click(); } }); } @@ -86,7 +121,8 @@ function updateTasklist(tasklistId) { data: "name=" + $("#updateTasklistInput" + tasklistId).val(), success: function(data) { console.log(data); - console.log($("#newTask").val()); + $('#tasklist_list'+tasklistId).empty(); + $('#tasklist_list'+tasklistId).append($(data).find("DIV")[1]).append($(data).find("DIV")[1]).append($(data).find("DIV")[1]); } }); } @@ -97,8 +133,7 @@ function createTask(tasklistId) { data: "name=" + $("#newTask").val(), success: function(data) { $(".tab-content").append($(data).find('DIV')[0]).append("
"); - $('#newtasks').empty(); - // $('#newTask').text(""); + restoreCreateTask(); } }); } @@ -110,6 +145,11 @@ function updateTask(tasklistId, taskId) { data: "name=" + $("#inputTask" + taskId).val(), success: function(data) { console.log(data); + $("#card"+taskId).empty(); + $("#card"+taskId).append($(data).find('DIV')[3]).append($(data).find('DIV')[3]) + .append($(data).find('DIV')[3]) + .append($(data).find('DIV')[3]) + .append("
"); } }); } @@ -119,19 +159,20 @@ function deleteTask(tasklistId, taskId) { type: "delete", url: "tasklists/" + tasklistId + "/tasks/" + taskId, success: function(data) { - console.log(data); + $('#tasklist'+tasklistId).click(); } }); } function setSelectedTasklist(selectedTasklist) { + console.log(selectedTasklist); localStorage.setItem("selectedTasklistCount", selectedTasklist); } function defaultSelectedTasklist() { $(document).ready(function() { console.log(localStorage.getItem("selectedTasklistCount")); - if (typeof (Storage) !== 'undefine') { + if (localStorage.getItem("selectedTasklistCount") === null) { $(document) .find(".tasklist_list")[0] .click(); @@ -143,33 +184,67 @@ function defaultSelectedTasklist() { } defaultSelectedTasklist(); -function inputForUpdateTasklist(tasklistId) { +function inputForUpdateTasklist(tasklistId,index) { return ( - "
" + - ""+ + "
" + + ""+ - "
" + - "
" + - "
"+ + "
" + + "" + - "
" + - "
" + - "
" - ); + ")>Save" + + "
"+ + "
"+ + "Cancel"+ + "
"); } -function restoreTasklist(tasklistId) { - $("#tasklist" + tasklistId).html(tasklistNamePartial[tasklistId]); +function restoreUpdateTasklistView(tasklistId,index){ +return ( +"
"+ + "
"+ + tasklistNamePartial[tasklistId]+ + "
"+ + "
"+ + "
"+ + "
"+ + "
"+ + "
"+ + "
"+ + "
") } -var tasklistNamePartial = []; +function restoreUpdateTasklist(tasklistId,index) { + $("#tasklist_list" + tasklistId).html(restoreUpdateTasklistView(tasklistId,index)); +} -function renderUpdateTasklist(tasklistId) { +var tasklistNamePartial = []; +var tasklistIndex = []; +function renderUpdateTasklist(tasklistId,index) { tasklistNamePartial[tasklistId] = $("#tasklist" + tasklistId).text(); - $("#tasklist_list" + tasklistId).html(inputForUpdateTasklist(tasklistId)); + console.log(tasklistNamePartial[tasklistId]) + tasklistIndex = index; + $("#tasklist_list" + tasklistId).html(inputForUpdateTasklist(tasklistId,index)); +} + +function updateTaskStatus(tasklistId,taskId){ +Rails.ajax({ + url: "/tasklists/"+tasklistId+"/tasks/"+taskId+"/checkbox_update" , + type: 'patch', + success: function(data){ + console.log(data); + } +}); } + +function restoreCreateTasklist(){ +$('#newtasklist').empty(); +} + +function restoreCreateTask(){ + $('#newtasks').empty(); + $('#newtasks').removeClass("card"); + +} \ No newline at end of file diff --git a/app/assets/stylesheets/tasklist.scss b/app/assets/stylesheets/tasklist.scss index ef4233e..744b2a1 100644 --- a/app/assets/stylesheets/tasklist.scss +++ b/app/assets/stylesheets/tasklist.scss @@ -17,14 +17,20 @@ cursor: pointer; #update, #taskUpdate { + color: #93922a; visibility: hidden; } #delete, #taskDelete { + color:#AD423F ; visibility: hidden; } +.card-body{ + border: 0px; +} + .card-body:hover{ #taskDelete{ visibility: visible; @@ -33,4 +39,10 @@ cursor: pointer; #taskUpdate{ visibility: visible; } +} + +checkbox:checked{ +.card-body{ +background-color: grey; +} } \ No newline at end of file diff --git a/app/controllers/tasklists_controller.rb b/app/controllers/tasklists_controller.rb index b14bba2..5b410c3 100644 --- a/app/controllers/tasklists_controller.rb +++ b/app/controllers/tasklists_controller.rb @@ -13,12 +13,8 @@ def create end def update - tasklist = current_user.tasklists.find(params[:id]) - if tasklist.update(tasklist_params) - redirect_to root_path - else - render plain: tasklist.errors.full_messages - end + @tasklist = current_user.tasklists.find(params[:id]) + render partial: 'tasklist' if @tasklist.update(tasklist_params) end def render_tasks @@ -27,7 +23,7 @@ def render_tasks end def destroy - Tasklist.find(params[:id]).delete + Tasklist.find(params[:id]).destroy redirect_to root_path end diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb index c1c0cd3..c665e09 100644 --- a/app/controllers/tasks_controller.rb +++ b/app/controllers/tasks_controller.rb @@ -12,19 +12,13 @@ def create end def update - @tasks = @tasklist.tasks.find(params[:id]) - if @tasks.update(tasklist_params) - redirect_to root_path - else - render 'edit' - end + @task = @tasklist.tasks.find(params[:id]) + render partial: 'task' if @task.update(tasklist_params) end def destroy - @tasks = @tasklist.tasks.find(params[:id]) - @tasks.destroy - # render json - redirect_to root_path + tasks = @tasklist.tasks.find(params[:id]) + tasks.destroy end def checkbox_update diff --git a/app/models/tasklist.rb b/app/models/tasklist.rb index 0ad2203..34b601b 100644 --- a/app/models/tasklist.rb +++ b/app/models/tasklist.rb @@ -1,5 +1,5 @@ class Tasklist < ApplicationRecord validates :name, presence: true - has_many :tasks, dependent: :destroy + has_many :tasks, dependent: :delete_all belongs_to :user end diff --git a/app/views/tasklists/_tasklist.html.haml b/app/views/tasklists/_tasklist.html.haml index 089f314..b97f0b7 100644 --- a/app/views/tasklists/_tasklist.html.haml +++ b/app/views/tasklists/_tasklist.html.haml @@ -1,7 +1,7 @@ -.row.algin-middle{id: "tasklist_list#{@tasklist.id}"} +.row.algin-middle.tasklistname{id: "tasklist_list#{@tasklist.id}"} .col-sm-8 .tasklist_list{onclick: "renderTask(#{@tasklist.id},#{current_user.tasklists.count - 1 })",id: "tasklist#{@tasklist.id}"} #{@tasklist.name} - .co-sm-1 - %a.fa.fa-edit.float-right{onclick: "renderUpdateTasklist(#{@tasklist.id})"} .col-sm-1 - =link_to '', tasklist_path(@tasklist.id),method: 'delete', class: "float-right fa fa-trash-alt" ,id: "delete" \ No newline at end of file + %a.fa.fa-edit.pull-right{onclick: "renderUpdateTasklist(#{@tasklist.id},#{current_user.tasklists.count - 1 })", id: "update"} + .col-sm-1 + =link_to '', tasklist_path(@tasklist.id),method: 'delete', class: "pull-right fa fa-trash-alt" ,id: "delete" \ No newline at end of file diff --git a/app/views/tasklists/_tasks.html.haml b/app/views/tasklists/_tasks.html.haml index 41f55fa..88d62a6 100644 --- a/app/views/tasklists/_tasks.html.haml +++ b/app/views/tasklists/_tasks.html.haml @@ -2,18 +2,21 @@ -@tasks.each do |task| .row .card.col-sm-12 - .row.card-body - .col-sm-10.align-self-center + .row.card-body{id: "card#{task.id}"} + .col-sm-1.align-self-center + %input{type: 'checkbox', id: "checkbox#{task.id}", onclick: "updateTaskStatus(#{params[:id]},#{task.id})", "checked": task.status} + .col-sm-8.align-self-center %div{id:"task#{task.id}",onClick:"renderUpdate(#{params[:id]},#{task.id})"} =task.name - .col-sm-1 - %button.pull.right.btn.fa.fa-edit{onclick: "renderUpdate(#{params[:id]},#{task.id})", id: 'taskUpdate'} - .col-sm-1 - %button.pull-right.btn.far.fa-trash-alt{onClick:"deleteTask(#{params[:id]},#{task.id})", id: 'taskDelete'} + .col-sm-1.align-self-center + %span.fa.fa-edit{onclick: "renderUpdate(#{params[:id]},#{task.id})", id: 'taskUpdate'} + .col-sm-1.align-self-center + %span.btn.far.fa-trash-alt{onClick:"deleteTask(#{params[:id]},#{task.id})", id: 'taskDelete'} %br %br .row - #newtasks + #newtasks{class: 'col-sm-12'} +%br .row %br %button{onClick:"addTask(#{params[:id]})",class: "btn btn-primary"} Add Task diff --git a/app/views/tasklists/index.html.haml b/app/views/tasklists/index.html.haml index 1172b9e..b89a52c 100644 --- a/app/views/tasklists/index.html.haml +++ b/app/views/tasklists/index.html.haml @@ -10,7 +10,7 @@ .container .row .col-sm-2 - Task list + Task lists %a.float-right.fa.fa-plus{onClick: 'addTasklist()'} %hr #newtasklist @@ -20,8 +20,8 @@ .row.align-middle.tasklistname{id: "tasklist_list#{tasklist.id}"} .col-sm-8 .tasklist_list{onClick: "renderTask(#{tasklist.id},#{tasklistCount})", id:"tasklist#{tasklist.id}"} #{tasklist.name} - .co-sm-1 - %a.fa.fa-edit.pull-right{onclick: "renderUpdateTasklist(#{tasklist.id})", id: 'update'} + .col-sm-1 + %a.fa.fa-edit.pull-right{onclick: "renderUpdateTasklist(#{tasklist.id}, #{tasklistCount})", id: 'update'} .col-sm-1 =link_to '', tasklist_path(tasklist.id),method: 'delete', class: "pull-right fa fa-trash-alt" ,id: "delete" - tasklistCount += 1 diff --git a/app/views/tasks/_task.html.haml b/app/views/tasks/_task.html.haml index ac8d1a4..b4292c6 100644 --- a/app/views/tasks/_task.html.haml +++ b/app/views/tasks/_task.html.haml @@ -1,12 +1,14 @@ .row .card.col-sm-12 - .row.card-body - .col-sm-10.align-self-center + .row.card-body{id: "card#{@task.id}"} + .col-sm-1.align-self-center + %input{type: 'checkbox', id: "checkbox#{@task.id}", onclick: "updateTaskStatus(#{@task.tasklist.id},#{@task.id})", "checked": @task.status} + .col-sm-8.align-self-center %div{id:"task#{@task.id}",onClick:"renderUpdate(#{@task.tasklist.id},#{@task.id})"} =@task.name - .col-sm-1 - %button.pull-right.btn.fa.fa-edit{onclick: "renderUpdate(#{@task.tasklist.id},#{@task.id})", id: "taskUpdate"} - .col-sm-1 - %button.pull-right.btn.far.fa-trash-alt{onClick:"deleteTask(#{@task.tasklist.id},#{@task.id})", id: "taskDelete"} + .col-sm-1.align-self-center + %span.fa.fa-edit{onclick: "renderUpdate(#{@task.tasklist.id},#{@task.id})", id: "taskUpdate"} + .col-sm-1.align-self-center + %span.far.fa-trash-alt{onClick:"deleteTask(#{@task.tasklist.id},#{@task.id})", id: "taskDelete"} %br \ No newline at end of file From 184dff7d207c456d6c4414d8f2e914b768d4b60d Mon Sep 17 00:00:00 2001 From: Shashank Bansal Date: Fri, 2 Aug 2019 18:59:20 +0530 Subject: [PATCH 06/18] dynamic data binding done --- app/assets/javascripts/application.js | 7 - app/assets/javascripts/custom.js | 383 ++++++++++++++++-------- app/views/tasklists/_tasklist.html.haml | 5 +- app/views/tasklists/_tasks.html.haml | 10 +- app/views/tasklists/index.html.haml | 10 +- app/views/tasks/_task.html.haml | 9 +- 6 files changed, 270 insertions(+), 154 deletions(-) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 2279d77..024e523 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -18,10 +18,3 @@ //= require bootstrap //= require custom.js -function ajaxcall(tasklist_id,id){ - Rails.ajax({ - type: "PATCH", - url: location.origin+"/tasklists/"+tasklist_id+"/tasks/"+id+"/checkbox_update", - success: function(result){console.log(result);} - }) -} diff --git a/app/assets/javascripts/custom.js b/app/assets/javascripts/custom.js index 7c2904a..7e4944f 100644 --- a/app/assets/javascripts/custom.js +++ b/app/assets/javascripts/custom.js @@ -1,103 +1,170 @@ +function bindView() { + $(document).ready(function() { + $("#newTasklistButton").on("click", addTasklist); + $(".tasklist_list").on("click", renderTask); + $(".tasklistUpdateButton").on("click", renderUpdateTasklist); + }); +} + +bindView(); + function inputForTask(tasklistId) { return ( - "
"+ - "
"+ + "
" + + "
" + "
" + - "
"+ - "
Cancel
" + "'>Save
" + + "
Cancel
" ); } var taskNamePartial = []; -var taskChecked =[]; -function restoreTask(tasklistId,taskId) { - console.log("i am calling"); +var taskChecked = []; + +function restoreTask() { + tasklistId = $(this).data("tasklistid"); + taskId = $(this).data("taskid"); $("#card" + taskId).empty(); - $("#card" + taskId).append(restoreTaskView(tasklistId,taskId)); + $("#card" + taskId).append(restoreTaskView(tasklistId, taskId)); + if (taskChecked[taskId] == true) { + $("#checkbox" + taskId).attr("checked", "checked"); + } + $(".taskname").on("click", renderUpdate); + $(".taskUpdate").on("click", renderUpdate); + $(":checkbox").on("click", updateTaskStatus); } -function restoreTaskView(tasklistId,taskId){ - return "
"+ - ""+ - "
"+ - "
"+ - "
"+taskNamePartial[taskId]+"
"+ - "
"+ - "
"+ - ""+ - "
"+ - "
"+ - ""+ - "
" +function restoreTaskView(tasklistId, taskId) { + return ( + "
" + + "" + + "
" + + "
" + + "
" + + taskNamePartial[taskId] + + "
" + + "
" + + "
" + + "" + + "
" + + "
" + + "" + + "
" + ); } function inputForTasklist() { - return "
"+ - "
"+ - "
"+ - "
"+ - "
"+ - "
"+ - "
"+ - ""+ - "Create"+ - ""+ - "
"+ - "
"+ - "Cancel
"; + return ( + "
" + + "
" + + "
" + + "
" + + "
" + + "
" + + "
" + + "" + + "Create" + + "" + + "
" + + "
" + + "Cancel
" + ); } function addTasklist() { - $("#newtasklist").html(inputForTasklist()).append("
"); + $("#newtasklist") + .html(inputForTasklist()) + .append("
"); + $("#createTasklistButton").on("click", createTasklist); + $("#cancelCreateTasklist").on("click", restoreCreateTasklist); } -function addTask(tasklistId) { +function addTask() { if ($("#newTask").length == 0) { - var input = inputForTask(tasklistId); - $('#newtasks').show(); + var input = inputForTask($(this).data("tasklistid")); + $("#newtasks").show(); $("#newtasks").addClass("card"); $("#newtasks").append(input); + $(".createNewTaskButton").on("click", createTask); + $(".cancelNewTaskButton").on("click", restoreCreateTask); } } -function renderTask(tasklistId, tasklistCount) { +function renderTask() { + tasklistId = $(this).data("tasklistid"); + index = $(this).data("index"); $.ajax({ url: "/tasklists/" + tasklistId + "/render_tasks", success: function(result) { $("#tasks").html(result); + $("#addTaskButton").on("click", addTask); + $(".taskname").on("click", renderUpdate); + $(".taskUpdate").on("click", renderUpdate); + $(".taskDelete").on("click", deleteTask); + $(":checkbox").on("click", updateTaskStatus); } }); - setSelectedTasklist(tasklistCount); + setSelectedTasklist(index); } - -function renderUpdate(tasklistId, taskId) { +function updateTaskView(tasklistId, taskId) { + var text = $("#task" + taskId).text(); + return ( + "
" + + "
" + + "
" + + "
" + + "
" + + "Cancel
" + ); +} +function renderUpdate() { + tasklistId = $(this).data("tasklistid"); + taskId = $(this).data("taskid"); if ( $("#task" + taskId).prop("tagName") == "DIV" && $("#task" + taskId).find($("#inputTask" + taskId)).length == 0 ) { var text = $("#task" + taskId).text(); taskNamePartial[taskId] = text; - taskChecked[taskId] = $('#checkbox'+taskId).prop("checked"); - $("#card" + taskId).html( - "
"+ - "
"+ - "
" + - "
" + - "
"+ - "Cancel
" - ); + taskChecked[taskId] = $("#checkbox" + taskId).prop("checked"); + $("#card" + taskId).html(updateTaskView(tasklistId, taskId)); + $(".updateTaskSaveButton").on("click", updateTask); + $(".updateTaskCancelButton").on("click", restoreTask); + $(":checkbox").on("click", updateTaskStatus); } } function createTasklist() { @@ -106,145 +173,203 @@ function createTasklist() { url: "/tasklists", data: "name=" + $("#tasklistnew").val(), success: function(data) { - $("#tasklists").append($(data).find('DIV')[0]).append("
"); - $('#newtasklist').empty(); - $('#tasklistnew').val(""); - $('#tasklists').find('.tasklist_list').click(); + $("#tasklists") + .append($(data).find("DIV")[0]) + .append("
"); + $("#newtasklist").empty(); + $("#tasklistnew").val(""); + $("#tasklists") + .find(".tasklist_list") + .click(); + $(".tasklist_list").on("click", renderTask); + $(".tasklistUpdateButton").on("click", renderUpdateTasklist); } }); } -function updateTasklist(tasklistId) { +function updateTasklist() { + tasklistId = $(this).data("tasklistid"); Rails.ajax({ type: "put", url: "/tasklists/" + tasklistId + "/", data: "name=" + $("#updateTasklistInput" + tasklistId).val(), success: function(data) { - console.log(data); - $('#tasklist_list'+tasklistId).empty(); - $('#tasklist_list'+tasklistId).append($(data).find("DIV")[1]).append($(data).find("DIV")[1]).append($(data).find("DIV")[1]); + $("#tasklist_list" + tasklistId).empty(); + $("#tasklist_list" + tasklistId) + .append($(data).find("DIV")[1]) + .append($(data).find("DIV")[1]) + .append($(data).find("DIV")[1]); + $(".tasklistUpdateButton").on("click", renderUpdateTasklist); } }); } -function createTask(tasklistId) { +function createTask() { + tasklistId = $(this).data("tasklistid"); Rails.ajax({ type: "post", url: "tasklists/" + tasklistId + "/tasks/", data: "name=" + $("#newTask").val(), success: function(data) { - $(".tab-content").append($(data).find('DIV')[0]).append("
"); + $(".tab-content") + .append($(data).find("DIV")[0]) + .append("
"); restoreCreateTask(); + $(".taskDelete").on("click", deleteTask); + $(":checkbox").on("click", updateTaskStatus); } }); } -function updateTask(tasklistId, taskId) { +function updateTask() { + tasklistId = $(this).data("tasklistid"); + taskId = $(this).data("taskid"); Rails.ajax({ type: "put", url: "tasklists/" + tasklistId + "/tasks/" + taskId, data: "name=" + $("#inputTask" + taskId).val(), success: function(data) { - console.log(data); - $("#card"+taskId).empty(); - $("#card"+taskId).append($(data).find('DIV')[3]).append($(data).find('DIV')[3]) - .append($(data).find('DIV')[3]) - .append($(data).find('DIV')[3]) - .append("
"); + $("#card" + taskId).empty(); + $("#card" + taskId) + .append($(data).find("DIV")[3]) + .append($(data).find("DIV")[3]) + .append($(data).find("DIV")[3]) + .append($(data).find("DIV")[3]) + .append("
"); + $(".taskname").on("click", renderUpdate); + $(".taskUpdate").on("click", renderUpdate); } }); } function deleteTask(tasklistId, taskId) { + tasklistId = $(this).data("tasklistid"); + taskId = $(this).data("taskid"); Rails.ajax({ type: "delete", url: "tasklists/" + tasklistId + "/tasks/" + taskId, success: function(data) { - $('#tasklist'+tasklistId).click(); + $("#tasklist" + tasklistId).click(); } }); } function setSelectedTasklist(selectedTasklist) { - console.log(selectedTasklist); localStorage.setItem("selectedTasklistCount", selectedTasklist); } function defaultSelectedTasklist() { $(document).ready(function() { - console.log(localStorage.getItem("selectedTasklistCount")); if (localStorage.getItem("selectedTasklistCount") === null) { $(document) .find(".tasklist_list")[0] .click(); - } else{ - $(document) - .find(".tasklist_list")[ - localStorage.getItem("selectedTasklistCount")].click(); - }}); + } else { + $(document) + .find(".tasklist_list") + [localStorage.getItem("selectedTasklistCount")].click(); + } + }); } + defaultSelectedTasklist(); -function inputForUpdateTasklist(tasklistId,index) { +function inputForUpdateTasklist(tasklistId, index) { return ( - "
"+ + "
" + "
" + "
"+ + "' value='" + + $("#tasklist" + tasklistId).text() + + "'>
" + "
" + - " Save" + + "
" + + "
" + + "Save" + - "
"+ - "
"+ - "Cancel"+ - "
"); + " data-index = " + + index + + ">Cancel" + + "
" + ); } -function restoreUpdateTasklistView(tasklistId,index){ -return ( -"
"+ - "
"+ - tasklistNamePartial[tasklistId]+ - "
"+ - "
"+ - "
"+ - "
"+ - "
"+ - "
"+ - "
"+ - "
") +function restoreUpdateTasklistView(tasklistId, index) { + return ( + "
" + + "
" + + tasklistNamePartial[tasklistId] + + "
" + + "
" + + "
" + + "
" + + "
" + + "
" + + "
" + + "
" + ); } -function restoreUpdateTasklist(tasklistId,index) { - $("#tasklist_list" + tasklistId).html(restoreUpdateTasklistView(tasklistId,index)); +function restoreUpdateTasklist() { + tasklistId = $(this).data("tasklistid"); + index = $(this).data("index"); + $("#tasklist_list" + tasklistId).html( + restoreUpdateTasklistView(tasklistId, index) + ); + $(".tasklistUpdateButton").on("click", renderUpdateTasklist); } var tasklistNamePartial = []; var tasklistIndex = []; -function renderUpdateTasklist(tasklistId,index) { + +function renderUpdateTasklist() { + tasklistId = $(this).data("tasklistid"); + index = $(this).data("index"); tasklistNamePartial[tasklistId] = $("#tasklist" + tasklistId).text(); - console.log(tasklistNamePartial[tasklistId]) tasklistIndex = index; - $("#tasklist_list" + tasklistId).html(inputForUpdateTasklist(tasklistId,index)); + $("#tasklist_list" + tasklistId).html( + inputForUpdateTasklist(tasklistId, index) + ); + $(".saveUpdateTasklistButton").bind( + "click", + { tasklistid: tasklistId, index: index }, + updateTasklist + ); + $(".cancelUpdateTasklistButton").bind("click", restoreUpdateTasklist); } -function updateTaskStatus(tasklistId,taskId){ -Rails.ajax({ - url: "/tasklists/"+tasklistId+"/tasks/"+taskId+"/checkbox_update" , - type: 'patch', - success: function(data){ - console.log(data); - } -}); +function updateTaskStatus() { + tasklistId = $(this).data("tasklistid"); + taskId = $(this).data("taskid"); + Rails.ajax({ + url: "/tasklists/" + tasklistId + "/tasks/" + taskId + "/checkbox_update", + type: "patch", + success: function(data) {} + }); } -function restoreCreateTasklist(){ -$('#newtasklist').empty(); +function restoreCreateTasklist() { + $("#newtasklist").empty(); } -function restoreCreateTask(){ - $('#newtasks').empty(); - $('#newtasks').removeClass("card"); - -} \ No newline at end of file +function restoreCreateTask() { + $("#newtasks").empty(); + $("#newtasks").removeClass("card"); + $(".taskname").on("click", renderUpdate); + $(".taskUpdate").on("click", renderUpdate); +} diff --git a/app/views/tasklists/_tasklist.html.haml b/app/views/tasklists/_tasklist.html.haml index b97f0b7..2d578ef 100644 --- a/app/views/tasklists/_tasklist.html.haml +++ b/app/views/tasklists/_tasklist.html.haml @@ -1,7 +1,8 @@ .row.algin-middle.tasklistname{id: "tasklist_list#{@tasklist.id}"} .col-sm-8 - .tasklist_list{onclick: "renderTask(#{@tasklist.id},#{current_user.tasklists.count - 1 })",id: "tasklist#{@tasklist.id}"} #{@tasklist.name} + .tasklist_list{"data-index": current_user.tasklists.count - 1, "data-tasklistid": @tasklist.id, id: "tasklist#{@tasklist.id}"} + = @tasklist.name .col-sm-1 - %a.fa.fa-edit.pull-right{onclick: "renderUpdateTasklist(#{@tasklist.id},#{current_user.tasklists.count - 1 })", id: "update"} + %a.fa.fa-edit.pull-right.tasklistUpdateButton{"data-index": current_user.tasklists.count - 1, "data-tasklistid": @tasklist.id, id: "update"} .col-sm-1 =link_to '', tasklist_path(@tasklist.id),method: 'delete', class: "pull-right fa fa-trash-alt" ,id: "delete" \ No newline at end of file diff --git a/app/views/tasklists/_tasks.html.haml b/app/views/tasklists/_tasks.html.haml index 88d62a6..bd56531 100644 --- a/app/views/tasklists/_tasks.html.haml +++ b/app/views/tasklists/_tasks.html.haml @@ -4,14 +4,14 @@ .card.col-sm-12 .row.card-body{id: "card#{task.id}"} .col-sm-1.align-self-center - %input{type: 'checkbox', id: "checkbox#{task.id}", onclick: "updateTaskStatus(#{params[:id]},#{task.id})", "checked": task.status} + %input{type: 'checkbox', id: "checkbox#{task.id}", "data-tasklistid": params[:id], "data-taskid": task.id, "checked": task.status} .col-sm-8.align-self-center - %div{id:"task#{task.id}",onClick:"renderUpdate(#{params[:id]},#{task.id})"} + %div.taskname{id:"task#{task.id}", "data-tasklistid": params[:id], "data-taskid": task.id} =task.name .col-sm-1.align-self-center - %span.fa.fa-edit{onclick: "renderUpdate(#{params[:id]},#{task.id})", id: 'taskUpdate'} + %span.fa.fa-edit#taskUpdate.taskUpdate{"data-tasklistid": params[:id], "data-taskid": task.id} .col-sm-1.align-self-center - %span.btn.far.fa-trash-alt{onClick:"deleteTask(#{params[:id]},#{task.id})", id: 'taskDelete'} + %span.far.fa-trash-alt#taskDelete.taskDelete{"data-tasklistid": params[:id], "data-taskid": task.id} %br %br .row @@ -19,4 +19,4 @@ %br .row %br - %button{onClick:"addTask(#{params[:id]})",class: "btn btn-primary"} Add Task + %button.btn.btn-primary#addTaskButton{"data-tasklistid": params[:id]} Add Task diff --git a/app/views/tasklists/index.html.haml b/app/views/tasklists/index.html.haml index b89a52c..61a4256 100644 --- a/app/views/tasklists/index.html.haml +++ b/app/views/tasklists/index.html.haml @@ -11,20 +11,18 @@ .row .col-sm-2 Task lists - %a.float-right.fa.fa-plus{onClick: 'addTasklist()'} + %a-#newTasklistButton.float-right.fa.fa-plus %hr #newtasklist #tasklists - - tasklistCount = 0 - -@tasklists.each do |tasklist| + -@tasklists.each_with_index do |tasklist,index| .row.align-middle.tasklistname{id: "tasklist_list#{tasklist.id}"} .col-sm-8 - .tasklist_list{onClick: "renderTask(#{tasklist.id},#{tasklistCount})", id:"tasklist#{tasklist.id}"} #{tasklist.name} + .tasklist_list{"data-tasklistid": tasklist.id, "data-index": index, id:"tasklist#{tasklist.id}"} #{tasklist.name} .col-sm-1 - %a.fa.fa-edit.pull-right{onclick: "renderUpdateTasklist(#{tasklist.id}, #{tasklistCount})", id: 'update'} + %a.fa.fa-edit.pull-right.tasklistUpdateButton{"data-tasklistid": tasklist.id, "data-index": index, id: 'update'} .col-sm-1 =link_to '', tasklist_path(tasklist.id),method: 'delete', class: "pull-right fa fa-trash-alt" ,id: "delete" - - tasklistCount += 1 %br .col-sm-1 .col-sm-8 diff --git a/app/views/tasks/_task.html.haml b/app/views/tasks/_task.html.haml index b4292c6..2f0ac6d 100644 --- a/app/views/tasks/_task.html.haml +++ b/app/views/tasks/_task.html.haml @@ -1,14 +1,13 @@ - .row .card.col-sm-12 .row.card-body{id: "card#{@task.id}"} .col-sm-1.align-self-center - %input{type: 'checkbox', id: "checkbox#{@task.id}", onclick: "updateTaskStatus(#{@task.tasklist.id},#{@task.id})", "checked": @task.status} + %input{type: 'checkbox', id: "checkbox#{@task.id}", "data-tasklistid": @task.tasklist.id, "data-taskid": @task.id, "checked": @task.status} .col-sm-8.align-self-center - %div{id:"task#{@task.id}",onClick:"renderUpdate(#{@task.tasklist.id},#{@task.id})"} + %div.taskname{id:"task#{@task.id}", "data-tasklistid": @task.tasklist.id, "data-taskid": @task.id} =@task.name .col-sm-1.align-self-center - %span.fa.fa-edit{onclick: "renderUpdate(#{@task.tasklist.id},#{@task.id})", id: "taskUpdate"} + %span.fa.fa-edit#taskUpdate.taskUpdate{"data-tasklistid": @task.tasklist.id, "data-taskid": @task.id} .col-sm-1.align-self-center - %span.far.fa-trash-alt{onClick:"deleteTask(#{@task.tasklist.id},#{@task.id})", id: "taskDelete"} + %span.far.fa-trash-alt.taskDelete#taskDelete{"data-tasklistid": @task.tasklist.id, "data-taskid": @task.id} %br \ No newline at end of file From 59148f52d637fd6ff32a3f99630571c3fcd1a483 Mon Sep 17 00:00:00 2001 From: Shashank Bansal Date: Fri, 2 Aug 2019 19:30:15 +0530 Subject: [PATCH 07/18] bindview function removed --- app/assets/javascripts/custom.js | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/app/assets/javascripts/custom.js b/app/assets/javascripts/custom.js index 7e4944f..b4ca391 100644 --- a/app/assets/javascripts/custom.js +++ b/app/assets/javascripts/custom.js @@ -1,12 +1,8 @@ -function bindView() { - $(document).ready(function() { - $("#newTasklistButton").on("click", addTasklist); - $(".tasklist_list").on("click", renderTask); - $(".tasklistUpdateButton").on("click", renderUpdateTasklist); - }); -} - -bindView(); +$(document).ready(function() { + $("#newTasklistButton").on("click", addTasklist); + $(".tasklist_list").on("click", renderTask); + $(".tasklistUpdateButton").on("click", renderUpdateTasklist); +}); function inputForTask(tasklistId) { return ( @@ -345,11 +341,7 @@ function renderUpdateTasklist() { $("#tasklist_list" + tasklistId).html( inputForUpdateTasklist(tasklistId, index) ); - $(".saveUpdateTasklistButton").bind( - "click", - { tasklistid: tasklistId, index: index }, - updateTasklist - ); + $(".saveUpdateTasklistButton").bind("click", updateTasklist); $(".cancelUpdateTasklistButton").bind("click", restoreUpdateTasklist); } From e24e9d54689753d82e246572ee41dd9d835d3edb Mon Sep 17 00:00:00 2001 From: Shashank Bansal Date: Fri, 2 Aug 2019 19:32:28 +0530 Subject: [PATCH 08/18] route change --- app/assets/javascripts/custom.js | 2 +- app/controllers/tasks_controller.rb | 2 +- config/routes.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/custom.js b/app/assets/javascripts/custom.js index b4ca391..74bbfb4 100644 --- a/app/assets/javascripts/custom.js +++ b/app/assets/javascripts/custom.js @@ -349,7 +349,7 @@ function updateTaskStatus() { tasklistId = $(this).data("tasklistid"); taskId = $(this).data("taskid"); Rails.ajax({ - url: "/tasklists/" + tasklistId + "/tasks/" + taskId + "/checkbox_update", + url: "/tasklists/" + tasklistId + "/tasks/" + taskId + "/updateStatus", type: "patch", success: function(data) {} }); diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb index c665e09..a84125d 100644 --- a/app/controllers/tasks_controller.rb +++ b/app/controllers/tasks_controller.rb @@ -21,7 +21,7 @@ def destroy tasks.destroy end - def checkbox_update + def updateStatus task = @tasklist.tasks.find(params[:id]) task.update!(status: !task.status) end diff --git a/config/routes.rb b/config/routes.rb index 6a73c0d..28dff83 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -13,7 +13,7 @@ end resources :tasks do member do - patch 'checkbox_update' + patch 'updateStatus' end end end From b2b88e2547ae0f0c3570a8ecc68957d7db49417b Mon Sep 17 00:00:00 2001 From: Shashank Bansal Date: Fri, 2 Aug 2019 19:51:58 +0530 Subject: [PATCH 09/18] intermediary commit before binding --- app/assets/javascripts/custom.js | 2 +- app/controllers/tasks_controller.rb | 2 +- app/views/tasklists/index.html.haml | 4 +++- config/routes.rb | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/custom.js b/app/assets/javascripts/custom.js index 74bbfb4..113a1c5 100644 --- a/app/assets/javascripts/custom.js +++ b/app/assets/javascripts/custom.js @@ -349,7 +349,7 @@ function updateTaskStatus() { tasklistId = $(this).data("tasklistid"); taskId = $(this).data("taskid"); Rails.ajax({ - url: "/tasklists/" + tasklistId + "/tasks/" + taskId + "/updateStatus", + url: "/tasklists/" + tasklistId + "/tasks/" + taskId + "/toggle_status", type: "patch", success: function(data) {} }); diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb index a84125d..9586fb0 100644 --- a/app/controllers/tasks_controller.rb +++ b/app/controllers/tasks_controller.rb @@ -21,7 +21,7 @@ def destroy tasks.destroy end - def updateStatus + def toggle_status task = @tasklist.tasks.find(params[:id]) task.update!(status: !task.status) end diff --git a/app/views/tasklists/index.html.haml b/app/views/tasklists/index.html.haml index 61a4256..62cff3f 100644 --- a/app/views/tasklists/index.html.haml +++ b/app/views/tasklists/index.html.haml @@ -27,4 +27,6 @@ .col-sm-1 .col-sm-8 .row - #tasks{style:"width:90%"} \ No newline at end of file + #tasks{style:"width:90%"} + + diff --git a/config/routes.rb b/config/routes.rb index 28dff83..2bf3541 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -13,7 +13,7 @@ end resources :tasks do member do - patch 'updateStatus' + patch 'toggle_status' end end end From adece414985b35232e6cdba1ff59d84c37614704 Mon Sep 17 00:00:00 2001 From: Shashank Bansal Date: Mon, 5 Aug 2019 18:32:21 +0530 Subject: [PATCH 10/18] itermediary commit before changing on's --- app/assets/javascripts/custom.js | 9 +++++---- app/assets/stylesheets/application.scss | 2 +- app/controllers/tasks_controller.rb | 12 +++++++----- app/views/tasklists/_tasklist.html.haml | 4 ++-- app/views/tasks/_task.html.haml | 2 +- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/app/assets/javascripts/custom.js b/app/assets/javascripts/custom.js index 113a1c5..9987f25 100644 --- a/app/assets/javascripts/custom.js +++ b/app/assets/javascripts/custom.js @@ -253,21 +253,22 @@ function setSelectedTasklist(selectedTasklist) { localStorage.setItem("selectedTasklistCount", selectedTasklist); } -function defaultSelectedTasklist() { +function setActiveTaskList() { + var storage = localStorage.getItem("selectedTasklistCount") $(document).ready(function() { - if (localStorage.getItem("selectedTasklistCount") === null) { + if (storage === null) { $(document) .find(".tasklist_list")[0] .click(); } else { $(document) .find(".tasklist_list") - [localStorage.getItem("selectedTasklistCount")].click(); + [storage].click(); } }); } -defaultSelectedTasklist(); +setActiveTaskList(); function inputForUpdateTasklist(tasklistId, index) { return ( diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index c77eaf1..cfd8164 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -14,4 +14,4 @@ @import "bootstrap"; @import "font-awesome-sprockets"; @import "font-awesome"; - @import "tasklist"; + @import "tasklist"; diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb index 9586fb0..9f77c90 100644 --- a/app/controllers/tasks_controller.rb +++ b/app/controllers/tasks_controller.rb @@ -3,6 +3,7 @@ class TasksController < ApplicationController before_action :authenticate_user! before_action :set_tasklist + before_action :set_task def index; end @@ -12,18 +13,15 @@ def create end def update - @task = @tasklist.tasks.find(params[:id]) render partial: 'task' if @task.update(tasklist_params) end def destroy - tasks = @tasklist.tasks.find(params[:id]) - tasks.destroy + @task.destroy end def toggle_status - task = @tasklist.tasks.find(params[:id]) - task.update!(status: !task.status) + @task.update!(status: !task.status) end private @@ -39,4 +37,8 @@ def tasklist_params def set_tasklist @tasklist = current_user.tasklists.find(params[:tasklist_id]) end + + def set_task + @task = @tasklist.tasks.find(params[:id]) + end end diff --git a/app/views/tasklists/_tasklist.html.haml b/app/views/tasklists/_tasklist.html.haml index 2d578ef..33417c1 100644 --- a/app/views/tasklists/_tasklist.html.haml +++ b/app/views/tasklists/_tasklist.html.haml @@ -1,8 +1,8 @@ -.row.algin-middle.tasklistname{id: "tasklist_list#{@tasklist.id}"} +.row.align-middle.tasklistname{id: "tasklist_list#{@tasklist.id}"} .col-sm-8 .tasklist_list{"data-index": current_user.tasklists.count - 1, "data-tasklistid": @tasklist.id, id: "tasklist#{@tasklist.id}"} = @tasklist.name .col-sm-1 %a.fa.fa-edit.pull-right.tasklistUpdateButton{"data-index": current_user.tasklists.count - 1, "data-tasklistid": @tasklist.id, id: "update"} .col-sm-1 - =link_to '', tasklist_path(@tasklist.id),method: 'delete', class: "pull-right fa fa-trash-alt" ,id: "delete" \ No newline at end of file + =link_to '', tasklist_path(@tasklist.id),method: 'delete', class: "pull-right fa fa-trash-alt" ,id: "delete" diff --git a/app/views/tasks/_task.html.haml b/app/views/tasks/_task.html.haml index 2f0ac6d..ef94c6e 100644 --- a/app/views/tasks/_task.html.haml +++ b/app/views/tasks/_task.html.haml @@ -7,7 +7,7 @@ %div.taskname{id:"task#{@task.id}", "data-tasklistid": @task.tasklist.id, "data-taskid": @task.id} =@task.name .col-sm-1.align-self-center - %span.fa.fa-edit#taskUpdate.taskUpdate{"data-tasklistid": @task.tasklist.id, "data-taskid": @task.id} + %span.fa.fa-edit#taskUpdate.updateTask{"data-tasklistid": @task.tasklist.id, "data-taskid": @task.id} .col-sm-1.align-self-center %span.far.fa-trash-alt.taskDelete#taskDelete{"data-tasklistid": @task.tasklist.id, "data-taskid": @task.id} %br \ No newline at end of file From df9e3529ee45be34cbb67024abc5234400387769 Mon Sep 17 00:00:00 2001 From: Shashank Bansal Date: Tue, 6 Aug 2019 05:16:43 +0530 Subject: [PATCH 11/18] changes made as per PR --- app/assets/javascripts/custom.js | 18 +++++------ app/assets/stylesheets/tasklist.scss | 5 +-- app/controllers/tasks_controller.rb | 4 +-- app/views/tasklists/_tasklist.html.haml | 17 +++++----- app/views/tasklists/_tasks.html.haml | 42 +++++++++++++------------ app/views/tasklists/index.html.haml | 30 +++++++++--------- app/views/tasks/_task.html.haml | 27 ++++++++-------- 7 files changed, 72 insertions(+), 71 deletions(-) diff --git a/app/assets/javascripts/custom.js b/app/assets/javascripts/custom.js index 9987f25..e224e3b 100644 --- a/app/assets/javascripts/custom.js +++ b/app/assets/javascripts/custom.js @@ -6,13 +6,14 @@ $(document).ready(function() { function inputForTask(tasklistId) { return ( - "
" + + "
  • "+ + "
    " + "
    " + "
    " + "
    " + - "
    Cancel
    " + ">Save
  • " + + "
    Cancel
    " ); } @@ -101,7 +102,6 @@ function addTask() { if ($("#newTask").length == 0) { var input = inputForTask($(this).data("tasklistid")); $("#newtasks").show(); - $("#newtasks").addClass("card"); $("#newtasks").append(input); $(".createNewTaskButton").on("click", createTask); $(".cancelNewTaskButton").on("click", restoreCreateTask); @@ -170,7 +170,7 @@ function createTasklist() { data: "name=" + $("#tasklistnew").val(), success: function(data) { $("#tasklists") - .append($(data).find("DIV")[0]) + .append($(data).find("li")[0]) .append("
    "); $("#newtasklist").empty(); $("#tasklistnew").val(""); @@ -206,9 +206,8 @@ function createTask() { url: "tasklists/" + tasklistId + "/tasks/", data: "name=" + $("#newTask").val(), success: function(data) { - $(".tab-content") - .append($(data).find("DIV")[0]) - .append("
    "); + $(".tab-content .list-group") + .append($(data).find("li")[0]); restoreCreateTask(); $(".taskDelete").on("click", deleteTask); $(":checkbox").on("click", updateTaskStatus); @@ -296,7 +295,7 @@ function inputForUpdateTasklist(tasklistId, index) { function restoreUpdateTasklistView(tasklistId, index) { return ( - "
    " + + "
    " + "
    Date: Tue, 6 Aug 2019 06:54:41 +0530 Subject: [PATCH 12/18] change made for constants and data attributes --- app/assets/javascripts/custom.js | 71 +++++++++++++++------------- app/views/tasklists/_tasks.html.haml | 10 ++-- 2 files changed, 42 insertions(+), 39 deletions(-) diff --git a/app/assets/javascripts/custom.js b/app/assets/javascripts/custom.js index e224e3b..3cc51f8 100644 --- a/app/assets/javascripts/custom.js +++ b/app/assets/javascripts/custom.js @@ -17,15 +17,12 @@ function inputForTask(tasklistId) { ); } -var taskNamePartial = []; -var taskChecked = []; - function restoreTask() { - tasklistId = $(this).data("tasklistid"); - taskId = $(this).data("taskid"); + const tasklistId = $(this).data("tasklistid"); + const taskId = $(this).data("taskid"); $("#card" + taskId).empty(); $("#card" + taskId).append(restoreTaskView(tasklistId, taskId)); - if (taskChecked[taskId] == true) { + if ($('#card'+taskId).data("status") == true) { $("#checkbox" + taskId).attr("checked", "checked"); } $(".taskname").on("click", renderUpdate); @@ -52,7 +49,7 @@ function restoreTaskView(tasklistId, taskId) { " data-taskid = " + taskId + ">" + - taskNamePartial[taskId] + + $('#card'+taskId).data("title") + "
    " + "
    " + "
    " + @@ -100,7 +97,7 @@ function addTasklist() { function addTask() { if ($("#newTask").length == 0) { - var input = inputForTask($(this).data("tasklistid")); + const input = inputForTask($(this).data("tasklistid")); $("#newtasks").show(); $("#newtasks").append(input); $(".createNewTaskButton").on("click", createTask); @@ -109,8 +106,8 @@ function addTask() { } function renderTask() { - tasklistId = $(this).data("tasklistid"); - index = $(this).data("index"); + const tasklistId = $(this).data("tasklistid"); + const index = $(this).data("index"); $.ajax({ url: "/tasklists/" + tasklistId + "/render_tasks", success: function(result) { @@ -124,8 +121,9 @@ function renderTask() { }); setSelectedTasklist(index); } + function updateTaskView(tasklistId, taskId) { - var text = $("#task" + taskId).text(); + const text = $("#task" + taskId).text(); return ( "
    " + "" + - tasklistNamePartial[tasklistId] + + $('#tasklist_list'+tasklistId).data("name") + "
    " + "
    " + "
    " + @@ -322,32 +321,36 @@ function restoreUpdateTasklistView(tasklistId, index) { } function restoreUpdateTasklist() { - tasklistId = $(this).data("tasklistid"); - index = $(this).data("index"); + const tasklistId = $(this).data("tasklistid"); + const index = $(this).data("index"); $("#tasklist_list" + tasklistId).html( restoreUpdateTasklistView(tasklistId, index) ); $(".tasklistUpdateButton").on("click", renderUpdateTasklist); + $('#tasklist_list'+tasklistId).removeAttr("data-index"); + $('#tasklist_list'+tasklistId).removeAttr("data-name"); } -var tasklistNamePartial = []; -var tasklistIndex = []; function renderUpdateTasklist() { - tasklistId = $(this).data("tasklistid"); - index = $(this).data("index"); - tasklistNamePartial[tasklistId] = $("#tasklist" + tasklistId).text(); + const tasklistId = $(this).data("tasklistid"); + const index = $(this).data("index"); + $('#tasklist_list'+tasklistId).attr("data-name",$("#tasklist" + tasklistId).text()); + $('#tasklist_list'+tasklistId).attr("data-index",index); + tasklistIndex = index; $("#tasklist_list" + tasklistId).html( inputForUpdateTasklist(tasklistId, index) ); $(".saveUpdateTasklistButton").bind("click", updateTasklist); $(".cancelUpdateTasklistButton").bind("click", restoreUpdateTasklist); + $('#tasklist_list'+tasklistId).removeAttr("data-index"); + $('#tasklist_list'+tasklistId).removeAttr("data-name"); } function updateTaskStatus() { - tasklistId = $(this).data("tasklistid"); - taskId = $(this).data("taskid"); + const tasklistId = $(this).data("tasklistid"); + const taskId = $(this).data("taskid"); Rails.ajax({ url: "/tasklists/" + tasklistId + "/tasks/" + taskId + "/toggle_status", type: "patch", diff --git a/app/views/tasklists/_tasks.html.haml b/app/views/tasklists/_tasks.html.haml index 8b02532..f41771d 100644 --- a/app/views/tasklists/_tasks.html.haml +++ b/app/views/tasklists/_tasks.html.haml @@ -6,14 +6,14 @@ .col-sm-12 .row{id: "card#{task.id}"} .col-sm-1.align-self-center - %input{type: 'checkbox', id: "checkbox#{task.id}", "data-tasklistid": params[:id], "data-taskid": task.id, "checked": task.status} + %input{type: 'checkbox', id: "checkbox#{task.id}", "data-tasklistid": task.tasklist.id, "data-taskid": task.id, "checked": task.status} .col-sm-8.align-self-center - %div.taskname{id:"task#{task.id}", "data-tasklistid": params[:id], "data-taskid": task.id} + %div.taskname{id:"task#{task.id}", "data-tasklistid": task.tasklist.id, "data-taskid": task.id} =task.name .col-sm-1.align-self-center - %span.fa.fa-edit#taskUpdate.taskUpdate{"data-tasklistid": params[:id], "data-taskid": task.id} + %span.fa.fa-edit#taskUpdate.taskUpdate{"data-tasklistid": task.tasklist.id, "data-taskid": task.id} .col-sm-1.align-self-center - %span.far.fa-trash-alt#taskDelete.taskDelete{"data-tasklistid": params[:id], "data-taskid": task.id} + %span.far.fa-trash-alt#taskDelete.taskDelete{"data-tasklistid": task.tasklist.id, "data-taskid": task.id} %br %ul.list-group .row @@ -21,4 +21,4 @@ %li.list-group-item .row %br - %button.btn.btn-primary#addTaskButton{"data-tasklistid": params[:id]} Add Task + %button.btn.btn-primary#addTaskButton{"data-tasklistid": @tasks.first.tasklist.id} Add Task From abb82cca4a0c285e192dea314b9986a518876419 Mon Sep 17 00:00:00 2001 From: Shashank Bansal Date: Tue, 6 Aug 2019 07:07:08 +0530 Subject: [PATCH 13/18] changes --- app/assets/javascripts/custom.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/custom.js b/app/assets/javascripts/custom.js index 3cc51f8..4a86427 100644 --- a/app/assets/javascripts/custom.js +++ b/app/assets/javascripts/custom.js @@ -335,17 +335,14 @@ function restoreUpdateTasklist() { function renderUpdateTasklist() { const tasklistId = $(this).data("tasklistid"); const index = $(this).data("index"); - $('#tasklist_list'+tasklistId).attr("data-name",$("#tasklist" + tasklistId).text()); - $('#tasklist_list'+tasklistId).attr("data-index",index); - + $("#tasklist_list"+tasklistId).attr("data-name",$("#tasklist" + tasklistId).text()); + $("#tasklist_list"+tasklistId).attr("data-index",index); tasklistIndex = index; $("#tasklist_list" + tasklistId).html( inputForUpdateTasklist(tasklistId, index) ); $(".saveUpdateTasklistButton").bind("click", updateTasklist); $(".cancelUpdateTasklistButton").bind("click", restoreUpdateTasklist); - $('#tasklist_list'+tasklistId).removeAttr("data-index"); - $('#tasklist_list'+tasklistId).removeAttr("data-name"); } function updateTaskStatus() { From a2810e39d628c6f439ef6651e78329699a05f476 Mon Sep 17 00:00:00 2001 From: Shashank Bansal Date: Tue, 6 Aug 2019 13:40:16 +0530 Subject: [PATCH 14/18] commit before changing bindings --- config/routes.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/routes.rb b/config/routes.rb index 2bf3541..791d893 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -7,6 +7,7 @@ devise_for :users, controllers: { session: 'users/session' } # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html root 'tasklists#index' + resources :tasklists do member do get 'render_tasks' From b59a80fdb53ec9e097b289d877b8b5e35bf9a9ec Mon Sep 17 00:00:00 2001 From: Shashank Bansal Date: Tue, 6 Aug 2019 14:39:50 +0530 Subject: [PATCH 15/18] js binding changed to dynamic Active tasklist set setActivetasklist fuction removed --- app/assets/javascripts/custom.js | 77 ++++++++++------------------ app/views/tasklists/_tasks.html.haml | 2 +- app/views/tasklists/index.html.haml | 2 +- 3 files changed, 30 insertions(+), 51 deletions(-) diff --git a/app/assets/javascripts/custom.js b/app/assets/javascripts/custom.js index 4a86427..5808f6a 100644 --- a/app/assets/javascripts/custom.js +++ b/app/assets/javascripts/custom.js @@ -1,7 +1,25 @@ $(document).ready(function() { + const storage = localStorage.getItem("selectedTasklistCount"); $("#newTasklistButton").on("click", addTasklist); $(".tasklist_list").on("click", renderTask); - $(".tasklistUpdateButton").on("click", renderUpdateTasklist); + $(".tasklistname").on("click",".tasklistUpdateButton", renderUpdateTasklist); + $("#tasks").on("click", ".taskname" , renderUpdate); + $("#tasks").on("click", ".taskUpdate" , renderUpdate); + $(":checkbox").on("click", updateTaskStatus); + $("#newtasklist").on("click","#createTasklistButton", createTasklist); + $("#newtasklist").on("click","#cancelCreateTasklist", restoreCreateTasklist); + $("#tasks").on("click", ".createNewTaskButton" ,createTask); + $("#tasks").on("click", ".cancelNewTaskButton" ,restoreCreateTask); + $("#tasks").on("click","#addTaskButton", addTask); + $("#tasks").on("click", ".taskDelete" ,deleteTask); + $("#tasks").on("click", ".updateTaskSaveButton" ,updateTask); + $("#tasks").on("click", ".updateTaskCancelButton" ,restoreTask); + if (storage === null) { + } else { + $(document) + .find("#tasklist"+storage).click(); + setSelectedTasklist(storage); + } }); function inputForTask(tasklistId) { @@ -25,9 +43,6 @@ function restoreTask() { if ($('#card'+taskId).data("status") == true) { $("#checkbox" + taskId).attr("checked", "checked"); } - $(".taskname").on("click", renderUpdate); - $(".taskUpdate").on("click", renderUpdate); - $(":checkbox").on("click", updateTaskStatus); } function restoreTaskView(tasklistId, taskId) { @@ -77,12 +92,12 @@ function inputForTasklist() { "
    " + "
    " + "
    " + - "
    " + + "
    " + "" + "Create" + "" + "
    " + - "
    " + + "
    " + "Cancel
    " ); } @@ -91,8 +106,6 @@ function addTasklist() { $("#newtasklist") .html(inputForTasklist()) .append("
    "); - $("#createTasklistButton").on("click", createTasklist); - $("#cancelCreateTasklist").on("click", restoreCreateTasklist); } function addTask() { @@ -100,8 +113,6 @@ function addTask() { const input = inputForTask($(this).data("tasklistid")); $("#newtasks").show(); $("#newtasks").append(input); - $(".createNewTaskButton").on("click", createTask); - $(".cancelNewTaskButton").on("click", restoreCreateTask); } } @@ -112,14 +123,9 @@ function renderTask() { url: "/tasklists/" + tasklistId + "/render_tasks", success: function(result) { $("#tasks").html(result); - $("#addTaskButton").on("click", addTask); - $(".taskname").on("click", renderUpdate); - $(".taskUpdate").on("click", renderUpdate); - $(".taskDelete").on("click", deleteTask); - $(":checkbox").on("click", updateTaskStatus); } }); - setSelectedTasklist(index); + setSelectedTasklist(tasklistId); } function updateTaskView(tasklistId, taskId) { @@ -156,9 +162,6 @@ function renderUpdate() { $('#card'+taskId).attr("data-title",text); $('#card'+taskId).attr("data-status", $("#checkbox" + taskId).prop("checked")); $("#card" + taskId).html(updateTaskView(tasklistId, taskId)); - $(".updateTaskSaveButton").on("click", updateTask); - $(".updateTaskCancelButton").on("click", restoreTask); - $(":checkbox").on("click", updateTaskStatus); } } @@ -169,15 +172,12 @@ function createTasklist() { data: "name=" + $("#tasklistnew").val(), success: function(data) { $("#tasklists") - .append($(data).find("li")[0]) - .append("
    "); + .append($(data).find("li")[0]); $("#newtasklist").empty(); $("#tasklistnew").val(""); $("#tasklists") .find(".tasklist_list") .click(); - $(".tasklist_list").on("click", renderTask); - $(".tasklistUpdateButton").on("click", renderUpdateTasklist); } }); } @@ -194,7 +194,6 @@ function updateTasklist() { .append($(data).find("DIV")[1]) .append($(data).find("DIV")[1]) .append($(data).find("DIV")[1]); - $(".tasklistUpdateButton").on("click", renderUpdateTasklist); } }); } @@ -208,8 +207,6 @@ function createTask() { $(".tab-content .list-group") .append($(data).find("li")[0]); restoreCreateTask(); - $(".taskDelete").on("click", deleteTask); - $(":checkbox").on("click", updateTaskStatus); } }); } @@ -227,10 +224,7 @@ function updateTask() { .append($(data).find("DIV")[3]) .append($(data).find("DIV")[3]) .append($(data).find("DIV")[3]) - .append($(data).find("DIV")[3]) - .append("
    "); - $(".taskname").on("click", renderUpdate); - $(".taskUpdate").on("click", renderUpdate); + .append($(data).find("DIV")[3]); } }); } @@ -248,25 +242,13 @@ function deleteTask() { } function setSelectedTasklist(selectedTasklist) { + var currentTasklist = localStorage.getItem("selectedTasklistCount"); + $('#tasklist_list'+currentTasklist).parent().removeClass('active'); localStorage.setItem("selectedTasklistCount", selectedTasklist); + currentTasklist = localStorage.getItem("selectedTasklistCount"); + $('#tasklist_list'+currentTasklist).parent().addClass('active'); } -function setActiveTaskList() { - const storage = localStorage.getItem("selectedTasklistCount") - $(document).ready(function() { - if (storage === null) { - $(document) - .find(".tasklist_list")[0] - .click(); - } else { - $(document) - .find(".tasklist_list") - [storage].click(); - } - }); -} - -setActiveTaskList(); function inputForUpdateTasklist(tasklistId, index) { return ( @@ -326,7 +308,6 @@ function restoreUpdateTasklist() { $("#tasklist_list" + tasklistId).html( restoreUpdateTasklistView(tasklistId, index) ); - $(".tasklistUpdateButton").on("click", renderUpdateTasklist); $('#tasklist_list'+tasklistId).removeAttr("data-index"); $('#tasklist_list'+tasklistId).removeAttr("data-name"); } @@ -361,6 +342,4 @@ function restoreCreateTasklist() { function restoreCreateTask() { $("#newtasks").empty(); - $(".taskname").on("click", renderUpdate); - $(".taskUpdate").on("click", renderUpdate); } diff --git a/app/views/tasklists/_tasks.html.haml b/app/views/tasklists/_tasks.html.haml index f41771d..93d4f70 100644 --- a/app/views/tasklists/_tasks.html.haml +++ b/app/views/tasklists/_tasks.html.haml @@ -21,4 +21,4 @@ %li.list-group-item .row %br - %button.btn.btn-primary#addTaskButton{"data-tasklistid": @tasks.first.tasklist.id} Add Task + %button.btn.btn-primary#addTaskButton{"data-tasklistid": params[:id]} Add Task diff --git a/app/views/tasklists/index.html.haml b/app/views/tasklists/index.html.haml index e899dc5..18c5b78 100644 --- a/app/views/tasklists/index.html.haml +++ b/app/views/tasklists/index.html.haml @@ -14,7 +14,7 @@ %li.list-group-item Task lists %a-#newTasklistButton.float-right.fa.fa-plus - %li.list-group-item.hide + %li.list-group-item #newtasklist #tasklists -@tasklists.each_with_index do |tasklist,index| From b323f6bb7f7052f6f0a601a303b13bf0e387ef5c Mon Sep 17 00:00:00 2001 From: Shashank Bansal Date: Tue, 6 Aug 2019 16:01:45 +0530 Subject: [PATCH 16/18] before action set in tasklist controller --- Gemfile | 2 + Gemfile.lock | 3 + app/assets/javascripts/application.js | 2 +- app/assets/javascripts/custom.js | 87 ++++++++++++------- app/assets/stylesheets/application.scss | 1 + app/controllers/tasklists_controller.rb | 22 +++-- app/controllers/tasks_controller.rb | 12 ++- .../20190806091556_remove_body_from_tasks.rb | 5 ++ db/schema.rb | 3 +- 9 files changed, 96 insertions(+), 41 deletions(-) create mode 100644 db/migrate/20190806091556_remove_body_from_tasks.rb diff --git a/Gemfile b/Gemfile index 490eae7..cb88a3b 100644 --- a/Gemfile +++ b/Gemfile @@ -45,6 +45,8 @@ gem 'haml-rails', '~> 2.0', '>= 2.0.1' gem 'hirb' gem 'jquery-rails' gem 'rubocop-rails', '~> 2.2', '>= 2.2.1' +gem 'toastr-rails', '~> 1.0', '>= 1.0.3' + group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: %i[mri mingw x64_mingw] diff --git a/Gemfile.lock b/Gemfile.lock index 93c6f17..589ee32 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -289,6 +289,8 @@ GEM thor (0.20.3) thread_safe (0.3.6) tilt (2.0.9) + toastr-rails (1.0.3) + railties (>= 3.1.0) turbolinks (5.2.0) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) @@ -336,6 +338,7 @@ DEPENDENCIES spring spring-watcher-listen (~> 2.0.0) sqlite3 + toastr-rails (~> 1.0, >= 1.0.3) turbolinks (~> 5) tzinfo-data uglifier (>= 1.3.0) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 024e523..13b91b4 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -17,4 +17,4 @@ //= require popper //= require bootstrap //= require custom.js - +//= require toastr diff --git a/app/assets/javascripts/custom.js b/app/assets/javascripts/custom.js index 5808f6a..e0af094 100644 --- a/app/assets/javascripts/custom.js +++ b/app/assets/javascripts/custom.js @@ -2,29 +2,32 @@ $(document).ready(function() { const storage = localStorage.getItem("selectedTasklistCount"); $("#newTasklistButton").on("click", addTasklist); $(".tasklist_list").on("click", renderTask); - $(".tasklistname").on("click",".tasklistUpdateButton", renderUpdateTasklist); - $("#tasks").on("click", ".taskname" , renderUpdate); - $("#tasks").on("click", ".taskUpdate" , renderUpdate); + $("#tasklists").on("click", ".tasklist_list" ,renderTask); + $("#tasklists").on("click", ".tasklistUpdateButton", renderUpdateTasklist); + $(".tasklistname").on("click", ".tasklistUpdateButton", renderUpdateTasklist); + $("#tasks").on("click", ".taskname", renderUpdate); + $("#tasks").on("click", ".taskUpdate", renderUpdate); $(":checkbox").on("click", updateTaskStatus); - $("#newtasklist").on("click","#createTasklistButton", createTasklist); - $("#newtasklist").on("click","#cancelCreateTasklist", restoreCreateTasklist); - $("#tasks").on("click", ".createNewTaskButton" ,createTask); - $("#tasks").on("click", ".cancelNewTaskButton" ,restoreCreateTask); - $("#tasks").on("click","#addTaskButton", addTask); - $("#tasks").on("click", ".taskDelete" ,deleteTask); - $("#tasks").on("click", ".updateTaskSaveButton" ,updateTask); - $("#tasks").on("click", ".updateTaskCancelButton" ,restoreTask); + $("#newtasklist").on("click", "#createTasklistButton", createTasklist); + $("#newtasklist").on("click", "#cancelCreateTasklist", restoreCreateTasklist); + $("#tasks").on("click", ".createNewTaskButton", createTask); + $("#tasks").on("click", ".cancelNewTaskButton", restoreCreateTask); + $("#tasks").on("click", "#addTaskButton", addTask); + $("#tasks").on("click", ".taskDelete", deleteTask); + $("#tasks").on("click", ".updateTaskSaveButton", updateTask); + $("#tasks").on("click", ".updateTaskCancelButton", restoreTask); if (storage === null) { } else { $(document) - .find("#tasklist"+storage).click(); - setSelectedTasklist(storage); + .find("#tasklist" + storage) + .click(); + setSelectedTasklist(storage); } }); function inputForTask(tasklistId) { return ( - "
  • "+ + "
  • " + "
    " + "
    " + "
    " + @@ -40,7 +43,7 @@ function restoreTask() { const taskId = $(this).data("taskid"); $("#card" + taskId).empty(); $("#card" + taskId).append(restoreTaskView(tasklistId, taskId)); - if ($('#card'+taskId).data("status") == true) { + if ($("#card" + taskId).data("status") == true) { $("#checkbox" + taskId).attr("checked", "checked"); } } @@ -64,7 +67,7 @@ function restoreTaskView(tasklistId, taskId) { " data-taskid = " + taskId + ">" + - $('#card'+taskId).data("title") + + $("#card" + taskId).data("title") + "
    " + "
  • " + "
    " + @@ -159,8 +162,11 @@ function renderUpdate() { $("#task" + taskId).find($("#inputTask" + taskId)).length == 0 ) { const text = $("#task" + taskId).text(); - $('#card'+taskId).attr("data-title",text); - $('#card'+taskId).attr("data-status", $("#checkbox" + taskId).prop("checked")); + $("#card" + taskId).attr("data-title", text); + $("#card" + taskId).attr( + "data-status", + $("#checkbox" + taskId).prop("checked") + ); $("#card" + taskId).html(updateTaskView(tasklistId, taskId)); } } @@ -171,13 +177,16 @@ function createTasklist() { url: "/tasklists", data: "name=" + $("#tasklistnew").val(), success: function(data) { - $("#tasklists") - .append($(data).find("li")[0]); + $("#tasklists").append($(data).find("li")[0]); $("#newtasklist").empty(); $("#tasklistnew").val(""); $("#tasklists") .find(".tasklist_list") .click(); + }, + error: function(data) { + const json = JSON.parse(JSON.stringify(data)); + toastr.error(json); } }); } @@ -194,6 +203,10 @@ function updateTasklist() { .append($(data).find("DIV")[1]) .append($(data).find("DIV")[1]) .append($(data).find("DIV")[1]); + }, + error: function(data) { + const json = JSON.parse(JSON.stringify(data)); + toastr.error(json); } }); } @@ -204,9 +217,12 @@ function createTask() { url: "tasklists/" + tasklistId + "/tasks/", data: "name=" + $("#newTask").val(), success: function(data) { - $(".tab-content .list-group") - .append($(data).find("li")[0]); + $(".tab-content .list-group").append($(data).find("li")[0]); restoreCreateTask(); + }, + error: function(data) { + const json = JSON.parse(JSON.stringify(data)); + toastr.error(json); } }); } @@ -225,6 +241,10 @@ function updateTask() { .append($(data).find("DIV")[3]) .append($(data).find("DIV")[3]) .append($(data).find("DIV")[3]); + }, + error: function(data) { + const json = JSON.parse(JSON.stringify(data)); + toastr.error(json); } }); } @@ -243,13 +263,16 @@ function deleteTask() { function setSelectedTasklist(selectedTasklist) { var currentTasklist = localStorage.getItem("selectedTasklistCount"); - $('#tasklist_list'+currentTasklist).parent().removeClass('active'); + $("#tasklist_list" + currentTasklist) + .parent() + .removeClass("active"); localStorage.setItem("selectedTasklistCount", selectedTasklist); currentTasklist = localStorage.getItem("selectedTasklistCount"); - $('#tasklist_list'+currentTasklist).parent().addClass('active'); + $("#tasklist_list" + currentTasklist) + .parent() + .addClass("active"); } - function inputForUpdateTasklist(tasklistId, index) { return ( "
    " + @@ -284,7 +307,7 @@ function restoreUpdateTasklistView(tasklistId, index) { " data-index = " + index + ">" + - $('#tasklist_list'+tasklistId).data("name") + + $("#tasklist_list" + tasklistId).data("name") + "
    " + "
    " + "
    " + @@ -308,16 +331,18 @@ function restoreUpdateTasklist() { $("#tasklist_list" + tasklistId).html( restoreUpdateTasklistView(tasklistId, index) ); - $('#tasklist_list'+tasklistId).removeAttr("data-index"); - $('#tasklist_list'+tasklistId).removeAttr("data-name"); + $("#tasklist_list" + tasklistId).removeAttr("data-index"); + $("#tasklist_list" + tasklistId).removeAttr("data-name"); } - function renderUpdateTasklist() { const tasklistId = $(this).data("tasklistid"); const index = $(this).data("index"); - $("#tasklist_list"+tasklistId).attr("data-name",$("#tasklist" + tasklistId).text()); - $("#tasklist_list"+tasklistId).attr("data-index",index); + $("#tasklist_list" + tasklistId).attr( + "data-name", + $("#tasklist" + tasklistId).text() + ); + $("#tasklist_list" + tasklistId).attr("data-index", index); tasklistIndex = index; $("#tasklist_list" + tasklistId).html( inputForUpdateTasklist(tasklistId, index) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index cfd8164..cc5fa5d 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -15,3 +15,4 @@ @import "font-awesome-sprockets"; @import "font-awesome"; @import "tasklist"; + @import 'toastr'; diff --git a/app/controllers/tasklists_controller.rb b/app/controllers/tasklists_controller.rb index 5b410c3..ecb6c25 100644 --- a/app/controllers/tasklists_controller.rb +++ b/app/controllers/tasklists_controller.rb @@ -2,6 +2,7 @@ class TasklistsController < ApplicationController before_action :authenticate_user! + before_action :set_tasklist, except: %i[index create] def index @tasklists = current_user.tasklists @@ -9,21 +10,28 @@ def index def create @tasklist = current_user.tasklists.build(tasklist_params) - render partial: 'tasklist' if @tasklist.save + if @tasklist.save + render partial: 'tasklist' + else + render json: @tasklist.errors.full_messages, status: 422 + end end def update - @tasklist = current_user.tasklists.find(params[:id]) - render partial: 'tasklist' if @tasklist.update(tasklist_params) + if @tasklist.update(tasklist_params) + render partial: 'tasklist' + else + render json: @tasklist.errors.full_messages, status: 422 + end end def render_tasks - @tasks = Tasklist.find(params[:id]).tasks + @tasks = @tasklist.tasks render partial: 'tasks' end def destroy - Tasklist.find(params[:id]).destroy + @tasklist.destroy redirect_to root_path end @@ -32,4 +40,8 @@ def destroy def tasklist_params params.permit(:name) end + + def set_tasklist + @tasklist = current_user.tasklists.find(params[:id]) + end end diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb index 514c33f..e0f312e 100644 --- a/app/controllers/tasks_controller.rb +++ b/app/controllers/tasks_controller.rb @@ -9,11 +9,19 @@ def index; end def create @task = @tasklist.tasks.build(tasklist_params) - render partial: 'task' if @task.save + if @task.save + render partial: 'task' + else + render json: @task.errors.full_messages, status: 422 + end end def update - render partial: 'task' if @task.update(tasklist_params) + if @task.update(tasklist_params) + render partial: 'task' + else + render json: @task.errors.full_messages, status: 422 + end end def destroy diff --git a/db/migrate/20190806091556_remove_body_from_tasks.rb b/db/migrate/20190806091556_remove_body_from_tasks.rb new file mode 100644 index 0000000..acb572b --- /dev/null +++ b/db/migrate/20190806091556_remove_body_from_tasks.rb @@ -0,0 +1,5 @@ +class RemoveBodyFromTasks < ActiveRecord::Migration[5.2] + def change + remove_column :tasks, :body + end +end diff --git a/db/schema.rb b/db/schema.rb index 2fb65ae..e1d6764 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2019_07_18_063627) do +ActiveRecord::Schema.define(version: 2019_08_06_091556) do create_table "active_admin_comments", force: :cascade do |t| t.string "namespace" @@ -48,7 +48,6 @@ create_table "tasks", force: :cascade do |t| t.string "name" - t.text "body" t.boolean "status" t.integer "tasklist_id" t.datetime "created_at", null: false From e123ee89022529c926f30b1d23449d114f992ef0 Mon Sep 17 00:00:00 2001 From: Shashank Bansal Date: Wed, 7 Aug 2019 14:28:59 +0530 Subject: [PATCH 17/18] mustache templating done --- Gemfile | 1 + Gemfile.lock | 2 + app/assets/javascripts/application.js | 1 + app/assets/javascripts/custom.js | 167 ++--- app/assets/stylesheets/tasklist.scss | 52 +- app/controllers/tasklists_controller.rb | 10 +- app/controllers/tasks_controller.rb | 8 +- app/models/tasklist.rb | 2 +- app/views/tasklists/_tasklist.html.haml | 1 + app/views/tasklists/_update.html.haml | 7 + app/views/tasklists/create_tasklist.js.haml | 4 + app/views/tasklists/errors.js.haml | 2 + app/views/tasklists/update_tasklist.js.haml | 2 + app/views/tasks/_update.html.haml | 10 + app/views/tasks/create_task.js.haml | 2 + app/views/tasks/errors.js.haml | 2 + app/views/tasks/update_task.js.haml | 2 + config/routes.rb | 2 +- package.json | 4 +- vendor/mustache/mustache.js | 682 ++++++++++++++++++++ 20 files changed, 803 insertions(+), 160 deletions(-) create mode 100644 app/views/tasklists/_update.html.haml create mode 100644 app/views/tasklists/create_tasklist.js.haml create mode 100644 app/views/tasklists/errors.js.haml create mode 100644 app/views/tasklists/update_tasklist.js.haml create mode 100644 app/views/tasks/_update.html.haml create mode 100644 app/views/tasks/create_task.js.haml create mode 100644 app/views/tasks/errors.js.haml create mode 100644 app/views/tasks/update_task.js.haml create mode 100644 vendor/mustache/mustache.js diff --git a/Gemfile b/Gemfile index cb88a3b..6e48664 100644 --- a/Gemfile +++ b/Gemfile @@ -46,6 +46,7 @@ gem 'hirb' gem 'jquery-rails' gem 'rubocop-rails', '~> 2.2', '>= 2.2.1' gem 'toastr-rails', '~> 1.0', '>= 1.0.3' +gem "mustache", "~> 1.0" group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console diff --git a/Gemfile.lock b/Gemfile.lock index 589ee32..53f325d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -179,6 +179,7 @@ GEM mini_portile2 (2.4.0) minitest (5.11.3) msgpack (1.3.0) + mustache (1.1.0) nio4r (2.4.0) nokogiri (1.10.3) mini_portile2 (~> 2.4.0) @@ -330,6 +331,7 @@ DEPENDENCIES jbuilder (~> 2.5) jquery-rails listen (>= 3.0.5, < 3.2) + mustache (~> 1.0) puma (~> 3.11) rails (~> 5.2.3) rubocop-rails (~> 2.2, >= 2.2.1) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 13b91b4..5d979eb 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -18,3 +18,4 @@ //= require bootstrap //= require custom.js //= require toastr +//= require mustache/mustache.js diff --git a/app/assets/javascripts/custom.js b/app/assets/javascripts/custom.js index e0af094..e33380b 100644 --- a/app/assets/javascripts/custom.js +++ b/app/assets/javascripts/custom.js @@ -1,5 +1,5 @@ $(document).ready(function() { - const storage = localStorage.getItem("selectedTasklistCount"); + const selectedTasklist = localStorage.getItem("selectedTasklistCount"); $("#newTasklistButton").on("click", addTasklist); $(".tasklist_list").on("click", renderTask); $("#tasklists").on("click", ".tasklist_list" ,renderTask); @@ -16,24 +16,24 @@ $(document).ready(function() { $("#tasks").on("click", ".taskDelete", deleteTask); $("#tasks").on("click", ".updateTaskSaveButton", updateTask); $("#tasks").on("click", ".updateTaskCancelButton", restoreTask); - if (storage === null) { + $("#tasklists").on("click", ".saveUpdateTasklistButton" ,updateTasklist); + $("#tasklists").on("click", ".cancelUpdateTasklistButton" ,restoreUpdateTasklist); + if (selectedTasklist === null) { } else { $(document) - .find("#tasklist" + storage) + .find("#tasklist" + selectedTasklist) .click(); - setSelectedTasklist(storage); + setSelectedTasklist(selectedTasklist); } }); -function inputForTask(tasklistId) { +function inputForTask() { return ( "
  • " + "
    " + "
    " + "
    " + - "
    " + + "
    " + "
    Cancel
  • " ); } @@ -41,48 +41,31 @@ function inputForTask(tasklistId) { function restoreTask() { const tasklistId = $(this).data("tasklistid"); const taskId = $(this).data("taskid"); + const title = $("#card" + taskId).data("title"); $("#card" + taskId).empty(); - $("#card" + taskId).append(restoreTaskView(tasklistId, taskId)); + $("#card" + taskId).append(Mustache.render(taskView(),{tasklistId: tasklistId, taskId: taskId,title: title})); if ($("#card" + taskId).data("status") == true) { $("#checkbox" + taskId).attr("checked", "checked"); } } -function restoreTaskView(tasklistId, taskId) { +function taskView() { return ( "
    " + - "" + + ""+ "
    " + "
    " + - "
    " + - $("#card" + taskId).data("title") + - "
    " + + "
    {{title}}
    " + "
    " + "
    " + "" + + "{{tasklistId}} data-taskid = {{taskId}}>" + "
    " + "
    " + "" + + "{{tasklistId}} data-taskid = {{taskId}} id = 'taskDelete'>" + "
    " ); } @@ -106,14 +89,12 @@ function inputForTasklist() { } function addTasklist() { - $("#newtasklist") - .html(inputForTasklist()) - .append("
    "); + $("#newtasklist").html(Mustache.render(inputForTasklist())); } function addTask() { if ($("#newTask").length == 0) { - const input = inputForTask($(this).data("tasklistid")); + const input = Mustache.render(inputForTask(),{tasklistId: $(this).data("tasklistid")}); $("#newtasks").show(); $("#newtasks").append(input); } @@ -123,7 +104,7 @@ function renderTask() { const tasklistId = $(this).data("tasklistid"); const index = $(this).data("index"); $.ajax({ - url: "/tasklists/" + tasklistId + "/render_tasks", + url: "/tasklists/" + tasklistId + "/get_tasks", success: function(result) { $("#tasks").html(result); } @@ -131,27 +112,17 @@ function renderTask() { setSelectedTasklist(tasklistId); } -function updateTaskView(tasklistId, taskId) { - const text = $("#task" + taskId).text(); +function updateTaskView() { return ( "
    " + - "
    " + + "
    " + "
    " + "
    " + + "{{tasklistId}} data-taskid = {{taskId}}> Save
    " + "
    " + "Cancel
    " + "{{tasklistId}} data-taskid = {{taskId}}>Cancel" ); } function renderUpdate() { @@ -167,7 +138,7 @@ function renderUpdate() { "data-status", $("#checkbox" + taskId).prop("checked") ); - $("#card" + taskId).html(updateTaskView(tasklistId, taskId)); + $("#card" + taskId).html(Mustache.render(updateTaskView(),{tasklistId: tasklistId, taskId: taskId,text: text})); } } @@ -177,16 +148,8 @@ function createTasklist() { url: "/tasklists", data: "name=" + $("#tasklistnew").val(), success: function(data) { - $("#tasklists").append($(data).find("li")[0]); - $("#newtasklist").empty(); - $("#tasklistnew").val(""); - $("#tasklists") - .find(".tasklist_list") - .click(); }, error: function(data) { - const json = JSON.parse(JSON.stringify(data)); - toastr.error(json); } }); } @@ -198,15 +161,8 @@ function updateTasklist() { url: "/tasklists/" + tasklistId + "/", data: "name=" + $("#updateTasklistInput" + tasklistId).val(), success: function(data) { - $("#tasklist_list" + tasklistId).empty(); - $("#tasklist_list" + tasklistId) - .append($(data).find("DIV")[1]) - .append($(data).find("DIV")[1]) - .append($(data).find("DIV")[1]); }, error: function(data) { - const json = JSON.parse(JSON.stringify(data)); - toastr.error(json); } }); } @@ -217,12 +173,9 @@ function createTask() { url: "tasklists/" + tasklistId + "/tasks/", data: "name=" + $("#newTask").val(), success: function(data) { - $(".tab-content .list-group").append($(data).find("li")[0]); - restoreCreateTask(); }, error: function(data) { - const json = JSON.parse(JSON.stringify(data)); - toastr.error(json); + } }); } @@ -235,16 +188,8 @@ function updateTask() { url: "tasklists/" + tasklistId + "/tasks/" + taskId, data: "name=" + $("#inputTask" + taskId).val(), success: function(data) { - $("#card" + taskId).empty(); - $("#card" + taskId) - .append($(data).find("DIV")[3]) - .append($(data).find("DIV")[3]) - .append($(data).find("DIV")[3]) - .append($(data).find("DIV")[3]); }, error: function(data) { - const json = JSON.parse(JSON.stringify(data)); - toastr.error(json); } }); } @@ -273,53 +218,36 @@ function setSelectedTasklist(selectedTasklist) { .addClass("active"); } -function inputForUpdateTasklist(tasklistId, index) { +function inputForUpdateTasklist() { return ( "
    " + "
    " + - "
    " + + "
    " + "
    " + - " Save" + + " Save" + "
    " + "
    " + "Cancel" + + "{{tasklistId}} data-index = {{index}} >Cancel" + "
    " ); } -function restoreUpdateTasklistView(tasklistId, index) { +function restoreUpdateTasklistView() { + return ( "
    " + - "
    " + - $("#tasklist_list" + tasklistId).data("name") + + "
    {{title}}"+ "
    " + "
    " + "
    " + "
    " + + "{{tasklistId}} data-index = {{index}})'>
    " + "
    " + "
    " + - "
    " + "
    " ); @@ -328,9 +256,10 @@ function restoreUpdateTasklistView(tasklistId, index) { function restoreUpdateTasklist() { const tasklistId = $(this).data("tasklistid"); const index = $(this).data("index"); + const title = $("#tasklist_list" + tasklistId).data("name"); $("#tasklist_list" + tasklistId).html( - restoreUpdateTasklistView(tasklistId, index) - ); + Mustache.render(restoreUpdateTasklistView(tasklistId, index), + {tasklistId: tasklistId, index: index, title:title})); $("#tasklist_list" + tasklistId).removeAttr("data-index"); $("#tasklist_list" + tasklistId).removeAttr("data-name"); } @@ -338,17 +267,13 @@ function restoreUpdateTasklist() { function renderUpdateTasklist() { const tasklistId = $(this).data("tasklistid"); const index = $(this).data("index"); - $("#tasklist_list" + tasklistId).attr( - "data-name", - $("#tasklist" + tasklistId).text() - ); - $("#tasklist_list" + tasklistId).attr("data-index", index); + const title = $("#tasklist" + tasklistId).text(); tasklistIndex = index; + $("#tasklist_list" + tasklistId).attr("data-name",$("#tasklist" + tasklistId).text()); + $("#tasklist_list" + tasklistId).attr("data-index", index); $("#tasklist_list" + tasklistId).html( - inputForUpdateTasklist(tasklistId, index) - ); - $(".saveUpdateTasklistButton").bind("click", updateTasklist); - $(".cancelUpdateTasklistButton").bind("click", restoreUpdateTasklist); + Mustache.render(inputForUpdateTasklist(), + {tasklistId: tasklistId, index: index, title: title})); } function updateTaskStatus() { diff --git a/app/assets/stylesheets/tasklist.scss b/app/assets/stylesheets/tasklist.scss index 46c6478..3f8b133 100644 --- a/app/assets/stylesheets/tasklist.scss +++ b/app/assets/stylesheets/tasklist.scss @@ -1,45 +1,43 @@ // Place all the styles related to the tasklist controller here. // They will automatically be included in application.css. // You can use Sass (SCSS) here: http://sass-lang.com/ -@import 'bootstrap'; +@import "bootstrap"; -.tasklistname:hover{ -cursor: pointer; -#delete{ - visibility: visible -} - -#update{ - visibility: visible; -} +.tasklistname:hover { + cursor: pointer; + #delete { + visibility: visible; + } + #update { + visibility: visible; + } } -#update, #taskUpdate -{ +#update, +#taskUpdate { color: #93922a; visibility: hidden; } -#delete, #taskDelete -{ - color:#AD423F ; +#delete, +#taskDelete { + color: #ad423f; visibility: hidden; } +.tab-content li:hover { + #taskDelete { + visibility: visible; + } -.tab-content li:hover{ -#taskDelete{ - visibility: visible; -} - -#taskUpdate{ - visibility: visible; -} + #taskUpdate { + visibility: visible; + } } -checkbox:checked{ -.card-body{ -background-color: grey; +checkbox:checked { + .card-body { + background-color: grey; + } } -} \ No newline at end of file diff --git a/app/controllers/tasklists_controller.rb b/app/controllers/tasklists_controller.rb index ecb6c25..c5a215c 100644 --- a/app/controllers/tasklists_controller.rb +++ b/app/controllers/tasklists_controller.rb @@ -11,21 +11,21 @@ def index def create @tasklist = current_user.tasklists.build(tasklist_params) if @tasklist.save - render partial: 'tasklist' + render :create_tasklist else - render json: @tasklist.errors.full_messages, status: 422 + render :errors end end def update if @tasklist.update(tasklist_params) - render partial: 'tasklist' + render :update_tasklist else - render json: @tasklist.errors.full_messages, status: 422 + render :errors end end - def render_tasks + def get_tasks @tasks = @tasklist.tasks render partial: 'tasks' end diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb index e0f312e..13035b3 100644 --- a/app/controllers/tasks_controller.rb +++ b/app/controllers/tasks_controller.rb @@ -10,17 +10,17 @@ def index; end def create @task = @tasklist.tasks.build(tasklist_params) if @task.save - render partial: 'task' + render :create_task else - render json: @task.errors.full_messages, status: 422 + render :errors end end def update if @task.update(tasklist_params) - render partial: 'task' + render :update_task else - render json: @task.errors.full_messages, status: 422 + render :errors end end diff --git a/app/models/tasklist.rb b/app/models/tasklist.rb index 34b601b..0ad2203 100644 --- a/app/models/tasklist.rb +++ b/app/models/tasklist.rb @@ -1,5 +1,5 @@ class Tasklist < ApplicationRecord validates :name, presence: true - has_many :tasks, dependent: :delete_all + has_many :tasks, dependent: :destroy belongs_to :user end diff --git a/app/views/tasklists/_tasklist.html.haml b/app/views/tasklists/_tasklist.html.haml index 8e37822..52969b7 100644 --- a/app/views/tasklists/_tasklist.html.haml +++ b/app/views/tasklists/_tasklist.html.haml @@ -7,3 +7,4 @@ %a.fa.fa-edit.pull-right.tasklistUpdateButton{"data-index": current_user.tasklists.count - 1, "data-tasklistid": @tasklist.id, id: "update"} .col-sm-1 =link_to '', tasklist_path(@tasklist.id),method: 'delete', class: "pull-right fa fa-trash-alt" ,id: "delete" + diff --git a/app/views/tasklists/_update.html.haml b/app/views/tasklists/_update.html.haml new file mode 100644 index 0000000..e0b8044 --- /dev/null +++ b/app/views/tasklists/_update.html.haml @@ -0,0 +1,7 @@ +.col-sm-6 + .tasklist_list{"data-index": current_user.tasklists.count - 1, "data-tasklistid": @tasklist.id, id: "tasklist#{@tasklist.id}"} + = @tasklist.name +.col-sm-1 + %a.fa.fa-edit.pull-right.tasklistUpdateButton{"data-index": current_user.tasklists.count - 1, "data-tasklistid": @tasklist.id, id: "update"} +.col-sm-1 + =link_to '', tasklist_path(@tasklist.id),method: 'delete', class: "pull-right fa fa-trash-alt" ,id: "delete" diff --git a/app/views/tasklists/create_tasklist.js.haml b/app/views/tasklists/create_tasklist.js.haml new file mode 100644 index 0000000..f3e4f00 --- /dev/null +++ b/app/views/tasklists/create_tasklist.js.haml @@ -0,0 +1,4 @@ +$("#tasklists").append("#{j render partial: 'tasklist'}"); +$("#newtasklist").empty(); +$("#tasklistnew").val(""); +$("#tasklists").find(".tasklist_list").click(); \ No newline at end of file diff --git a/app/views/tasklists/errors.js.haml b/app/views/tasklists/errors.js.haml new file mode 100644 index 0000000..811db66 --- /dev/null +++ b/app/views/tasklists/errors.js.haml @@ -0,0 +1,2 @@ +-@tasklist.errors.full_messages.each do |error_message| + toastr.error("#{error_message}"); \ No newline at end of file diff --git a/app/views/tasklists/update_tasklist.js.haml b/app/views/tasklists/update_tasklist.js.haml new file mode 100644 index 0000000..5a048e3 --- /dev/null +++ b/app/views/tasklists/update_tasklist.js.haml @@ -0,0 +1,2 @@ +$("#tasklist_list#{@tasklist.id}").empty(); +$("#tasklist_list#{@tasklist.id}").append("#{j render partial: 'update'}") \ No newline at end of file diff --git a/app/views/tasks/_update.html.haml b/app/views/tasks/_update.html.haml new file mode 100644 index 0000000..5d079fd --- /dev/null +++ b/app/views/tasks/_update.html.haml @@ -0,0 +1,10 @@ +.col-sm-1.align-self-center + %input{type: 'checkbox', id: "checkbox#{@task.id}", "data-tasklistid": @task.tasklist.id, "data-taskid": @task.id, "checked": @task.status} +.col-sm-8.align-self-center + %div.taskname{id:"task#{@task.id}", "data-tasklistid": @task.tasklist.id, "data-taskid": @task.id} + =@task.name +.col-sm-1.align-self-center + %span.fa.fa-edit#taskUpdate.updateTask{"data-tasklistid": @task.tasklist.id, "data-taskid": @task.id} +.col-sm-1.align-self-center + %span.far.fa-trash-alt.taskDelete#taskDelete{"data-tasklistid": @task.tasklist.id, "data-taskid": @task.id} + %br \ No newline at end of file diff --git a/app/views/tasks/create_task.js.haml b/app/views/tasks/create_task.js.haml new file mode 100644 index 0000000..978a1e2 --- /dev/null +++ b/app/views/tasks/create_task.js.haml @@ -0,0 +1,2 @@ +$(".tab-content .list-group").append("#{j render partial: 'task'}"); +$("#newtasks").empty(); \ No newline at end of file diff --git a/app/views/tasks/errors.js.haml b/app/views/tasks/errors.js.haml new file mode 100644 index 0000000..d1b1e97 --- /dev/null +++ b/app/views/tasks/errors.js.haml @@ -0,0 +1,2 @@ +- @task.errors.full_messages.each do |error_message| + toastr.error("#{error_message}"); \ No newline at end of file diff --git a/app/views/tasks/update_task.js.haml b/app/views/tasks/update_task.js.haml new file mode 100644 index 0000000..5869a59 --- /dev/null +++ b/app/views/tasks/update_task.js.haml @@ -0,0 +1,2 @@ +$("#card#{@task.id}").empty(); +$("#card#{@task.id}").html("#{j render partial: 'update'}"); diff --git a/config/routes.rb b/config/routes.rb index 791d893..2caaa3e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -10,7 +10,7 @@ resources :tasklists do member do - get 'render_tasks' + get 'get_tasks' end resources :tasks do member do diff --git a/package.json b/package.json index 4a29ede..ead6a81 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,7 @@ { "name": "todo", "private": true, - "dependencies": {} + "dependencies": { + "mustache": "^3.0.1" + } } diff --git a/vendor/mustache/mustache.js b/vendor/mustache/mustache.js new file mode 100644 index 0000000..8ec1b44 --- /dev/null +++ b/vendor/mustache/mustache.js @@ -0,0 +1,682 @@ +/*! + * mustache.js - Logic-less {{mustache}} templates with JavaScript + * http://github.com/janl/mustache.js + */ + +/*global define: false Mustache: true*/ + +(function defineMustache (global, factory) { + if (typeof exports === 'object' && exports && typeof exports.nodeName !== 'string') { + factory(exports); // CommonJS + } else if (typeof define === 'function' && define.amd) { + define(['exports'], factory); // AMD + } else { + global.Mustache = {}; + factory(global.Mustache); // script, wsh, asp + } +}(this, function mustacheFactory (mustache) { + + var objectToString = Object.prototype.toString; + var isArray = Array.isArray || function isArrayPolyfill (object) { + return objectToString.call(object) === '[object Array]'; + }; + + function isFunction (object) { + return typeof object === 'function'; + } + + /** + * More correct typeof string handling array + * which normally returns typeof 'object' + */ + function typeStr (obj) { + return isArray(obj) ? 'array' : typeof obj; + } + + function escapeRegExp (string) { + return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&'); + } + + /** + * Null safe way of checking whether or not an object, + * including its prototype, has a given property + */ + function hasProperty (obj, propName) { + return obj != null && typeof obj === 'object' && (propName in obj); + } + + /** + * Safe way of detecting whether or not the given thing is a primitive and + * whether it has the given property + */ + function primitiveHasOwnProperty (primitive, propName) { + return ( + primitive != null + && typeof primitive !== 'object' + && primitive.hasOwnProperty + && primitive.hasOwnProperty(propName) + ); + } + + // Workaround for https://issues.apache.org/jira/browse/COUCHDB-577 + // See https://github.com/janl/mustache.js/issues/189 + var regExpTest = RegExp.prototype.test; + function testRegExp (re, string) { + return regExpTest.call(re, string); + } + + var nonSpaceRe = /\S/; + function isWhitespace (string) { + return !testRegExp(nonSpaceRe, string); + } + + var entityMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '/': '/', + '`': '`', + '=': '=' + }; + + function escapeHtml (string) { + return String(string).replace(/[&<>"'`=\/]/g, function fromEntityMap (s) { + return entityMap[s]; + }); + } + + var whiteRe = /\s*/; + var spaceRe = /\s+/; + var equalsRe = /\s*=/; + var curlyRe = /\s*\}/; + var tagRe = /#|\^|\/|>|\{|&|=|!/; + + /** + * Breaks up the given `template` string into a tree of tokens. If the `tags` + * argument is given here it must be an array with two string values: the + * opening and closing tags used in the template (e.g. [ "<%", "%>" ]). Of + * course, the default is to use mustaches (i.e. mustache.tags). + * + * A token is an array with at least 4 elements. The first element is the + * mustache symbol that was used inside the tag, e.g. "#" or "&". If the tag + * did not contain a symbol (i.e. {{myValue}}) this element is "name". For + * all text that appears outside a symbol this element is "text". + * + * The second element of a token is its "value". For mustache tags this is + * whatever else was inside the tag besides the opening symbol. For text tokens + * this is the text itself. + * + * The third and fourth elements of the token are the start and end indices, + * respectively, of the token in the original template. + * + * Tokens that are the root node of a subtree contain two more elements: 1) an + * array of tokens in the subtree and 2) the index in the original template at + * which the closing tag for that section begins. + */ + function parseTemplate (template, tags) { + if (!template) + return []; + + var sections = []; // Stack to hold section tokens + var tokens = []; // Buffer to hold the tokens + var spaces = []; // Indices of whitespace tokens on the current line + var hasTag = false; // Is there a {{tag}} on the current line? + var nonSpace = false; // Is there a non-space char on the current line? + + // Strips all whitespace tokens array for the current line + // if there was a {{#tag}} on it and otherwise only space. + function stripSpace () { + if (hasTag && !nonSpace) { + while (spaces.length) + delete tokens[spaces.pop()]; + } else { + spaces = []; + } + + hasTag = false; + nonSpace = false; + } + + var openingTagRe, closingTagRe, closingCurlyRe; + function compileTags (tagsToCompile) { + if (typeof tagsToCompile === 'string') + tagsToCompile = tagsToCompile.split(spaceRe, 2); + + if (!isArray(tagsToCompile) || tagsToCompile.length !== 2) + throw new Error('Invalid tags: ' + tagsToCompile); + + openingTagRe = new RegExp(escapeRegExp(tagsToCompile[0]) + '\\s*'); + closingTagRe = new RegExp('\\s*' + escapeRegExp(tagsToCompile[1])); + closingCurlyRe = new RegExp('\\s*' + escapeRegExp('}' + tagsToCompile[1])); + } + + compileTags(tags || mustache.tags); + + var scanner = new Scanner(template); + + var start, type, value, chr, token, openSection; + while (!scanner.eos()) { + start = scanner.pos; + + // Match any text between tags. + value = scanner.scanUntil(openingTagRe); + + if (value) { + for (var i = 0, valueLength = value.length; i < valueLength; ++i) { + chr = value.charAt(i); + + if (isWhitespace(chr)) { + spaces.push(tokens.length); + } else { + nonSpace = true; + } + + tokens.push([ 'text', chr, start, start + 1 ]); + start += 1; + + // Check for whitespace on the current line. + if (chr === '\n') + stripSpace(); + } + } + + // Match the opening tag. + if (!scanner.scan(openingTagRe)) + break; + + hasTag = true; + + // Get the tag type. + type = scanner.scan(tagRe) || 'name'; + scanner.scan(whiteRe); + + // Get the tag value. + if (type === '=') { + value = scanner.scanUntil(equalsRe); + scanner.scan(equalsRe); + scanner.scanUntil(closingTagRe); + } else if (type === '{') { + value = scanner.scanUntil(closingCurlyRe); + scanner.scan(curlyRe); + scanner.scanUntil(closingTagRe); + type = '&'; + } else { + value = scanner.scanUntil(closingTagRe); + } + + // Match the closing tag. + if (!scanner.scan(closingTagRe)) + throw new Error('Unclosed tag at ' + scanner.pos); + + token = [ type, value, start, scanner.pos ]; + tokens.push(token); + + if (type === '#' || type === '^') { + sections.push(token); + } else if (type === '/') { + // Check section nesting. + openSection = sections.pop(); + + if (!openSection) + throw new Error('Unopened section "' + value + '" at ' + start); + + if (openSection[1] !== value) + throw new Error('Unclosed section "' + openSection[1] + '" at ' + start); + } else if (type === 'name' || type === '{' || type === '&') { + nonSpace = true; + } else if (type === '=') { + // Set the tags for the next time around. + compileTags(value); + } + } + + // Make sure there are no open sections when we're done. + openSection = sections.pop(); + + if (openSection) + throw new Error('Unclosed section "' + openSection[1] + '" at ' + scanner.pos); + + return nestTokens(squashTokens(tokens)); + } + + /** + * Combines the values of consecutive text tokens in the given `tokens` array + * to a single token. + */ + function squashTokens (tokens) { + var squashedTokens = []; + + var token, lastToken; + for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { + token = tokens[i]; + + if (token) { + if (token[0] === 'text' && lastToken && lastToken[0] === 'text') { + lastToken[1] += token[1]; + lastToken[3] = token[3]; + } else { + squashedTokens.push(token); + lastToken = token; + } + } + } + + return squashedTokens; + } + + /** + * Forms the given array of `tokens` into a nested tree structure where + * tokens that represent a section have two additional items: 1) an array of + * all tokens that appear in that section and 2) the index in the original + * template that represents the end of that section. + */ + function nestTokens (tokens) { + var nestedTokens = []; + var collector = nestedTokens; + var sections = []; + + var token, section; + for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { + token = tokens[i]; + + switch (token[0]) { + case '#': + case '^': + collector.push(token); + sections.push(token); + collector = token[4] = []; + break; + case '/': + section = sections.pop(); + section[5] = token[2]; + collector = sections.length > 0 ? sections[sections.length - 1][4] : nestedTokens; + break; + default: + collector.push(token); + } + } + + return nestedTokens; + } + + /** + * A simple string scanner that is used by the template parser to find + * tokens in template strings. + */ + function Scanner (string) { + this.string = string; + this.tail = string; + this.pos = 0; + } + + /** + * Returns `true` if the tail is empty (end of string). + */ + Scanner.prototype.eos = function eos () { + return this.tail === ''; + }; + + /** + * Tries to match the given regular expression at the current position. + * Returns the matched text if it can match, the empty string otherwise. + */ + Scanner.prototype.scan = function scan (re) { + var match = this.tail.match(re); + + if (!match || match.index !== 0) + return ''; + + var string = match[0]; + + this.tail = this.tail.substring(string.length); + this.pos += string.length; + + return string; + }; + + /** + * Skips all text until the given regular expression can be matched. Returns + * the skipped string, which is the entire tail if no match can be made. + */ + Scanner.prototype.scanUntil = function scanUntil (re) { + var index = this.tail.search(re), match; + + switch (index) { + case -1: + match = this.tail; + this.tail = ''; + break; + case 0: + match = ''; + break; + default: + match = this.tail.substring(0, index); + this.tail = this.tail.substring(index); + } + + this.pos += match.length; + + return match; + }; + + /** + * Represents a rendering context by wrapping a view object and + * maintaining a reference to the parent context. + */ + function Context (view, parentContext) { + this.view = view; + this.cache = { '.': this.view }; + this.parent = parentContext; + } + + /** + * Creates a new context using the given view with this context + * as the parent. + */ + Context.prototype.push = function push (view) { + return new Context(view, this); + }; + + /** + * Returns the value of the given name in this context, traversing + * up the context hierarchy if the value is absent in this context's view. + */ + Context.prototype.lookup = function lookup (name) { + var cache = this.cache; + + var value; + if (cache.hasOwnProperty(name)) { + value = cache[name]; + } else { + var context = this, intermediateValue, names, index, lookupHit = false; + + while (context) { + if (name.indexOf('.') > 0) { + intermediateValue = context.view; + names = name.split('.'); + index = 0; + + /** + * Using the dot notion path in `name`, we descend through the + * nested objects. + * + * To be certain that the lookup has been successful, we have to + * check if the last object in the path actually has the property + * we are looking for. We store the result in `lookupHit`. + * + * This is specially necessary for when the value has been set to + * `undefined` and we want to avoid looking up parent contexts. + * + * In the case where dot notation is used, we consider the lookup + * to be successful even if the last "object" in the path is + * not actually an object but a primitive (e.g., a string, or an + * integer), because it is sometimes useful to access a property + * of an autoboxed primitive, such as the length of a string. + **/ + while (intermediateValue != null && index < names.length) { + if (index === names.length - 1) + lookupHit = ( + hasProperty(intermediateValue, names[index]) + || primitiveHasOwnProperty(intermediateValue, names[index]) + ); + + intermediateValue = intermediateValue[names[index++]]; + } + } else { + intermediateValue = context.view[name]; + + /** + * Only checking against `hasProperty`, which always returns `false` if + * `context.view` is not an object. Deliberately omitting the check + * against `primitiveHasOwnProperty` if dot notation is not used. + * + * Consider this example: + * ``` + * Mustache.render("The length of a football field is {{#length}}{{length}}{{/length}}.", {length: "100 yards"}) + * ``` + * + * If we were to check also against `primitiveHasOwnProperty`, as we do + * in the dot notation case, then render call would return: + * + * "The length of a football field is 9." + * + * rather than the expected: + * + * "The length of a football field is 100 yards." + **/ + lookupHit = hasProperty(context.view, name); + } + + if (lookupHit) { + value = intermediateValue; + break; + } + + context = context.parent; + } + + cache[name] = value; + } + + if (isFunction(value)) + value = value.call(this.view); + + return value; + }; + + /** + * A Writer knows how to take a stream of tokens and render them to a + * string, given a context. It also maintains a cache of templates to + * avoid the need to parse the same template twice. + */ + function Writer () { + this.cache = {}; + } + + /** + * Clears all cached templates in this writer. + */ + Writer.prototype.clearCache = function clearCache () { + this.cache = {}; + }; + + /** + * Parses and caches the given `template` according to the given `tags` or + * `mustache.tags` if `tags` is omitted, and returns the array of tokens + * that is generated from the parse. + */ + Writer.prototype.parse = function parse (template, tags) { + var cache = this.cache; + var cacheKey = template + ':' + (tags || mustache.tags).join(':'); + var tokens = cache[cacheKey]; + + if (tokens == null) + tokens = cache[cacheKey] = parseTemplate(template, tags); + + return tokens; + }; + + /** + * High-level method that is used to render the given `template` with + * the given `view`. + * + * The optional `partials` argument may be an object that contains the + * names and templates of partials that are used in the template. It may + * also be a function that is used to load partial templates on the fly + * that takes a single argument: the name of the partial. + * + * If the optional `tags` argument is given here it must be an array with two + * string values: the opening and closing tags used in the template (e.g. + * [ "<%", "%>" ]). The default is to mustache.tags. + */ + Writer.prototype.render = function render (template, view, partials, tags) { + var tokens = this.parse(template, tags); + var context = (view instanceof Context) ? view : new Context(view); + return this.renderTokens(tokens, context, partials, template, tags); + }; + + /** + * Low-level method that renders the given array of `tokens` using + * the given `context` and `partials`. + * + * Note: The `originalTemplate` is only ever used to extract the portion + * of the original template that was contained in a higher-order section. + * If the template doesn't use higher-order sections, this argument may + * be omitted. + */ + Writer.prototype.renderTokens = function renderTokens (tokens, context, partials, originalTemplate, tags) { + var buffer = ''; + + var token, symbol, value; + for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { + value = undefined; + token = tokens[i]; + symbol = token[0]; + + if (symbol === '#') value = this.renderSection(token, context, partials, originalTemplate); + else if (symbol === '^') value = this.renderInverted(token, context, partials, originalTemplate); + else if (symbol === '>') value = this.renderPartial(token, context, partials, tags); + else if (symbol === '&') value = this.unescapedValue(token, context); + else if (symbol === 'name') value = this.escapedValue(token, context); + else if (symbol === 'text') value = this.rawValue(token); + + if (value !== undefined) + buffer += value; + } + + return buffer; + }; + + Writer.prototype.renderSection = function renderSection (token, context, partials, originalTemplate) { + var self = this; + var buffer = ''; + var value = context.lookup(token[1]); + + // This function is used to render an arbitrary template + // in the current context by higher-order sections. + function subRender (template) { + return self.render(template, context, partials); + } + + if (!value) return; + + if (isArray(value)) { + for (var j = 0, valueLength = value.length; j < valueLength; ++j) { + buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate); + } + } else if (typeof value === 'object' || typeof value === 'string' || typeof value === 'number') { + buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate); + } else if (isFunction(value)) { + if (typeof originalTemplate !== 'string') + throw new Error('Cannot use higher-order sections without the original template'); + + // Extract the portion of the original template that the section contains. + value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender); + + if (value != null) + buffer += value; + } else { + buffer += this.renderTokens(token[4], context, partials, originalTemplate); + } + return buffer; + }; + + Writer.prototype.renderInverted = function renderInverted (token, context, partials, originalTemplate) { + var value = context.lookup(token[1]); + + // Use JavaScript's definition of falsy. Include empty arrays. + // See https://github.com/janl/mustache.js/issues/186 + if (!value || (isArray(value) && value.length === 0)) + return this.renderTokens(token[4], context, partials, originalTemplate); + }; + + Writer.prototype.renderPartial = function renderPartial (token, context, partials, tags) { + if (!partials) return; + + var value = isFunction(partials) ? partials(token[1]) : partials[token[1]]; + if (value != null) + return this.renderTokens(this.parse(value, tags), context, partials, value); + }; + + Writer.prototype.unescapedValue = function unescapedValue (token, context) { + var value = context.lookup(token[1]); + if (value != null) + return value; + }; + + Writer.prototype.escapedValue = function escapedValue (token, context) { + var value = context.lookup(token[1]); + if (value != null) + return mustache.escape(value); + }; + + Writer.prototype.rawValue = function rawValue (token) { + return token[1]; + }; + + mustache.name = 'mustache.js'; + mustache.version = '3.0.1'; + mustache.tags = [ '{{', '}}' ]; + + // All high-level mustache.* functions use this writer. + var defaultWriter = new Writer(); + + /** + * Clears all cached templates in the default writer. + */ + mustache.clearCache = function clearCache () { + return defaultWriter.clearCache(); + }; + + /** + * Parses and caches the given template in the default writer and returns the + * array of tokens it contains. Doing this ahead of time avoids the need to + * parse templates on the fly as they are rendered. + */ + mustache.parse = function parse (template, tags) { + return defaultWriter.parse(template, tags); + }; + + /** + * Renders the `template` with the given `view` and `partials` using the + * default writer. If the optional `tags` argument is given here it must be an + * array with two string values: the opening and closing tags used in the + * template (e.g. [ "<%", "%>" ]). The default is to mustache.tags. + */ + mustache.render = function render (template, view, partials, tags) { + if (typeof template !== 'string') { + throw new TypeError('Invalid template! Template should be a "string" ' + + 'but "' + typeStr(template) + '" was given as the first ' + + 'argument for mustache#render(template, view, partials)'); + } + + return defaultWriter.render(template, view, partials, tags); + }; + + // This is here for backwards compatibility with 0.4.x., + /*eslint-disable */ // eslint wants camel cased function name + mustache.to_html = function to_html (template, view, partials, send) { + /*eslint-enable*/ + + var result = mustache.render(template, view, partials); + + if (isFunction(send)) { + send(result); + } else { + return result; + } + }; + + // Export the escaping function so that the user may override it. + // See https://github.com/janl/mustache.js/issues/244 + mustache.escape = escapeHtml; + + // Export these mainly for testing, but also for advanced usage. + mustache.Scanner = Scanner; + mustache.Context = Context; + mustache.Writer = Writer; + + return mustache; +})); From 7765f9150b859badf6c8402005112ca80f4556e0 Mon Sep 17 00:00:00 2001 From: Shashank Bansal Date: Wed, 7 Aug 2019 14:46:59 +0530 Subject: [PATCH 18/18] changes related to empty spaces at the end of file done --- app/assets/javascripts/custom.js | 5 ++--- app/views/tasklists/_tasks.html.haml | 1 + app/views/tasklists/_update.html.haml | 1 + app/views/tasklists/create_tasklist.js.haml | 2 +- app/views/tasklists/errors.js.haml | 2 +- app/views/tasklists/index.html.haml | 2 -- app/views/tasklists/update_tasklist.js.haml | 2 +- app/views/tasks/_task.html.haml | 2 +- app/views/tasks/_update.html.haml | 2 +- app/views/tasks/create_task.js.haml | 2 +- app/views/tasks/errors.js.haml | 2 +- app/views/tasks/update_task.js.haml | 1 + 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/custom.js b/app/assets/javascripts/custom.js index e33380b..d3d373a 100644 --- a/app/assets/javascripts/custom.js +++ b/app/assets/javascripts/custom.js @@ -234,8 +234,7 @@ function inputForUpdateTasklist() { ); } -function restoreUpdateTasklistView() { - +function renderTasklistEditView() { return ( "
    " + "