Giter Club home page Giter Club logo

Comments (9)

tiliv avatar tiliv commented on May 27, 2024

I like the idea of this one. There are a few fields that make it difficult to automate 100% (it's hard to know what data-url should be without the developer's help, for example), but I think it can be done.

As a first step, I imagine a helper that you could interact with something like this:

# Direct use, but might be a lot for just one line
datatable_options = {
    'columns': [
        ("My Field", 'my_field', helpers.make_xeditable(type=..., url=...)),
    ]
}

# Or if there are common fields, you could use it like a helper-factory
my_xeditable = helpers.make_xeditable(type='select2', url=reverse('update:url:name'))
datatable_options = {
    'columns': [
        ("My Field", 'my_field', my_xeditable),
        ("Another Field", 'another_field', my_xeditable),
        # Can still specify new kwargs by chaining the calls together
        ("Third Field", 'third_field', my_xeditable(title="Special case")),
    ]
}

In the latter case, the helper is still able to accept new arguments at runtime, which would include the actual instance, current value, pk, etc. The type could be omitted in the default scenario where it can be read from the field type (like the default form field widgets).

The Javascript case is a little special for that select2 situation. I'm not sure what the best thing to do is, but adding the core helper should be a good place to start.

Thanks for the recommendation!

from django-datatable-view.

ScottEAdams avatar ScottEAdams commented on May 27, 2024

Yeah, the select 2 one is a bit special because of the ajax request. Probably some similar issues if you wanted to use other x-editable input types such as typeahead. But then again you can just override using javascript anyway so its a non-issue :)

from django-datatable-view.

tiliv avatar tiliv commented on May 27, 2024

I've merged the xeditable branch into master, and I'd be curious what you think of how it works so far, before I go pushing it into the release.

If you have a free moment to try it out, pull down the latest master copy and give this a shot:

from datatableview.views import XEditableDatatableView
from datatableview import helpers

