From fdb716ea9a22863b193b7a068f86feffd8b7fa58 Mon Sep 17 00:00:00 2001 From: church29 Date: Tue, 11 Feb 2014 16:47:06 -0800 Subject: [PATCH 01/16] Postdata does not submit until submit is clicked now --- cyder/base/views.py | 2 +- media/js/tables.js | 29 ++++++++++++++++++++++------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/cyder/base/views.py b/cyder/base/views.py index 86c4217a7..8c24a4f39 100644 --- a/cyder/base/views.py +++ b/cyder/base/views.py @@ -456,7 +456,7 @@ def table_update(request, pk, obj_type=None): if form.is_valid(): form.save() return HttpResponse() - return HttpResponse(json.dumps({'error': form.errors})) + return HttpResponse(json.dumps({'error': str(form.errors)})) class BaseListView(ListView): diff --git a/media/js/tables.js b/media/js/tables.js index 0941dc1f1..10c4bd462 100755 --- a/media/js/tables.js +++ b/media/js/tables.js @@ -1,4 +1,4 @@ -function enableEditableGrid() { +function enableEditableGrid(allPostData) { var $eg = $('#eg'); var csrfToken = $('#view-metadata').attr('data-csrfToken'); if (!$eg) { @@ -35,13 +35,13 @@ function enableEditableGrid() { can be validated and the object can be updated. */ var postData = {}; + var data = {}; postData[editableGrid.getColumnName(columnIndex)] = newValue; postData['csrfmiddlewaretoken'] = csrfToken; - $.post($(row).attr('data-url'), postData, function(resp) { - if (resp && resp.error) { - $(row).after($('').html(resp.error[0])); - } - }, 'json'); + data['row'] = row; + data['postData'] = postData; + data['url'] = $(row).attr('data-url'); + allPostData.push(data); }; editableGrid.attachToHTMLTable('egtable'); editableGrid.renderGrid(); @@ -49,6 +49,7 @@ function enableEditableGrid() { $(document).ready(function() { + var allPostData = []; var $enableEg = $('#enable-eg'); if ($enableEg.length) { $enableEg[0].reset(); @@ -57,12 +58,26 @@ $(document).ready(function() { $enableEg.find('input').removeAttr('disabled').change(function() { $this = $(this); if ($this.attr('checked')) { - enableEditableGrid(); + enableEditableGrid(allPostData); $this.attr('disabled', true); } $('#enable-eg').remove(); $('.spreadsheet-mode').show(); + $('#action-bar').find('a').each(function() { + $(this).css('display', 'none') + }); + $('#action-bar').append('Submit'); + $('#eg_submit').click( function() { + jQuery.each(allPostData, function(i, data) { + $.post(data.url, data.postData, function(resp) { + if (resp && resp.error) { + $(data.row).after($('').html(resp.error)); + } + }, 'json'); + }); + }); + }); } }); From 29f5f2f813ff4c59743d8cb400d817fba6793f5b Mon Sep 17 00:00:00 2001 From: church29 Date: Tue, 11 Feb 2014 17:24:12 -0800 Subject: [PATCH 02/16] added confirm str with list of changes --- media/js/tables.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/media/js/tables.js b/media/js/tables.js index 10c4bd462..867182ae7 100755 --- a/media/js/tables.js +++ b/media/js/tables.js @@ -41,6 +41,8 @@ function enableEditableGrid(allPostData) { data['row'] = row; data['postData'] = postData; data['url'] = $(row).attr('data-url'); + data['oldValue'] = oldValue; + data['newValue'] = newValue; allPostData.push(data); }; editableGrid.attachToHTMLTable('egtable'); @@ -69,15 +71,20 @@ $(document).ready(function() { }); $('#action-bar').append('Submit'); $('#eg_submit').click( function() { + var confirm_str = "Are you sure you want to make these changes:\n"; jQuery.each(allPostData, function(i, data) { - $.post(data.url, data.postData, function(resp) { - if (resp && resp.error) { - $(data.row).after($('').html(resp.error)); - } - }, 'json'); + confirm_str += data.oldValue + " -> " + data.newValue + ",\n"; }); + if (confirm(confirm_str)) { + jQuery.each(allPostData, function(i, data) { + $.post(data.url, data.postData, function(resp) { + if (resp && resp.error) { + $(data.row).after($('').html(resp.error)); + } + }, 'json'); + }); + }; }); - }); } }); From 7dc94ae985786034431f8937104b374ebaadc2bd Mon Sep 17 00:00:00 2001 From: church29 Date: Tue, 11 Feb 2014 17:31:26 -0800 Subject: [PATCH 03/16] prevent error stacking --- media/js/tables.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/media/js/tables.js b/media/js/tables.js index 867182ae7..ad149341a 100755 --- a/media/js/tables.js +++ b/media/js/tables.js @@ -76,10 +76,13 @@ $(document).ready(function() { confirm_str += data.oldValue + " -> " + data.newValue + ",\n"; }); if (confirm(confirm_str)) { + $('.errors').each(function() { + $(this).remove(); + }); jQuery.each(allPostData, function(i, data) { $.post(data.url, data.postData, function(resp) { if (resp && resp.error) { - $(data.row).after($('').html(resp.error)); + $(data.row).after($('').html(resp.error)); } }, 'json'); }); From 7af1a58aa68823c3e591feefdc4bf7176823e4d2 Mon Sep 17 00:00:00 2001 From: church29 Date: Tue, 11 Feb 2014 17:43:20 -0800 Subject: [PATCH 04/16] remove item from postdata list if it submits successfully --- media/js/tables.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/media/js/tables.js b/media/js/tables.js index ad149341a..ebca72d16 100755 --- a/media/js/tables.js +++ b/media/js/tables.js @@ -51,6 +51,7 @@ function enableEditableGrid(allPostData) { $(document).ready(function() { + $.ajaxSetup({async:false}); var allPostData = []; var $enableEg = $('#enable-eg'); if ($enableEg.length) { @@ -79,13 +80,19 @@ $(document).ready(function() { $('.errors').each(function() { $(this).remove(); }); + var successIndex = []; jQuery.each(allPostData, function(i, data) { $.post(data.url, data.postData, function(resp) { if (resp && resp.error) { $(data.row).after($('').html(resp.error)); - } + } else { + successIndex.push(i); + }; }, 'json'); }); + jQuery.each(successIndex, function(i, index) { + allPostData.splice(index, 1); + }); }; }); }); From 7c89092a16b70e61f4f2685cf271253bc7fbc0a0 Mon Sep 17 00:00:00 2001 From: church29 Date: Tue, 11 Feb 2014 17:45:05 -0800 Subject: [PATCH 05/16] refresh if all changes were successful --- media/js/tables.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/media/js/tables.js b/media/js/tables.js index ebca72d16..478c7cca2 100755 --- a/media/js/tables.js +++ b/media/js/tables.js @@ -81,18 +81,24 @@ $(document).ready(function() { $(this).remove(); }); var successIndex = []; + var success = true; jQuery.each(allPostData, function(i, data) { $.post(data.url, data.postData, function(resp) { if (resp && resp.error) { $(data.row).after($('').html(resp.error)); + success = false; } else { successIndex.push(i); }; }, 'json'); }); - jQuery.each(successIndex, function(i, index) { - allPostData.splice(index, 1); - }); + if (success) { + location.reload(); + } else { + jQuery.each(successIndex, function(i, index) { + allPostData.splice(index, 1); + }); + }; }; }); }); From d4d91bc0a88f6ca63a479c9981cd2d206f694839 Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 5 Mar 2014 14:45:28 -0800 Subject: [PATCH 06/16] Fix issue with tables shifting around when entering spreadsheet mode --- media/js/tables.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/media/js/tables.js b/media/js/tables.js index 478c7cca2..ac1d598ab 100755 --- a/media/js/tables.js +++ b/media/js/tables.js @@ -6,15 +6,13 @@ function enableEditableGrid(allPostData) { } // Remove Action column. - if ($('th:contains("Actions")')) { - $('th:contains("Actions")').remove(); - $('td:last-child').remove(); + if ($('.actions_column')) { + $('.actions_column').remove(); } // Remove Info column. - if ($('th:contains("Info")')) { - $('th:contains("Info")').remove(); - $('td:first-child').remove(); + if ($('.info_column')) { + $('.info_column').remove(); } // Strip links and paragraph tags, remove table cell markdown until From 53088ff9878de56f927543ba0c007e4add4a49e7 Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 5 Mar 2014 14:49:13 -0800 Subject: [PATCH 07/16] Added confirmation to exiting spreadsheet mode --- media/js/tables.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/media/js/tables.js b/media/js/tables.js index ac1d598ab..959ac8980 100755 --- a/media/js/tables.js +++ b/media/js/tables.js @@ -55,6 +55,14 @@ $(document).ready(function() { if ($enableEg.length) { $enableEg[0].reset(); + $('.exit-spreadsheet').click( function(e) { + e.preventDefault(); + if (confirm('Are you sure you want to exit spreadsheet mode? ' + + 'Your changes will not be submitted')) { + location.reload(); + }; + }); + // Enable editable grid on checkbox. $enableEg.find('input').removeAttr('disabled').change(function() { $this = $(this); From fb15e58373aa65ea3e0d63a29d4ee082cf7f675e Mon Sep 17 00:00:00 2001 From: church29 Date: Sun, 9 Mar 2014 19:40:30 -0700 Subject: [PATCH 08/16] Change exit spreadsheet mode to discard changes --- cyder/templates/base/list.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cyder/templates/base/list.html b/cyder/templates/base/list.html index f498c18be..33655531c 100644 --- a/cyder/templates/base/list.html +++ b/cyder/templates/base/list.html @@ -37,7 +37,7 @@ From 780f63358dae5f0ae168b033bfabe6bf8f11c377 Mon Sep 17 00:00:00 2001 From: church29 Date: Sun, 9 Mar 2014 20:14:39 -0700 Subject: [PATCH 09/16] Updated format of changes confirm box --- media/js/tables.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/media/js/tables.js b/media/js/tables.js index 959ac8980..b12b39c86 100755 --- a/media/js/tables.js +++ b/media/js/tables.js @@ -78,9 +78,9 @@ $(document).ready(function() { }); $('#action-bar').append('Submit'); $('#eg_submit').click( function() { - var confirm_str = "Are you sure you want to make these changes:\n"; + var confirm_str = "Are you sure you want to make the following changes?\n"; jQuery.each(allPostData, function(i, data) { - confirm_str += data.oldValue + " -> " + data.newValue + ",\n"; + confirm_str += data.oldValue + " -> " + data.newValue + "\n"; }); if (confirm(confirm_str)) { $('.errors').each(function() { From 1a1bfdfe1373a760101817b4519d6bef4ec9ee55 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 3 Apr 2014 13:55:40 -0700 Subject: [PATCH 10/16] Post error next to field in tables --- cyder/base/views.py | 11 +++++++---- media/js/tables.js | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/cyder/base/views.py b/cyder/base/views.py index f872fe7a1..70f342285 100644 --- a/cyder/base/views.py +++ b/cyder/base/views.py @@ -436,8 +436,9 @@ def table_update(request, pk, obj_type=None): obj = get_object_or_404(Klass, pk=pk) if not perm_soft(request, ACTION_UPDATE, obj=obj): - return HttpResponse(json.dumps({'error': 'You do not have appropriate' - ' permissions.'})) + return HttpResponse(json.dumps({ + 'error': {'__all__': [u'You do not have' + ' appropriate permissions.']}})) # DNS specific. qd = request.POST.copy() @@ -447,14 +448,16 @@ def table_update(request, pk, obj_type=None): # Call prune tree later if error, else domain leak. label, domain = ensure_label_domain(fqdn) except ValidationError, e: - return HttpResponse(json.dumps({'error': e.messages})) + return HttpResponse( + json.dumps({'error': {'__all__': [e.messages]}})) qd['label'], qd['domain'] = label, str(domain.pk) form = FormKlass(qd, instance=obj) if form.is_valid(): form.save() return HttpResponse() - return HttpResponse(json.dumps({'error': str(form.errors)})) + #import pdb; pdb.set_trace() + return HttpResponse(json.dumps({'error': (form.errors)})) class BaseListView(ListView): diff --git a/media/js/tables.js b/media/js/tables.js index b12b39c86..6f1e2d350 100755 --- a/media/js/tables.js +++ b/media/js/tables.js @@ -88,10 +88,23 @@ $(document).ready(function() { }); var successIndex = []; var success = true; + var error_str = ''; + var substr1_end; + var substr2_start; jQuery.each(allPostData, function(i, data) { $.post(data.url, data.postData, function(resp) { if (resp && resp.error) { - $(data.row).after($('').html(resp.error)); + jQuery.each(resp.error, function(field, error) { + if (field == '__all__') { + alert(error); + } else { + field = $(data.row).find('.' + field + '_column'); + if (field.find('font')) { + field.find('font').remove(); + }; + field.append(' ' + err + ''); + }; + }); success = false; } else { successIndex.push(i); From da8d2c167931ec0b8e19afe55da7f9baa84c26e8 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 3 Apr 2014 14:03:24 -0700 Subject: [PATCH 11/16] Add error class to msg --- media/js/tables.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/media/js/tables.js b/media/js/tables.js index 6f1e2d350..924659be7 100755 --- a/media/js/tables.js +++ b/media/js/tables.js @@ -99,10 +99,7 @@ $(document).ready(function() { alert(error); } else { field = $(data.row).find('.' + field + '_column'); - if (field.find('font')) { - field.find('font').remove(); - }; - field.append(' ' + err + ''); + field.append(' ' + error + ''); }; }); success = false; From 45d07dab735ef44d0aa07fc77a98c783fc19bf3a Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 3 Apr 2014 14:44:36 -0700 Subject: [PATCH 12/16] Cleanup js --- media/js/tables.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/media/js/tables.js b/media/js/tables.js index 924659be7..6f95fde63 100755 --- a/media/js/tables.js +++ b/media/js/tables.js @@ -88,9 +88,6 @@ $(document).ready(function() { }); var successIndex = []; var success = true; - var error_str = ''; - var substr1_end; - var substr2_start; jQuery.each(allPostData, function(i, data) { $.post(data.url, data.postData, function(resp) { if (resp && resp.error) { From 8cfac2f64bb0612ba0460f534885645f8bc61974 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 3 Apr 2014 14:48:02 -0700 Subject: [PATCH 13/16] cleanup table_update --- cyder/base/views.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cyder/base/views.py b/cyder/base/views.py index 70f342285..0f5e9a526 100644 --- a/cyder/base/views.py +++ b/cyder/base/views.py @@ -434,7 +434,6 @@ def table_update(request, pk, obj_type=None): Klass, FormKlass = get_klasses(obj_type) obj = get_object_or_404(Klass, pk=pk) - if not perm_soft(request, ACTION_UPDATE, obj=obj): return HttpResponse(json.dumps({ 'error': {'__all__': [u'You do not have' @@ -456,7 +455,7 @@ def table_update(request, pk, obj_type=None): if form.is_valid(): form.save() return HttpResponse() - #import pdb; pdb.set_trace() + return HttpResponse(json.dumps({'error': (form.errors)})) From d81658ab4810db4fcf52b6d1b8716a76582c0e00 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 3 Apr 2014 15:08:34 -0700 Subject: [PATCH 14/16] Fix issue with updating values already containing an error --- media/js/tables.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/media/js/tables.js b/media/js/tables.js index 6f95fde63..2366a660f 100755 --- a/media/js/tables.js +++ b/media/js/tables.js @@ -41,7 +41,7 @@ function enableEditableGrid(allPostData) { data['url'] = $(row).attr('data-url'); data['oldValue'] = oldValue; data['newValue'] = newValue; - allPostData.push(data); + allPostData[rowIndex + '-' + columnIndex] = data; }; editableGrid.attachToHTMLTable('egtable'); editableGrid.renderGrid(); @@ -50,7 +50,7 @@ function enableEditableGrid(allPostData) { $(document).ready(function() { $.ajaxSetup({async:false}); - var allPostData = []; + var allPostData = {}; var $enableEg = $('#enable-eg'); if ($enableEg.length) { $enableEg[0].reset(); @@ -88,7 +88,7 @@ $(document).ready(function() { }); var successIndex = []; var success = true; - jQuery.each(allPostData, function(i, data) { + jQuery.each(allPostData, function(key, data) { $.post(data.url, data.postData, function(resp) { if (resp && resp.error) { jQuery.each(resp.error, function(field, error) { @@ -101,15 +101,15 @@ $(document).ready(function() { }); success = false; } else { - successIndex.push(i); + successIndex.push(key); }; }, 'json'); }); if (success) { location.reload(); } else { - jQuery.each(successIndex, function(i, index) { - allPostData.splice(index, 1); + jQuery.each(successIndex, function(index, key) { + delete allPostData[key]; }); }; }; From f9cd60753afe7a9a5b46f48638e8fe4eec5d733f Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 3 Apr 2014 15:17:16 -0700 Subject: [PATCH 15/16] handle errors returned to __all__ rather than a field --- media/js/tables.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/media/js/tables.js b/media/js/tables.js index 2366a660f..51637447b 100755 --- a/media/js/tables.js +++ b/media/js/tables.js @@ -93,10 +93,16 @@ $(document).ready(function() { if (resp && resp.error) { jQuery.each(resp.error, function(field, error) { if (field == '__all__') { - alert(error); + $(data.row).after( + '' + error + + ''); } else { - field = $(data.row).find('.' + field + '_column'); - field.append(' ' + error + ''); + field = $(data.row).find( + '.' + field + '_column'); + field.append( + ' ' + + error + ''); }; }); success = false; From ee5d763d834d036183aa93cfac2a6ba302f0d6ba Mon Sep 17 00:00:00 2001 From: church29 Date: Fri, 12 Dec 2014 10:15:39 -0800 Subject: [PATCH 16/16] Apply patch recommended by drkitty --- cyder/base/views.py | 10 ++++++++++ cyder/cydhcp/vlan/models.py | 2 +- cyder/cydns/forms.py | 2 -- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/cyder/base/views.py b/cyder/base/views.py index d18300498..9adbdee3e 100644 --- a/cyder/base/views.py +++ b/cyder/base/views.py @@ -459,6 +459,16 @@ def table_update(request, pk, obj_type=None): qd['label'], qd['domain'] = label, str(domain.pk) form = FormKlass(qd, instance=obj) + # Set the fields that weren't modified + for key in form.fields: + if key not in qd: + old_value = form.initial[key] + if isinstance(old_value, list): + # ManyToManyFields need special treatment + form.data.setlist(key, old_value) + else: + form.data[key] = old_value + if form.is_valid(): form.save() return HttpResponse() diff --git a/cyder/cydhcp/vlan/models.py b/cyder/cydhcp/vlan/models.py index defb55d6c..fd521106e 100644 --- a/cyder/cydhcp/vlan/models.py +++ b/cyder/cydhcp/vlan/models.py @@ -48,7 +48,7 @@ def details(self): """For tables.""" data = super(Vlan, self).details() data['data'] = [ - ('Name', 'name', self), + ('Name', 'name', self.name), ('Number', 'number', self.number), ] return data diff --git a/cyder/cydns/forms.py b/cyder/cydns/forms.py index 1b77d917e..c8bdd23b2 100644 --- a/cyder/cydns/forms.py +++ b/cyder/cydns/forms.py @@ -14,8 +14,6 @@ def __init__(self, *args, **kwargs): class DNSForm(ViewChoiceForm): - comment = forms.CharField(widget=forms.HiddenInput, required=False) - def clean(self): super(DNSForm, self).clean() validate_views(self.cleaned_data)