Commit dd608b0e authored by Carsten  Rose's avatar Carsten Rose
Browse files

Merge remote-tracking branch 'origin/raos_work' into typeahead-pedantic

parents b1a60df4 99a3c4e0
......@@ -89,6 +89,7 @@ CREATE TABLE IF NOT EXISTS `FormElement` (
`bsNoteColumns` VARCHAR(255) NOT NULL DEFAULT '',
`rowLabelInputNote` SET('row', 'label', '/label', 'input', '/input', 'note', '/note', '/row') NOT NULL DEFAULT 'row,label,/label,input,/input,note,/note,/row',
`note` TEXT NOT NULL,
`adminNote` TEXT NOT NULL,
`tooltip` VARCHAR(255) NOT NULL DEFAULT '',
`placeholder` VARCHAR(512) NOT NULL DEFAULT '',
......@@ -180,7 +181,7 @@ VALUES
'', '', '', 4, '', '', ''),
(1, '', 'FormElements', 'show', 'subrecord', 'all', 'native', 500, 0, 0, '', '', '',
'{{!SELECT IF( fe.enabled="yes", IF( fe.enabled="yes" AND fe.feIdContainer=0 AND !ISNULL(feCX.id) AND fe.class="native", "danger", IF( fe.class="container", "text-info", IF( fe.class="action", "text-success", ""))), "text-muted") AS _rowClass, IF( fe.enabled="yes", IF(fe.feIdContainer=0 AND !ISNULL(feCX.id) AND fe.class="native", "Please choose a container for this formelement", fe.class), "Disabled") AS _rowTitle, fe.id, CONCAT( IFNULL( CONCAT( feC.name, " (", fe.feIdContainer, ")"),"")) AS Container, fe.name, fe.label, fe.mode, fe.class, fe.type, fe.ord, IF(fe.dynamicUpdate="yes", \'<span class="glyphicon glyphicon-random"></span>\',"") AS "dyn|||nostrip", fe.parameter FROM FormElement AS fe LEFT JOIN FormElement AS feC ON feC.id=fe.feIdContainer AND feC.formId=fe.formId LEFT JOIN FormElement AS feCX ON feCX.class="container" AND feCX.enabled="yes" AND feCX.formId=fe.formId WHERE fe.formId={{id:R0}} GROUP BY fe.id ORDER BY fe.class DESC, feC.ord, fe.ord, fe.id}}',
'{{!SELECT IF( fe.enabled="yes", IF( fe.enabled="yes" AND fe.feIdContainer=0 AND !ISNULL(feCX.id) AND fe.class="native", "danger", IF( fe.class="container", "text-info", IF( fe.class="action", "text-success", ""))), "text-muted") AS _rowClass, IF( fe.enabled="yes", IF(fe.feIdContainer=0 AND !ISNULL(feCX.id) AND fe.class="native", "Please choose a container for this formelement", fe.class), "Disabled") AS _rowTitle, fe.id, CONCAT( IFNULL( CONCAT( feC.name, " (", fe.feIdContainer, ")"),"")) AS Container, fe.name AS "Name|50", fe.label, fe.mode, fe.class, fe.type, fe.ord, IF(fe.dynamicUpdate="yes", \'<span class="glyphicon glyphicon-random"></span>\',"") AS "dyn|||nostrip", fe.parameter FROM FormElement AS fe LEFT JOIN FormElement AS feC ON feC.id=fe.feIdContainer AND feC.formId=fe.formId LEFT JOIN FormElement AS feCX ON feCX.class="container" AND feCX.enabled="yes" AND feCX.formId=fe.formId WHERE fe.formId={{id:R0}} GROUP BY fe.id ORDER BY fe.class DESC, feC.ord, fe.ord, fe.id}}',
'form=formElement\ndetail=id:formId', 5, 'new,edit,delete', '', '');
......@@ -249,12 +250,14 @@ VALUES
(2, 'parameter', 'Parameter', 'show', 'text', 'all', 'native', 520, '40,8', 0, '',
'', '', '', '', 103, '', 'no', '', '', '', '', ''),
(2, 'clientJs', 'ClientJS', 'show', 'text', 'all', 'native', 530, 0, 0, '', '', '', '', '', 103, '', 'no', '', '', '', '', ''),
(2, 'feGroup', 'feGroup', 'show', 'text', 'all', 'native', 600, 0, 0, '', '', '', '', '', 104, '', 'no', '', '', '', '', ''),
(2, 'deleted', 'Deleted', 'show', 'checkbox', 'all', 'native', 610, 0, 0, '', '', '', '', '', 104, '', 'no', '', '',
(2, 'adminNote', 'Admin Note', 'show', 'text', 'all', 'native', 600, 0, 0, '', '', '', '', '', 104, '', 'no', '', '', '', '', ''),
(2, 'feGroup', 'feGroup', 'show', 'text', 'all', 'native', 610, 0, 0, '', '', '', '', '', 104, '', 'no', '', '', '',
'', ''),
(2, 'deleted', 'Deleted', 'show', 'checkbox', 'all', 'native', 620, 0, 0, '', '', '', '', '', 104, '', 'no', '', '',
'', '', ''),
(2, 'modified', 'Modified', 'readonly', 'text', 'all', 'native', 620, 0, 20, '', '', '', '', '', 104, '', 'no',
(2, 'modified', 'Modified', 'readonly', 'text', 'all', 'native', 630, 0, 20, '', '', '', '', '', 104, '', 'no',
'', '', '', '', ''),
(2, 'created', 'Created', 'readonly', 'text', 'all', 'native', 630, 0, 20, '', '', '', '', '', 104, '', 'no', '',
(2, 'created', 'Created', 'readonly', 'text', 'all', 'native', 640, 0, 20, '', '', '', '', '', 104, '', 'no', '',
'', '', '', '');
......
......@@ -31,7 +31,7 @@ var QfqNS = QfqNS || {};
throw new Error("Form '" + formId + "' does not exist.");
}
this.formChanged = formChanged || false;
this.formChanged = !!formChanged;
this.$form = $(document.forms[this.formId]);
this.$form.on("change", this.changeHandler.bind(this));
this.$form.on("invalid.bs.validator", this.validationError.bind(this));
......@@ -60,7 +60,7 @@ var QfqNS = QfqNS || {};
};
n.Form.prototype.getFormChanged = function () {
return this.formChanged || this.ignoreChangeState;
return this.formChanged;
};
n.Form.prototype.markChanged = function () {
......
......@@ -842,7 +842,7 @@ var QfqNS = QfqNS || {};
/**
* @private
* @param triggeredBy
* @param obj
*/
n.QfqForm.prototype.startUploadHandler = function (obj) {
$(obj.target).after(
......@@ -852,7 +852,7 @@ var QfqNS = QfqNS || {};
/**
* @private
* @param triggeredBy
* @param obj
*/
n.QfqForm.prototype.endUploadHandler = function (obj) {
var $siblings = $(obj.target).siblings();
......
......@@ -47,7 +47,7 @@ var QfqNS = QfqNS || {};
var suggestions = new Bloodhound(bloodhoundConfiguration);
n.TypeAhead.makeShadowElement($element);
$shadowElement = n.TypeAhead.makeShadowElement($element);
$element.typeahead({
hint: n.TypeAhead.getHint($element),
......@@ -76,22 +76,50 @@ var QfqNS = QfqNS || {};
});
if (!!$element.data('typeahead-pedantic')) {
$element.bind('typeahead:change', (function (bloodHound) {
return function (event) {
var $typeAhead = $(event.delegateTarget);
var $shadowElement = n.TypeAhead.getShadowElement($typeAhead);
if ($shadowElement.val() === '') {
$typeAhead.typeahead('val', '');
$typeAhead.closest('form').change();
}
};
})(suggestions)
);
$element.bind('typeahead:change', n.TypeAhead.makePedanticHandler(suggestions));
$element.on('keydown', (function (suggestions) {
return function (event) {
if (event.which === 13) {
n.TypeAhead.makePedanticHandler(suggestions)(event);
}
};
})(suggestions));
// The pedantic handler will test if the shadow element has a value set (the KEY). If not, the
// typeahead element is cleared. Thus we have to guarantee that no value exists in the shadow
// element, the instant the user starts typing since we don't know the outcome of the search.
//
// If we don't clear the shadow element the instant the user starts typing, and simply let the
// `typeahead:select` or `typeahead:autocomplete` handler set the selected value, the
// user might do following steps and end up in an inconsistent state:
//
// 1. Use typeahead to select/autocomplete a suggestion
// 2. delete the suggestion
// 3. enter a random string
// 4. submit form
//
// This would leave a stale value in the shadow element (from step 1.), and the pedantic handler
// would not clear the typeahead element, giving the impression the value in the typeahead element will be submitted.
$element.on('input', (function ($shadowElement) {
return function () {
$shadowElement.val('');
};
})($shadowElement));
}
});
};
n.TypeAhead.makePedanticHandler = function (bloodhound) {
return function (event) {
var $typeAhead = $(event.delegateTarget);
var $shadowElement = n.TypeAhead.getShadowElement($typeAhead);
if ($shadowElement.val() === '') {
$typeAhead.typeahead('val', '');
$typeAhead.closest('form').change();
}
};
};
n.TypeAhead.makeUrl = function (endpoint, element) {
return endpoint + "?query=%QUERY" + "&sip=" + n.TypeAhead.getSip(element);
};
......
......@@ -39,6 +39,16 @@ describe("Form", function () {
expect(form.getFormChanged()).toBe(false);
});
it("should have formChanged() == false upon explicit initialization", function () {
form = new QfqNS.Form("myForm", false);
expect(form.getFormChanged()).toBe(false);
});
it("should have formChanged() == true upon explicit initialization", function () {
form = new QfqNS.Form("myForm", true);
expect(form.getFormChanged()).toBe(true);
});
it("should set the proper state upon form state change", function () {
expect(form.getFormChanged()).toBe(false);
$('#firstname').change();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment