Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

pretom's avatar

Edit function can't work properly in vue js and laravel

I build a Task Management project using laravel & vue js which is worked very nicely.But edit function can't work properly in this application.I tried a lot but failed.Even when clicked edit option this would work to same as create/add function.How can I solve this problem.I will share my code below:

resource/js/app.js


require("./bootstrap");

window.Vue = require("vue");

/ / Register our components
Vue.component("kanban-board", require("./components/KanbanBoard.vue").default);


const app = new Vue({
 el: "#app"
});

resource/js/components/KanbanBoard.vue

   <template>
     <div class="relative p-2 flex overflow-x-auto h-full">
      <!-- Columns (Statuses) -->
           <div
             v-for="status in statuses"
              :key="status.slug"
            class="mr-6 w-4/5 max-w-xs flex-shrink-0"
             >
             <div class="rounded-md shadow-md overflow-hidden">
                <div class="p-1 flex justify-between items-baseline bg-green-500 ">
                 <h4 class="font-medium text-white">
                   {{ status.title }}
              </h4>
     
       </div>
       <div class="p-2 bg-green-300">
         <!-- AddTaskForm -->
         <AddTaskForm
           v-if="newTaskForStatus === status.id"
           :status-id="status.id"
           v-on:task-added="handleTaskAdded"
           v-on:task-canceled="closeAddTaskForm"
         />
         <!-- ./AddTaskForm -->
         <!-- EditTaskForm -->
         <AddTaskForm
           v-if="editTaskForStatus === status.id"
           :status-id="status.id"
           v-on:task-edit="handleTaskEdit"
           v-on:task-canceled="closeEditTaskForm"
         />
         <!-- ./EditTaskForm -->

         <!-- Tasks -->
         <draggable
           class="flex-1 overflow-hidden"
            v-model="status.tasks"
           v-bind="taskDragOptions"
           @end="handleTaskMoved"
         >
            <transition-group
             class="flex-1 flex flex-col h-full overflow-x-hidden overflow-y-auto rounded shadow-xs"
             tag="div"
           >
             <div
            v-for="task in status.tasks"
            :key="task.id"
            class="mb-3 p-4 flex flex-col bg-white rounded-md shadow transform hover:shadow-md cursor- 
             pointer"
             >
           
             <button
             type="submit"
          @click="openEditTaskForm(status.id)"
           class="py-1 px-2 text-sm text-black-500 hover:underline"
             >
           Edit Task
          </button>
          <span class="block mb-2 text-xl text-gray-900">
      
                Task-100{{ task.id }}
              
              </span>
                <span class="block mb-2 text-xl text-gray-900">
                 {{ task.title }}
               </span>
               <p class="text-gray-700">
                 {{ task.description }}
               </p>
             </div>
             <!-- ./Tasks -->
           </transition-group>
            </draggable>
          <!-- No Tasks -->
             <div
           v-show="!status.tasks.length && newTaskForStatus !== status.id"
           class="flex-1 p-4 flex flex-col items-center justify-center"
         >
           <!-- <span class="text-gray-600">No tasks yet</span> -->
        <button
             class="mt-1 text-sm text-orange-600 hover:underline"
             @click="openAddTaskForm(status.id)"
           >
               Add one
           </button>
         </div>
         <!-- ./No Tasks -->
       </div>
      </div>
      <button
       type="submit"
       @click="openAddTaskForm(status.id)"
      class="px-12 py-1 leading-5 text-white bg-orange-600 hover:bg-orange-500 rounded"
     >
      Add
     </button>
   </div>
   <!-- ./Columns -->
 </div>
   </template>

         <script>
      import draggable from "vuedraggable";
      import AddTaskForm from "./AddTaskForm";
     import EditTaskForm from "./EditTaskForm";

         export default {

        components: { draggable, AddTaskForm,EditTaskForm },
        props: {
           initialData: Array
               },
          data() {
             return {
              statuses: [],
 
 
                  newTaskForStatus: 0,
                    editTaskForStatus: 0
                };
            },

             computed: {
                  taskDragOptions() {
                return {
                       animation: 200,
                      group: "task-list",
                     dragClass: "status-drag"
                 };
             }
            },
                mounted() {
                    // 'clone' the statuses so we don't alter the prop when making changes
                      this.statuses = JSON.parse(JSON.stringify(this.initialData));

                    },

               methods: {


                  openAddTaskForm(statusId) {
                   this.newTaskForStatus = statusId;
                },
                closeAddTaskForm() {
                this.newTaskForStatus = 0;
                },
                handleTaskAdded(newTask) {
                     // Find the index of the status where we should add the task 
            const statusIndex = this.statuses.findIndex(
                 status => status.id === newTask.status_id
              );

               // Add newly created task to our column
                   this.statuses[statusIndex].tasks.push(newTask);

                  // Reset and close the AddTaskForm
                  this.closeAddTaskForm();
                      },
                 handleTaskMoved(evt) {
                 axios.put("/tasks/sync", { columns: this.statuses }).catch(err => {
                    console.log(err.response);
                  });
                },
                   openEditTaskForm(statusId) {
                     this.editTaskForStatus = statusId;
               },
                    closeEditTaskForm() {
                      this.editTaskForStatus = 0;
                    },
                 handleTaskEdit(editTask) {
                 // Find the index of the status where we should add the task 
                       const statusIndex = this.statuses.findIndex(
                      status => status.id === editTask.status_id
                  );

                // Add newly created task to our column
                this.statuses[statusIndex].tasks.push(editTask);

                // Reset and close the AddTaskForm
               this.closeEditTaskForm();
                     }
                  }
                   };
                  </script>

          <style scoped>
                .status-drag {
                     transition: transform 0.5s;
                  transition-property: all;
            }
        </style>

