Ticket #13221: django.patch

File django.patch, 10.3 KB (added by IsakovAN, 14 years ago)
  • contrib/admin/media/css/widgets.css

    diff -r -U 3 django.orig/contrib/admin/media/css/widgets.css django/contrib/admin/media/css/widgets.css
    old new  
    504504    border-top: 1px solid #ddd;
    505505}
    506506
     507form .vManyToManyRawIdAdminField + strong > ul{
     508        display:inline-block;
     509        margin-left:0px;
     510        padding:0 5px 0 0;
     511}
     512
     513.vForeignKeyRawIdAdminField + strong, .vManyToManyRawIdAdminField + strong ul li,.related-clear{
     514        cursor:pointer;
     515        margin:0 2px;
     516}
     517
     518strong:empty + a.related-clear {display:none;}
  • contrib/admin/media/js/admin/RelatedObjectLookups.js

    diff -r -U 3 django.orig/contrib/admin/media/js/admin/RelatedObjectLookups.js django/contrib/admin/media/js/admin/RelatedObjectLookups.js
    old new  
    4141    return false;
    4242}
    4343
    44 function dismissRelatedLookupPopup(win, chosenId) {
     44function dismissRelatedLookupPopup(win, chosenId, choosenRepr) {
     45        if(choosenRepr == null)
     46                choosenRepr = choosenId;
    4547    var name = windowname_to_id(win.name);
    4648    var elem = document.getElementById(name);
    47     if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
     49    var display = elem;
     50    while (display.tagName != 'STRONG')
     51                display = display.nextElementSibling;
     52    if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1) {
    4853        elem.value += ',' + chosenId;
     54        var li = document.createElement('LI')
     55                if( li.attachEvent ) {
     56                        li.attachEvent('onclick', 'go_to(this,'+chosenId+')');
     57                } else {
     58                        li.setAttribute('onclick', 'go_to(this,'+chosenId+')');
     59                }
     60                li.innerHTML = choosenRepr+'<a class="related-clear" onclick="return clear_related(this,'+chosenId+')">X</a>';
     61        for (var i = 0; i < display.childNodes.length; i++)
     62                        if (display.childNodes[i].tagName == 'UL')
     63                                display.childNodes[i].appendChild(li);
    4964    } else {
    50         document.getElementById(name).value = chosenId;
     65        elem.value = chosenId;
     66                display.innerHTML = choosenRepr;
     67                display.className = display.className;
    5168    }
    5269    win.close();
    5370}
     
    7390    newRepr = html_unescape(newRepr);
    7491    var name = windowname_to_id(win.name);
    7592    var elem = document.getElementById(name);
     93    var display = elem;
     94    while(display.tagName != 'STRONG')
     95                display = display.nextElementSibling;
    7696    if (elem) {
    7797        if (elem.nodeName == 'SELECT') {
    7898            var o = new Option(newRepr, newId);
    7999            elem.options[elem.options.length] = o;
    80100            o.selected = true;
    81101        } else if (elem.nodeName == 'INPUT') {
    82             if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
     102            if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1) {
    83103                elem.value += ',' + newId;
     104                var li = document.createElement('LI')
     105                                if( li.attachEvent ) {
     106                                        li.attachEvent('onclick', 'go_to(this,'+newId+')');
     107                                } else {
     108                                        li.setAttribute('onclick', 'go_to(this,'+newId+')');
     109                                }
     110                                li.innerHTML = newRepr+'<a class="related-clear" onclick="return clear_related(this,'+newId+')">X</a>';
     111                for (var i = 0; i < display.childNodes.length; i++)
     112                                        if (display.childNodes[i].tagName == 'UL') {
     113                                                display.childNodes[i].appendChild(li);
     114                                                break;
     115                                        }
    84116            } else {
    85117                elem.value = newId;
     118                        display.innerHTML = newRepr;
     119                                display.className = display.className;
    86120            }
    87121        }
    88122    } else {
     
    94128    }
    95129    win.close();
    96130}
     131
     132function go_to(el,id){
     133        if (id == null) {
     134                while(el.tagName != 'INPUT')
     135                        el = el.previousElementSibling;
     136                id = el.value;
     137        } else
     138                el = el.parentNode.parentNode;
     139        if ( id ) {
     140                while( el.className.indexOf('related-lookup') == -1 )
     141                        el = el.nextElementSibling;
     142                window.open(el.href.replace(/\?.*/,'')+id+'/', '_blank');
     143        }
     144}
     145
     146function clear_related(el,id){
     147        if ( id ){
     148                el=el.parentNode;
     149                while(el.tagName != 'LI')
     150                        el = el.parentNode;
     151                var tg = el.parentNode;
     152                tg.removeChild(el);
     153                while(tg.tagName != 'STRONG')
     154                        tg = tg.parentNode;
     155                while(tg.tagName != 'INPUT')
     156                        tg = tg.previousElementSibling;
     157                tg.value = clear_ids(tg.value.replace(id,'','g').split(','));
     158        } else {
     159                while(el.tagName != 'STRONG')
     160                        el = el.previousElementSibling;
     161                el.innerHTML = '';
     162                el.className = el.className;
     163                while(el.tagName != 'INPUT')
     164                        el = el.previousElementSibling;
     165                el.value = '';
     166        }
     167}
     168
     169function clear_ids(list){
     170        var new_list = [];
     171        for(var i in list)
     172                if (list[i] && new_list.indexOf(list[i]) == -1)
     173                        new_list.push(list[i]);
     174        return new_list;
     175}
  • contrib/admin/options.py

    diff -r -U 3 django.orig/contrib/admin/options.py django/contrib/admin/options.py
    old new  
    522522            for formset in formsets:
    523523                for added_object in formset.new_objects:
    524524                    change_message.append(_('Added %(name)s "%(object)s".')
    525                                           % {'name': added_object._meta.verbose_name,
     525                                          % {'name': force_unicode(added_object._meta.verbose_name),
    526526                                             'object': force_unicode(added_object)})
    527527                for changed_object, changed_fields in formset.changed_objects:
    528528                    change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
    529529                                          % {'list': get_text_list(changed_fields, _('and')),
    530                                              'name': changed_object._meta.verbose_name,
     530                                             'name': force_unicode(changed_object._meta.verbose_name),
    531531                                             'object': force_unicode(changed_object)})
    532532                for deleted_object in formset.deleted_objects:
    533533                    change_message.append(_('Deleted %(name)s "%(object)s".')
    534                                           % {'name': deleted_object._meta.verbose_name,
     534                                          % {'name': force_unicode(deleted_object._meta.verbose_name),
    535535                                             'object': force_unicode(deleted_object)})
    536536        change_message = ' '.join(change_message)
    537537        return change_message or _('No fields changed.')
  • contrib/admin/templatetags/admin_list.py

    diff -r -U 3 django.orig/contrib/admin/templatetags/admin_list.py django/contrib/admin/templatetags/admin_list.py
    old new  
    225225            value = result.serializable_value(attr)
    226226            result_id = repr(force_unicode(value))[1:]
    227227            yield mark_safe(u'<%s%s><a href="%s"%s>%s</a></%s>' % \
    228                 (table_tag, row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %s); return false;"' % result_id or ''), conditional_escape(result_repr), table_tag))
     228                (table_tag, row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %s, \'%s\'); return false;"' % (result_id or '',escape(result))), conditional_escape(result), table_tag))
    229229        else:
    230230            # By default the fields come from ModelAdmin.list_editable, but if we pull
    231231            # the fields out of the form instead of list_editable custom admins
  • contrib/admin/widgets.py

    diff -r -U 3 django.orig/contrib/admin/widgets.py django/contrib/admin/widgets.py
    old new  
    117117            url = ''
    118118        if not attrs.has_key('class'):
    119119            attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript looks for this hook.
     120        attrs['readonly'] = 1
    120121        output = [super(ForeignKeyRawIdWidget, self).render(name, value, attrs)]
     122        if value:
     123            tvalue = self.value_for_label(value)
     124        else:
     125            tvalue = ''
     126        output.append(self.label_for_tvalue(tvalue))
    121127        # TODO: "id_" is hard-coded here. This should instead use the correct
    122128        # API to determine the ID dynamically.
    123129        output.append('<a href="%s%s" class="related-lookup" id="lookup_id_%s" onclick="return showRelatedObjectLookupPopup(this);"> ' % \
    124130            (related_url, url, name))
    125131        output.append('<img src="%simg/admin/selector-search.gif" width="16" height="16" alt="%s" /></a>' % (settings.ADMIN_MEDIA_PREFIX, _('Lookup')))
    126         if value:
    127             output.append(self.label_for_value(value))
    128132        return mark_safe(u''.join(output))
    129133
    130134    def base_url_parameters(self):
     
    146150        params.update({TO_FIELD_VAR: self.rel.get_related_field().name})
    147151        return params
    148152
    149     def label_for_value(self, value):
     153    def value_for_label(self, value):
    150154        key = self.rel.get_related_field().name
    151155        obj = self.rel.to._default_manager.get(**{key: value})
    152         return '&nbsp;<strong>%s</strong>' % escape(truncate_words(obj, 14))
     156        return escape(truncate_words(obj, 14))
     157
     158    def label_for_tvalue(self, tvalue):
     159        return '&nbsp;<strong onClick="go_to(this);">%s</strong><a class="related-clear" onclick="return clear_related(this)" title="%s">X</a>' % (tvalue,_('Clear'))
    153160
    154161class ManyToManyRawIdWidget(ForeignKeyRawIdWidget):
    155162    """
     
    170177    def url_parameters(self):
    171178        return self.base_url_parameters()
    172179
    173     def label_for_value(self, value):
    174         return ''
     180    def value_for_label(self, value):
     181        result = ''
     182        key = self.rel.get_related_field().name
     183        for i in value.split(','):
     184            obj = self.rel.to._default_manager.get(**{key: int(i)})
     185            result += '<li onClick="go_to(this,%s);"><a class="related-clear" onclick="return clear_related(this,%s)" title="%s">X</a></li>' %(i,escape(truncate_words(obj, 14)),i,_('Clear'))
     186        return result
     187
     188    def label_for_tvalue(self, tvalue):
     189        return '&nbsp;<strong><ul>%s</ul></strong>' % tvalue
    175190
    176191    def value_from_datadict(self, data, files, name):
    177192        value = data.get(name, None)
Back to Top