[Django]-Django/django-tables2 html table on row click to edit form

3๐Ÿ‘

I couldnโ€™t find any solution that suits my needs.

All the solutions I found requires some weird processing in Javascript and parsing slugs and PKโ€™s from the table to redirect to the correct URL.

My solution?

Define an absolute URL in your models.py

def get_absolute_url(self):
    return reverse('product:detail', kwargs={'slug': self.slug})

Then in your tables.py, we add a data-href attribute to each column that we want to be clickable. This allows us to restrict which columns become clickable.

class ProductTable(tables.Table):
    clickable = {'td': {'data-href': lambda record: record.get_absolute_url}}
    name = tables.Column(attrs=clickable)
    in_stock = tables.Column(attrs=clickable)

    class Meta:
        model = Product
        fields = (name, in_stock)

And in your template just add this simple event listener,

$(document).ready(function($) {
    $("td").click(function() {
        window.location = $(this).data("href");
    });
});

Alternatively, if you just want the whole row to be clickable, just use Row attributes as defined in the docs,

class ProductTable(tables.Table):
    class Meta:
        model = Product
        row_attrs = {'data-href': lambda record: record.get_absolute_url}
        fields = (name, in_stock)

and then change your template script too

$(document).ready(function($) {
    $("tr").click(function() {
        window.location = $(this).data("href");
    });
});

1๐Ÿ‘

I think i may have found a implementation for the above.

Putting a click event for a dialogue box with Django Tables2

it is for deleting a row but the concept is the same

I will test and check

๐Ÿ‘คKieron Gilbey

1๐Ÿ‘

Simple code to do that on row click or col

row_attrs = {
        "onClick": lambda record: "document.location.href='/app/view/{0}';".format(record.id)
    }

if you want to use it on col use tables.Column
Docs

๐Ÿ‘คkhaled-s

0๐Ÿ‘

Ok after spending this evening on this, I have found a way to perform this action without adding the href tag into the python code,

by using Ajax I can get the account code from the table and then pass this through to the url

$('table tbody tr').click(function () {
    let account = $(this).closest('tr').find('td.account').text();
    window.location = account;
});

adding the primary key to the url.py

    path('<slug:account>/', views.customer_edit, name='customer_edit'),

and adding the customer_edit def to the views.py

def customer_edit(request, account):
    customer = get_object_or_404(Customer, pk=account)
    if request.method == 'POST':
        form = CustomerEdit(request.POST, instance=customer)
        if form.is_valid():
            customer.save()
            return redirect(reverse('customer:customer'))

    else:
        form = CustomerEdit(instance=customer)
        args = {'customer': customer, 'form': form}
        return render(request, 'customer/customer_edit.html', args)

this is the most optimum way I could find to redirect to another view from Django without having the url specified inside of the python file, I am 100% that there is better ways to do this but for now this will be the accepted answer

๐Ÿ‘คKieron Gilbey

0๐Ÿ‘

I may be a little confused about what you are trying to do. It seems like you are for some reason trying to have the view render a new response back from the click events on the table. That is why you are getting tripped up with all this JavaScript rendering. You should simply have those cells render as links that go to where you need them to.

Take a look at the django-tables2 documentation for TemplateColumn. You will want to just have it point to a template that creates the url given the record pk.

https://django-tables2.readthedocs.io/en/latest/pages/api-reference.html?highlight=templatecolumn#templatecolumn

tables.py
class CustomerTable(tables.Table):
    account = tables.TemplateColumn(template_name="_account.html")

    def render_title(self, record, value, column, bound_column, bound_row):
            value = self.value_title(record, value)
            return mark_safe(  # noqa: S308, S703
                column.render(record, self, value, bound_column, bound_row=bound_row)
            )



_account.html
<a href={% url('customer_edit', args=[record.pk]) %}>your text here</a>
๐Ÿ‘คnatehawkboss

Leave a comment