class MyDatatable(XEditableDatatableView):
    datatable_options = {
        'columns': [
            ("Driver", 'driver', helpers.make_xeditable(type="select2"),
        ],

If the field has choices, the "type" will automatically be detected as "select", but you can decide to go with "select2" without any additional configuration.

The xeditable ajax update URL automatically generated by the helper, and XEditableDatatableView can actually service that ajax request without any configuration at all. It builds a dynamic form of just the one field in question and enforces native field validation (which are raised as proper error messages in the xeditable fashion).

To make this work on the client side, you can use the following Javascript on your template:

<script type="text/javascript">
    function confirm_datatable_options(options) {
        var options = { /* editable() options can go here */ };
        options.fnRowCallback = datatableview.make_xeditable(options);
        return options;
    }
</script>

datatableview is a new javascript object which holds this callback. It's intended to be used with fnRowCallback specifically, because of which parameters the callback gives. No options are required for it to work out the box, but you can specify whichever you like and the JS make_xeditable will insert the required CSRF token header for the ajax, etc.

Let me know if anything feels wrong! Thanks for opening this as a recommended helper!

from django-datatable-view.

ScottEAdams avatar ScottEAdams commented on May 27, 2024

i will have to look into it a bit more because I just uninstalled the release version and installed master but before I had done anything it was throwing the following error

ERROR Internal Server Error: /custom/
Traceback (most recent call last):
  File "/workspace/git/admin_project/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 114, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/workspace/git/admin_project/venv/local/lib/python2.7/site-packages/django/views/generic/base.py", line 69, in view
    return self.dispatch(request, *args, **kwargs)
  File "/workspace/git/admin_project/venv/local/lib/python2.7/site-packages/django/views/generic/base.py", line 87, in dispatch
    return handler(request, *args, **kwargs)
  File "/workspace/git/admin_project/venv/src/datatableview/datatableview/views.py", line 50, in get
    return self.get_ajax(request, *args, **kwargs)
  File "/workspace/git/admin_project/project-admin/project_admin/apps/project/views.py", line 261, in get_ajax
    response = HttpResponse(self.serialize_to_json(object_list), mimetype="application/json")
  File "/workspace/git/admin_project/venv/src/datatableview/datatableview/views.py", line 384, in serialize_to_json
    return json.dumps(response_data, indent=indent)
  File "/usr/lib/python2.7/json/__init__.py", line 250, in dumps
    sort_keys=sort_keys, **kw).encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 209, in encode
    chunks = list(chunks)
  File "/usr/lib/python2.7/json/encoder.py", line 442, in _iterencode
    o = _default(o)
  File "/usr/lib/python2.7/json/encoder.py", line 184, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: [<Custom: 2013-11-21 13:21:08+00:00>, <Custom: 2013-11-21 13:13:05+00:00>, <Custom: 2013-11-21 13:13:04+00:00>, <Custom: 2013-11-21 13:12:57+00:00>, <Custom: 2013-11-21 13:12:48+00:00>, <Custom: 2013-11-21 08:15:17+00:00>, <Custom: 2013-11-21 08:14:34+00:00>, <Custom: 2013-11-21 08:14:31+00:00>, <Custom: 2013-11-21 08:14:30+00:00>, <Custom: 2013-11-21 08:14:29+00:00>, <Custom: 2013-11-21 07:10:49+00:00>, <Custom: 2013-11-21 07:08:11+00:00>, <Custom: 2013-11-21 07:08:09+00:00>, <Custom: 2013-11-21 07:08:07+00:00>, <Custom: 2013-11-21 07:08:05+00:00>, <Custom: 2013-11-20 17:38:09+00:00>, <Custom: 2013-11-20 17:37:57+00:00>, <Custom: 2013-11-20 17:37:56+00:00>, <Custom: 2013-11-20 17:37:56+00:00>, <Custom: 2013-11-20 17:37:56+00:00>, '...(remaining elements truncated)...'] is not JSON serializable

I do have a custom implementation of the get_ajax method for that view though so will have to try master on something a bit more straightforward.

from django-datatable-view.

ScottEAdams avatar ScottEAdams commented on May 27, 2024

OK, fixed the above error. I saw that you had made some minor changes to get_ajax (or perhaps I wasnt implementing it correctly before!). I use a custom get_ajax for adding filters to my tables, I can explain that idea a bit more on another idea issue. I will come back when I have played around with xeditable implementation.

from django-datatable-view.

tiliv avatar tiliv commented on May 27, 2024

Ah yesโ€”I have notes in the release draft about the method signature changes, but of course that's not published yet. My mistake.

Here's the copy-paste of it, for reference:

A backwards-incompatible change has been made to the return value of get_object_list() and apply_queryset_options(), and the parameter type of serialize_to_json(). The former two methods previously returned a 3-tuple of (object_list, total, filtered_total), and the latter method received this 3-tuple as a single argument. This was not ideal, so the former two are now updated to return a list-like object, and the latter method now receives just the python dictionary to serialize.

A new method has been broken out of the DatatableView request-response workflow:

get_json_response_object() โ€” This method receives several arguments that will be placed into a dictionary. If custom fields need to be added to the AJAX response object, you can implement this method, call super() to get the normal object, and then add to it:

class MyDatatableView(DatatableView):
    datatable_options = { ... }
    def get_json_response_object(self, object_list, *args, **kwargs):
        data = super(MyDatatableView, self).get_json_response_object(object_list, *args, **kwargs)

        # Keep customizations JSON-compatible! :) 
        data.update({
            'special_arg': self.kwargs['special_arg'],
        })
        return data

This setup should work better for cases where people are trying to modify the response object's contents.

from django-datatable-view.

ScottEAdams avatar ScottEAdams commented on May 27, 2024

I still couldnt get it to work on a simpler datatable view but its highly likely that its related to my setup in some way (I am using bootstrapped datatables and bootstrapped xeditable if that makes any difference). The field showed up as a link to # but on click I got no response (which is why I think its related to the js im using). Unfortunately I havent really got the time to muck about with it at the moment. I guess if its working for you though then its good to go.

from django-datatable-view.

ScottEAdams avatar ScottEAdams commented on May 27, 2024

Heres a link to the bootstrapped datatables btw - https://github.com/Jowin/Datatables-Bootstrap3/

from django-datatable-view.

tiliv avatar tiliv commented on May 27, 2024

I modified my test project to use those assets and things seem to work okay for me still. My guess is you might not have the view inheriting from the modified XEditableDatatableView, which services those ajax requests by default. (You likely had views set up to handle those before, and you can still use them if you like, but you'd need to supply a url keyword to the helper.)

Thanks for the extra attention, at any rate. If you find anything odd in my implementation in the future, please don't hesitate to point it out. I'm relatively new to the xeditable stuff, which is why I took a while to learn how it works and figure something out.

from django-datatable-view.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.