/* The FlattenerStore doesn't need this, but it has at least two
* uses: 1) FlattenerFilterDialog, 2) setting column header labels
- * to IDL defaults. */
+ * to IDL defaults.
+ *
+ * To call these 'Terminii' can be misleading. In certain
+ * (actually probably common) cases, they won't really be the last
+ * field in a path, but the next-to-last. Read on. */
"_calculateMapTerminii": function() {
- function _fm_get_field_def(hint, field) {
- /* XXX this assumes we have the whole IDL loaded. I guess
- * we could teach this to work by loading classes on demand
- * when we don't have the whole IDL loaded. */
- return fieldmapper.IDL.fmclasses[hint].fields.filter(
- function(f) { return f.name == field; }
- ).shift();
+ function _fm_is_selector_for_class(hint, field) {
+ var cl = fieldmapper.IDL.fmclasses[hint];
+ return (cl.field_map[cl.pkey].selector == field);
}
function _follow_to_end(hint, path) {
+ var last_field, last_hint;
+ var orig_path = dojo.clone(path);
+ var field;
+
while (field = path.shift()) {
- var field_def = _fm_get_field_def(hint, field);
- if (field_def["class"])
+ /* XXX this assumes we have the whole IDL loaded. I
+ * guess we could teach this to work by loading classes
+ * on demand when we don't have the whole IDL loaded. */
+ var field_def =
+ fieldmapper.IDL.fmclasses[hint].field_map[field];
+
+ if (field_def["class"] && path.length) {
+ last_field = field;
+ last_hint = hint;
+
hint = field_def["class"];
- else
- break;
+ } else if (path.length) {
+ /* There are more fields left but we can't follow
+ * the chain via IDL any further. */
+ throw new Error(
+ "_calculateMapTerminii can't parse path " +
+ orig_path + " (at " + field + ")"
+ );
+ } else {
+ break; /* keeps field defined after loop */
+ }
+ }
+
+ var datatype = field_def.datatype;
+ /* Back off the last field in the path if it's a selector
+ * for its class, because the preceding field will be
+ * a better thing to hand to AutoFieldWidget.
+ */
+ if (orig_path.length > 1 &&
+ _fm_is_selector_for_class(hint, field)) {
+ hint = last_hint;
+ field = last_field;
+ datatype = "link";
}
return {
"fmClass": hint,
"name": field,
"label": field_def.label,
- "datatype": field_def.datatype
+ "datatype": datatype
};
}
this.mapTerminii.push(terminus);
}
+ console.log(dojo.toJson(this.mapTerminii));
},
"_supplementHeaderNames": function() {
function PCrudFilterRowManager() {
var self = this;
- this._init = function(container, field_store, fm_class) {
+ this._init = function(container, field_store, fm_class, indirect) {
this.container = container;
this.field_store = field_store;
this.fm_class = fm_class;
this.rows = {};
this.row_index = 0;
+ /* 'indirect' is really for FlattenerFilterDialog */
+ this.indirect = indirect || false;
+
this._build_table();
};
this.compile = function() {
if (this.value_widgets) {
var values = this.value_widgets.map(
- function(widg) { return widg.getFormattedValue(); }
+ function(widg) {
+ return widg[
+ self.filter_row_manager.indirect && widg.linkClass ?
+ "getDisplayString" : "getFormattedValue"
+ ]();
+ }
);
if (!values.length) {
[dijit.Dialog, openils.widget.AutoWidget],
{
+ "indirect": false,
+
constructor : function(args) {
for(var k in args)
this[k] = args[k];
this.filter_row_manager = new PCrudFilterRowManager(
dojo.create("div", {}, this.domNode),
- this.fieldStore, this.fmClass
+ this.fieldStore, this.fmClass, this.indirect
);
this._buildButtons();