resource/js/components/AddTask.vue

        <template>
         <form
                class="relative mb-3 flex flex-col justify-between bg-white rounded-md shadow overflow-hidden"
                      @submit.prevent="handleAddNewTask"
                     >
             <div class="p-3 flex-1">
               <input
                   class="block w-full px-2 py-1 text-lg border-b border-blue-800 rounded"
                    type="text"
                  placeholder="Enter a title"
                  v-model.trim="newTask.title"
              />
                <textarea
                  class="mt-3 p-2 block w-full p-1 border text-sm rounded"
                    rows="2"
                  placeholder="Add a description"
                     v-model.trim="newTask.description"
                  ></textarea>
                 <div v-show="errorMessage">
                     <span class="text-xs text-red-500">
                 {{ errorMessage }}
                    </span>
               </div>
                </div>
               <div class="p-3 flex justify-between items-end text-sm bg-gray-100">
                    <button
                     @click="$emit('task-canceled')"
                   type="reset"
                     class="py-1 leading-5 text-gray-600 hover:text-gray-700"
                       >
                   cancel
                  </button>
                <button
                    type="submit"
                  class="px-3 py-1 leading-5 text-white bg-orange-600 hover:bg-orange-500 rounded"
                  >
                  Add
                </button>
               </div>
                  </form>
               </template>

           <script>
            export default {
              props: {
                  statusId: Number
               },
              data() {
                return {
             newTask: {
                  title: "",
               description: "",
                status_id: null
              },
                errorMessage: ""
             };
             },
               mounted() {
                     this.newTask.status_id = this.statusId;
           },
                  methods: {
                 handleAddNewTask() {
                      // Basic validation so we don't send an empty task to the server
                   if (!this.newTask.title) {
                               this.errorMessage = "The title field is required";
                   return;
                     }

                         // Send new task to server
                 axios
                      .post("/tasks", this.newTask)
                      .then(res => {
                       // Tell the parent component we've added a new task and include it
                        this.$emit("task-added", res.data);
                    })
                     .catch(err => {
                       // Handle the error returned from our request
                    this.handleErrors(err);
                      });
             },
                   handleErrors(err) {
                 if (err.response && err.response.status === 422) {
                  // We have a validation error
                const errorBag = err.response.data.errors;
                  if (errorBag.title) {
                     this.errorMessage = errorBag.title[0];
                     } else if (errorBag.description) {
                      this.errorMessage = errorBag.description[0];
                   } else {
                  this.errorMessage = err.response.message;
            }
                } else {
              // We have bigger problems
                 console.log(err.response);
        }
         }
        }
          };
                 </script>

