Path: blob/master/webroot/rsrc/js/phuix/PHUIXFormControl.js
12241 views
/**1* @provides phuix-form-control-view2* @requires javelin-install3* javelin-dom4*/56JX.install('PHUIXFormControl', {78members: {9_node: null,10_labelNode: null,11_errorNode: null,12_inputNode: null,13_className: null,14_valueSetCallback: null,15_valueGetCallback: null,16_rawInputNode: null,17_tokenizer: null,1819setLabel: function(label) {20JX.DOM.setContent(this._getLabelNode(), label);21return this;22},2324setError: function(error) {25JX.DOM.setContent(this._getErrorNode(), error);26return this;27},2829setClass: function(className) {30this._className = className;31return this;32},3334setControl: function(type, spec) {35var node = this._getInputNode();3637var input;38switch (type) {39case 'tokenizer':40input = this._newTokenizer(spec);41break;42case 'select':43input = this._newSelect(spec);44break;45case 'points':46input = this._newPoints(spec);47break;48case 'optgroups':49input = this._newOptgroups(spec);50break;51case 'static':52input = this._newStatic(spec);53break;54case 'checkboxes':55input = this._newCheckboxes(spec);56break;57case 'text':58input = this._newText(spec);59break;60case 'remarkup':61input = this._newRemarkup(spec);62break;63default:64// TODO: Default or better error?65JX.$E('Bad Input Type');66return;67}6869JX.DOM.setContent(node, input.node);70this._valueGetCallback = input.get;71this._valueSetCallback = input.set;72this._rawInputNode = input.node;73this._tokenizer = input.tokenizer || null;7475return this;76},7778setValue: function(value) {79this._valueSetCallback(value);80return this;81},8283getValue: function() {84return this._valueGetCallback();85},8687getRawInputNode: function() {88return this._rawInputNode;89},9091getTokenizer: function() {92return this._tokenizer;93},9495getNode: function() {96if (!this._node) {9798var attrs = {99className: 'aphront-form-control ' + this._className + ' grouped'100};101102var content = [103this._getLabelNode(),104this._getErrorNode(),105this._getInputNode()106];107108this._node = JX.$N('div', attrs, content);109}110111return this._node;112},113114_getLabelNode: function() {115if (!this._labelNode) {116var attrs = {117className: 'aphront-form-label'118};119120this._labelNode = JX.$N('label', attrs);121}122123return this._labelNode;124},125126_getErrorNode: function() {127if (!this._errorNode) {128var attrs = {129className: 'aphront-form-error'130};131132this._errorNode = JX.$N('span', attrs);133}134135return this._errorNode;136},137138_getInputNode: function() {139if (!this._inputNode) {140var attrs = {141className: 'aphront-form-input'142};143144this._inputNode = JX.$N('div', attrs);145}146147return this._inputNode;148},149150_newTokenizer: function(spec) {151var build = JX.Prefab.newTokenizerFromTemplate(152spec.markup,153spec.config);154build.tokenizer.start();155156function get_value() {157return JX.keys(build.tokenizer.getTokens());158}159160function set_value(map) {161var tokens = get_value();162for (var ii = 0; ii < tokens.length; ii++) {163build.tokenizer.removeToken(tokens[ii]);164}165for (var k in map) {166var v = JX.Prefab.transformDatasourceResults(map[k]);167build.tokenizer.addToken(k, v);168}169}170171set_value(spec.value || {});172173return {174node: build.node,175get: get_value,176set: set_value,177tokenizer: build.tokenizer178};179},180181_newSelect: function(spec) {182var node = JX.Prefab.renderSelect(183spec.options,184spec.value,185{},186spec.order);187188return {189node: node,190get: function() {191return node.value;192},193set: function(value) {194node.value = value;195}196};197},198199_newStatic: function(spec) {200var node = JX.$N(201'div',202{203className: 'phui-form-static-action'204},205spec.description || '');206207return {208node: node,209get: function() {210return true;211},212set: function() {213return;214}215};216},217218_newCheckboxes: function(spec) {219var checkboxes = [];220var checkbox_list = [];221for (var ii = 0; ii < spec.keys.length; ii++) {222var key = spec.keys[ii];223var checkbox_id = 'checkbox-' + Math.floor(Math.random() * 1000000);224225var checkbox = JX.$N(226'input',227{228type: 'checkbox',229value: key,230id: checkbox_id231});232233checkboxes.push(checkbox);234235var label = JX.$N(236'label',237{238className: 'phuix-form-checkbox-label',239htmlFor: checkbox_id240},241JX.$H(spec.labels[key] || ''));242243var display = JX.$N(244'div',245{246className: 'phuix-form-checkbox-item'247},248[checkbox, label]);249250checkbox_list.push(display);251}252253var node = JX.$N(254'div',255{256className: 'phuix-form-checkbox-action'257},258checkbox_list);259260var get_value = function() {261var list = [];262for (var ii = 0; ii < checkboxes.length; ii++) {263if (checkboxes[ii].checked) {264list.push(checkboxes[ii].value);265}266}267return list;268};269270var set_value = function(value) {271value = value || [];272273if (!value.length) {274value = [];275}276277var map = {};278var ii;279for (ii = 0; ii < value.length; ii++) {280map[value[ii]] = true;281}282283for (ii = 0; ii < checkboxes.length; ii++) {284if (map.hasOwnProperty(checkboxes[ii].value)) {285checkboxes[ii].checked = 'checked';286} else {287checkboxes[ii].checked = false;288}289}290};291292set_value(spec.value);293294return {295node: node,296get: get_value,297set: set_value298};299},300301_newPoints: function(spec) {302return this._newText(spec);303},304305_newText: function(spec) {306var attrs = {307type: 'text',308value: spec.value309};310311var node = JX.$N('input', attrs);312313return {314node: node,315get: function() {316return node.value;317},318set: function(value) {319node.value = value;320}321};322},323324_newRemarkup: function(spec) {325var attrs = {};326327// We could imagine a world where this renders a full remarkup control328// with all the hint buttons and client behaviors, but today much of that329// behavior is defined server-side and thus this isn't a world we330// currently live in.331332var node = JX.$N('textarea', attrs);333node.value = spec.value || '';334335return {336node: node,337get: function() {338return node.value;339},340set: function(value) {341node.value = value;342}343};344},345346_newOptgroups: function(spec) {347var value = spec.value || null;348349var optgroups = [];350for (var ii = 0; ii < spec.groups.length; ii++) {351var group = spec.groups[ii];352var options = [];353for (var jj = 0; jj < group.options.length; jj++) {354var option = group.options[jj];355options.push(JX.$N('option', {value: option.key}, option.label));356357if (option.selected && (value === null)) {358value = option.key;359}360}361optgroups.push(JX.$N('optgroup', {label: group.label}, options));362}363364var node = JX.$N('select', {}, optgroups);365node.value = value;366367return {368node: node,369get: function() {370return node.value;371},372set: function(value) {373node.value = value;374}375};376}377378}379380});381382383