- Timestamp:
- 06/30/07 19:36:35 (19 months ago)
- Location:
- unicoders/trunk/unicoders
- Files:
-
- 5 modified
-
adminedit/media/scripts/adminedit.js (modified) (4 diffs)
-
adminedit/templates/adminedit/field_view.html (modified) (1 diff)
-
adminedit/urls.py (modified) (1 diff)
-
adminedit/views.py (modified) (2 diffs)
-
media/scripts/adminedit.js (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
unicoders/trunk/unicoders/adminedit/media/scripts/adminedit.js
r76 r77 1 var ADMIN_URL = '/admin/'; 2 var ADMINEDIT_URL = '/adminedit/'; 3 var THROBBER ='<img src="/media/images/throbber.gif" class="throbber"/>'; 4 var MESSAGE = '<ul class="messagelist"><li>Click any field to edit it in place</li></ul>'; 5 6 function stopPropagation(event) { event.stopPropagation(); } 7 1 8 function getFieldId(cell) { 2 9 var cell = $(cell); … … 19 26 } 20 27 21 function getTypeName() {22 return document.location.href.split('/').slice(-2, -1)[0];23 }24 function getObjectId(cell) {25 var id = $(cell).parent().find('a').attr('href');26 return id.substring(0, id.length-1);27 }28 29 28 function getUrl(cell) { 30 // build the url 31 var type = getTypeName(); 32 var id = getObjectId(cell); 33 var field = getFieldId(cell); 34 return '/adminedit/edit/'+type+'/'+id+'/'+field; 29 return $(cell).parent().find('a').attr('href') + getFieldId(cell); 35 30 } 36 31 … … 38 33 return $(cell).parent().find('th input')[0].checked; 39 34 } 40 function editField() { 35 36 function focusForm(cell) { 37 var form = $(cell).find('input, textarea, select'); 38 if (form.length > 0) form[0].focus(); 39 } 40 41 42 function edit() { 43 var cell = this; 44 var bool = null; 45 46 function editOne(c, b) { 47 if (b != null) { 48 editBooleanField(c, !b); 49 } else { 50 editField(c); 51 } 52 } 53 54 // special case for bool fields 55 if ($(cell).find('img').length > 0) bool = ($(cell).find('img').attr('alt') == 'True'); 56 41 57 // if the row we are editing is selected 42 if (isRowSelected( this)) {58 if (isRowSelected(cell)) { 43 59 // do the same edit on all the other rows that are selected 44 getCellsInColumn( this).each(function() {45 if (isRowSelected(this)) edit SingleField.call(this, false);60 getCellsInColumn(cell).each(function() { 61 if (isRowSelected(this)) editOne(this, bool); 46 62 }); 47 63 } else { 48 editSingleField.call(this, true); 49 } 50 } 51 52 function setupForm(target, single) { 53 var form = $(target).find('input, textarea, select'); 64 editOne(cell, bool); 65 focusForm(cell); 66 } 67 } 68 69 function save() { 70 var form = this; 71 var cell = $(form).parent(); 72 // if the row we are editing is selected 73 if (isRowSelected(cell)) { 74 // save all the other rows that are selected 75 getCellsInColumn(cell).each(function() { 76 if (isRowSelected(this)) saveField($(this).find('input, textarea, select')); 77 }); 78 } else { 79 saveField(form); 80 focusForm(cell); 81 } 82 } 83 84 function editBooleanField(cell, value) { 85 var args = {}; 86 args['toggle'] = value; 87 88 // throbber 89 $(cell).append(THROBBER); 90 91 $.post(getUrl(cell), args, function(data) { 92 var img = $($(cell).find('img')[0]); 93 94 data = data.split('\n')[0]; 95 96 if ((data == 'True') || (data == 'False')) { 97 img.attr('alt', data); 98 // remove the throbber 99 $(cell).find('img.throbber').remove(); 100 } 101 102 if (data == 'True') { 103 img.attr('src', img.attr('src').replace('-no', '-yes')); 104 } else if (data == 'False') { 105 img.attr('src', img.attr('src').replace('-yes', '-no')); 106 } 107 }); 108 } 109 110 function editField(cell) { 111 // throbber 112 $(cell).append(THROBBER); 113 114 // ajax request for the form widget 115 $.get(getUrl(cell), function(data) { 116 // insert the ajax response in the page 117 $(cell).html(data); 118 setupForm(cell); 119 }); 120 } 121 122 function saveField(form) { 123 var cell = $(form).parent(); 124 125 // throbber 126 cell.append(THROBBER); 127 128 // just one argument to the post: the field we are editing with its new value 129 var args = {}; 130 if ($(form).attr('value')) { 131 args[$(form).attr('name')] = $(form).attr('value'); 132 } else { 133 args[$(form).attr('name')] = ''; 134 } 135 136 // ajax post to edit the object 137 $.post(getUrl(cell), args, function(data) { 138 // display the new value in the page 139 $(cell).html(data); 140 141 // in case of validation error 142 setupForm(cell); 143 }); 144 } 145 146 function setupForm(cell) { 147 var form = $(cell).find('input, textarea, select'); 54 148 if (form.length == 0) return; 55 149 56 150 // do not start the edit again if we click on a form element 57 form.click( function(event) { event.stopPropagation(); event.preventDefault(); });151 form.click(stopPropagation); 58 152 // on blur: save 59 form.blur( function() { saveField.call(this, single); });153 form.blur(save); 60 154 // on enter: save 61 155 form.keypress(function(event) { 62 if (event.keyCode == 13) save Field.call(this, single);63 }); 64 65 156 if (event.keyCode == 13) save.call(this); 157 }); 158 159 // edit all selected fields simultaneously 66 160 function changeField() { 67 161 function innerChangeField() { 68 var cell = $(target);69 if (target.tagName == 'A') cell = $(target).parent();70 162 getCellsInColumn(cell).each(function() { 71 163 if (isRowSelected(this)) { … … 75 167 }); 76 168 }; 77 setTimeout(innerChangeField, 10); 169 // let the current element edit before updating the other ones 170 setTimeout(innerChangeField, 1); 78 171 } 79 172 form.change(changeField); 80 173 form.keypress(changeField); 81 82 // focus on the new form widget 83 if (single) form[0].focus(); 84 } 85 86 function editSingleField(single) { 87 var target = this; 88 // keep the link if present 89 if ($(target).find('a').length > 0) { 90 target = $(this).find('a')[0]; 91 } 92 93 // throbber 94 $(target).append('<img src="/media/images/throbber.gif"/>'); 95 96 // ajax request for the form widget 97 $.get(getUrl(this), function(data) { 98 // insert the ajax response in the page 99 $(target).html(data); 100 101 setupForm(target, single); 102 }); 103 } 104 105 function saveField(single) { 106 var cell = $(this).parent(); 107 // var target = cell; 108 // if (cell[0].tagName == 'SPAN') cell = cell.parent(); 109 110 if (!single) { 111 var column = getCellsInColumn(cell); 112 var form = this; 113 column.each(function() { 114 if (isRowSelected(this)) saveField.call($(this).find('input, textarea, select'), true); 115 }); 116 } else { 117 118 // throbber 119 cell.append('<img src="/media/images/throbber.gif"/>'); 120 121 // just one argument to the post: the field we are editing with its new value 122 var args = {}; 123 if ($(this).attr('value')) { 124 args[$(this).attr('name')] = $(this).attr('value'); 125 } else { 126 args[$(this).attr('name')] = ''; 127 } 128 129 // ajax post to edit the object 130 $.post(getUrl(cell), args, function(data) { 131 // display the new value in the page 132 $(cell).html(data); 133 134 // in case of validation error 135 setupForm(cell, single); 136 }); 137 } 138 } 174 } 175 139 176 140 177 $(document).ready(function() { 178 // activate only on change-list pages 141 179 if ($('body').attr('class') != 'change-list') return; 142 180 143 $('#content h1').append('<ul class="messagelist"><li>Click any field to edit it in place</li></ul>'); 144 145 // on click: edit 146 $('td, th').click(editField); 181 // show help message 182 $('#content h1').append(MESSAGE); 183 184 // on click on a table cell: edit 185 $('tbody td, tbody th').click(edit); 147 186 // when clicking on a link, do not edit 148 $('td a, th a').click(function(event) { event.stopPropagation(); }); 149 150 // add checkboxes to each row 151 $('tr').prepend($('<th><input type="checkbox"/></th>')); 187 $('tbody td a, tbody th a').click(stopPropagation); 188 189 // add checkboxes to each row and save the links 190 $('tr').each(function() { 191 var url = window.location.href + $(this).find('a').attr('href'); 192 url = url.replace(ADMIN_URL, ADMINEDIT_URL); 193 194 $(this).prepend($('<th><a class="adminedit_link" href="'+url+'"></a><input type="checkbox"/></th>')); 195 }); 152 196 153 197 // select/deselect all -
unicoders/trunk/unicoders/adminedit/templates/adminedit/field_view.html
r75 r77 1 { { field }}1 {% ifequal field None %}(None){% else %}{{ field }}{% endifequal %} -
unicoders/trunk/unicoders/adminedit/urls.py
r75 r77 2 2 3 3 urlpatterns = patterns('unicoders.adminedit.views', 4 (r'^ edit/(?P<type>.+)/(?P<id>[0-9]+)/(?P<field>.+)$', 'field_edit'),4 (r'^(?P<app>.+)/(?P<model>.+)/(?P<id>[0-9]+)/(?P<field>.+)$', 'field_edit'), 5 5 ) -
unicoders/trunk/unicoders/adminedit/views.py
r76 r77 4 4 from django.contrib import admin 5 5 6 def field_edit(request, type, id, field):7 c = ContentType.objects.get( name__exact=type).model_class()6 def field_edit(request, app, model, id, field): 7 c = ContentType.objects.get(app_label=app, model=model).model_class() 8 8 Form = forms.form_for_instance(c.objects.get(id=id)) 9 9 … … 17 17 form = Form(request.POST) 18 18 o = c.objects.get(id=id) 19 20 # special case for boolean fields 21 if 'toggle' in request.POST: 22 setattr(o, field, request.POST['toggle'] == 'true') 23 o.save() 24 return field_view(o, field) 25 19 26 try: 20 27 setattr(o, field, form[field].field.clean(request.POST.get(field, None))) -
unicoders/trunk/unicoders/media/scripts/adminedit.js
r76 r77 1 var ADMIN_URL = '/admin/'; 2 var ADMINEDIT_URL = '/adminedit/'; 3 var THROBBER ='<img src="/media/images/throbber.gif" class="throbber"/>'; 4 var MESSAGE = '<ul class="messagelist"><li>Click any field to edit it in place</li></ul>'; 5 6 function stopPropagation(event) { event.stopPropagation(); } 7 1 8 function getFieldId(cell) { 2 9 var cell = $(cell); … … 19 26 } 20 27 21 function getTypeName() {22 return document.location.href.split('/').slice(-2, -1)[0];23 }24 function getObjectId(cell) {25 var id = $(cell).parent().find('a').attr('href');26 return id.substring(0, id.length-1);27 }28 29 28 function getUrl(cell) { 30 // build the url 31 var type = getTypeName(); 32 var id = getObjectId(cell); 33 var field = getFieldId(cell); 34 return '/adminedit/edit/'+type+'/'+id+'/'+field; 29 return $(cell).parent().find('a').attr('href') + getFieldId(cell); 35 30 } 36 31 … … 38 33 return $(cell).parent().find('th input')[0].checked; 39 34 } 40 function editField() { 35 36 function focusForm(cell) { 37 var form = $(cell).find('input, textarea, select'); 38 if (form.length > 0) form[0].focus(); 39 } 40 41 42 function edit() { 43 var cell = this; 44 var bool = null; 45 46 function editOne(c, b) { 47 if (b != null) { 48 editBooleanField(c, !b); 49 } else { 50 editField(c); 51 } 52 } 53 54 // special case for bool fields 55 if ($(cell).find('img').length > 0) bool = ($(cell).find('img').attr('alt') == 'True'); 56 41 57 // if the row we are editing is selected 42 if (isRowSelected( this)) {58 if (isRowSelected(cell)) { 43 59 // do the same edit on all the other rows that are selected 44 getCellsInColumn( this).each(function() {45 if (isRowSelected(this)) edit SingleField.call(this, false);60 getCellsInColumn(cell).each(function() { 61 if (isRowSelected(this)) editOne(this, bool); 46 62 }); 47 63 } else { 48 editSingleField.call(this, true); 49 } 50 } 51 52 function setupForm(target, single) { 53 var form = $(target).find('input, textarea, select'); 64 editOne(cell, bool); 65 focusForm(cell); 66 } 67 } 68 69 function save() { 70 var form = this; 71 var cell = $(form).parent(); 72 // if the row we are editing is selected 73 if (isRowSelected(cell)) { 74 // save all the other rows that are selected 75 getCellsInColumn(cell).each(function() { 76 if (isRowSelected(this)) saveField($(this).find('input, textarea, select')); 77 }); 78 } else { 79 saveField(form); 80 focusForm(cell); 81 } 82 } 83 84 function editBooleanField(cell, value) { 85 var args = {}; 86 args['toggle'] = value; 87 88 // throbber 89 $(cell).append(THROBBER); 90 91 $.post(getUrl(cell), args, function(data) { 92 var img = $($(cell).find('img')[0]); 93 94 data = data.split('\n')[0]; 95 96 if ((data == 'True') || (data == 'False')) { 97 img.attr('alt', data); 98 // remove the throbber 99 $(cell).find('img.throbber').remove(); 100 } 101 102 if (data == 'True') { 103 img.attr('src', img.attr('src').replace('-no', '-yes')); 104 } else if (data == 'False') { 105 img.attr('src', img.attr('src').replace('-yes', '-no')); 106 } 107 }); 108 } 109 110 function editField(cell) { 111 // throbber 112 $(cell).append(THROBBER); 113 114 // ajax request for the form widget 115 $.get(getUrl(cell), function(data) { 116 // insert the ajax response in the page 117 $(cell).html(data); 118 setupForm(cell); 119 }); 120 } 121 122 function saveField(form) { 123 var cell = $(form).parent(); 124 125 // throbber 126 cell.append(THROBBER); 127 128 // just one argument to the post: the field we are editing with its new value 129 var args = {}; 130 if ($(form).attr('value')) { 131 args[$(form).attr('name')] = $(form).attr('value'); 132 } else { 133 args[$(form).attr('name')] = ''; 134 } 135 136 // ajax post to edit the object 137 $.post(getUrl(cell), args, function(data) { 138 // display the new value in the page 139 $(cell).html(data); 140 141 // in case of validation error 142 setupForm(cell); 143 }); 144 } 145 146 function setupForm(cell) { 147 var form = $(cell).find('input, textarea, select'); 54 148 if (form.length == 0) return; 55 149 56 150 // do not start the edit again if we click on a form element 57 form.click( function(event) { event.stopPropagation(); event.preventDefault(); });151 form.click(stopPropagation); 58 152 // on blur: save 59 form.blur( function() { saveField.call(this, single); });153 form.blur(save); 60 154 // on enter: save 61 155 form.keypress(function(event) { 62 if (event.keyCode == 13) save Field.call(this, single);63 }); 64 65 156 if (event.keyCode == 13) save.call(this); 157 }); 158 159 // edit all selected fields simultaneously 66 160 function changeField() { 67 161 function innerChangeField() { 68 var cell = $(target);69 if (target.tagName == 'A') cell = $(target).parent();70 162 getCellsInColumn(cell).each(function() { 71 163 if (isRowSelected(this)) { … … 75 167 }); 76 168 }; 77 setTimeout(innerChangeField, 10); 169 // let the current element edit before updating the other ones 170 setTimeout(innerChangeField, 1); 78 171 } 79 172 form.change(changeField); 80 173 form.keypress(changeField); 81 82 // focus on the new form widget 83 if (single) form[0].focus(); 84 } 85 86 function editSingleField(single) { 87 var target = this; 88 // keep the link if present 89 if ($(target).find('a').length > 0) { 90 target = $(this).find('a')[0]; 91 } 92 93 // throbber 94 $(target).append('<img src="/media/images/throbber.gif"/>'); 95 96 // ajax request for the form widget 97 $.get(getUrl(this), function(data) { 98 // insert the ajax response in the page 99 $(target).html(data); 100 101 setupForm(target, single); 102 }); 103 } 104 105 function saveField(single) { 106 var cell = $(this).parent(); 107 // var target = cell; 108 // if (cell[0].tagName == 'SPAN') cell = cell.parent(); 109 110 if (!single) { 111 var column = getCellsInColumn(cell); 112 var form = this; 113 column.each(function() { 114 if (isRowSelected(this)) saveField.call($(this).find('input, textarea, select'), true); 115 }); 116 } else { 117 118 // throbber 119 cell.append('<img src="/media/images/throbber.gif"/>'); 120 121 // just one argument to the post: the field we are editing with its new value 122 var args = {}; 123 if ($(this).attr('value')) { 124 args[$(this).attr('name')] = $(this).attr('value'); 125 } else { 126 args[$(this).attr('name')] = ''; 127 } 128 129 // ajax post to edit the object 130 $.post(getUrl(cell), args, function(data) { 131 // display the new value in the page 132 $(cell).html(data); 133 134 // in case of validation error 135 setupForm(cell, single); 136 }); 137 } 138 } 174 } 175 139 176 140 177 $(document).ready(function() { 178 // activate only on change-list pages 141 179 if ($('body').attr('class') != 'change-list') return; 142 180 143 $('#content h1').append('<ul class="messagelist"><li>Click any field to edit it in place</li></ul>'); 144 145 // on click: edit 146 $('td, th').click(editField); 181 // show help message 182 $('#content h1').append(MESSAGE); 183 184 // on click on a table cell: edit 185 $('tbody td, tbody th').click(edit); 147 186 // when clicking on a link, do not edit 148 $('td a, th a').click(function(event) { event.stopPropagation(); }); 149 150 // add checkboxes to each row 151 $('tr').prepend($('<th><input type="checkbox"/></th>')); 187 $('tbody td a, tbody th a').click(stopPropagation); 188 189 // add checkboxes to each row and save the links 190 $('tr').each(function() { 191 var url = window.location.href + $(this).find('a').attr('href'); 192 url = url.replace(ADMIN_URL, ADMINEDIT_URL); 193 194 $(this).prepend($('<th><a class="adminedit_link" href="'+url+'"></a><input type="checkbox"/></th>')); 195 }); 152 196 153 197 // select/deselect all