|
| 1 | +import html |
1 | 2 | import json |
2 | 3 | import pytest |
3 | 4 |
|
4 | 5 | from docs.models import ( |
5 | 6 | Album, |
6 | 7 | Artist, |
| 8 | + FavoriteArtist, |
7 | 9 | ) |
8 | 10 | from iommi.declarative.namespace import Namespace |
9 | 11 | from iommi.edit_table import ( |
@@ -840,3 +842,181 @@ def test_parent_form_save(abort_on_fail): |
840 | 842 | </form> |
841 | 843 | """, |
842 | 844 | ) |
| 845 | + |
| 846 | + |
| 847 | +@pytest.mark.django_db |
| 848 | +def test_orderable_edit_table(fav_artists): |
| 849 | + class FavoriteArtists(EditTable): |
| 850 | + class Meta: |
| 851 | + auto__model = FavoriteArtist |
| 852 | + auto__include = ['artist__name', 'comment', 'sort_order'] |
| 853 | + columns__comment__field__include = True |
| 854 | + sortable = False |
| 855 | + |
| 856 | + verify_table_html( |
| 857 | + table=FavoriteArtists().bind(request=req('get')), |
| 858 | + # language=html |
| 859 | + expected_html=f""" |
| 860 | + <table class="table" data-new-row-endpoint="/new_row" data-next-virtual-pk="-1"> |
| 861 | + <thead> |
| 862 | + <tr> |
| 863 | + <th class="first_column subheader">Name</th> |
| 864 | + <th class="first_column subheader">Comment</th> |
| 865 | + <th class="first_column subheader">Sort order</th> |
| 866 | + </tr> |
| 867 | + </thead> |
| 868 | + <tbody data-iommi-reorderable data-iommi-reorderable-field-selector="[data-reordering-value]" data-iommi-reorderable-handle-selector="[data-iommi-path="columns__sort_order__cell"]"> |
| 869 | + <tr data-pk="{fav_artists[0].pk}"> |
| 870 | + <td>Black Sabbath</td> |
| 871 | + <td><input id="id_columns__comment__{fav_artists[0].pk}" name="columns/comment/{fav_artists[0].pk}" type="text" value="Love it!"></td> |
| 872 | + <td class="reordering-handle-cell" title="Drag and drop to reorder"><input data-reordering-value id="id_columns__sort_order__{fav_artists[0].pk}" name="columns/sort_order/{fav_artists[0].pk}" type="hidden" value="0"></td> |
| 873 | + </tr> |
| 874 | + <tr data-pk="{fav_artists[1].pk}"> |
| 875 | + <td>Ozzy Osbourne</td> |
| 876 | + <td><input id="id_columns__comment__{fav_artists[1].pk}" name="columns/comment/{fav_artists[1].pk}" type="text" value="I love this too!"></td> |
| 877 | + <td class="reordering-handle-cell" title="Drag and drop to reorder"><input data-reordering-value id="id_columns__sort_order__{fav_artists[1].pk}" name="columns/sort_order/{fav_artists[1].pk}" type="hidden" value="1"></td> |
| 878 | + </tr> |
| 879 | + <tr data-pk="{fav_artists[2].pk}"> |
| 880 | + <td>Damnation</td> |
| 881 | + <td><input id="id_columns__comment__{fav_artists[2].pk}" name="columns/comment/{fav_artists[2].pk}" type="text" value="And this as well"></td> |
| 882 | + <td class="reordering-handle-cell" title="Drag and drop to reorder"><input data-reordering-value id="id_columns__sort_order__{fav_artists[2].pk}" name="columns/sort_order/{fav_artists[2].pk}" type="hidden" value="2"></td> |
| 883 | + </tr> |
| 884 | + </tbody> |
| 885 | + </table> |
| 886 | + """, |
| 887 | + ) |
| 888 | + |
| 889 | + |
| 890 | +@pytest.mark.django_db |
| 891 | +def test_orderable_edit_table_sortablejs_options(fav_artists): |
| 892 | + sortablejs_options = { |
| 893 | + "multiDrag": True, # Enable multi-drag |
| 894 | + "selectedClass": 'selected', # The class applied to the selected items |
| 895 | + "fallbackTolerance": 3, # So that we can select items on mobile |
| 896 | + } |
| 897 | + class FavoriteArtists(EditTable): |
| 898 | + class Meta: |
| 899 | + auto__model = FavoriteArtist |
| 900 | + auto__include = ['artist__name', 'comment', 'sort_order'] |
| 901 | + columns__comment__field__include = True |
| 902 | + reorderable = sortablejs_options |
| 903 | + sortable = False |
| 904 | + |
| 905 | + verify_table_html( |
| 906 | + table=FavoriteArtists().bind(request=req('get')), |
| 907 | + # language=html |
| 908 | + expected_html=f""" |
| 909 | + <table class="table" data-new-row-endpoint="/new_row" data-next-virtual-pk="-1"> |
| 910 | + <thead> |
| 911 | + <tr> |
| 912 | + <th class="first_column subheader">Name</th> |
| 913 | + <th class="first_column subheader">Comment</th> |
| 914 | + <th class="first_column subheader">Sort order</th> |
| 915 | + </tr> |
| 916 | + </thead> |
| 917 | + <tbody data-iommi-reorderable="{html.escape(json.dumps(sortablejs_options, separators=(',', ':')))}" data-iommi-reorderable-field-selector="[data-reordering-value]" data-iommi-reorderable-handle-selector="[data-iommi-path="columns__sort_order__cell"]"> |
| 918 | + <tr data-pk="{fav_artists[0].pk}"> |
| 919 | + <td>Black Sabbath</td> |
| 920 | + <td><input id="id_columns__comment__{fav_artists[0].pk}" name="columns/comment/{fav_artists[0].pk}" type="text" value="Love it!"></td> |
| 921 | + <td class="reordering-handle-cell" title="Drag and drop to reorder"><input data-reordering-value id="id_columns__sort_order__{fav_artists[0].pk}" name="columns/sort_order/{fav_artists[0].pk}" type="hidden" value="0"></td> |
| 922 | + </tr> |
| 923 | + <tr data-pk="{fav_artists[1].pk}"> |
| 924 | + <td>Ozzy Osbourne</td> |
| 925 | + <td><input id="id_columns__comment__{fav_artists[1].pk}" name="columns/comment/{fav_artists[1].pk}" type="text" value="I love this too!"></td> |
| 926 | + <td class="reordering-handle-cell" title="Drag and drop to reorder"><input data-reordering-value id="id_columns__sort_order__{fav_artists[1].pk}" name="columns/sort_order/{fav_artists[1].pk}" type="hidden" value="1"></td> |
| 927 | + </tr> |
| 928 | + <tr data-pk="{fav_artists[2].pk}"> |
| 929 | + <td>Damnation</td> |
| 930 | + <td><input id="id_columns__comment__{fav_artists[2].pk}" name="columns/comment/{fav_artists[2].pk}" type="text" value="And this as well"></td> |
| 931 | + <td class="reordering-handle-cell" title="Drag and drop to reorder"><input data-reordering-value id="id_columns__sort_order__{fav_artists[2].pk}" name="columns/sort_order/{fav_artists[2].pk}" type="hidden" value="2"></td> |
| 932 | + </tr> |
| 933 | + </tbody> |
| 934 | + </table> |
| 935 | + """, |
| 936 | + ) |
| 937 | + |
| 938 | + |
| 939 | +@pytest.mark.django_db |
| 940 | +def test_orderable_edit_table_reorder_handle(): |
| 941 | + obj1 = TFoo.objects.create(a=1, b='test_reorder_handle') |
| 942 | + obj2 = TFoo.objects.create(a=2, b='test_reorder_handle') |
| 943 | + |
| 944 | + class MyEditTable(EditTable): |
| 945 | + class Meta: |
| 946 | + auto__model = TFoo |
| 947 | + rows = TFoo.objects.filter(b='test_reorder_handle') |
| 948 | + auto__include = ['a', 'b'] |
| 949 | + columns__a = EditColumn.reorder_handle() |
| 950 | + sortable = False |
| 951 | + |
| 952 | + verify_table_html( |
| 953 | + table=MyEditTable().bind(request=req('get')), |
| 954 | + # language=html |
| 955 | + expected_html=f""" |
| 956 | + <table class="table" data-new-row-endpoint="/new_row" data-next-virtual-pk="-1"> |
| 957 | + <thead> |
| 958 | + <tr> |
| 959 | + <th class="first_column subheader">B</th> |
| 960 | + <th class="first_column subheader">A</th> |
| 961 | + </tr> |
| 962 | + </thead> |
| 963 | + <tbody data-iommi-reorderable data-iommi-reorderable-field-selector="[data-reordering-value]" data-iommi-reorderable-handle-selector="[data-iommi-path="columns__a__cell"]"> |
| 964 | + <tr data-pk="{obj1.pk}"> |
| 965 | + <td>test_reorder_handle</td> |
| 966 | + <td class="reordering-handle-cell" title="Drag and drop to reorder"><input data-reordering-value id="id_columns__a__{obj1.pk}" name="columns/a/{obj1.pk}" type="hidden" value="1"></td> |
| 967 | + </tr> |
| 968 | + <tr data-pk="{obj2.pk}"> |
| 969 | + <td>test_reorder_handle</td> |
| 970 | + <td class="reordering-handle-cell" title="Drag and drop to reorder"><input data-reordering-value id="id_columns__a__{obj2.pk}" name="columns/a/{obj2.pk}" type="hidden" value="2"></td> |
| 971 | + </tr> |
| 972 | + </tbody> |
| 973 | + </table> |
| 974 | + """, |
| 975 | + ) |
| 976 | + |
| 977 | + |
| 978 | +@pytest.mark.django_db |
| 979 | +def test_orderable_sortable_edit_table(fav_artists): |
| 980 | + """ |
| 981 | + when sorted by any column, the reordering turns off |
| 982 | + """ |
| 983 | + class FavoriteArtists(EditTable): |
| 984 | + class Meta: |
| 985 | + auto__model = FavoriteArtist |
| 986 | + auto__include = ['artist__name', 'comment', 'sort_order'] |
| 987 | + columns__comment__field__include = True |
| 988 | + |
| 989 | + fav_artists_data = FavoriteArtist.objects.order_by('artist__name') |
| 990 | + |
| 991 | + verify_table_html( |
| 992 | + table=FavoriteArtists().bind(request=req('get', order='artist_name')), |
| 993 | + # language=html |
| 994 | + expected_html=f""" |
| 995 | + <table class="table" data-new-row-endpoint="/new_row" data-next-virtual-pk="-1"> |
| 996 | + <thead> |
| 997 | + <tr> |
| 998 | + <th class="ascending first_column iommi_sort_header sorted subheader"> |
| 999 | + <a href="?order=-artist_name">Name</a> |
| 1000 | + </th> |
| 1001 | + <th class="first_column iommi_sort_header subheader"> |
| 1002 | + <a href="?order=comment">Comment</a> |
| 1003 | + </th> |
| 1004 | + </tr> |
| 1005 | + </thead> |
| 1006 | + <tbody> |
| 1007 | + <tr data-pk="{fav_artists_data[0].pk}"> |
| 1008 | + <td>{fav_artists_data[0].artist.name}</td> |
| 1009 | + <td><input id="id_columns__comment__{fav_artists_data[0].pk}" name="columns/comment/{fav_artists_data[0].pk}" type="text" value="{fav_artists_data[0].comment}"></td> |
| 1010 | + </tr> |
| 1011 | + <tr data-pk="{fav_artists_data[1].pk}"> |
| 1012 | + <td>{fav_artists_data[1].artist.name}</td> |
| 1013 | + <td><input id="id_columns__comment__{fav_artists_data[1].pk}" name="columns/comment/{fav_artists_data[1].pk}" type="text" value="{fav_artists_data[1].comment}"></td> |
| 1014 | + </tr> |
| 1015 | + <tr data-pk="{fav_artists_data[2].pk}"> |
| 1016 | + <td>{fav_artists_data[2].artist.name}</td> |
| 1017 | + <td><input id="id_columns__comment__{fav_artists_data[2].pk}" name="columns/comment/{fav_artists_data[2].pk}" type="text" value="{fav_artists_data[2].comment}"></td> |
| 1018 | + </tr> |
| 1019 | + </tbody> |
| 1020 | + </table> |
| 1021 | + """, |
| 1022 | + ) |
0 commit comments