Commit 8296f78f authored by Rafael Ostertag's avatar Rafael Ostertag
Browse files

Added QfqNS.Element.getElement() function. Elements can now be set...

Added QfqNS.Element.getElement() function. Elements can now be set readonly/disabled. Renamed QfqNS.Element.Input to QfqNS.Element.Text.
parent 1bfd90fa
......@@ -2,6 +2,8 @@
* @author Rafael Ostertag <rafael.ostertag@math.uzh.ch>
*/
/* global $ */
if (!QfqNS) {
var QfqNS = {};
}
......@@ -13,6 +15,17 @@ if (!QfqNS.Element) {
(function (n) {
'use strict';
/**
* The Form element.
*
* It is not intended to be used directly. Use the specialized Objects such as Text and Radio.
*
* Its sole purpose is, to provide the means to check the type of $element
*
* @param $element {jQuery} jQuery object representing the Form Control.
*
* @constructor
*/
n.Element = function ($element) {
if (!$element || $element.length === 0) {
throw new Error("No element");
......@@ -54,4 +67,12 @@ if (!QfqNS.Element) {
return isOfType;
};
n.Element.prototype.setReadOnly = function (readOnly) {
this.formGroup.setReadOnly(readOnly);
};
n.Element.prototype.setEnabled = function (enabled) {
this.formGroup.setEnabled(enabled);
};
})(QfqNS.Element);
\ No newline at end of file
......@@ -13,6 +13,17 @@ if (!QfqNS.Element) {
(function (n) {
'use strict';
/**
* Form Group represents a `<input>/<select>` element including the label and help block.
*
* It is not meant to be used directly. Use Element instead.
*
* @param $enclosedElement {jQuery} a jQuery object contained in the Form Group. It used to find the enclosing
* HTML element having the `.form-group` class assigned.
*
*
* @constructor
*/
n.FormGroup = function ($enclosedElement) {
if (!$enclosedElement || $enclosedElement.length === 0) {
throw new Error("No enclosed element");
......@@ -58,7 +69,55 @@ if (!QfqNS.Element) {
};
n.FormGroup.prototype.setReadOnly = function (readonly) {
this.$element.propr('readonly', readonly);
this.$element.prop('readonly', readonly);
this.handleReadOnlyEmulationIfRequired(readonly);
};
/**
* @private
* @param readonlyState
*/
n.FormGroup.prototype.handleReadOnlyEmulationIfRequired = function (readonlyState) {
if (!this.readOnlyEmulationRequired()) {
return;
}
if (readonlyState) {
// In case we're called with readonlyState===true twice in a row, make sure only one handler will be
// active at a time
this.$element.off('click', this.readOnlyHandler);
this.$element.on('click', this.readOnlyHandler);
} else {
this.$element.off('click', this.readOnlyHandler);
}
};
n.FormGroup.prototype.readOnlyEmulationRequired = function () {
// Keep this at top, since select does not feature the type attribute.
if (n.readOnlyIgnored.indexOf(this.$element[0].nodeName.toLowerCase())) {
return true;
}
if (!this.$element[0].hasAttribute('type')) {
// if there is no type attribute, browsers default to text, which is `properly implements` read only.
return false;
}
if (n.readOnlyIgnored.indexOf(this.$element[0].getAttribute('type').toLowerCase())) {
return true;
}
return false;
};
/**
* Read Only click handler.
*
* Since the readonly attribute does not work as expected on certain input types, emulate read only
*/
n.FormGroup.prototype.readOnlyHandler = function () {
return false;
};
......
/**
* @author Rafael Ostertag <rafael.ostertag@math.uzh.ch>
*/
/* global $ */
if (!QfqNS) {
var QfqNS = {};
}
if (!QfqNS.Element) {
QfqNS.Element = {};
}
(function (n) {
'use strict';
n.getElement = function (name) {
var $element = $('[name=' + name + ']');
if ($element.length === 0) {
throw Error('No element with name "' + name + '" found.');
}
if ($element[0].nodeName.toLowerCase() === "select") {
return new n.Select($element);
}
if (!$element[0].hasAttribute('type')) {
return new n.Text($element);
}
var type = $element[0].getAttribute('type').toLowerCase();
switch (type) {
case 'checkbox':
return new n.Checkbox($element);
case 'radio':
return new n.Radio($element);
case 'text':
return new n.Text($element);
default:
throw new Error("Don't know how to handle <input> of type '" + type + "'");
}
};
})(QfqNS.Element);
\ No newline at end of file
......@@ -19,7 +19,7 @@ if (!QfqNS.Element) {
* @param $element
* @constructor
*/
function Input($element) {
function Text($element) {
n.Element.call(this, $element);
if (!this.isType("text")) {
......@@ -27,17 +27,17 @@ if (!QfqNS.Element) {
}
}
Input.prototype = Object.create(n.Element.prototype);
Input.prototype.constructor = Input;
Text.prototype = Object.create(n.Element.prototype);
Text.prototype.constructor = Text;
Input.prototype.setValue = function (val) {
Text.prototype.setValue = function (val) {
this.formGroup.$element.val(val);
};
Input.prototype.getValue = function () {
Text.prototype.getValue = function () {
return this.formGroup.$element.val();
};
n.Input = Input;
n.Text = Text;
})(QfqNS.Element);
\ No newline at end of file
......@@ -45,4 +45,17 @@ if (!QfqNS.Element) {
'color'
];
/*
* See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input for input types ignoring the readonly
* attribute.
*/
n.readOnlyIgnored = [
'hidden',
'range',
'checkbox',
'radio',
'file',
'select'
];
})(QfqNS.Element);
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="../css/bootstrap.min.css">
<link rel="stylesheet" href="../css/bootstrap-theme.min.css">
<link rel="stylesheet" href="../css/jqx.base.css">
<link rel="stylesheet" href="../css/jqx.darkblue.css">
<link rel="stylesheet" href="../css/qfq-bs.css">
<title>Readonly Element Mock</title>
</head>
<body>
<button id="readonlyon">Readonly On</button>
<button id="readonlyoff">Readonly Off</button>
<button id="disabledon">Disabled On</button>
<button id="disabledoff">Disabled Off</button>
<div class="container-fluid">
<div class="row hidden-xs">
<div class="col-md-12">
<h1>Title with a long text</h1>
</div>
</div>
<form id="myForm" class="form-horizontal">
<div class="form-group">
<div class="col-md-2">
<label for="text" class="control-label">Text input</label>
</div>
<div class="col-md-6">
<input id="text" type="text" class="form-control">
</div>
</div>
<div class="form-group">
<div class="col-md-2">
<label for="select" class="control-label">Select</label>
</div>
<div class="col-md-6">
<select id="select" class="form-control">
<option>a</option>
<option>b</option>
<option>c</option>
</select>
</div>
</div>
<div class="form-group">
<div class="col-md-2">
<b class="control-label">
Radio
</b>
</div>
<div class="col-md-6">
<div class="radio">
<label>
<input type="radio" name="gender">a
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="gender">b
</label>
</div>
</div>
<div class="col-md-4">
<p class="help-block"></p>
</div>
</div>
<div class="form-group">
<div class="col-md-2">
<b class="control-label">
Checkbox
</b>
</div>
<div class="col-md-6">
<div class="checkbox">
<label>
<input type="checkbox" id="checkbox">
</label>
<p class="help-block"></p>
</div>
</div>
</div>
</form>
</div>
<script src="../js/jquery.min.js"></script>
<script src="../js/bootstrap.min.js"></script>
<script src="../js/jqx-all.js"></script>
<script src="../js/qfq.debug.js"></script>
<script type="text/javascript">
$(function () {
var textInput, select, radio, checkbox;
textInput = new QfqNS.Element.Text($('#text'));
select = new QfqNS.Element.Select($('#select'));
radio = new QfqNS.Element.Radio($('input[type=radio]'));
checkbox = new QfqNS.Element.Checkbox($('#checkbox'));
QfqNS.Log.level = 0;
$('#readonlyon').click(function () {
textInput.setReadOnly(true);
select.setReadOnly(true);
radio.setReadOnly(true);
checkbox.setReadOnly(true);
});
$('#readonlyoff').click(function () {
textInput.setReadOnly(false);
select.setReadOnly(false);
radio.setReadOnly(false);
checkbox.setReadOnly(false);
});
$('#disabledon').click(function () {
textInput.setEnabled(false);
select.setEnabled(false);
radio.setEnabled(false);
checkbox.setEnabled(false);
});
$('#disabledoff').click(function () {
textInput.setEnabled(true);
select.setEnabled(true);
radio.setEnabled(true);
checkbox.setEnabled(true);
});
});
</script>
</body>
</html>
\ No newline at end of file
......@@ -28,6 +28,7 @@
<script src="spec/ElementRadioSpec.js"></script>
<script src="spec/ElementSelectSpec.js"></script>
<script src="spec/ElementCheckboxSpec.js"></script>
<script src="spec/ElementSpec.js"></script>
<script src="spec/BSTabsSpec.js"></script>
<script src="spec/PageTitleSpec.js"></script>
<script src="spec/FormSpec.js"></script>
......@@ -211,7 +212,7 @@
<label for="personTitle" class="control-label">Titel</label>
</div>
<div class="col-md-6">
<select id="personTitle" class="form-control">
<select id="personTitle" class="form-control" name="personTitle">
<option>none</option>
<option>Dr.</option>
<option>Prof. Dr.</option>
......
......@@ -22,5 +22,4 @@ describe("Element Element", function () {
expect(element.isType("checkbox")).toBe(false);
});
});
/**
* @author Rafael Ostertag <rafael.ostertag@math.uzh.ch>
*/
/* global describe */
/* global it */
/* global expect */
/* global QfqNS */
/* global beforeAll */
/* global jasmine */
/* global $ */
describe('Element namespace function getElement()', function () {
'use strict';
it("should get the proper element instance for radio", function () {
var element = QfqNS.Element.getElement('gender');
expect(element instanceof QfqNS.Element.Radio).toBe(true);
});
it("should get the proper element instance for text", function () {
var element = QfqNS.Element.getElement('personHandle');
expect(element instanceof QfqNS.Element.Text).toBe(true);
});
it("should get the proper element instance for checkbox", function () {
var element = QfqNS.Element.getElement('reminder');
expect(element instanceof QfqNS.Element.Checkbox).toBe(true);
});
it("should get the proper element instance for select", function () {
var element = QfqNS.Element.getElement('personTitle');
expect(element instanceof QfqNS.Element.Select).toBe(true);
});
it("should throw on non-existent name", function () {
expect(function () {
QfqNS.Element.getElement('no_such_name');
}).toThrow();
});
});
......@@ -16,18 +16,16 @@ describe("Element Text", function () {
beforeAll(function () {
$textInput = $("input[name='personHandle']");
textInput = new QfqNS.Element.Input($textInput);
textInput = new QfqNS.Element.Text($textInput);
});
it("should throw on wrong type", function () {
expect(function () {
new QfqNS.Element.Input($("input[name='gender']"));
new QfqNS.Element.Text($("input[name='gender']"));
}).toThrow();
});
it("should set text", function () {
textInput.setValue("new value");
expect($textInput.val()).toBe("new value");
});
......
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