1

I am building a datatable with multi-column sorting functionality. As up to now, the sorting functionality is working fine, what I am unable to get is, right parameters into the url. As I am only passing $sorts to the component, as a prop, hence I'm using this.$inertia.get to pass the $sorts back to the controller, which is returning back the sorted data. But due to passing sorts: this.sorts within the Inertia get method, its returning back the url query as http://127.0.0.1:8000/users?sorts[name]=asc. How can I get the required parameter within the Inertia get method so I get a url query as suchhttp://127.0.0.1:8000/users?sort_field=name&sort_direction=asc as well as pass the $sorts as well so it returns back the expected data.

sorting

Controller

public $sorts = [];

public function initalizeSortingRequest()
{
    $this->sorts = request()->get('sorts', $this->sorts);
}

public function applySorting($query)
{
    foreach ($this->sorts as $sort_field => $sort_direction) {
        $query->orderBy($sort_field, $sort_direction);
    }
        
    return $query;
}

Component

<script >
    methods: {
        sortBy(field) {
            if (!this.sorts[field]) {
                this.sorts[field] = 'asc';
            } else if (this.sorts[field] == 'asc') {
                this.sorts[field] = 'desc';
            } else {
                delete this.sorts[field];
            }

            let route = this.route('users.index', {
                sorts: this.sorts
            })
            this.$inertia.get(route, {}, {
                only: ['usersData'],
                preserveState: true,
                preserveScroll: true
            })
        }
    } 
</script>

1 Answer 1

3

I recently made a screencast on building a datatable with InertiaJS and Laravel.
The gist of it is:

import AppLayout from '@/Layouts/AppLayout';
import Pagination from '../Jetstream/Pagination';
import { pickBy, throttle } from 'lodash';

export default {
  components: {
    AppLayout,
    Pagination,
  },
  props: {
    users: Object,
    filters: Object,
  },
  data() {
    return {
      params: {
        search: this.filters.search,
        field: this.filters.field,
        direction: this.filters.direction,
      },
    };
  },
  methods: {
    sort(field) {
      this.params.field = field;
      this.params.direction = this.params.direction === 'asc' ? 'desc' : 'asc';
    },
  },
  watch: {
    params: {
      handler: throttle(function () {
        let params = pickBy(this.params);

        this.$inertia.get(this.route('users'), params, { replace: true, preserveState: true });
      }, 150),
      deep: true,
    },
  },
};

Then in the controller index action:

public function index()
{
    request()->validate([
        'direction' => ['in:asc,desc'],
        'field' => ['in:name,city']
    ]);

    $query = User::query();

    if (request('search')) {
        $query->where('name', 'LIKE', '%'.request('search').'%');
    }

    if (request()->has(['field', 'direction'])) {
        $query->orderBy(request('field'), request('direction'));
    }

    return Inertia::render('Users', [
        'users' => $query->paginate()->withQueryString(),
        'filters' => request()->all(['search', 'field', 'direction'])
    ]);
}

You can watch the screencast here.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.