2 <!-- Application: Evergreen Staff Client -->
3 <!-- Screen: Serial Notes -->
8 <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
10 <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
11 <?xml-stylesheet href="chrome://open_ils_staff_client/skin/global.css" type="text/css"?>
12 <?xml-stylesheet href="/xul/server/skin/global.css" type="text/css"?>
13 <?xml-stylesheet href="/xul/server/skin/patron_display.css" type="text/css"?>
15 <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
17 <!DOCTYPE window PUBLIC "" ""[
18 <!--#include virtual="/opac/locale/${locale}/lang.dtd"-->
21 <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
23 <?xul-overlay href="/xul/server/OpenILS/util_overlay.xul"?>
25 <window id="notes_win" width="700" height="550" oils_persist="height width sizemode"
26 onload="try{ my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
27 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
29 <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
31 <script type="text/javascript">var myPackageDir = 'open_ils_staff_client'; var IAMXUL = true; var g = {};</script>
32 <scripts id="openils_util_scripts"/>
34 <script type="text/javascript" src="/xul/server/main/JSAN.js"/>
38 function $(id) { return document.getElementById(id); }
42 if (typeof JSAN == 'undefined') {
43 throw( $("commonStrings").getString('common.jsan.missing') );
45 JSAN.errorLevel = "die"; // none, warn, or die
46 JSAN.addRepository('/xul/server/');
48 JSAN.use('util.error'); g.error = new util.error();
49 JSAN.use('util.network'); g.network = new util.network();
50 JSAN.use('util.date'); JSAN.use('util.money');
51 JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.init({'via':'stash'});
53 g.error.sdump('D_TRACE','my_init() for notes.xul');
55 g.notes = xul_param('notes');
56 g.disable_create = xul_param('disable_create');
57 // in the code below, by default, function_type and
58 // fm_type (aka classname) are assumed the same other
60 if (g.notes) { // we have the notes passed in
61 g.function_type_map = xul_param('function_type_map');
62 if (!g.function_type_map) { // didn't get one, build one
63 g.function_type_map = {};
64 for (i = 0; i < g.notes.length; i++) {
65 g.function_type_map[g.notes[i].classname] = g.notes[i].classname.toUpperCase();
68 g.section_titles = xul_param('section_titles');
69 g.section_id_names = xul_param('section_id_names');
70 } else { // we need to retreieve the notes
71 g.object_type = xul_param('object_type');
72 g.object_id = xul_param('object_id');
73 function_type = xul_param('function_type');
74 g.fm_type = xul_param('fm_type');
76 g.fm_type = function_type.toLowerCase();
78 g.function_type = function_type;
79 g.function_type_map = {};
80 g.function_type_map[g.fm_type] = function_type;
81 g.constructor = xul_param('constructor');
84 var window_title = xul_param('title',{'modal_xulG':true});
86 try { document.title = window_title; } catch(E) {}
92 var err_msg = $("commonStrings").getFormattedString('common.exception', ['serial/notes.xul', js2JSON(E)]);
93 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
99 retrieve_notes(); render_notes();
102 function retrieve_notes() {
104 g.notes = g.network.simple_request(
105 'FM_' + g.function_type_map[g.fm_type] + '_RETRIEVE_ALL', [
106 { 'authtoken' : ses(), 'object_id' : g.object_id }
111 function apply(node,field,value) {
116 case 'description' : n.appendChild( document.createTextNode( value ) ); break;
117 case 'image' : n.src = value; break;
118 default : n.value = value; break;
124 function render_notes() {
125 JSAN.use('util.widgets'); util.widgets.remove_children('notes_panel');
126 var np = $('notes_panel');
127 if (!g.disable_create) {
128 var hbox = document.createElement('hbox'); np.appendChild(hbox);
129 var btn = document.createElement('button'); hbox.appendChild(btn);
130 btn.setAttribute('label', $('catStrings').getString('staff.cat.copy_notes.render_notes.label'));
131 btn.setAttribute('accesskey', $('catStrings').getString('staff.cat.copy_notes.render_notes.accesskey'));
132 btn.setAttribute('oncommand','new_note()');
135 var hb; // keep button bar reference for adding close button
138 var section_indices = {};
139 for (var i = 0; i < g.notes.length; i++) {
140 var note = g.notes[i];
142 if (g.section_titles) {
143 if (note.classname != section_type || note[g.section_id_names[note.classname]]() != section_id) {
144 section_type = note.classname;
145 if (!(section_type in section_indices)) {
146 section_indices[section_type] = 0;
148 section_indices[section_type]++;
150 var section_title = g.section_titles[section_type][section_indices[section_type]];
151 section_id = note[g.section_id_names[section_type]]();
153 // add the title to the window
154 var hbox = document.createElement('hbox');
155 np.appendChild(hbox);
156 var desc = document.createElement('description');
157 desc.appendChild(document.createTextNode(section_title));
158 hbox.appendChild(desc);
163 var node = $('note_template').cloneNode(true); np.appendChild(node); node.hidden = false;
164 apply(node,'create_date',note.create_date().toString().substr(0,10));
165 util.widgets.apply(node,'name','create_date',
169 $('catStrings').getString('staff.cat.copy_notes.widgets_apply.note_id') + " "
171 + $('catStrings').getString('staff.cat.copy_notes.widgets_apply.creator_id') + " "
176 apply(node,'title',note.title());
177 apply(node,'pub',get_bool( g.notes[i].pub() ) ? $('catStrings').getString('staff.cat.copy_notes.widgets.public') : $('catStrings').getString('staff.cat.copy_notes.widgets.private'));
178 apply(node,'alert',get_bool( g.notes[i].alert() ) ? '/xul/server/skin/media/images/bell.png' : '');
179 apply(node,'value',g.notes[i].value());
180 apply(node,'id',g.notes[i].id());
181 apply(node,'creator',g.notes[i].creator());
184 hb = document.createElement('hbox'); np.appendChild(hb);
185 var btn0 = document.createElement('button'); hb.appendChild(btn0);
186 btn0.setAttribute('label', $('serialStrings').getString('staff.serial.notes.do_edit_note.label'));
187 btn0.setAttribute('image',"/xul/server/skin/media/images/up_arrow.gif");
189 btn0.addEventListener(
191 function(index){ return function() { new_note(index) } }(i),
194 var btn1 = document.createElement('button'); hb.appendChild(btn1);
195 btn1.setAttribute('label', $('catStrings').getString('staff.cat.copy_notes.delete_note.label'));
196 btn1.setAttribute('image',"/xul/server/skin/media/images/up_arrow.gif");
198 btn1.addEventListener(
200 function(index){ return function() {
201 var r = g.error.yns_alert(
202 $('catStrings').getFormattedString('staff.cat.copy_notes.delete_note.prompt.msg', [g.notes[index].title(), g.notes[index].create_date().toString().substr(0,10)]),
203 $('catStrings').getString('staff.cat.copy_notes.delete_note.prompt.title'),
204 $('catStrings').getString('staff.cat.copy_notes.delete_note.prompt.yes'),
205 $('catStrings').getString('staff.cat.copy_notes.delete_note.prompt.no'),
207 $('commonStrings').getString('common.confirm')
210 g.network.simple_request('FM_'+g.function_type_map[g.notes[index].classname]+'_DELETE',[ses(),g.notes[index].id()]);
211 g.notes.splice(index, 1);
212 setTimeout(function() {
213 alert($('catStrings').getString('staff.cat.copy_notes.delete_note.success'));
216 if(!xulG.notes_updated) xulG.notes_updated = {};
217 xulG.notes_updated[g.notes[index].classname] = 1;
225 if (!hb) { // no notes yet, fill the space and add a bar
226 var spacer = document.createElement('spacer'); np.appendChild(spacer); spacer.flex = 1;
227 hb = document.createElement('hbox'); np.appendChild(hb);
229 var spacer = document.createElement('spacer');
230 hb.appendChild(spacer); spacer.flex = 1;
231 var btn2 = document.createElement('button'); hb.appendChild(btn2);
232 btn2.setAttribute('label', $('catStrings').getString('staff.cat.copy_notes.delete_note.close_window'));
233 btn2.setAttribute('oncommand','window.close();');
237 function xml_encode(str) {
238 return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
241 function new_note(index) {
246 var edit_mode; // for clarity
248 var button_accesskey;
250 if (typeof index != 'undefined') {
252 public = get_bool(g.notes[index].pub());
253 alert = get_bool(g.notes[index].alert());
254 title = xml_encode(g.notes[index].title());
255 value = xml_encode(g.notes[index].value());
256 label_text = $('serialStrings').getString('staff.serial.notes.edit_note.label');
257 button_accesskey = $('serialStrings').getString('staff.serial.notes.edit_note.accesskey');
259 label_text = $('catStrings').getString('staff.cat.copy_notes.new_note.add_note.label');
260 button_accesskey = $('catStrings').getString('staff.cat.copy_notes.new_note.add_note.accesskey');
264 value = value.replace(/\n/g, " "); // preserve newlines
265 var xml = '<groupbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1"> \
266 <caption label="' + label_text + '"/> \
267 <grid flex="1"><columns><column/><column flex="1"/></columns> \
269 <row><label value="' + $('catStrings').getString('staff.cat.copy_notes.new_note.public') + '"/><checkbox id="pub" name="fancy_data" checked="' + public + '"/></row> \
270 <row><label value="' + fieldmapper.IDL.fmclasses[g.notes[index].classname].field_map.alert.label + '"/><checkbox id="alert" name="fancy_data" checked="' + alert + '"/></row> \
271 <row><label value="' + $('catStrings').getString('staff.cat.copy_notes.new_note.title') + '"/><textbox id="title" name="fancy_data" context="clipboard" value="' + title + '"/></row> \
272 <row><label value="' + $('catStrings').getString('staff.cat.copy_notes.new_note.note') + '"/><textbox multiline="true" id="note" name="fancy_data" context="clipboard" value="' + value + '"/></row> \
273 <row><spacer/><hbox> \
274 <button label="' + $('catStrings').getString('staff.cat.copy_notes.new_note.cancel.label') + '" name="fancy_cancel" accesskey="' + $('catStrings').getString('staff.cat.copy_notes.new_note.cancel.accesskey') + '"/> \
275 <button label="' + label_text + '" accesskey="' + button_accesskey + '" name="fancy_submit"/></hbox></row> \
276 </rows></grid></groupbox>';
277 JSAN.use('util.window'); var win = new util.window();
278 var fancy_prompt_data = win.open(
279 urls.XUL_FANCY_PROMPT,
280 'fancy_prompt', 'chrome,resizable,modal,width=700,height=500',
281 { 'xml' : xml, 'focus' : 'title', 'title' : label_text }
283 if (fancy_prompt_data.fancy_status == 'complete') {
286 note = g.notes[index];
288 note = new g.constructor();
290 note[g.object_type]( g.object_id );
292 note.title( fancy_prompt_data.title );
293 note.value( fancy_prompt_data.note );
294 note.pub( get_bool( fancy_prompt_data.pub ) ? get_db_true() : get_db_false() );
295 note.alert( get_bool( fancy_prompt_data.alert ) ? get_db_true() : get_db_false() );
296 var r = g.network.simple_request('FM_'+g.function_type_map[note.classname]+'_UPDATE',[ ses(), note ]);
297 if (typeof r.ilsevent != 'undefined') throw(r);
298 // not every note type support pcrud, so we can't do this
299 // for now, if they pass in a pile of notes (g.notes mode),
300 // they simply won't be able to add notes
301 // One alternative would be to teach the UPDATE functions
302 // to send back the updated note objects
304 if (!edit_mode) { // fetch new note and add to pile
305 note = g.network.request(
307 'open-ils.pcrud.retrieve.' + note.classname,
313 if (!edit_mode) { // force re-fetch of notes
316 if(!xulG.notes_updated) xulG.notes_updated = {};
317 xulG.notes_updated[note.classname] = 1;
318 setTimeout(function() {
323 g.error.standard_unexpected_error_alert($('catStrings').getString('staff.cat.copy_notes.new_note.error'),E);
330 <messagecatalog id="catStrings" src="/xul/server/locale/<!--#echo var='locale'-->/cat.properties" />
331 <messagecatalog id="serialStrings" src="/xul/server/locale/<!--#echo var='locale'-->/serial.properties" />
333 <stack hidden="true" id="note_template" flex="1">
334 <vbox flex="1" style="background-color: black; margin:3px"/>
335 <vbox flex="1" style="background-color: #FFDE00; -moz-border-radius-topright: 35px; border: 2px groove ThreeDFace; margin:3px;" >
337 <description name="title" style="font-weight: bold"/>
339 <description name="create_date" style="font-weight: bold"/>
340 <description name="pub" style="font-weight: bold"/>
341 <image name="alert" src=""/>
343 <description style="white-space: pre-wrap;" name="value"/>
347 <vbox flex="1" class="my_overflow" id="notes_panel">