Intelligently toggle column visibility and reload only the datagrids
Updated 11 months, 2 weeks ago
| Christian Hammond | Reviewers | ||
| trunk | reviewboard | ||
| None | Navi | ||
We were taking the easy way out before with datagrid column customization and just pre-generating the toggle URLs up-front. When toggling the visibility of a column, we would change the URL. However, this would be problematic if you were then to rearrange columns and reload the page, as the original order would still be in the URL, causing your custom order to be wiped out. We now smooth out the whole column customization process by making this all dynamic. Clicking a column in the menu generates the new column string based on the existing order in the grid and then saves the result to the server, requesting the new grid. We then unregister the old grid, load in the new one and register that. The result is no more column specs in the URL, so no more wiping out of orders. The experience feels smoother, since we only reload the grid, rather than the whole page. *UPDATE* The latest change works in IE, but changes a bit how datagrids work, so it's worth looking at. I recommend viewing the interdiff as it's going to be a lot more clear. IE refuses to load script tags when setting innerHTML. We were using the script tags to register the data grid and set up the columns. Now we scan for the grids and columns and set them up. This forces more requirements on what the HTML must be like when using the JavaScript, but I think that's fine.
Tested that I could add and remove columns as much as I wanted and still reorder things without losing any settings at all. Tested in Firefox and IE.
| /trunk/djblets/djblets/datagrid/grids.py | |||
|---|---|---|---|
| Revision 11688 | New Change | ||
| 1 |
|
1 |
|
| 2 | from django.core.paginator import InvalidPage, ObjectPaginator |
2 | from django.core.paginator import InvalidPage, ObjectPaginator |
| 3 | from django.http import Http404, HttpResponse |
3 | from django.http import Http404, HttpResponse |
| 4 | from django.shortcuts import render_to_response |
4 | from django.shortcuts import render_to_response |
| 5 | from django.template.context import RequestContext |
5 | from django.template.context import RequestContext |
| 6 | from django.template.defaultfilters import date, timesince |
6 | from django.template.defaultfilters import date, timesince |
| 7 | from django.template.loader import render_to_string |
7 | from django.template.loader import render_to_string |
| 8 | from django.utils.safestring import mark_safe |
8 | from django.utils.safestring import mark_safe |
| 9 | from django.utils.translation import ugettext as _ |
9 | from django.utils.translation import ugettext as _ |
| 10 | from django.views.decorators.cache import cache_control |
||
| 10 | 11 | ||
| 11 | 12 | ||
| 12 | class Column(object): |
13 | class Column(object): |
| 13 | """ |
14 | """ |
| 14 | A column in a data grid. |
15 | A column in a data grid. |
| ... | 415 lines hidden [Expand] | ||
| 430 | 431 | ||
| 431 | if self.profile_sort_field and sort_str != profile_sort_list: |
432 | if self.profile_sort_field and sort_str != profile_sort_list: |
| 432 | setattr(profile, self.profile_sort_field, sort_str) |
433 | setattr(profile, self.profile_sort_field, sort_str) |
| 433 | profile_dirty = True |
434 | profile_dirty = True |
| 434 | 435 | ||
| 436 | print "Saving profile if... %s" % profile_dirty |
||
| 435 | if profile_dirty: |
437 | if profile_dirty: |
| 436 | profile.save() |
438 | profile.save() |
| 437 | 439 | ||
| 438 | self.state_loaded = True |
440 | self.state_loaded = True |
| 439 | 441 | ||
| ... | 97 lines hidden [Expand] | ||
| 537 | 'pages': self.paginator.pages, |
539 | 'pages': self.paginator.pages, |
| 538 | 'hits': self.paginator.hits, |
540 | 'hits': self.paginator.hits, |
| 539 | 'page_range': self.paginator.page_range, |
541 | 'page_range': self.paginator.page_range, |
| 540 | }))) |
542 | }))) |
| 541 | 543 | ||
| 544 | @cache_control(no_cache=True, no_store=True, max_age=0, |
||
| 545 | must_revalidate=True) |
||
| 546 | def render_listview_to_response(self): |
||
| 547 | """ |
||
| 548 | Renders the listview to a response, preventing caching in the |
||
| 549 | process. |
||
| 550 | """ |
||
| 551 | return HttpResponse(unicode(self.render_listview())) |
||
| 552 | |||
| 542 | def render_to_response(self, template_name, extra_context={}): |
553 | def render_to_response(self, template_name, extra_context={}): |
| 543 | """ |
554 | """ |
| 544 | Renders a template containing this datagrid as a context variable. |
555 | Renders a template containing this datagrid as a context variable. |
| 545 | """ |
556 | """ |
| 546 | self.load_state() |
557 | self.load_state() |
| 547 | 558 | ||
| 548 | # If the caller is requesting just this particular grid, return it. |
559 | # If the caller is requesting just this particular grid, return it. |
| 549 | if self.request.GET.get('gridonly', False) and \ |
560 | if self.request.GET.get('gridonly', False) and \ |
| 550 | self.request.GET.get('datagrid-id', None) == self.id: |
561 | self.request.GET.get('datagrid-id', None) == self.id: |
| 551 | return HttpResponse(unicode(self.render_listview())) |
562 | return self.render_listview_to_response() |
| 552 | 563 | ||
| 553 | context = { |
564 | context = { |
| 554 | 'datagrid': self |
565 | 'datagrid': self |
| 555 | } |
566 | } |
| 556 | context.update(extra_context) |
567 | context.update(extra_context) |
| ... | 11 lines hidden [Expand] | ||
| /trunk/djblets/djblets/datagrid/templates/datagrid/listview.html | |||
|---|---|---|---|
| Revision 11688 | New Change | ||
| 1 |
|
1 |
|
| 2 | <div class="datagrid-wrapper" id="{{datagrid.id}}"> |
2 | <div class="datagrid-wrapper" id="{{datagrid.id}}"> |
| 3 | <div class="datagrid-titlebox"> |
3 | <div class="datagrid-titlebox"> |
| 4 | {% block datagrid_title %} |
4 | {% block datagrid_title %} |
| 5 | <h1 class="datagrid-title">{{datagrid.title}}</h1> |
5 | <h1 class="datagrid-title">{{datagrid.title}}</h1> |
| 6 | {% endblock %} |
6 | {% endblock %} |
| 7 | </div> |
7 | </div> |
| 8 | <div class="datagrid-main"> |
8 | <div class="datagrid-main"> |
| 9 | <table class="datagrid"> |
9 | <table class="datagrid"> |
| 10 | <colgroup> |
10 | <colgroup> |
| 11 | {% for column in datagrid.columns %} |
11 | {% for column in datagrid.columns %} |
| 12 | <col class="{{column.field_name}}"{% ifnotequal column.width 0 %} width="{{column.width}}%"{% endifnotequal %} /> |
12 | <col class="{{column.id}}"{% ifnotequal column.width 0 %} width="{{column.width}}%"{% endifnotequal %} /> |
| 13 | {% endfor %} |
13 | {% endfor %} |
| 14 | <col class="datagrid-customize" /> |
14 | <col class="datagrid-customize" /> |
| 15 | </colgroup> |
15 | </colgroup> |
| 16 | <thead> |
16 | <thead> |
| 17 | <tr class="datagrid-headers"> |
17 | <tr class="datagrid-headers"> |
| ... | 13 lines hidden [Expand] | ||
| 31 | </table> |
31 | </table> |
| 32 | {% if is_paginated %} |
32 | {% if is_paginated %} |
| 33 | {% paginator %} |
33 | {% paginator %} |
| 34 | {% endif %} |
34 | {% endif %} |
| 35 | </div> |
35 | </div> |
| 36 | </div> |
||
| 37 | <table class="datagrid-menu" id="{{datagrid.id}}-menu" style="visibility:hidden;position:absolute;top:0px;left:-1000px;"> |
36 | <table class="datagrid-menu" id="{{datagrid.id}}-menu" style="visibility:hidden;position:absolute;top:0px;left:-1000px;"> |
| 38 | {% for column in datagrid.all_columns %} |
37 | {% for column in datagrid.all_columns %} |
| 39 | {% with column.toggle_url as toggle_url %} |
38 | {% with column.toggle_url as toggle_url %} |
| 40 | <tr> |
39 | <tr> |
| 41 | <td><div class="datagrid-menu-checkbox" onclick="javascript:window.location='{{toggle_url}}';">{% if column.active %}<img src="{{MEDIA_URL}}images/djblets/datagrid/checkmark.png" width="8" height="8" border="0" alt="X" />{% endif %}</div></td> |
40 | <td><div class="datagrid-menu-checkbox" onclick="DJBLETS.datagrids.toggleColumn('{{datagrid.id}}', '{{column.id}}');">{% if column.active %}<img src="{{MEDIA_URL}}images/djblets/datagrid/checkmark.png" width="8" height="8" border="0" alt="X" />{% endif %}</div></td> |
| 42 | <td class="datagrid-menu-label"><a href=".{{toggle_url}}"> |
41 | <td class="datagrid-menu-label"><a href="#" onclick="DJBLETS.datagrids.toggleColumn('{{datagrid.id}}', '{{column.id}}');"> |
| 43 | {% if column.image_url %} |
42 | {% if column.image_url %} |
| 44 | <img src="{{column.image_url}}" width="{{column.image_width}}" height="{{column.image_height}}" alt="{{column.image_alt}}" /> |
43 | <img src="{{column.image_url}}" width="{{column.image_width}}" height="{{column.image_height}}" alt="{{column.image_alt}}" /> |
| 45 | {% endif %} |
44 | {% endif %} |
| 46 | {{column.detailed_label|default_if_none:""}}</a> |
45 | {{column.detailed_label|default_if_none:""}}</a> |
| 47 | {% endwith %} |
46 | {% endwith %} |
| 48 | {% endfor %} |
47 | {% endfor %} |
| 49 | </table> |
48 | </table> |
| 50 | <script type="text/javascript"> |
49 | </div> |
| 51 | DJBLETS.datagrids.registerDataGrid("{{datagrid.id}}", [ |
||
| 52 | {% for column in datagrid.columns %}"{{column.id}}"{% if not forloop.last %}, {%endif %}{% endfor %} |
||
| 53 | ]); |
||
| 54 | </script> |
||
| /trunk/djblets/djblets/media/js/datagrid.js | |||
|---|---|---|---|
| Revision 11688 | New Change | ||
| 1 |
|
1 |
|
| 2 | if (!DJBLETS) { |
2 | if (!DJBLETS) { |
| 3 | var DJBLETS = {}; |
3 | var DJBLETS = {}; |
| 4 | } |
4 | } |
| 5 | 5 | ||
| 6 | DJBLETS.datagrids = { |
6 | DJBLETS.datagrids = { |
| 7 | activeMenu: null, |
7 | activeMenu: null, |
| 8 | registeredGrids: [], |
||
| 9 | activeColumns: {}, |
8 | activeColumns: {}, |
| 10 | 9 | ||
| 11 | /* |
10 | /* |
| 12 | * Registers a datagrid. This will cause drag and drop and column |
11 | * Registers a datagrid. This will cause drag and drop and column |
| 13 | * customization to be enabled. |
12 | * customization to be enabled. |
| 14 | * |
13 | * |
| 15 | * @param {string} datagrid_id The ID of the datagrid. |
14 | * @param {HTMLElement} grid The datagrid element. |
| 16 | * @param {array} activeColumns The list of active columns in order. |
||
| 17 | */ |
15 | */ |
| 18 | registerDataGrid: function(datagrid_id, activeColumns) { |
16 | registerDataGrid: function(grid) { |
| 19 | this.registeredGrids.push(datagrid_id); |
17 | this.activeColumns[grid] = []; |
| 20 | this.activeColumns[datagrid_id] = activeColumns; |
18 | |
| 19 | var cols = grid.getElementsByTagName("col"); |
||
| 20 | for (var j = 0; j < cols.length; j++) { |
||
| 21 | if (cols[j].className != "datagrid-customize") { |
||
| 22 | this.activeColumns[grid].push(cols[j].className); |
||
| 23 | } |
||
| 24 | } |
||
| 25 | |||
| 26 | var headers = grid.getElementsByTagName("th"); |
||
| 27 | |||
| 28 | for (var j = 0; j < headers.length; j++) { |
||
| 29 | var header = getEl(headers[j]); |
||
| 30 | header.unselectable(); |
||
| 31 | |||
| 32 | if (!header.hasClass("edit-columns")) { |
||
| 33 | new DJBLETS.datagrids.DDColumn(header, grid); |
||
| 34 | } |
||
| 35 | } |
||
| 36 | }, |
||
| 37 | |||
| 38 | /* |
||
| 39 | * Unregisters a datagrid. This is used when we're getting ready to |
||
| 40 | * reload a grid. |
||
| 41 | * |
||
| 42 | * @param {HTMLElement} grid The datagrid. |
||
| 43 | */ |
||
| 44 | unregisterDataGrid: function(grid) { |
||
| 45 | this.activeColumns[grid] = []; |
||
| 21 | }, |
46 | }, |
| 22 | 47 | ||
| 23 | /* |
48 | /* |
| 24 | * Hides the currently open columns menu. |
49 | * Hides the currently open columns menu. |
| 25 | */ |
50 | */ |
| 26 | hideColumnsMenu: function() { |
51 | hideColumnsMenu: function() { |
| 52 | if (this.activeMenu != null) { |
||
| 27 | this.activeMenu.hide(); |
53 | this.activeMenu.hide(); |
| 28 | this.activeMenu = null; |
54 | this.activeMenu = null; |
| 55 | } |
||
| 29 | }, |
56 | }, |
| 30 | 57 | ||
| 31 | /* |
58 | /* |
| 32 | * Toggles the visibility of the specified columns menu. |
59 | * Toggles the visibility of the specified columns menu. |
| 33 | * |
60 | * |
| ... | 22 lines hidden [Expand] | ||
| 56 | YAHOO.util.Event.stopEvent(evt); |
83 | YAHOO.util.Event.stopEvent(evt); |
| 57 | } |
84 | } |
| 58 | }, |
85 | }, |
| 59 | 86 | ||
| 60 | /* |
87 | /* |
| 61 | * Callback handler for when the page finishes loading. Enables |
88 | * Callback handler for when the page finishes loading. Registers |
| 62 | * drag and drop for the datagrids. |
89 | * the grids and enables drag and drop for the datagrids. |
| 63 | */ |
90 | */ |
| 64 | onPageLoad: function() { |
91 | onPageLoad: function() { |
| 65 | for (var i = 0; i < this.registeredGrids.length; i++) { |
92 | var grids = YAHOO.util.Dom.getElementsByClassName("datagrid-wrapper", |
| 66 | var grid = getEl(this.registeredGrids[i]); |
93 | "div"); |
| 67 | var headers = grid.getChildrenByTagName("th"); |
94 | for (var i = 0; i < grids.length; i++) { |
| 95 | this.registerDataGrid(grids[i]); |
||
| 96 | } |
||
| 97 | }, |
||
| 68 | 98 | ||
| 69 | for (var j = 0; j < headers.length; j++) { |
99 | /* |
| 70 | headers[j].unselectable(); |
100 | * Saves the new columns list on the server. |
| 101 | * |
||
| 102 | * @param {{string}} gridId The ID of the datagrid. |
||
| 103 | * @param {{string}} columnsStr The columns to display. |
||
| 104 | * @param {{function}} onSuccess Optional callback on successful save. |
||
| 105 | */ |
||
| 106 | saveColumns: function(gridId, columnsStr, onSuccess) { |
||
| 107 | var url = window.location.pathname + |
||
| 108 | "?gridonly=1&datagrid-id=" + gridId + |
||
| 109 | "&columns=" + columnsStr; |
||
| 110 | |||
| 111 | YAHOO.util.Connect.asyncRequest("GET", url, { |
||
| 112 | success: onSuccess |
||
| 113 | }); |
||
| 114 | }, |
||
| 71 | 115 | ||
| 72 | if (!headers[j].hasClass("edit-columns")) { |
116 | /* |
| 73 | new DJBLETS.datagrids.DDColumn(headers[j], grid); |
117 | * Toggles the visibility of a column. This will build the resulting |
| 118 | * columns string and request a save of the columns, followed by a |
||
| 119 | * reload of the page. |
||
| 120 | * |
||
| 121 | * @param {{string}} gridId The ID of the datagrid. |
||
| 122 | * @param {{string}} columnId The ID of the column to toggle. |
||
| 123 | */ |
||
| 124 | toggleColumn: function(gridId, columnId) { |
||
| 125 | var addingColumn = true; |
||
| 126 | var grid = document.getElementById(gridId); |
||
| 127 | var curColumns = this.activeColumns[grid]; |
||
| 128 | var newColumnsStr = ""; |
||
| 129 | |||
| 130 | for (var i = 0; i < curColumns.length; i++) { |
||
| 131 | if (curColumns[i] == columnId) { |
||
| 132 | /* We're removing this column. */ |
||
| 133 | addingColumn = false; |
||
| 134 | } else { |
||
| 135 | newColumnsStr += curColumns[i]; |
||
| 136 | |||
| 137 | if (i < curColumns.length - 1) { |
||
| 138 | newColumnsStr += ","; |
||
| 74 | } |
139 | } |
| 75 | } |
140 | } |
| 76 | } |
141 | } |
| 142 | |||
| 143 | if (addingColumn) { |
||
| 144 | newColumnsStr += "," + columnId; |
||
| 145 | } |
||
| 146 | |||
| 147 | this.saveColumns(gridId, newColumnsStr, function(res) { |
||
| 148 | this.hideColumnsMenu(); |
||
| 149 | this.unregisterDataGrid(gridId); |
||
| 150 | |||
| 151 | /* The resulting text *should* be datagrid HTML. */ |
||
| 152 | var oldEl = getEl(gridId); |
||
| 153 | oldEl.dom.id = ""; |
||
| 154 | |||
| 155 | YAHOO.ext.DomHelper.insertHtml("beforeBegin", oldEl.dom, |
||
| 156 | res.responseText); |
||
| 157 | oldEl.remove(); |
||
| 158 | |||
| 159 | this.registerDataGrid(document.getElementById(gridId)); |
||
| 160 | }.createDelegate(this)); |
||
| 77 | } |
161 | } |
| 78 | } |
162 | } |
| 79 | 163 | ||
| 80 | 164 | ||
| 81 | /* |
165 | /* |
| ... | 37 lines hidden [Expand] | ||
| 119 | * Sets up the movement constraints for this column. This locks the |
203 | * Sets up the movement constraints for this column. This locks the |
| 120 | * column into the column header region. It has the effect of only |
204 | * column into the column header region. It has the effect of only |
| 121 | * allowing the column to slide left and right. |
205 | * allowing the column to slide left and right. |
| 122 | */ |
206 | */ |
| 123 | initConstraints: function() { |
207 | initConstraints: function() { |
| 124 | var thead = this.grid.getChildrenByTagName("thead")[0]; |
208 | var thead = getEl(this.grid.getElementsByTagName("thead")[0]); |
| 125 | var headerRegion = thead.getRegion(); |
209 | var headerRegion = thead.getRegion(); |
| 126 | var colRegion = this.el.getRegion(); |
210 | var colRegion = this.el.getRegion(); |
| 127 | 211 | ||
| 128 | this.setXConstraint(colRegion.left - headerRegion.left, |
212 | this.setXConstraint(colRegion.left - headerRegion.left, |
| 129 | headerRegion.right - colRegion.right); |
213 | headerRegion.right - colRegion.right); |
| ... | 41 lines hidden [Expand] | ||
| 171 | dragEl.hide(); |
255 | dragEl.hide(); |
| 172 | this.el.show(); |
256 | this.el.show(); |
| 173 | 257 | ||
| 174 | this.columnMidpoints = []; |
258 | this.columnMidpoints = []; |
| 175 | 259 | ||
| 176 | this.saveColumns(); |
260 | /* Build the new columns list. */ |
| 261 | var columns = DJBLETS.datagrids.activeColumns[this.grid]; |
||
| 262 | var columnsStr = ""; |
||
| 263 | |||
| 264 | for (var i = 0; i < columns.length; i++) { |
||
| 265 | columnsStr += columns[i]; |
||
| 266 | |||
| 267 | if (i != columns.length - 1) { |
||
| 268 | columnsStr += ","; |
||
| 269 | } |
||
| 270 | } |
||
| 271 | |||
| 272 | DJBLETS.datagrids.saveColumns(this.grid.id, columnsStr); |
||
| 177 | }, |
273 | }, |
| 178 | 274 | ||
| 179 | /* |
275 | /* |
| 180 | * Handles movement while in drag mode. |
276 | * Handles movement while in drag mode. |
| 181 | * |
277 | * |
| ... | 46 lines hidden [Expand] | ||
| 228 | * of the currently dragged column. |
324 | * of the currently dragged column. |
| 229 | */ |
325 | */ |
| 230 | buildColumnInfo: function() { |
326 | buildColumnInfo: function() { |
| 231 | /* Grab the list of midpoints for each column. */ |
327 | /* Grab the list of midpoints for each column. */ |
| 232 | this.columnMidpoints = []; |
328 | this.columnMidpoints = []; |
| 233 | var columns = this.grid.getChildrenByTagName("th"); |
329 | var columns = getEl(this.grid).getChildrenByTagName("th"); |
| 234 | 330 | ||
| 235 | for (var i = 0; i < columns.length; i++) { |
331 | for (var i = 0; i < columns.length; i++) { |
| 236 | if (!columns[i].hasClass("edit-columns")) { |
332 | if (!columns[i].hasClass("edit-columns")) { |
| 237 | this.columnMidpoints.push(columns[i].getX() + |
333 | this.columnMidpoints.push(columns[i].getX() + |
| 238 | columns[i].getWidth() / 2); |
334 | columns[i].getWidth() / 2); |
| ... | 16 lines hidden [Expand] | ||
| 255 | * @param {int} beforeIndex The index of the column to place the first |
351 | * @param {int} beforeIndex The index of the column to place the first |
| 256 | * before. |
352 | * before. |
| 257 | */ |
353 | */ |
| 258 | swapColumnBefore: function(index, beforeIndex) { |
354 | swapColumnBefore: function(index, beforeIndex) { |
| 259 | /* Swap the column info. */ |
355 | /* Swap the column info. */ |
| 260 | var colTags = this.grid.getChildrenByTagName("col"); |
356 | var colTags = getEl(this.grid).getChildrenByTagName("col"); |
| 261 | colTags[index].insertBefore(colTags[beforeIndex]); |
357 | colTags[index].insertBefore(colTags[beforeIndex]); |
| 262 | 358 | ||
| 263 | /* Swap the list of active columns */ |
359 | /* Swap the list of active columns */ |
| 264 | var tempName = DJBLETS.datagrids.activeColumns[this.grid.id][index]; |
360 | var tempName = DJBLETS.datagrids.activeColumns[this.grid][index]; |
| 265 | DJBLETS.datagrids.activeColumns[this.grid.id][index] = |
361 | DJBLETS.datagrids.activeColumns[this.grid][index] = |
| 266 | DJBLETS.datagrids.activeColumns[this.grid.id][beforeIndex]; |
362 | DJBLETS.datagrids.activeColumns[this.grid][beforeIndex]; |
| 267 | DJBLETS.datagrids.activeColumns[this.grid.id][beforeIndex] = tempName; |
363 | DJBLETS.datagrids.activeColumns[this.grid][beforeIndex] = tempName; |
| 268 | 364 | ||
| 269 | /* Swap the cells. This will include the headers. */ |
365 | /* Swap the cells. This will include the headers. */ |
| 270 | var table = this.grid.getChildrenByTagName("table")[0].dom; |
366 | var table = getEl(this.grid).getChildrenByTagName("table")[0].dom; |
| 271 | for (var i = 0; i < table.rows.length; i++) { |
367 | for (var i = 0; i < table.rows.length; i++) { |
| 272 | var row = table.rows[i]; |
368 | var row = table.rows[i]; |
| 273 | var cell = row.cells[index]; |
369 | var cell = row.cells[index]; |
| 274 | var beforeCell = row.cells[beforeIndex]; |
370 | var beforeCell = row.cells[beforeIndex]; |
| 275 | 371 | ||
| ... | 5 lines hidden [Expand] | ||
| 281 | beforeCell.colSpan = tempColSpan; |
377 | beforeCell.colSpan = tempColSpan; |
| 282 | } |
378 | } |
| 283 | 379 | ||
| 284 | /* Everything has changed, so rebuild our view of things. */ |
380 | /* Everything has changed, so rebuild our view of things. */ |
| 285 | this.buildColumnInfo(); |
381 | this.buildColumnInfo(); |
| 286 | }, |
||
| 287 | |||
| 288 | /* |
||
| 289 | * Saves the new columns list on the server. |
||
| 290 | */ |
||
| 291 | saveColumns: function() { |
||
| 292 | var columns = ""; |
||
| 293 | var grid_id = this.grid.id; |
||
| 294 | var len = DJBLETS.datagrids.activeColumns[grid_id].length; |
||
| 295 | |||
| 296 | for (var i = 0; i < len; i++) { |
||
| 297 | columns += DJBLETS.datagrids.activeColumns[grid_id][i]; |
||
| 298 | |||
| 299 | if (i != len - 1) { |
||
| 300 | columns += ","; |
||
| 301 | } |
||
| 302 | } |
||
| 303 | |||
| 304 | var url = window.location.pathname + |
||
| 305 | "?gridonly=1&datagrid-id=" + grid_id + "&columns=" + columns; |
||
| 306 | |||
| 307 | YAHOO.util.Connect.asyncRequest("GET", url); |
||
| 308 | } |
382 | } |
| 309 | }); |
383 | }); |
| 310 | 384 | ||
| 311 | YAHOO.util.Event.on(window, "load", |
385 | YAHOO.util.Event.on(window, "load", |
| 312 | DJBLETS.datagrids.onPageLoad.createDelegate(DJBLETS.datagrids)); |
386 | DJBLETS.datagrids.onPageLoad.createDelegate(DJBLETS.datagrids)); |
| 313 | YAHOO.util.Event.on(document, "click", function(e) { |
387 | YAHOO.util.Event.on(document, "click", function(e) { |
| 314 | if (DJBLETS.< | ||