Commit 90f5063e authored by Carsten  Rose's avatar Carsten Rose
Browse files

Merge remote-tracking branch 'origin/raos_work' into crose_work

parents c271395e e4984da4
/doc/*.pdf
/.doc_plantuml
/.support
/.support_plantuml
......
......@@ -72,107 +72,6 @@ DELETE
* HTML Code:
<button type="button" class="record-delete" data-sip={{SIP}} ><span class="glyphicon glyphicon-trash"></span></button>
USER INTERFACE
==============
Button status
-------------
* Form modified:
* Buttons enabled: Save, Close, New, Delete
* Button disable: -
* Form not modified:
* Buttons enabled: Close, New, Delete
* Button disabled: Save
Save Button
-----------
* User presses the button
* Reset all validation states
* Client validates HTML Form
* Form is submitted to server
* Success:
* Show message provided by server
* Current formelements and data will be reloaded.
* Process server reponse 'redirect':
* 'client': No redirect.
* 'no': No redirect.
* 'url': Redirect to URL
* Failure: Happens on communication errors, if data validation fails, form actions fails or saving data fails.
* Show error message.
* Client: Ignore server reponse 'redirect'. Client stays on current page.
Close Button
------------
* User presses the button
* Form not modified by user: Client redirects to previous page.
* Form modified by user: Ask User 'You have unsaved changes. Do you want to close?'
* Yes: Client redirects to previous page.
* No: Client stays on current page.
* Save & Close:
* Client reset all validation states
* Client validates HTML Form
* Client submits form to server.
* Success: Process server response 'redirect':
* 'client': Client shows previous page.
* 'no': No redirect.
* 'url': Redirect to URL
* Failure: Happens on communication errors, if data validation fails, form actions fails or saving data fails.
* Show error message.
* Client: No redirect. Ignore server reponse 'redirect'.
Delete Button: Main record
--------------------------
* User presses the button. Ask User 'Do you really want to delete the record?
* Yes:
* Delete record on server.
* Process server reponse 'redirect':
* 'client': Client redirects to previous page.
* 'no': Error message.
* 'url': Redirect to URL
* No:
* Client does not delete record on server.
* No redirect. Client stays on current page.
New Button
----------
* User presses the button
* Form not modified by user: Client redirects to href url.
* Form modified by user: Ask User 'You have unsaved changes. Do you want to save first?'
* Yes:
* Client reset all validation states
* Client validates HTML Form
* Form is submitted to server
* Success:
* Client: Ignore server reponse 'redirect'. Client redirects to href url.
* Failure: Happens on communication errors, if data validation fails, form actions fails or saving data fails.
* Show error message.
* Client: Ignore server reponse 'redirect'. Client stays on current page.
* No:
* Client does not save the modified record.
* Client redirects to href url.
* Cancel:
* Client does not save the modified record.
* Client stays on current page.
File Handling: Upload
---------------------
* No previous uploaded file present
1. User presses the Browse button
1. User selects file
1. File is uploaded to qfq immediately
1. Browse button gets disabled and hidden
1. File delete button is shown
1. User cancels file selection
1. no action
* Previous uploaded file present
1. User deletes file
1. File delete button gets disabled and hidden
1. Browse button gets enabled and displayed
Form Build (load)
.................
......@@ -314,4 +213,4 @@ Checkbox
</label>
</div>
\ No newline at end of file
# HTML
This document explains the HTML markup used by QFQ.
## Hooks
Hooks are used on by the Client to gather information required for
asynchronous requests and to add predefined event handlers to HTML Elements.
### form.data-toggle="validator"
Adding the attribute `data-toggle="validator"` to a `<form>` element,
enables the Bootstrap Validator on that HTML Form.
### .data-sip
Asynchronous requests require to pass a SID to the Server. Elements
triggering an asynchronous request, may gather the SIP from the
`data-sip` attribute assigned to the HTML Form Element.
### .class="record-delete"
HTML Form Buttons having the class `record-delete` set, will get an
`onclick` handler attached by `QfqNS.QfqRecordList`. Each `<button>`
also requires an `data-sip` attribute.
### .data-load=""
HTML Form Elements having the attribute `data-load`, will trigger a
call to `api/load.php` upon change.
### id="save-button"
### id="close-button"
### id="delete-button"
### id="form-new-button"
SOURCES = CODING.md HTML.md PROTOCOL.md UI.md LAYOUT.md
PDFDOCS = $(patsubst %.md,%.pdf,$(SOURCES))
all: $(PDFDOCS)
.md.pdf:
pandoc -o $@ $<
.SUFFIXES: .md .pdf
USER INTERFACE
==============
Button states
-------------
If the HTML Form has no modifications, the `Close`, `New` and `Delete`
buttons are enabled. The `Save` button is disabled.
If the HTML Form has modifications, the `Save`, `Close`, `New`, and
`Delete` button is enabled. No button is disabled.
Save Button
-----------
* User presses the Save button
1. Reset all validation states
1. Client validates HTML Form
1. Form is submitted to server
* Success:
1. Show message provided by server
1. Current formelements and data will be reloaded.
1. Process server reponse 'redirect':
* 'client': No redirect.
* 'no': No redirect.
* 'url': Redirect to URL
* Failure: Happens on communication errors, if data validation
fails, form actions fails or saving data fails.
1. Show error message.
1. Client: Ignore server reponse 'redirect'. Client stays on current page.
Close Button
------------
* User presses the Close button
1. Form not modified by user: Client redirects to previous page.
1. Form modified by user: Ask User 'You have unsaved changes. Do you want to close?'
* Yes: Client redirects to previous page.
* No: Client stays on current page.
* Save & Close:
1. Client reset all validation states
1. Client validates HTML Form
1. Client submits form to server.
* Success: Process server response 'redirect':
* 'client': Client shows previous page.
* 'no': No redirect.
* 'url': Redirect to URL
* Failure: Happens on communication errors, if data validation
fails, form actions fails or saving data fails.
* Show error message.
* Client: No redirect. Ignore server reponse 'redirect'.
Delete Button: Main record
--------------------------
* User presses the button. Ask User 'Do you really want to delete the record?
* Yes:
* Delete record on server.
* Process server reponse 'redirect':
* 'client': Client redirects to previous page.
* 'no': Error message.
* 'url': Redirect to URL
* No:
* Client does not delete record on server.
* No redirect. Client stays on current page.
New Button
----------
* User presses the button
* Form not modified by user: Client redirects to href url.
* Form modified by user: Ask User 'You have unsaved changes. Do you want to save first?'
* Yes:
* Client reset all validation states
* Client validates HTML Form
* Form is submitted to server
* Success:
* Client: Ignore server reponse 'redirect'. Client redirects to href url.
* Failure: Happens on communication errors, if data validation fails, form actions fails or saving data fails.
* Show error message.
* Client: Ignore server reponse 'redirect'. Client stays on current page.
* No:
* Client does not save the modified record.
* Client redirects to href url.
* Cancel:
* Client does not save the modified record.
* Client stays on current page.
File Handling: Upload
---------------------
* No previous uploaded file present
1. User presses the Browse button
1. User selects file
1. File is uploaded to qfq immediately
1. Browse button gets disabled and hidden
1. File delete button is shown
1. User cancels file selection
1. no action
* Previous uploaded file present
1. User deletes file
1. File delete button gets disabled and hidden
1. Browse button gets enabled and displayed
......@@ -19,20 +19,38 @@ QfqNS.Element = QfqNS.Element || {};
function Checkbox($element) {
n.FormGroup.call(this, $element);
if (!this.isType("checkbox")) {
var type = "checkbox";
if (!this.isType(type)) {
throw new Error("$element is not of type 'checkbox'");
}
// We allow one Form Group to have several checkboxes. Therefore, we have to remember which checkbox was
// selected if possible.
if ($element.length === 1 && $element.attr('type') === type) {
this.$singleElement = $element;
} else {
this.$singleElement = null;
}
}
Checkbox.prototype = Object.create(n.FormGroup.prototype);
Checkbox.prototype.constructor = Checkbox;
Checkbox.prototype.setValue = function (val) {
this.$element.prop('checked', val);
if (this.$singleElement) {
this.$singleElement.prop('checked', val);
} else {
this.$element.prop('checked', val);
}
};
Checkbox.prototype.getValue = function () {
return this.$element.prop('checked');
if (this.$singleElement) {
return this.$singleElement.prop('checked');
} else {
return this.$element.prop('checked');
}
};
n.Checkbox = Checkbox;
......
......@@ -172,6 +172,38 @@
</div>
</div>
<div class="form-group">
<div class="col-md-2">
<b class="control-label">
Checkbox 3 test
</b>
</div>
<div class="col-md-6">
<div class="checkbox">
<label>
<input name='checkbox3_1' type="checkbox" value="reminder_value">
</label>
</div>
<div class="checkbox">
<label>
<input name='checkbox3_2' type="checkbox" value="reminder_value">
</label>
</div>
<div class="checkbox">
<label>
<input name='checkbox3_3' type="checkbox" value="reminder_value">
</label>
</div>
</div>
<div class="col-md-4">
</div>
</div>
</form>
</div>
......
Copyright (c) 2008-2014 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Jasmine Spec Runner v2.4.1</title>
<link rel="shortcut icon" type="image/png" href="../lib/jasmine-2.4.1/jasmine_favicon.png">
<link rel="stylesheet" href="../lib/jasmine-2.4.1/jasmine.css">
<script src="../lib/jasmine-2.4.1/jasmine.js"></script>
<script src="../lib/jasmine-2.4.1/jasmine-html.js"></script>
<script src="../lib/jasmine-2.4.1/boot.js"></script>
<script src="../helper/mock-ajax.js"></script>
<script src="../../../js/jquery.min.js"></script>
<script src="../../../js/bootstrap.min.js"></script>
<script src="../../../js/EventEmitter.min.js"></script>
<!-- include source files here... -->
<script src="../../../js/qfq.debug.js"></script>
<!-- include spec files here... -->
<script src="spec/FileUploadSpec.js"></script>
</head>
<body>
<div class="col-md-2 ">
<div class="btn-toolbar pull-right" role="toolbar">
<div class="btn-group" role="group">
<button id="save-button" type="button" class="btn btn-default navbar-btn"><span
class="glyphicon glyphicon-ok"></span></button>
<button id="close-button" type="button" class="btn btn-default navbar-btn"><span
class="glyphicon glyphicon-remove"></span></button>
</div>
<div class="btn-group" role="group">
<button id="delete-button" type="button" class="btn btn-default navbar-btn"><span
class="glyphicon glyphicon-trash"></span></button>
</div>
<div class="btn-group" role="group">
<a id="form-new-button" href="personmock.html?s=badcaffe1" class="btn btn-default navbar-btn"><span
class="glyphicon glyphicon-plus"></span></a>
</div>
</div>
</div>
<form id="myForm" class="form-horizontal" data-toggle="validator">
</form>
<script type="text/template" id="fileupload_new">
<input type="hidden" name="s" value="badcaffee1234">
<div class="form-group">
<div class="col-md-2">
<label for="fileupload" class="control-label">File upload</label>
</div>
<div class="col-md-6">
<div class="col-md-6">
<div class="uploaded-file hidden"><span class="uploaded-file-name">john.doe.png</span>
<button class="delete-file" data-sip="filedeletesip"
name="trash-picture:1"><span
class="glyphicon glyphicon-trash"></span></button>
</div>
<input id="fileupload" name="picture:1" class="hidden" type="file"
data-sip="fileuploadsip">
<div class="help-block with-errors"></div>
</div>
</div>
</div>
</script>
</body>
</html>
......@@ -316,6 +316,39 @@
</div>
</div>
<div class="form-group">
<div class="col-md-2">
<b class="control-label">
Checkbox 3 test
</b>
</div>
<div class="col-md-6">
<div class="checkbox">
<label>
<input name='checkbox3_1' type="checkbox" value="reminder_value">
</label>
</div>
<div class="checkbox">
<label>
<input name='checkbox3_2' type="checkbox" value="reminder_value">
</label>
</div>
<div class="checkbox">
<label>
<input name='checkbox3_3' type="checkbox" value="reminder_value">
</label>
</div>
</div>
<div class="col-md-4">
</div>
</div>
</form>
</section>
......
......@@ -290,8 +290,40 @@
</div>
</div>
</form>
<div class="form-group">
<div class="col-md-2">
<b class="control-label">
Checkbox 3 test
</b>
</div>
<div class="col-md-6">
<div class="checkbox">
<label>
<input name='checkbox3_1' type="checkbox" value="reminder_value">
</label>
</div>
<div class="checkbox">
<label>
<input name='checkbox3_2' type="checkbox" value="reminder_value">
</label>
</div>
<div class="checkbox">
<label>
<input name='checkbox3_3' type="checkbox" value="reminder_value">
</label>
</div>
</div>
<div class="col-md-4">
</div>
</div>
</form>
</section>
<% with (scripts) { %>
<% [].concat(polyfills, jasmine, boot, vendor, helpers, src, specs,reporters).forEach(function(script){ %>
......
......@@ -47,4 +47,31 @@ describe("Element Checkbox", function () {
expect($reminderCheckbox.prop('checked')).toBe(true);
expect($checkbox2.prop('checked')).toBe(false);
});
it('should properly handle several checkboxes in one Form Group', function () {
var $checkbox3_1 = $("[name='checkbox3_1']");
var $checkbox3_2 = $("[name='checkbox3_2']");
var $checkbox3_3 = $("[name='checkbox3_3']");
var checkbox3_1 = new QfqNS.Element.Checkbox($checkbox3_1);
checkbox3_1.setValue(true);
expect(checkbox3_1.getValue()).toBe(true);
expect($checkbox3_1.prop('checked')).toBe(true);
expect($checkbox3_2.prop('checked')).toBe(false);
expect($checkbox3_3.prop('checked')).toBe(false);
$('#myForm')[0].reset();
var checkbox3_2 = new QfqNS.Element.Checkbox($checkbox3_2);
checkbox3_2.setValue(true);
expect(checkbox3_2.getValue()).toBe(true);
expect($checkbox3_2.prop('checked')).toBe(true);
expect($checkbox3_1.prop('checked')).toBe(false);
expect($checkbox3_3.prop('checked')).toBe(false);
});
});
\ No newline at end of file
......@@ -97,7 +97,7 @@ describe("Element FormGroup", function () {
expect(personGender.hasHelpBlock()).toBe(true);
});
it("should properly disable the item", function () {
xit("should properly disable the item", function () {
personGender.setEnabled(false);
});
});
\ No newline at end of file
Supports Markdown
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