solid-ui 2.4.22-dc624c1d → 2.4.22-dc79c0e3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -44,6 +44,7 @@ exports.findClosest = findClosest;
44
44
  exports.formsFor = formsFor;
45
45
  exports.makeDescription = makeDescription;
46
46
  exports.makeSelectForCategory = makeSelectForCategory;
47
+ exports.makeSelectForChoice = makeSelectForChoice;
47
48
  exports.makeSelectForNestedCategory = makeSelectForNestedCategory;
48
49
  exports.makeSelectForOptions = makeSelectForOptions;
49
50
  exports.newButton = newButton;
@@ -93,6 +94,8 @@ var _solidLogic = require("solid-logic");
93
94
 
94
95
  var utils = _interopRequireWildcard(require("../utils"));
95
96
 
97
+ var _multiSelect = require("./multiSelect");
98
+
96
99
  var widgets = _interopRequireWildcard(require("../widgets"));
97
100
 
98
101
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
@@ -155,14 +158,16 @@ _fieldFunction.field[ns.ui('Form').uri] = _fieldFunction.field[ns.ui('Group').ur
155
158
  var ui = ns.ui;
156
159
  if (container) container.appendChild(box); // Prevent loops
157
160
 
161
+ if (!form) return;
158
162
  var key = subject.toNT() + '|' + form.toNT();
159
163
 
160
164
  if (already[key]) {
161
165
  // been there done that
162
- box.appendChild(dom.createTextNode('Group: see above ' + key));
163
- var plist = [$rdf.st(subject, ns.owl('sameAs'), subject)]; // @@ need prev subject
166
+ box.appendChild(dom.createTextNode('Group: see above ' + key)); // TODO fix dependency cycle to solid-panes by calling outlineManager
167
+ // const plist = [$rdf.st(subject, ns.owl('sameAs'), subject)] // @@ need prev subject
168
+ // dom.outlineManager.appendPropertyTRs(box, plist)
169
+ // dom.appendChild(plist)
164
170
 
165
- dom.outlineManager.appendPropertyTRs(box, plist);
166
171
  return box;
167
172
  }
168
173
 
@@ -263,47 +268,43 @@ _fieldFunction.field[ns.ui('Options').uri] = function (dom, container, already,
263
268
  values = kb.each(subject, dependingOn);
264
269
  }
265
270
 
266
- if (values.length === 0) {
267
- box.appendChild((0, _error.errorMessageBlock)(dom, "Can't select subform as no value of: " + dependingOn));
268
- } else {
269
- for (var i = 0; i < cases.length; i++) {
270
- var c = cases[i];
271
- var tests = kb.each(c, ui('for'), null, formDoc); // There can be multiple 'for'
271
+ for (var i = 0; i < cases.length; i++) {
272
+ var c = cases[i];
273
+ var tests = kb.each(c, ui('for'), null, formDoc); // There can be multiple 'for'
272
274
 
273
- var match = false;
275
+ var match = false;
274
276
 
275
- for (var j = 0; j < tests.length; j++) {
276
- var _iterator = _createForOfIteratorHelper(values),
277
- _step;
277
+ for (var j = 0; j < tests.length; j++) {
278
+ var _iterator = _createForOfIteratorHelper(values),
279
+ _step;
278
280
 
279
- try {
280
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
281
- var value = _step.value;
282
- var test = tests[j];
281
+ try {
282
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
283
+ var value = _step.value;
284
+ var test = tests[j];
283
285
 
284
- if (value.sameTerm(tests) || value.termType === test.termType && value.value === test.value) {
285
- match = true;
286
- }
286
+ if (value.sameTerm(tests) || value.termType === test.termType && value.value === test.value) {
287
+ match = true;
287
288
  }
288
- } catch (err) {
289
- _iterator.e(err);
290
- } finally {
291
- _iterator.f();
292
289
  }
290
+ } catch (err) {
291
+ _iterator.e(err);
292
+ } finally {
293
+ _iterator.f();
293
294
  }
295
+ }
294
296
 
295
- if (match) {
296
- var _field3 = kb.the(c, ui('use'));
297
+ if (match) {
298
+ var _field3 = kb.the(c, ui('use'));
297
299
 
298
- if (!_field3) {
299
- box.appendChild((0, _error.errorMessageBlock)(dom, 'No "use" part for case in form ' + form));
300
- return box;
301
- } else {
302
- appendForm(dom, box, already, subject, _field3, dataDoc, callbackFunction);
303
- }
304
-
305
- break;
300
+ if (!_field3) {
301
+ box.appendChild((0, _error.errorMessageBlock)(dom, 'No "use" part for case in form ' + form));
302
+ return box;
303
+ } else {
304
+ appendForm(dom, box, already, subject, _field3, dataDoc, callbackFunction);
306
305
  }
306
+
307
+ break;
307
308
  }
308
309
  } // @@ Add box.refresh() to sync fields with values
309
310
 
@@ -591,7 +592,7 @@ _fieldFunction.field[ns.ui('Multiple').uri] = function (dom, container, already,
591
592
  // delete button and move buttons
592
593
 
593
594
  if (kb.updater.editable(dataDoc.uri)) {
594
- buttons.deleteButtonWithCheck(dom, subField, utils.label(property), deleteThisItem);
595
+ buttons.deleteButtonWithCheck(dom, subField, multipleUIlabel, deleteThisItem);
595
596
 
596
597
  if (ordered) {
597
598
  // Add controsl in a frame
@@ -642,7 +643,7 @@ _fieldFunction.field[ns.ui('Multiple').uri] = function (dom, container, already,
642
643
 
643
644
  var _shim = dom.createElement('div');
644
645
 
645
- _shim.appendChild(subField); // Subfield has its own laytout
646
+ _shim.appendChild(subField); // Subfield has its own layout
646
647
 
647
648
 
648
649
  frame.appendChild(_shim);
@@ -691,6 +692,8 @@ _fieldFunction.field[ns.ui('Multiple').uri] = function (dom, container, already,
691
692
  return shim;
692
693
  }
693
694
 
695
+ var multipleUIlabel = kb.any(form, ui('label'));
696
+ if (!multipleUIlabel) multipleUIlabel = utils.label(property);
694
697
  var min = kb.any(form, ui('min')); // This is the minimum number -- default 0
695
698
 
696
699
  min = min ? 0 + min.value : 0;
@@ -731,10 +734,9 @@ _fieldFunction.field[ns.ui('Multiple').uri] = function (dom, container, already,
731
734
  img.setAttribute('src', plusIconURI); // plus sign
732
735
 
733
736
  img.setAttribute('style', 'margin: 0.2em; width: 1.5em; height:1.5em');
734
- img.title = 'Click to add one or more ' + utils.predicateLabel(property, reverse);
735
- var prompt = tail.appendChild(dom.createElement('span'));
736
- prompt.textContent = (values.length === 0 ? 'Add one or more ' : 'Add more ') + utils.predicateLabel(property, reverse); // utils.label(property)
737
-
737
+ img.title = 'Click to add another ' + multipleUIlabel;
738
+ var prompt = dom.createElement('span');
739
+ prompt.textContent = (values.length === 0 ? 'Add another ' : 'Add ') + multipleUIlabel;
738
740
  tail.addEventListener('click', /*#__PURE__*/function () {
739
741
  var _ref3 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee5(_eventNotUsed) {
740
742
  return _regenerator["default"].wrap(function _callee5$(_context5) {
@@ -756,6 +758,7 @@ _fieldFunction.field[ns.ui('Multiple').uri] = function (dom, container, already,
756
758
  return _ref3.apply(this, arguments);
757
759
  };
758
760
  }(), true);
761
+ tail.appendChild(prompt);
759
762
  }
760
763
 
761
764
  function createListIfNecessary() {
@@ -1030,23 +1033,25 @@ _fieldFunction.field[ns.ui('Classifier').uri] = function (dom, container, alread
1030
1033
  ** -- radio buttons
1031
1034
  ** -- auto-complete typing
1032
1035
  **
1033
- ** Todo: Deal with multiple. Maybe merge with multiple code.
1036
+ ** TODO: according to ontology ui:choice can also have ns.ui('default') - this is not implemented yet
1034
1037
  */
1035
1038
 
1036
1039
 
1037
1040
  _fieldFunction.field[ns.ui('Choice').uri] = function (dom, container, already, subject, form, dataDoc, callbackFunction) {
1038
1041
  var ui = ns.ui;
1039
1042
  var kb = _solidLogic.store;
1040
- var multiple = false;
1041
1043
  var formDoc = form.doc ? form.doc() : null; // @@ if blank no way to know
1042
1044
 
1043
1045
  var p;
1044
- var box = dom.createElement('div'); // Set flexDirection column?
1046
+ var box = dom.createElement('div');
1047
+ box.setAttribute('class', 'choiceBox'); // Set flexDirection column?
1045
1048
 
1046
1049
  if (container) container.appendChild(box);
1047
1050
  var lhs = dom.createElement('div');
1051
+ lhs.setAttribute('class', 'formFieldName choiceBox-label');
1048
1052
  box.appendChild(lhs);
1049
1053
  var rhs = dom.createElement('div');
1054
+ rhs.setAttribute('class', 'formFieldValue choiceBox-selectBox');
1050
1055
  box.appendChild(rhs);
1051
1056
  var property = kb.any(form, ui('property'));
1052
1057
 
@@ -1055,103 +1060,125 @@ _fieldFunction.field[ns.ui('Choice').uri] = function (dom, container, already, s
1055
1060
  }
1056
1061
 
1057
1062
  lhs.appendChild((0, _basic.fieldLabel)(dom, property, form));
1063
+ var uiFrom = kb.any(form, ui('from'));
1064
+
1065
+ if (!uiFrom) {
1066
+ return (0, _error.errorMessageBlock)(dom, "No 'from' for Choice: " + form);
1067
+ }
1068
+
1058
1069
  var subForm = kb.any(form, ui('use')); // Optional
1059
1070
 
1060
1071
  var follow = kb.anyJS(form, ui('follow'), null, formDoc); // data doc moves to new subject?
1061
1072
 
1062
- var possible = [];
1063
- var possibleProperties;
1064
- var firstSelectOptionText = '* Select from ' + utils.label(subject, true) + ' *';
1065
1073
  var opts = {
1066
1074
  form: form,
1067
1075
  subForm: subForm,
1068
- multiple: multiple,
1069
- firstSelectOptionText: firstSelectOptionText,
1070
1076
  disambiguate: false
1071
1077
  };
1072
- var uiFrom = kb.any(form, ui('from'));
1073
1078
 
1074
- if (!uiFrom) {
1075
- return (0, _error.errorMessageBlock)(dom, "No 'from' for Choice: " + form);
1076
- }
1079
+ function getSelectorOptions() {
1080
+ var possible = [];
1081
+ var possibleProperties;
1082
+ possible = kb.each(undefined, ns.rdf('type'), uiFrom, formDoc);
1077
1083
 
1078
- possible = kb.each(undefined, ns.rdf('type'), uiFrom, formDoc);
1084
+ for (var x in kb.findMembersNT(uiFrom)) {
1085
+ possible.push(kb.fromNT(x));
1086
+ } // Use rdfs
1079
1087
 
1080
- for (var x in kb.findMembersNT(uiFrom)) {
1081
- possible.push(kb.fromNT(x));
1082
- } // Use rdfs
1083
1088
 
1089
+ if (uiFrom.sameTerm(ns.rdfs('Class'))) {
1090
+ for (p in buttons.allClassURIs()) {
1091
+ possible.push(kb.sym(p));
1092
+ } // log.debug("%%% Choice field: possible.length 2 = "+possible.length)
1084
1093
 
1085
- if (uiFrom.sameTerm(ns.rdfs('Class'))) {
1086
- for (p in buttons.allClassURIs()) {
1087
- possible.push(kb.sym(p));
1088
- } // log.debug("%%% Choice field: possible.length 2 = "+possible.length)
1094
+ } else if (uiFrom.sameTerm(ns.rdf('Property'))) {
1095
+ possibleProperties = buttons.propertyTriage(kb);
1089
1096
 
1090
- } else if (uiFrom.sameTerm(ns.rdf('Property'))) {
1091
- possibleProperties = buttons.propertyTriage(kb);
1097
+ for (p in possibleProperties.op) {
1098
+ possible.push(kb.fromNT(p));
1099
+ }
1092
1100
 
1093
- for (p in possibleProperties.op) {
1094
- possible.push(kb.fromNT(p));
1095
- }
1101
+ for (p in possibleProperties.dp) {
1102
+ possible.push(kb.fromNT(p));
1103
+ }
1096
1104
 
1097
- for (p in possibleProperties.dp) {
1098
- possible.push(kb.fromNT(p));
1099
- }
1105
+ opts.disambiguate = true; // This is a big class, and the labels won't be enough.
1106
+ } else if (uiFrom.sameTerm(ns.owl('ObjectProperty'))) {
1107
+ possibleProperties = buttons.propertyTriage(kb);
1100
1108
 
1101
- opts.disambiguate = true; // This is a big class, and the labels won't be enough.
1102
- } else if (uiFrom.sameTerm(ns.owl('ObjectProperty'))) {
1103
- possibleProperties = buttons.propertyTriage(kb);
1109
+ for (p in possibleProperties.op) {
1110
+ possible.push(kb.fromNT(p));
1111
+ }
1104
1112
 
1105
- for (p in possibleProperties.op) {
1106
- possible.push(kb.fromNT(p));
1107
- }
1113
+ opts.disambiguate = true;
1114
+ } else if (uiFrom.sameTerm(ns.owl('DatatypeProperty'))) {
1115
+ possibleProperties = buttons.propertyTriage(kb);
1108
1116
 
1109
- opts.disambiguate = true;
1110
- } else if (uiFrom.sameTerm(ns.owl('DatatypeProperty'))) {
1111
- possibleProperties = buttons.propertyTriage(kb);
1117
+ for (p in possibleProperties.dp) {
1118
+ possible.push(kb.fromNT(p));
1119
+ }
1112
1120
 
1113
- for (p in possibleProperties.dp) {
1114
- possible.push(kb.fromNT(p));
1121
+ opts.disambiguate = true;
1115
1122
  }
1116
1123
 
1117
- opts.disambiguate = true;
1118
- }
1124
+ return possible; // return sortByLabel(possible)
1125
+ } // TODO: this checks for any occurrence, regardless of true or false setting
1119
1126
 
1120
- var sortedPossible = sortByLabel(possible); // TODO: this checks for any occurance regardles if it is set to true or false
1121
1127
 
1122
1128
  if (kb.any(form, ui('canMintNew'))) {
1123
1129
  opts.mint = '* Create new *'; // @@ could be better
1124
1130
  }
1125
1131
 
1126
- var selector = makeSelectForOptions(dom, kb, subject, property, sortedPossible, uiFrom, opts, dataDoc, callbackFunction);
1127
- rhs.appendChild(selector);
1128
- var object;
1132
+ var multiSelect = kb.any(form, ui('multiselect')); // Optional
1129
1133
 
1130
- if (selector.currentURI) {
1131
- object = $rdf.sym(selector.currentURI);
1132
- } else {
1133
- object = kb.any(subject, property);
1134
- }
1134
+ var selector; // from ui:property
1135
1135
 
1136
- if (object && subForm) {
1137
- removeNextSiblingsAfterElement(selector);
1138
- addSubFormChoice(dom, rhs, already, object, subForm, follow ? object.doc() : dataDoc, callbackFunction);
1139
- }
1136
+ var selectedOptions = kb.each(subject, property, null, dataDoc).map(function (object) {
1137
+ return object.value;
1138
+ });
1140
1139
 
1141
- return box;
1142
- };
1143
- /**
1144
- * Removes all sibling elements after specified
1145
- * @param {HTMLElement} currentElement
1146
- * @private
1147
- */
1140
+ rhs.refresh = function () {
1141
+ // from ui:from + ui:property
1142
+ var possibleOptions = getSelectorOptions();
1143
+ possibleOptions.push(selectedOptions);
1144
+ possibleOptions = sortByLabel(possibleOptions);
1145
+ selector = makeSelectForChoice(dom, rhs, kb, subject, property, possibleOptions, selectedOptions, uiFrom, opts, dataDoc, callbackFunction);
1146
+ rhs.innerHTML = '';
1147
+ rhs.appendChild(selector);
1148
+
1149
+ if (multiSelect) {
1150
+ var multiSelectDiv = new _multiSelect.IconicMultiSelect({
1151
+ placeholder: selector.selected,
1152
+ select: selector,
1153
+ container: rhs,
1154
+ textField: 'textField',
1155
+ valueField: 'valueField'
1156
+ });
1157
+ multiSelectDiv.init();
1158
+ multiSelectDiv.subscribe(function (event) {
1159
+ if (event.action === 'REMOVE_OPTION') {
1160
+ selectedOptions = selectedOptions.filter(function (value) {
1161
+ return value !== event.value;
1162
+ });
1163
+ }
1148
1164
 
1165
+ if (event.action === 'CLEAR_ALL_OPTIONS') {
1166
+ selectedOptions = [];
1167
+ }
1149
1168
 
1150
- function removeNextSiblingsAfterElement(currentElement) {
1151
- while (currentElement.nextElementSibling) {
1152
- currentElement.nextElementSibling.remove();
1153
- }
1154
- }
1169
+ if (event.action === 'ADD_OPTION') {
1170
+ selectedOptions.push(event.value);
1171
+ }
1172
+
1173
+ selector.update(selectedOptions);
1174
+ });
1175
+ }
1176
+ };
1177
+
1178
+ rhs.refresh();
1179
+ if (selector && selector.refresh) selector.refresh();
1180
+ return box;
1181
+ };
1155
1182
 
1156
1183
  function addSubFormChoice(dom, selectDiv, already, subject, subForm, dataDoc, callbackFunction) {
1157
1184
  (0, _fieldFunction.fieldFunction)(dom, subForm)(dom, selectDiv, already, subject, subForm, dataDoc, callbackFunction);
@@ -1358,7 +1385,8 @@ function promptForNew(dom, kb, subject, predicate, theClass, form, dataDoc, call
1358
1385
  b.setAttribute('type', 'button');
1359
1386
  b.setAttribute('style', 'float: right;');
1360
1387
  b.innerHTML = 'Goto ' + utils.label(theClass);
1361
- b.addEventListener('click', function (_e) {
1388
+ b.addEventListener('click', // TODO fix dependency cycle to solid-panes by calling outlineManager
1389
+ function (_e) {
1362
1390
  dom.outlineManager.GotoSubject(theClass, true, undefined, true, undefined);
1363
1391
  }, false);
1364
1392
  return box;
@@ -1493,17 +1521,15 @@ function makeDescription(dom, kb, subject, predicate, dataDoc, callbackFunction)
1493
1521
  // @param subject - a term, the subject of the statement(s) being edited.
1494
1522
  // @param predicate - a term, the predicate of the statement(s) being edited
1495
1523
  // @param possible - a list of terms, the possible value the object can take
1496
- // @param options.multiple - Boolean - Whether more than one at a time is allowed
1497
- // @param options.firstSelectOptionText - a string to be displayed as the
1524
+ // @param options.nullLabel - a string to be displayed as the
1498
1525
  // option for none selected (for non multiple)
1499
- // @param options.mint - User may create thing if this sent to the prompt string eg "New foo"
1500
1526
  // @param options.subForm - If mint, then the form to be used for minting the new thing
1501
1527
  // @param dataDoc - The web document being edited
1502
1528
  // @param callbackFunction - takes (boolean ok, string errorBody)
1503
1529
  */
1504
1530
 
1505
1531
 
1506
- function makeSelectForOptions(dom, kb, subject, predicate, possible, uiFrom, options, dataDoc, callbackFunction) {
1532
+ function makeSelectForOptions(dom, kb, subject, predicate, possible, options, dataDoc, callbackFunction) {
1507
1533
  log.debug('Select list length now ' + possible.length);
1508
1534
  var n = 0;
1509
1535
  var uris = {}; // Count them
@@ -1520,7 +1546,7 @@ function makeSelectForOptions(dom, kb, subject, predicate, possible, uiFrom, opt
1520
1546
  } // uris is now the set of possible options
1521
1547
 
1522
1548
 
1523
- if (n === 0 && !options.mint) {
1549
+ if (n === 0) {
1524
1550
  return (0, _error.errorMessageBlock)(dom, "Can't do selector with no options, subject= " + subject + ' property = ' + predicate + '.');
1525
1551
  }
1526
1552
 
@@ -1546,6 +1572,8 @@ function makeSelectForOptions(dom, kb, subject, predicate, possible, uiFrom, opt
1546
1572
  actual = getActual();
1547
1573
 
1548
1574
  var onChange = function onChange(_e) {
1575
+ select.disabled = true; // until data written back - gives user feedback too
1576
+
1549
1577
  var ds = [];
1550
1578
  var is = [];
1551
1579
 
@@ -1555,43 +1583,18 @@ function makeSelectForOptions(dom, kb, subject, predicate, possible, uiFrom, opt
1555
1583
  }
1556
1584
  };
1557
1585
 
1558
- var newObject;
1559
-
1560
1586
  for (var _i = 0; _i < select.options.length; _i++) {
1561
1587
  var opt = select.options[_i];
1562
-
1563
- if (opt.selected && opt.AJAR_mint) {
1564
- // not sure if this if is used because I cannot find mintClass
1565
- if (options.mintClass) {
1566
- var thisForm = promptForNew(dom, kb, subject, predicate, options.mintClass, null, dataDoc, function (ok, body) {
1567
- if (!ok) {
1568
- callbackFunction(ok, body, {
1569
- change: 'new'
1570
- }); // @@ if ok, need some form of refresh of the select for the new thing
1571
- }
1572
- });
1573
- select.parentNode.appendChild(thisForm);
1574
- newObject = thisForm.AJAR_subject;
1575
- } else {
1576
- newObject = newThing(dataDoc);
1577
- }
1578
-
1579
- is.push($rdf.st(subject, predicate, kb.sym(newObject), dataDoc));
1580
- if (uiFrom) is.push($rdf.st(newObject, ns.rdf('type'), kb.sym(uiFrom), dataDoc)); // not sure if this if is used because I cannot find mintStatementsFun
1581
-
1582
- if (options.mintStatementsFun) {
1583
- is = is.concat(options.mintStatementsFun(newObject));
1584
- }
1585
-
1586
- select.currentURI = newObject;
1587
- }
1588
-
1589
1588
  if (!opt.AJAR_uri) continue; // a prompt or mint
1590
1589
 
1591
1590
  if (opt.selected && !(opt.AJAR_uri in actual)) {
1592
1591
  // new class
1593
1592
  is.push($rdf.st(subject, predicate, kb.sym(opt.AJAR_uri), dataDoc));
1594
- select.currentURI = opt.AJAR_uri;
1593
+ }
1594
+
1595
+ if (!opt.selected && opt.AJAR_uri in actual) {
1596
+ // old class
1597
+ removeValue(kb.sym(opt.AJAR_uri));
1595
1598
  }
1596
1599
 
1597
1600
  if (opt.selected) select.currentURI = opt.AJAR_uri;
@@ -1611,25 +1614,25 @@ function makeSelectForOptions(dom, kb, subject, predicate, possible, uiFrom, opt
1611
1614
  sel = sel.superSelect;
1612
1615
  }
1613
1616
 
1614
- log.info('selectForOptions: data doc = ' + dataDoc); // refresh subForm
1617
+ log.info('selectForOptions: data doc = ' + dataDoc);
1618
+ kb.updater.update(ds, is, function (uri, ok, body) {
1619
+ actual = getActual(); // refresh
1615
1620
 
1616
- removeNextSiblingsAfterElement(select);
1617
- addSubFormChoice(dom, select.parentNode, {}, $rdf.sym(select.currentURI), options.subForm, dataDoc, function (ok, body) {
1618
1621
  if (ok) {
1619
- kb.updater.update(ds, is, function (uri, success, errorBody) {
1620
- actual = getActual(); // refresh
1621
-
1622
- if (!success) select.parentNode.appendChild((0, _error.errorMessageBlock)(dom, 'Error updating select: ' + errorBody));
1623
- }); // if (callbackFunction) callbackFunction(ok, { widget: 'select', event: 'new' })
1622
+ select.disabled = false; // data written back
1624
1623
  } else {
1625
- select.parentNode.appendChild((0, _error.errorMessageBlock)(dom, 'Error updating data in field of select: ' + body));
1624
+ return select.parentNode.appendChild((0, _error.errorMessageBlock)(dom, 'Error updating data in select: ' + body));
1626
1625
  }
1626
+
1627
+ if (callbackFunction) callbackFunction(ok, {
1628
+ widget: 'select',
1629
+ event: 'change'
1630
+ });
1627
1631
  });
1628
1632
  };
1629
1633
 
1630
1634
  var select = dom.createElement('select');
1631
1635
  select.setAttribute('style', style.formSelectSTyle);
1632
- if (options.multiple) select.setAttribute('multiple', 'true');
1633
1636
  select.currentURI = null;
1634
1637
 
1635
1638
  select.refresh = function () {
@@ -1672,22 +1675,11 @@ function makeSelectForOptions(dom, kb, subject, predicate, possible, uiFrom, opt
1672
1675
  select.appendChild(option);
1673
1676
  }
1674
1677
 
1675
- if (editable && options.mint) {
1676
- var mint = dom.createElement('option');
1677
- mint.appendChild(dom.createTextNode(options.mint));
1678
- mint.AJAR_mint = true; // Flag it
1679
-
1680
- select.insertBefore(mint, select.firstChild);
1681
- }
1682
-
1683
- if (!select.currentURI && !options.multiple) {
1678
+ if (!select.currentURI) {
1684
1679
  var prompt = dom.createElement('option');
1685
- prompt.appendChild(dom.createTextNode(options.firstSelectOptionText));
1686
- prompt.selected = true;
1687
- prompt.disabled = true;
1688
- prompt.value = true;
1689
- prompt.hidden = true;
1680
+ prompt.appendChild(dom.createTextNode(options.nullLabel));
1690
1681
  select.insertBefore(prompt, select.firstChild);
1682
+ prompt.selected = true;
1691
1683
  }
1692
1684
 
1693
1685
  if (editable) {
@@ -1706,27 +1698,16 @@ function makeSelectForOptions(dom, kb, subject, predicate, possible, uiFrom, opt
1706
1698
  function makeSelectForCategory(dom, kb, subject, category, dataDoc, callbackFunction) {
1707
1699
  var du = kb.any(category, ns.owl('disjointUnionOf'));
1708
1700
  var subs;
1709
- var multiple = false;
1710
1701
 
1711
1702
  if (!du) {
1712
1703
  subs = kb.each(undefined, ns.rdfs('subClassOf'), category);
1713
- multiple = true;
1714
1704
  } else {
1715
1705
  subs = du.elements;
1716
1706
  }
1717
1707
 
1718
1708
  log.debug('Select list length ' + subs.length);
1719
-
1720
- if (subs.length === 0) {
1721
- return (0, _error.errorMessageBlock)(dom, "Can't do " + (multiple ? 'multiple ' : '') + 'selector with no subclasses of category: ' + category);
1722
- }
1723
-
1724
- if (subs.length === 1) {
1725
- return (0, _error.errorMessageBlock)(dom, "Can't do " + (multiple ? 'multiple ' : '') + 'selector with only 1 subclass of category: ' + category + ':' + subs[1]);
1726
- }
1727
-
1728
- return makeSelectForOptions(dom, kb, subject, ns.rdf('type'), subs, null, {
1729
- multiple: multiple
1709
+ return makeSelectForOptions(dom, kb, subject, ns.rdf('type'), subs, {
1710
+ nullLabel: '* Select type *'
1730
1711
  }, dataDoc, callbackFunction);
1731
1712
  }
1732
1713
  /** Make SELECT element to select subclasses recurively
@@ -1760,8 +1741,7 @@ function makeSelectForNestedCategory(dom, kb, subject, category, dataDoc, callba
1760
1741
  function onChange(ok, body) {
1761
1742
  if (ok) update();
1762
1743
  callbackFunction(ok, body);
1763
- } // eslint-disable-next-line prefer-const
1764
-
1744
+ }
1765
1745
 
1766
1746
  var select = makeSelectForCategory(dom, kb, subject, category, dataDoc, onChange);
1767
1747
  container.appendChild(select);
@@ -1916,4 +1896,263 @@ function newThing(doc) {
1916
1896
  var now = new Date();
1917
1897
  return $rdf.sym(doc.uri + '#' + 'id' + ('' + now.getTime()));
1918
1898
  }
1899
+ /** Make SELECT element to select options
1900
+ //
1901
+ // @param subject - a term, the subject of the statement(s) being edited.
1902
+ // @param predicate - a term, the predicate of the statement(s) being edited
1903
+ // @param possible - a list of terms, the possible value the object can take
1904
+ // @param options.mint - User may create thing if this sent to the prompt string eg "New foo"
1905
+ // @param options.subForm - If mint, then the form to be used for minting the new thing
1906
+ // @param dataDoc - The web document being edited
1907
+ // @param callbackFunction - takes (boolean ok, string errorBody)
1908
+ */
1909
+
1910
+
1911
+ function makeSelectForChoice(dom, container, kb, subject, predicate, inputPossibleOptions, selectedOptions, uiFrom, options, dataDoc, callbackFunction) {
1912
+ var optionsFromClassUIfrom = {}; // Count them
1913
+
1914
+ var editable = kb.updater.editable(dataDoc.uri);
1915
+
1916
+ for (var i = 0; i < inputPossibleOptions.length; i++) {
1917
+ var sub = inputPossibleOptions[i]; // @@ Maybe; make this so it works with blank nodes too
1918
+ // if (!sub.uri) debug.warn(`makeSelectForChoice: option does not have an uri: ${sub}, with predicate: ${predicate}`)
1919
+
1920
+ if (!sub.uri || sub.uri in optionsFromClassUIfrom) continue;
1921
+ optionsFromClassUIfrom[sub.uri] = true;
1922
+ }
1923
+
1924
+ var isEmpty = Object.keys(optionsFromClassUIfrom).length === 0;
1925
+
1926
+ if (isEmpty && !options.mint) {
1927
+ return (0, _error.errorMessageBlock)(dom, "Can't do selector with no options, subject= " + subject + ' property = ' + predicate + '.');
1928
+ }
1929
+
1930
+ log.debug('makeSelectForChoice: dataDoc=' + dataDoc);
1931
+
1932
+ function determineFitstSelectOptionText() {
1933
+ var firstSelectOptionText = '--- choice ---';
1934
+
1935
+ if (predicate && !(predicate.termType === 'BlankNode')) {
1936
+ firstSelectOptionText = '* Select for property: ' + utils.label(predicate) + ' *';
1937
+ }
1938
+
1939
+ if (subject && !(subject.termType === 'BlankNode')) {
1940
+ firstSelectOptionText = '* Select for ' + utils.label(subject, true) + ' *';
1941
+ }
1942
+
1943
+ return firstSelectOptionText;
1944
+ }
1945
+
1946
+ function determinFirstSelectOption() {
1947
+ var option = dom.createElement('option');
1948
+ option.appendChild(dom.createTextNode(determineFitstSelectOptionText()));
1949
+ option.disabled = true;
1950
+ option.value = true;
1951
+ option.hidden = true;
1952
+ option.selected = true;
1953
+ return option;
1954
+ }
1955
+
1956
+ var onChange = function onChange(_e) {
1957
+ container.removeChild(container.lastChild);
1958
+ select.refresh();
1959
+ };
1960
+
1961
+ var select = dom.createElement('select');
1962
+ select.setAttribute('style', style.formSelectSTyle);
1963
+ select.setAttribute('id', 'formSelect');
1964
+ select.currentURI = null;
1965
+
1966
+ for (var uri in optionsFromClassUIfrom) {
1967
+ select.appendChild(createOption(uri));
1968
+ }
1969
+
1970
+ if (editable && options.mint) {
1971
+ var mint = dom.createElement('option');
1972
+ mint.appendChild(dom.createTextNode(options.mint));
1973
+ mint.AJAR_mint = true; // Flag it
1974
+
1975
+ select.insertBefore(mint, select.firstChild);
1976
+ }
1977
+
1978
+ if (select.children.length === 0) select.insertBefore(determinFirstSelectOption(), select.firstChild);
1979
+
1980
+ select.update = function (newSelectedOptions) {
1981
+ selectedOptions = newSelectedOptions;
1982
+ var ds = [];
1983
+ var is = [];
1984
+
1985
+ var removeValue = function removeValue(t) {
1986
+ if (kb.holds(subject, predicate, t, dataDoc)) {
1987
+ ds.push($rdf.st(subject, predicate, t, dataDoc)); // console.log("----value removed " + t)
1988
+ }
1989
+ };
1990
+
1991
+ var addValue = function addValue(t) {
1992
+ if (!kb.holds(subject, predicate, t, dataDoc)) {
1993
+ is.push($rdf.st(subject, predicate, t, dataDoc)); // console.log("----value added " + t)
1994
+ }
1995
+
1996
+ if (uiFrom && !kb.holds(t, ns.rdf('type'), kb.sym(uiFrom), dataDoc)) {
1997
+ is.push($rdf.st(t, ns.rdf('type'), kb.sym(uiFrom), dataDoc)); // console.log("----added type to value " + uiFrom)
1998
+ }
1999
+ };
2000
+
2001
+ var existingValues = kb.each(subject, predicate, null, dataDoc).map(function (object) {
2002
+ return object.value;
2003
+ });
2004
+
2005
+ var _iterator2 = _createForOfIteratorHelper(existingValues),
2006
+ _step2;
2007
+
2008
+ try {
2009
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
2010
+ var value = _step2.value;
2011
+ if (!containsObject(value, selectedOptions)) removeValue($rdf.sym(value));
2012
+ }
2013
+ } catch (err) {
2014
+ _iterator2.e(err);
2015
+ } finally {
2016
+ _iterator2.f();
2017
+ }
2018
+
2019
+ var _iterator3 = _createForOfIteratorHelper(selectedOptions),
2020
+ _step3;
2021
+
2022
+ try {
2023
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
2024
+ var _value = _step3.value;
2025
+ if (!(_value in existingValues)) addValue($rdf.sym(_value));
2026
+ }
2027
+ } catch (err) {
2028
+ _iterator3.e(err);
2029
+ } finally {
2030
+ _iterator3.f();
2031
+ }
2032
+
2033
+ kb.updater.update(ds, is, function (uri, ok, body) {
2034
+ if (!ok) return select.parentNode.appendChild((0, _error.errorMessageBlock)(dom, 'Error updating data in select: ' + body));
2035
+ select.refresh();
2036
+ if (callbackFunction) callbackFunction(ok, {
2037
+ widget: 'select',
2038
+ event: 'change'
2039
+ });
2040
+ });
2041
+ };
2042
+
2043
+ select.refresh = function () {
2044
+ select.disabled = true; // unlocked any conflict we had got into
2045
+
2046
+ var is = [];
2047
+ var newObject;
2048
+
2049
+ for (var _i3 = 0; _i3 < select.options.length; _i3++) {
2050
+ var opt = select.options[_i3];
2051
+
2052
+ if (opt.selected && opt.AJAR_mint) {
2053
+ // not sure if this 'if' is used because I cannot find mintClass
2054
+ if (options.mintClass) {
2055
+ var thisForm = promptForNew(dom, kb, subject, predicate, options.mintClass, null, dataDoc, function (ok, body) {
2056
+ if (!ok) {
2057
+ callbackFunction(ok, body, {
2058
+ change: 'new'
2059
+ }); // @@ if ok, need some form of refresh of the select for the new thing
2060
+ }
2061
+ });
2062
+ select.parentNode.appendChild(thisForm);
2063
+ newObject = thisForm.AJAR_subject;
2064
+ } else {
2065
+ newObject = newThing(dataDoc);
2066
+ }
2067
+
2068
+ is.push($rdf.st(subject, predicate, kb.sym(newObject), dataDoc));
2069
+ if (uiFrom) is.push($rdf.st(newObject, ns.rdf('type'), kb.sym(uiFrom), dataDoc)); // not sure if this 'if' is used because I cannot find mintStatementsFun
2070
+
2071
+ if (options.mintStatementsFun) {
2072
+ is = is.concat(options.mintStatementsFun(newObject));
2073
+ }
2074
+
2075
+ select.currentURI = newObject;
2076
+ }
2077
+
2078
+ if (!opt.AJAR_uri) continue; // a prompt or mint
2079
+
2080
+ if (opt.selected && containsObject(opt.AJAR_uri, selectedOptions)) {
2081
+ select.currentURI = opt.AJAR_uri;
2082
+ }
2083
+
2084
+ if (!containsObject(opt.AJAR_uri, selectedOptions)) opt.setAttribute('selected', 'false');
2085
+ if (containsObject(opt.AJAR_uri, selectedOptions)) opt.setAttribute('selected', 'true');
2086
+ }
2087
+
2088
+ log.info('selectForOptions: data doc = ' + dataDoc);
2089
+
2090
+ if (select.currentURI) {
2091
+ addSubFormChoice(dom, container, {}, $rdf.sym(select.currentURI), options.subForm, dataDoc, function (ok, body) {
2092
+ if (ok) {
2093
+ kb.updater.update([], is, function (uri, success, errorBody) {
2094
+ if (!success) container.appendChild((0, _error.errorMessageBlock)(dom, 'Error updating select: ' + errorBody));
2095
+ });
2096
+ if (callbackFunction) callbackFunction(ok, {
2097
+ widget: 'select',
2098
+ event: 'new'
2099
+ });
2100
+ } else {
2101
+ container.appendChild((0, _error.errorMessageBlock)(dom, 'Error updating data in field of select: ' + body));
2102
+ }
2103
+ });
2104
+ }
2105
+
2106
+ select.disabled = false;
2107
+ };
2108
+
2109
+ function createOption(uri) {
2110
+ var option = dom.createElement('option');
2111
+ var c = kb.sym(uri);
2112
+ var label;
2113
+
2114
+ if (options.disambiguate) {
2115
+ label = utils.labelWithOntology(c, true); // Init. cap
2116
+ } else {
2117
+ label = utils.label(c, true);
2118
+ }
2119
+
2120
+ option.appendChild(dom.createTextNode(label)); // Init.
2121
+
2122
+ option.setAttribute('value', uri);
2123
+ var backgroundColor = kb.any(c, kb.sym('http://www.w3.org/ns/ui#backgroundColor'));
2124
+
2125
+ if (backgroundColor) {
2126
+ option.setAttribute('style', 'background-color: ' + backgroundColor.value + '; ');
2127
+ }
2128
+
2129
+ option.AJAR_uri = uri;
2130
+
2131
+ if (c.value === '' + select.currentURI || containsObject(c.value, selectedOptions)) {
2132
+ option.selected = true;
2133
+ option.setAttribute('selected', 'true');
2134
+ }
2135
+
2136
+ return option;
2137
+ }
2138
+
2139
+ if (editable) {
2140
+ select.addEventListener('change', onChange, false);
2141
+ }
2142
+
2143
+ return select;
2144
+ } // makeSelectForChoice
2145
+
2146
+
2147
+ function containsObject(obj, list) {
2148
+ var i;
2149
+
2150
+ for (i = 0; i < list.length; i++) {
2151
+ if (list[i] === obj) {
2152
+ return true;
2153
+ }
2154
+ }
2155
+
2156
+ return false;
2157
+ }
1919
2158
  //# sourceMappingURL=forms.js.map