1 dojo.require("dojo.dnd.Container");
2 dojo.require("dojo.dnd.Source");
3 dojo.require('openils.widget.AutoGrid');
4 dojo.require('dijit.form.FilteringSelect');
5 dojo.require('openils.PermaCrud');
6 dojo.require('openils.widget.AutoFieldWidget');
7 dojo.requireLocalization('openils.conify', 'conify');
8 var localeStrings = dojo.i18n.getLocalization('openils.conify', 'conify');
12 var formula, entryTbody, entryTemplate, dndSource;
15 var _collection_code_textboxes = [];
16 var _collection_code_kludge_active = false;
17 var fundSearchFilter = {active : 't'};
18 var fundLabelFormat = ['${0} (${1})', 'code', 'year'];
20 function gridDataLoader() {
21 fListGrid.resetStore();
22 fListGrid.showLoadProgressIndicator();
23 fieldmapper.standardRequest(
24 ["open-ils.acq", "open-ils.acq.distribution_formula.ranged.retrieve"], {
27 openils.User.authtoken,
28 fListGrid.displayOffset,
29 fListGrid.displayLimit
31 "onresponse": function(r) {
32 var form = openils.Util.readResponse(r);
33 formCache[form.id()] = form;
34 fListGrid.store.newItem(form.toStoreItem());
36 "oncomplete": function() {
37 fListGrid.hideLoadProgressIndicator();
43 function setFundSearchFilter(callback) {
44 new openils.User().getPermOrgList(
45 ['ADMIN_ACQ_DISTRIB_FORMULA'],
47 fundSearchFilter.org = orgs;
48 if (callback) callback();
50 true, true // descendants, id_list
56 pcrud = new openils.PermaCrud();
59 openils.Util.hide('formula-list-div');
60 setFundSearchFilter(drawFormulaSummary);
63 openils.Util.hide('formula-entry-div');
64 fListGrid.onPostCreate = function(fmObject) {
65 location.href = location.href + '/' + fmObject.id();
68 fListGrid.dataLoader = gridDataLoader;
73 function cloneSelectedFormula() {
74 var item = fListGrid.getSelectedItems()[0];
76 var formula = new fieldmapper.acqf().fromStoreItem(item);
77 fieldmapper.standardRequest(
78 ['open-ils.acq', 'open-ils.acq.distribution_formula.clone'],
82 openils.User.authtoken,
84 dojo.string.substitute(localeStrings.ACQ_DISTRIB_FORMULA_NAME_CLONE, [formula.name()])
86 oncomplete : function(r) {
87 if(r = openils.Util.readResponse(r)) {
88 location.href = oilsBasePath + '/conify/global/acq/distribution_formula/' + r;
95 openils.Util.addOnLoad(draw);
97 function getItemCount(rowIndex, item) {
99 var form = formCache[this.grid.store.getValue(item, "id")];
102 dojo.forEach(form.entries(), function(e) { count = count + e.item_count(); });
106 function byName(node, name) {
107 return dojo.query('[name='+name+']', node)[0];
110 function drawFormulaSummary() {
111 openils.Util.show('formula-entry-div');
113 var entries = pcrud.search('acqdfe', {formula: formulaId}, {order_by:{acqdfe : 'position'}});
114 formula = pcrud.retrieve('acqdf', formulaId);
115 formula.entries(entries);
117 dojo.byId('formula_head').innerHTML = formula.name();
118 dojo.byId('formula_head').onclick = function() {
119 var name = prompt(localeStrings.ACQ_DISTRIB_FORMULA_NAME_PROMPT, formula.name());
120 if(name && name != formula.name()) {
122 pcrud = new openils.PermaCrud();
123 pcrud.update(formula);
124 dojo.byId('formula_head').innerHTML = name;
128 dojo.forEach(entries, function(entry) { addEntry(entry); } );
131 function addEntry(entry) {
134 entryTbody = dojo.byId('formula-entry-tbody');
135 entryTemplate = entryTbody.removeChild(dojo.byId('formula-entry-tempate'));
136 dndSource = new dojo.dnd.Source(entryTbody);
137 dndSource.selectAll();
138 dndSource.deleteSelectedNodes();
139 dndSource.clearItems();
143 entry = new fieldmapper.acqdfe();
144 entry.formula(formulaId);
146 entry.owning_lib(openils.User.user.ws_ou());
147 entry.id(virtualId--);
149 formula.entries().push(entry);
152 var row = entryTbody.appendChild(entryTemplate.cloneNode(true));
153 row.setAttribute('entry', entry.id());
154 dndSource.insertNodes(false, [row]);
155 byName(row, 'delete').onclick = function() {
156 entry.isdeleted(true);
157 entryTbody.removeChild(row);
162 ['owning_lib', 'location', 'fund', 'circ_modifier', 'collection_code', 'item_count'],
164 new openils.widget.AutoFieldWidget({
169 labelFormat: (field == 'fund') ? fundLabelFormat : null,
170 searchFormat: (field == 'fund') ? fundLabelFormat : null,
171 searchFilter : (field == 'fund') ? fundSearchFilter : null,
172 parentNode : byName(row, field),
173 orgDefaultsToWs : true,
174 orgLimitPerms : ['ADMIN_ACQ_DISTRIB_FORMULA'],
175 widgetClass : (field == 'item_count') ? 'dijit.form.NumberSpinner' : null,
176 dijitArgs : (field == 'item_count') ? {min:1, places:0} : null
179 if (field == "collection_code") {
180 /* kludge for glitchy textbox */
181 _collection_code_textboxes.push(w);
183 dojo.connect(w, 'onChange',
185 entry[field]( newVal );
186 entry.ischanged(true);
194 /* For some reason (bug) the dndSource intercepts onMouseDown events
195 * that should hit dijit textboxes in our table thingy. Other dijits
196 * (buttons, filteringselects, etc) seem not to be affected. This
197 * workaround deals with the only textboxes we have for now: the ones
198 * for the collection_code field. */
199 if (!_collection_code_kludge_active) {
200 _collection_code_kludge_active = true;
201 var original = dojo.hitch(dndSource, dndSource.onMouseDown);
202 dndSource.onMouseDown = function(e) {
203 var hits = _collection_code_textboxes.filter(
205 var c = dojo.coords(w.domNode);
206 if (e.clientX >= c.x && e.clientX < c.x + c.w) {
207 if (e.clientY >= c.y && e.clientY < c.y + c.h) {
224 function saveFormula() {
226 var updatedEntries = [];
227 var deletedEntries = [];
229 // remove deleted entries from consideration for collision protection
230 for(var i = 0; i < formula.entries().length; i++) {
231 if(formula.entries()[i].isdeleted())
232 deletedEntries.push(formula.entries().splice(i--, 1)[0])
235 // update entry positions and create temporary collision avoidance entries
237 dndSource.getAllNodes(),
240 var entryId = node.getAttribute('entry');
241 var entry = formula.entries().filter(function(e) {return (e.id() == entryId)})[0];
243 if(entry.position() != pos) {
245 // update the position
246 var changedEntry = entry.clone();
247 changedEntry.position(pos);
248 changedEntry.ischanged(true);
249 updatedEntries.push(changedEntry);
251 // clear the virtual ID
252 if(changedEntry.isnew())
253 changedEntry.id(null);
255 var oldEntry = formula.entries().filter(function(e) {return (e.position() == pos)})[0];
258 // move the entry currently in that spot temporarily into negative territory
259 var moveMe = oldEntry.clone();
260 moveMe.ischanged(true);
261 moveMe.position(moveMe.position() * -1);
262 updatedEntries.unshift(moveMe);
269 // finally, for every entry that changed w/o changing position
270 // throw it on the list for update
274 if(entry.ischanged() && !entry.isdeleted() && !entry.isnew()) {
275 if(updatedEntries.filter(function(e) { return (e.id() == entry.id()) }).length == 0)
276 updatedEntries.push(entry);
281 updatedEntries = deletedEntries.concat(updatedEntries);
282 if(updatedEntries.length) {
283 pcrud = new openils.PermaCrud();
285 pcrud.apply(updatedEntries);
287 alert('error updating: ' + E);
290 location.href = location.href;