1 /*global SelectBox, interpolate*/
2 // Handles related-objects functionality: lookup link for raw_id_fields
3 // and Add Another links.
8 // IE doesn't accept periods or dashes in the window name, but the element IDs
9 // we use to generate popup window names may contain them, therefore we map them
10 // to allowed characters in a reversible way so that we can locate the correct
11 // element when the popup window is dismissed.
12 function id_to_windowname(text) {
13 text = text.replace(/\./g, '__dot__');
14 text = text.replace(/\-/g, '__dash__');
18 function windowname_to_id(text) {
19 text = text.replace(/__dot__/g, '.');
20 text = text.replace(/__dash__/g, '-');
24 function showAdminPopup(triggeringLink, name_regexp, add_popup) {
25 var name = triggeringLink.id.replace(name_regexp, '');
26 name = id_to_windowname(name);
27 var href = triggeringLink.href;
29 if (href.indexOf('?') === -1) {
35 var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
40 function showRelatedObjectLookupPopup(triggeringLink) {
41 return showAdminPopup(triggeringLink, /^lookup_/, true);
44 function dismissRelatedLookupPopup(win, chosenId) {
45 var name = windowname_to_id(win.name);
46 var elem = document.getElementById(name);
47 if (elem.className.indexOf('vManyToManyRawIdAdminField') !== -1 && elem.value) {
48 elem.value += ',' + chosenId;
50 document.getElementById(name).value = chosenId;
55 function showRelatedObjectPopup(triggeringLink) {
56 return showAdminPopup(triggeringLink, /^(change|add|delete)_/, false);
59 function updateRelatedObjectLinks(triggeringLink) {
60 var $this = $(triggeringLink);
61 var siblings = $this.nextAll('.change-related, .delete-related');
62 if (!siblings.length) {
65 var value = $this.val();
67 siblings.each(function() {
69 elm.attr('href', elm.attr('data-href-template').replace('__fk__', value));
72 siblings.removeAttr('href');
76 function dismissAddRelatedObjectPopup(win, newId, newRepr) {
77 var name = windowname_to_id(win.name);
78 var elem = document.getElementById(name);
80 var elemName = elem.nodeName.toUpperCase();
81 if (elemName === 'SELECT') {
82 elem.options[elem.options.length] = new Option(newRepr, newId, true, true);
83 } else if (elemName === 'INPUT') {
84 if (elem.className.indexOf('vManyToManyRawIdAdminField') !== -1 && elem.value) {
85 elem.value += ',' + newId;
90 // Trigger a change event to update related links if required.
91 $(elem).trigger('change');
93 var toId = name + "_to";
94 var o = new Option(newRepr, newId);
95 SelectBox.add_to_cache(toId, o);
96 SelectBox.redisplay(toId);
101 function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) {
102 var id = windowname_to_id(win.name).replace(/^edit_/, '');
103 var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
104 var selects = $(selectsSelector);
105 selects.find('option').each(function() {
106 if (this.value === objId) {
107 this.textContent = newRepr;
114 function dismissDeleteRelatedObjectPopup(win, objId) {
115 var id = windowname_to_id(win.name).replace(/^delete_/, '');
116 var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
117 var selects = $(selectsSelector);
118 selects.find('option').each(function() {
119 if (this.value === objId) {
122 }).trigger('change');
126 // Global for testing purposes
127 window.id_to_windowname = id_to_windowname;
128 window.windowname_to_id = windowname_to_id;
130 window.showRelatedObjectLookupPopup = showRelatedObjectLookupPopup;
131 window.dismissRelatedLookupPopup = dismissRelatedLookupPopup;
132 window.showRelatedObjectPopup = showRelatedObjectPopup;
133 window.updateRelatedObjectLinks = updateRelatedObjectLinks;
134 window.dismissAddRelatedObjectPopup = dismissAddRelatedObjectPopup;
135 window.dismissChangeRelatedObjectPopup = dismissChangeRelatedObjectPopup;
136 window.dismissDeleteRelatedObjectPopup = dismissDeleteRelatedObjectPopup;
138 // Kept for backward compatibility
139 window.showAddAnotherPopup = showRelatedObjectPopup;
140 window.dismissAddAnotherPopup = dismissAddRelatedObjectPopup;
142 $(document).ready(function() {
143 $("a[data-popup-opener]").click(function(event) {
144 event.preventDefault();
145 opener.dismissRelatedLookupPopup(window, $(this).data("popup-opener"));
147 $('body').on('click', '.related-widget-wrapper-link', function(e) {
150 var event = $.Event('django:show-related', {href: this.href});
151 $(this).trigger(event);
152 if (!event.isDefaultPrevented()) {
153 showRelatedObjectPopup(this);
157 $('body').on('change', '.related-widget-wrapper select', function(e) {
158 var event = $.Event('django:update-related');
159 $(this).trigger(event);
160 if (!event.isDefaultPrevented()) {
161 updateRelatedObjectLinks(this);
164 $('.related-widget-wrapper select').trigger('change');
165 $('.related-lookup').click(function(e) {
167 var event = $.Event('django:lookup-related');
168 $(this).trigger(event);
169 if (!event.isDefaultPrevented()) {
170 showRelatedObjectLookupPopup(this);