Sorting issues table rows by clicking column headings

Step 01: Adding visual changes for table headers inside Index.vue inside template tag like below

<thead class="thead-dark">      
  <tr>
    <th>       
    <div style="cursor: pointer;" class="" @click="updateOrdering('id')">
          <span :class="{ 'font-bold text-info': order_column === 'id' }">
              ID
          </span>
              <span :class="{
                'text-info': order_direction === 'asc' && order_column === 'id',
                'd-none': order_direction !== '' && order_direction !== 'asc' && order_column === 'id',
              }">&uarr;</span>
              <span :class="{
                'text-info': order_direction === 'desc' && order_column === 'id',
                'd-none': order_direction !== '' && order_direction !== 'desc' && order_column === 'id',
              }">&darr;</span>
    </div>          
</th>         
<th>Client</th>
<th>
    <div style="cursor: pointer;" class="" @click="updateOrdering('title')">
          <span :class="{ 'font-bold text-info': order_column === 'title' }">
              Issue
          </span>
              <span :class="{
                'text-info': order_direction === 'asc' && order_column === 'title',
                'd-none': order_direction !== '' && order_direction !== 'asc' && order_column === 'title',
              }">&uarr;</span>
              <span :class="{
                'text-info': order_direction === 'desc' && order_column === 'title',
                'd-none': order_direction !== '' && order_direction !== 'desc' && order_column === 'title',
              }">&darr;</span>
    </div>          
</th>
<th style="width: 40%;">Description</th>
<th>
    <div style="cursor: pointer;" class="" @click="updateOrdering('created_at')">
          <span :class="{ 'font-bold text-info': order_column === 'created_at' }">
              Created
          </span>
              <span :class="{
                'text-info': order_direction === 'asc' && order_column === 'created_at',
                'd-none': order_direction !== '' && order_direction !== 'asc' && order_column === 'created_at',
              }">&uarr;</span>
              <span :class="{
                'text-info': order_direction === 'desc' && order_column === 'created_at',
                'd-none': order_direction !== '' && order_direction !== 'desc' && order_column === 'created_at',
              }">&darr;</span>
    </div>          
    </th>
  </tr>
</thead>

three changes to note here as we have added one method updateOrdering and two variables order_column and order_direction which are used to check which column header is being clicked and uparrow and downarrow are being changed accordingly to represent ascending and descending rows.

Step 02: now adding below changes inside script tag for component

const order_column = ref('created_at')
const order_direction = ref('desc')

const updateOrdering = (column) => {
    order_column.value = column;
    order_direction.value = (order_direction.value === 'asc') ? 'desc' : 'asc';
    getIssues(1, search_client.value, order_column.value, order_direction.value );
}

Step 03: Adding following changes inside issues.js composable for passing order_column and order_direction value to api end point

const getIssues = async (page = 1, client = '', 
                order_column = 'created_at',
                order_direction = 'desc'
        ) => { 
    axios.get('/api/issues?page=' + page + '&client=' + client 
                                    + '&order_column=' + order_column 
                                    + '&order_direction=' + order_direction )
        .then(response => {
            issues.value = response.data;
        })
}

Step 04: Changing index() method of Api/IssuesController like below to sync the changes of client_id filtering for order_column and order_direction parameters with validation

public function index() {

    $order_column = request('order_column', 'created_at');
    if (! in_array($order_column, ['id', 'title', 'created_at'])) { 
        $order_column = 'created_at';
    } 
    $order_direction = request('order_direction', 'desc');
    if (! in_array($order_direction, ['asc', 'desc'])) { 
        $order_direction = 'desc';
    } 

    $issues = Issue::with('client')
    ->when(request('client'), function (Builder $query) { 
        $query->where('client_id', request('client'));
    }) 
    ->orderBy($order_column, $order_direction)
    ->paginate(10);
    return IssueResource::collection($issues);
 }

Related Posts


Seeding users and role_user data

Seeding clients and issues data

Adding client column in table

Storing issue in db table

Update issue

Showing user data and logout

Permission securing backend

Permission securing frontend