resource/js/components/EditTask.vue

      <template>
           <form
             class="relative mb-3 flex flex-col justify-between bg-white rounded-md shadow overflow-hidden"
              @submit.prevent="handleEditTask"
              >
           <div class="p-3 flex-1">
          <input
              class="block w-full px-2 py-1 text-lg border-b border-blue-800 rounded"
                 type="text"
   
                 @blur="handleEditTask(task)"
                v-model="editTask.title"
                />
               <textarea
                  class="mt-3 p-2 block w-full p-1 border text-sm rounded"
                 rows="2"
                       p
                  @blur="handleEditTask(task)"
                     v-model="editTask.description"
                     ></textarea>
                  <div v-show="errorMessage">
                          <span class="text-xs text-red-500">
                       {{ errorMessage }}
                  </span>
                   </div>
             </div>
                 <div class="p-3 flex justify-between items-end text-sm bg-gray-100">
             <button
                   @click="$emit('task-canceled')"
                    type="reset"
                       class="py-1 leading-5 text-gray-600 hover:text-gray-700"
                 >
               cancel
             </button>
              <button
                   type="submit"
                         class="px-3 py-1 leading-5 text-white bg-orange-600 hover:bg-orange-500 rounded"
                >
                   Add
               </button>
             </div>
             </form>
          </template>

        <script>
             export default {
                props: {
              statusId: Number
             },
           data() {
           return {
                editTask: {
       
              title:task.title,
                 description:task.description,
                status_id: null
               },
                 errorMessage: ""
        };
        },
        mounted() {
           this.editTask.status_id = this.statusId;
         },
          methods: {
            handleEditTask() {

            // Basic validation so we don't send an empty task to the server
             if (!this.editTask.title) {
                  this.errorMessage = "The title field is required";
                 return;
              }

                  // Send edit task to server
            axios
                 .patch("tasks/{task}", this.editTask)
                   .then(res => {
                     // Tell the parent component we've added a new task and include it
                 this.$emit("task-edit", res.data);
                })
               .catch(err => {
                 // Handle the error returned from our request
                this.handleErrors(err);
               });
            },
              handleErrors(err) {
                if (err.response && err.response.status === 422) {
               // We have a validation error
               const errorBag = err.response.data.errors;
               if (errorBag.title) {
                   this.errorMessage = errorBag.title[0];
               } else if (errorBag.description) {
                this.errorMessage = errorBag.description[0];
                } else {
                    this.errorMessage = err.response.message;
                }
              } else {
             // We have bigger problems
                console.log(err.response);
          }
      }
    }
 };
      </script>

app/Http/Controllers/TaskController

    <?php

         namespace App\Http\Controllers;

       use App\Task;
          use Illuminate\Http\Request;

       class TaskController extends Controller
                  {
                 public function index()
              {
                  $tasks = auth()->user()->statuses()->with('tasks')->get();

                    return view('tasks.index', compact('tasks'));
               }

               public function create()
              {
                    //
                 }

                 public function store(Request $request)
                   {
                         $this->validate($request, [
                        'title' => ['required', 'string', 'max:56'],
                       'description' => ['nullable', 'string'],
                              'status_id' => ['required', 'exists:statuses,id']
                            ]);

                   return $request->user()
                    ->tasks()
                    ->create($request->only('title', 'description', 'status_id'));
                   }       

                 public function sync(Request $request)
              {
                       $this->validate(request(), [
                        'title' => ['required', 'string', 'max:56'],
                     'description' => ['nullable', 'string'],
                    'columns' => ['required', 'array']
                ]);

                   foreach ($request->columns as $status) {
                    foreach ($status['tasks'] as $i => $task) {
                         $order = $i + 1;
                             if ($task['status_id'] !== $status['id'] || $task['order'] !== $order) {
                           request()->user()->tasks()
                               ->find($task['id'])
                                 ->update(['status_id' => $status['id'], 'order' => $order],$request->only('title', 'description', 
              'status_id'));
                    }
                 } 
            }

              return $request->user()->statuses()->with('tasks')->get();
           }

             public function show(Task $task)
             {
    //
            }

              public function edit(Request $request)
              {
   
    
                 }

                    public function update(Request $request, Task $task)
                   {
                     $this->validate($request, [
                    'title' => ['required', 'string', 'max:56'],
                      'description' => ['nullable', 'string'],
                    'status_id' => ['required', 'exists:statuses,id']
                      ]);

                  return $request->user()
                        ->tasks()
                          ->update($request->only('title', 'description', 'status_id'));
                    }

                  public function destroy(Task $task)
                   {
                 //
               }
              }

resource/views/tasks/index.blade.php

         @extends('layouts.app')

         @section('content')
         <div class="md:mx-4 relative overflow-hidden">
        <main class="h-full flex flex-col overflow-auto">
            <kanban-board :initial-data="{{ $tasks }}"></kanban-board>
           </main>
           </div>
            @endsection

web.php

         Route::group(['middleware' => 'auth'], function () {
             Route::get('tasks', 'TaskController@index')->name('tasks.index');
             Route::post('tasks', 'TaskController@store')->name('tasks.store');
            Route::put('tasks/sync', 'TaskController@sync')->name('tasks.sync');
           Route::put('tasks/{task}', 'TaskController@update')->name('tasks.update');
          });

       Route::group(['middleware' => 'auth'], function () {
          Route::post('statuses', 'StatusController@store')->name('statuses.store');
         Route::put('statuses', 'StatusController@update')->name('statuses.update');
          });
0 likes
3 replies
automica's avatar

@pretom can you reformat your question please?

to code indent use 3 back ticks before and after your codeblocks.

pretom's avatar

plz anyone help me to solve it

Please or to participate in this conversation.