Minor correction to EmbedWidget.js to handle window names with dashes.
[philo.git] / philo / static / philo / js / EmbedWidget.js
1 ;(function ($) {
2         var widget = window.embedWidget;
3         
4         widget = {
5                 options: {},
6                 optgroups: {},
7                 init: function () {
8                         var EmbedFields = widget.EmbedFields = $('.embedding'),
9                                 EmbedWidgets = widget.EmbedWidgets,
10                                 EmbedBars = widget.EmbedBars,
11                                 EmbedButtons = widget.EmbedButtons,
12                                 EmbedSelects = widget.EmbedSelects;
13
14                         EmbedFields.wrap($('<div class="embed-widget" />'));
15                         EmbedWidgets = $('.embed-widget');
16                         EmbedWidgets.prepend($('<div class="embed-toolbar" />'));
17                         EmbedBars = $('.embed-toolbar');
18                         EmbedBars.append('<select class="embed-select"></select><button class="embed-button">Embed</button>');
19                         EmbedButtons = $('.embed-button');
20                         EmbedSelects = $('.embed-select');
21                         
22                         widget.parseContentTypes();
23                         EmbedSelects.each(widget.populateSelect);
24                         
25                         EmbedButtons.click(widget.buttonHandler);
26                         
27                         // overload the dismissRelatedLookupPopup function
28                         oldDismissRelatedLookupPopup = window.dismissRelatedLookupPopup;
29                         window.dismissRelatedLookupPopup = function (win, chosenId) {
30                                 var name = windowname_to_id(win.name),
31                                         elem = $('#'+name), val;
32                                 // if the original element was an embed widget, run our script
33                                 if (elem.parent().hasClass('embed-widget')) {
34                                         contenttype = $('select',elem.parent()).val();
35                                         widget.appendEmbed(elem, contenttype, chosenId);
36                                         elem.focus();
37                                         win.close();
38                                         return;
39                                 }
40                                 // otherwise, do what you usually do
41                                 oldDismissRelatedLookupPopup.apply(this, arguments);
42                         }
43                         
44                         // overload the dismissAddAnotherPopup function
45                         oldDismissAddAnotherPopup = window.dismissAddAnotherPopup;
46                         window.dismissAddAnotherPopup = function (win, newId, newRepr) {
47                                 var name = windowname_to_id(win.name),
48                                         elem = $('#'+win.name), val;
49                                 if (elem.parent().hasClass('embed-widget')) {
50                                         dismissRelatedLookupPopup(win, newId);
51                                 }
52                                 // otherwise, do what you usually do
53                                 oldDismissAddAnotherPopup.apply(this, arguments);
54                         }
55                         
56                         // Add grappelli to the body class if the admin is grappelli. This will allow us to customize styles accordingly.
57                         if (window.grappelli) {
58                                 $(document.body).addClass('grappelli');
59                         }
60                 },
61                 parseContentTypes: function () {
62                         var string = widget.EmbedFields.eq(0).attr('data-content-types'),
63                                 data = $.parseJSON(string),
64                                 i=0,
65                                 current_app_label = '',
66                                 optgroups = {};
67                                 
68                                 // this loop relies on data being clustered by app
69                                 for(i=0; i < data.length; i++){
70                                         item = data[i]
71                                         // run this next loop every time we encounter a new app label
72                                         if (item.app_label !== current_app_label) {
73                                                 current_app_label = item.app_label;
74                                                 optgroups[current_app_label] = {}
75                                         }
76                                         optgroups[current_app_label][item.verbose_name] = [item.app_label,item.object_name].join('.');
77                                         
78                                         widget.optgroups = optgroups;
79                                 }
80                 },
81                 populateSelect: function () {
82                         var $this = $(this),
83                                 optgroups = widget.optgroups,
84                                 optgroup_els = {},
85                                 optgroup_el, group;
86                                 
87                         // append a title
88                         $this.append('<option value="">Media Types</option>');
89                         
90                         // for each group
91                         for (name in optgroups){
92                                 if(optgroups.hasOwnProperty(name)){
93                                         // assign the group to variable group, temporarily
94                                         group = optgroups[name];
95                                         // create an element for this group and assign it to optgroup_el, temporarily
96                                         optgroup_el = optgroup_els[name] = $('<optgroup label="'+name+'" />');
97                                         // append this element to the select menu
98                                         $this.append(optgroup_el);
99                                         // for each item in the group
100                                         for (name in group) {
101                                                 // append an option to the optgroup
102                                                 optgroup_el.append('<option value='+group[name]+'>'+name+'</option>');
103                                         }
104                                 }
105                         }
106                 },
107                 buttonHandler: function (e) {
108                         var $this = $(this),
109                                 select = $this.prev('select'),
110                                 embed_widget = $this.closest('.embed-widget'),
111                                 textarea = embed_widget.children('.embedding').eq(0),
112                                 val, app_label, object_name,
113                                 href,
114                                 win;
115                         
116                         // prevent the button from submitting the form
117                         e.preventDefault();
118                         
119                         // handle the case that they haven't chosen a type to embed
120                         if (select.val()==='') {
121                                 alert('Please select a media type to embed.');
122                                 textarea.focus();
123                                 return;
124                         }
125                         
126                         // split the val into app and object
127                         val = select.val();
128                         app_label = val.split('.')[0];
129                         object_name = val.split('.')[1];
130                         
131                         // generate the url for the popup
132                         // TODO: Find a better way to get the admin URL if possible. This will break if the URL patterns for the admin ever change.
133                         href=['../../../', app_label,  '/', object_name, '/?pop=1'].join('');
134                         
135                         // open a new window
136                         win = window.open(href, id_to_windowname(textarea.attr('id')), 'height=500,width=980,resizable=yes,scrollbars=yes');
137                 },
138                 appendEmbed: function (textarea, embed_type, embed_id) {
139                         var $textarea = $(textarea),
140                                 textarea = $textarea[0], // make sure we're *not* working with a jQuery object
141                                 current_selection = [textarea.selectionStart, textarea.selectionEnd],
142                                 current_text = $textarea.val(),
143                                 embed_string = ['{% embed', embed_type, embed_id, '%}'].join(' '),
144                                 new_text = current_text.substring(0, current_selection[0]) + embed_string + current_text.substring(current_selection[1]),
145                                 new_cursor_pos = current_selection[0]+embed_string.length;
146                         $textarea.val(new_text);
147                         textarea.setSelectionRange(new_cursor_pos, new_cursor_pos);
148                 }
149         }
150         
151         $(widget.init);
152 }(django.jQuery));