Jatin has uploaded a new change for review. https://gerrit.wikimedia.org/r/143598
Change subject: Added new input type - tokens ...................................................................... Added new input type - tokens Added a new input type - tokens into SF. This input type can be used wherever multiple values are allowed. Also, changed structure of select2 files by introducing a new base class that has some basic properties which can be inherited and extended by combobox and tokens. Change-Id: I51f2029e0f70f4aa1d99faadb9fd27b334e6ea3d --- M SemanticForms.php M i18n/en.json M includes/SF_FormPrinter.php M includes/forminputs/SF_TextWithAutocompleteInput.php A includes/forminputs/SF_TokensInput.php M libs/SemanticForms.js A libs/ext.sf.select2.base.js A libs/ext.sf.select2.combobox.js A libs/ext.sf.select2.tokens.js 9 files changed, 778 insertions(+), 3 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/SemanticForms refs/changes/98/143598/1 diff --git a/SemanticForms.php b/SemanticForms.php index 738f2ba..6e999ea 100644 --- a/SemanticForms.php +++ b/SemanticForms.php @@ -194,6 +194,7 @@ $GLOBALS['wgAutoloadClasses']['SFTreeInput'] = __DIR__ . '/includes/forminputs/SF_TreeInput.php'; $GLOBALS['wgAutoloadClasses']['SFCategoryInput'] = __DIR__ . '/includes/forminputs/SF_CategoryInput.php'; $GLOBALS['wgAutoloadClasses']['SFCategoriesInput'] = __DIR__ . '/includes/forminputs/SF_CategoriesInput.php'; +$GLOBALS['wgAutoloadClasses']['SFTokensInput'] = __DIR__ . '/includes/forminputs/SF_TokensInput.php'; $GLOBALS['wgJobClasses']['createPage'] = 'SFCreatePageJob'; $GLOBALS['wgAutoloadClasses']['SFCreatePageJob'] = __DIR__ . '/includes/SF_CreatePageJob.php'; @@ -316,7 +317,9 @@ 'ext.semanticforms.select2' => $sfgResourceTemplate + array( 'scripts' => array( 'libs/select2.js', - 'libs/ext.sf.select2.js', + 'libs/ext.sf.select2.base.js', + 'libs/ext.sf.select2.combobox.js', + 'libs/ext.sf.select2.tokens.js', ), 'styles' => array( 'skins/select2/select2.css', diff --git a/i18n/en.json b/i18n/en.json index e99a926..145274b 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -75,6 +75,7 @@ "sf_forminputs_width": "The width of this input, in pixels", "sf_forminputs_checkboxes_select_all": "Select all", "sf_forminputs_checkboxes_select_none": "Select none", + "sf_forminputs_maxtokens": "Maximum number of values that can be tokenized for a field", "createform": "Create a form", "sf-createform-with-name": "Create form: $1", "sf_createform_nameinput": "Form name", @@ -204,6 +205,6 @@ "sf-select2-searching": "Searching...", "sf-select2-input-too-short": "Please enter $1 or more characters", "sf-select2-input-too-long": "Search input too long", - "sf-select2-selection-too-big": "You cannot select any more choices", + "sf-select2-selection-too-big": "You can select only $1 choices", "sf-select2-load-more": "Loading more results..." } \ No newline at end of file diff --git a/includes/SF_FormPrinter.php b/includes/SF_FormPrinter.php index 8618929..3afd029 100644 --- a/includes/SF_FormPrinter.php +++ b/includes/SF_FormPrinter.php @@ -48,6 +48,7 @@ $this->registerInputType( 'SFTreeInput' ); $this->registerInputType( 'SFCategoryInput' ); $this->registerInputType( 'SFCategoriesInput' ); + $this->registerInputType( 'SFTokensInput' ); // All-purpose setup hook. wfRunHooks( 'sfFormPrinterSetup', array( $this ) ); diff --git a/includes/forminputs/SF_TextWithAutocompleteInput.php b/includes/forminputs/SF_TextWithAutocompleteInput.php index 712a4d7..acfdd29 100644 --- a/includes/forminputs/SF_TextWithAutocompleteInput.php +++ b/includes/forminputs/SF_TextWithAutocompleteInput.php @@ -88,7 +88,7 @@ } public static function setAutocompleteValues( $field_args ) { - global $sfgAutocompleteValues; + global $sfgAutocompleteValues, $sfgMaxLocalAutocompleteValues; // Get all autocomplete-related values, plus delimiter value // (it's needed also for the 'uploadable' link, if there is one). @@ -122,6 +122,10 @@ } else { $autocompleteValues = SFUtils::getAutocompleteValues( $autocompletionSource, $autocompleteFieldType ); } + if( count($autocompleteValues) > $sfgMaxLocalAutocompleteValues && + $autocompleteFieldType != 'values' && !array_key_exists( 'values dependent on', $field_args ) ) { + $remoteDataType = $autocompleteFieldType; + } $sfgAutocompleteValues[$autocompleteSettings] = $autocompleteValues; } return array( $autocompleteSettings, $remoteDataType, $delimiter ); diff --git a/includes/forminputs/SF_TokensInput.php b/includes/forminputs/SF_TokensInput.php new file mode 100644 index 0000000..2ba93a2 --- /dev/null +++ b/includes/forminputs/SF_TokensInput.php @@ -0,0 +1,146 @@ +<?php +/** + * File holding the SFTokensInput class + * + * @file + * @ingroup SF + */ + +/** + * The SFTokensInput class. + * + * @ingroup SFFormInput + */ +class SFTokensInput extends SFFormInput { + public static function getName() { + return 'tokens'; + } + + public static function getDefaultPropTypes() { + return array(); + } + + public static function getOtherPropTypesHandled() { + $otherPropTypesHandled = array( '_wpg' ); + if ( defined( 'SMWDataItem::TYPE_STRING' ) ) { + // SMW < 1.9 + $otherPropTypesHandled[] = '_str'; + } else { + $otherPropTypesHandled[] = '_txt'; + } + return $otherPropTypesHandled; + } + + public static function getDefaultPropTypeLists() { + return array(); + } + + public static function getOtherPropTypeListsHandled() { + $otherPropTypesListsHandled = array( '_wpg' ); + if ( defined( 'SMWDataItem::TYPE_STRING' ) ) { + // SMW < 1.9 + $otherPropTypesListsHandled[] = '_str'; + } else { + $otherPropTypesListsHandled[] = '_txt'; + } + return $otherPropTypesListsHandled; + } + + public static function getHTML( $cur_value, $input_name, $is_mandatory, $is_disabled, $other_args ) { + global $sfgTabIndex, $sfgFieldNum; + + list( $autocompleteSettings, $remoteDataType, $delimiter ) = SFTextWithAutocompleteInput::setAutocompleteValues( $other_args ); + + $className = 'sfTokens '; + $className .= ( $is_mandatory ) ? 'mandatoryField' : 'createboxInput'; + if ( array_key_exists( 'class', $other_args ) ) { + $className .= ' ' . $other_args['class']; + } + $input_id = 'input_' . $sfgFieldNum; + + if ( array_key_exists( 'size', $other_args ) ) { + $size = $other_args['size']; + } else { + $size = '35'; + } + + $inputAttrs = array( + 'id' => $input_id, + 'size' => $size, + 'class' => $className, + 'tabindex' => $sfgTabIndex, + 'autocompletesettings' => $autocompleteSettings, + ); + if ( array_key_exists( 'origName', $other_args ) ) { + $inputAttrs['origName'] = $other_args['origName']; + } + if ( array_key_exists( 'existing values only', $other_args ) ) { + $inputAttrs['existingvaluesonly'] = 'true'; + } + if ( !is_null( $remoteDataType ) ) { + $inputAttrs['autocompletedatatype'] = $remoteDataType; + } + if ( $is_disabled ) { + $inputAttrs['disabled'] = true; + } + if ( array_key_exists( 'maxlength', $other_args ) ) { + $inputAttrs['maxlength'] = $other_args['maxlength']; + } + if ( array_key_exists( 'placeholder', $other_args ) ) { + $inputAttrs['placeholder'] = $other_args['placeholder']; + } + if ( array_key_exists( 'max tokens', $other_args ) ) { + $inputAttrs['maxtokens'] = $other_args['max tokens']; + } + $text = "\n\t" . Html::input( $input_name, $cur_value, 'text', $inputAttrs ) . "\n"; + + $spanClass = 'inputSpan'; + if ( $is_mandatory ) { + $spanClass .= ' mandatoryFieldSpan'; + } + $text = "\n" . Html::rawElement( 'span', array( 'class' => $spanClass ), $text ); + + return $text; + } + + + public static function getParameters() { + $params = parent::getParameters(); + $params[] = array( + 'name' => 'size', + 'type' => 'int', + 'description' => wfMessage( 'sf_forminputs_size' )->text() + ); + $params[] = array( + 'name' => 'placeholder', + 'type' => 'string', + 'description' => wfMessage( 'sf_forminputs_placeholder' )->text() + ); + $params[] = array( + 'name' => 'existing values only', + 'type' => 'boolean', + 'description' => wfMessage( 'sf_forminputs_existingvaluesonly' )->text() + ); + $params[] = array( + 'name' => 'max tokens', + 'type' => 'int', + 'description' => wfMessage( 'sf_forminputs_maxtokens' )->text() + ); + $params = array_merge( $params, SFTextWithAutocompleteInput::getAutocompletionParameters() ); + + return $params; + } + + /** + * Returns the HTML code to be included in the output page for this input. + */ + public function getHtmlText() { + return self::getHTML( + $this->mCurrentValue, + $this->mInputName, + $this->mIsMandatory, + $this->mIsDisabled, + $this->mOtherArgs + ); + } +} diff --git a/libs/SemanticForms.js b/libs/SemanticForms.js index df3e462..5e6fc5b 100644 --- a/libs/SemanticForms.js +++ b/libs/SemanticForms.js @@ -983,6 +983,10 @@ this.find('.sfComboBox').not('#semantic_property_starter, .multipleTemplateStarter .sfComboBox, .select2-container').each( function() { combobox.apply($(this)); }); + var tokens = new sf.select2.tokens(); + this.find('.sfTokens').not('#semantic_property_starter, .multipleTemplateStarter .sfComboBox, .select2-container').each( function() { + tokens.apply($(this)); + }); this.find('.autoGrow').autoGrow(); this.find('.sfFancyBox').fancybox({ diff --git a/libs/ext.sf.select2.base.js b/libs/ext.sf.select2.base.js new file mode 100644 index 0000000..f3e4ca3 --- /dev/null +++ b/libs/ext.sf.select2.base.js @@ -0,0 +1,252 @@ +/* +* ext.sf.select2.base.js +* +* Base class to handle autocomplete +* for various input types using Select2 JS library +* +* @file +* +* +* @licence GNU GPL v2+ +* @author Jatin Mehta +* +*/ + +( function ( $, mw, sf ) { + 'use strict'; + /** + * Inheritance class for the sf.select2 constructor + * + * + * @class + */ + sf.select2 = sf.select2 = sf.select2 || {}; + + /** + * Class constructor + * + * + * @class + * @constructor + */ + sf.select2.base = function() { + + }; + + sf.select2.base.prototype = { + /* + * Applies select2 to the HTML element + * + * @param {HTMLElement} element + * + */ + apply: function( element ) { + this.id = element.attr( "id" ); + var opts = this.setOptions(); + + element.select2(opts); + element.on( "change", this.onChange ); + }, + /* + * Used to remove the select2 applied to the HTML element, + * the selected value will remain preserved. + * + * @param {HTMLElement} element + * + */ + destroy: function( element ) { + element.select2( "destroy" ); + }, + /* + * Returns options to be set by select2 + * + * @return {object} opts + * + */ + setOptions: function() { + var input_id = this.id; + var opts = {}; + var input_id = "#" + input_id; + var input_tagname = $(input_id).prop( "tagName" ); + var autocomplete_opts = this.getAutocompleteOpts(); + + if ( autocomplete_opts.autocompletedatatype != undefined ) { + opts.ajax = this.getAjaxOpts(); + opts.minimumInputLength = 1; + opts.formatInputTooShort = mw.msg( "sf-select2-input-too-short", opts.minimumInputLength ); + opts.formatResult = this.formatResult; + opts.formatSelection = this.formatSelection; + opts.escapeMarkup = function (m) { return m; }; + } else if ( input_tagname == "INPUT" ) { + opts.data = this.getData( autocomplete_opts.autocompletesettings ); + } + var sfgAutocompleteOnAllChars = mw.config.get( 'sfgAutocompleteOnAllChars' ); + if ( !sfgAutocompleteOnAllChars ) { + opts.matcher = function( term, text ) { return text.toUpperCase().indexOf(term.toUpperCase())==0; }; + } + opts.formatSearching = mw.msg( "sf-select2-searching" ); + opts.formatNoMatches = mw.msg( "sf-select2-no-matches" ); + opts.placeholder = $(input_id).attr( "placeholder" ); + if ( $(input_id).attr( "existingvaluesonly" ) !== "true" && input_tagname == "INPUT" ) { + opts.createSearchChoice = function( term, data ) { if ( $(data).filter(function() { return this.text.localeCompare( term )===0; }).length===0 ) {return { id:term, text:term };} }; + } + if ( $(input_id).val() != "" && input_tagname == "INPUT" ) { + opts.initSelection = function ( element, callback ) { var data = {id: element.val(), text: element.val()}; callback(data); }; + } + opts.allowClear = true; + var size = $(input_id).attr("size"); + if ( size == undefined ) { + size = 35; //default value + } + opts.containerCss = { 'min-width': size * 6 }; + opts.containerCssClass = 'sf-select2-container'; + opts.dropdownCssClass = 'sf-select2-dropdown'; + + return opts; + }, + /* + * Returns HTML text to be used by select2 for + * showing remote data retrieved + * + * @param {object} value + * @param {object} container + * @param {object} query + * + * @return {string} markup + * + */ + formatResult: function(value, container, query) { + var term = query.term.toLowerCase(); + var result = value.text; + var start = result.toLowerCase().indexOf(term); + var end = start + term.length - 1; + var markup = result.substr(0, start) + + '<span class="select2-match">' + + result.substr(start, end - start + 1) + + '</span>' + + result.substr(end + 1); + + return markup; + }, + /* + * Returns string/HTML text to be used by select2 to + * show selection + * + * @param {object} value (The selected result object) + * + * @return {string} + * + */ + formatSelection: function(value) { + return value.text; + }, + /* + * If a field is dependent on some other field in the form + * then it returns its name. + * + * @return {string} + * + */ + dependentOn: function() { + var input_id = "#" + this.id; + var name_attr = this.nameAttr( $(input_id) ); + var name = $(input_id).attr( name_attr ); + var dependent_on_me = []; + + var sfgDependentFields = mw.config.get( 'sfgDependentFields' ); + for ( var i = 0; i < sfgDependentFields.length; i++ ) { + var dependentFieldPair = sfgDependentFields[i]; + if ( dependentFieldPair[1] == name ) { + return dependentFieldPair[0]; + } + } + return null; + }, + /* + * Returns the array of names of fields in the form which are dependent + * on the field passed as a param to this function, + * + * @param {HTMLElement} element + * + * @return {associative array} dependent_on_me + * + */ + dependentOnMe: function( element ) { + var name_attr = this.nameAttr(element); + var name = element.attr( name_attr ); + var dependent_on_me = []; + + var sfgDependentFields = mw.config.get( 'sfgDependentFields' ); + for ( var i = 0; i < sfgDependentFields.length; i++ ) { + var dependentFieldPair = sfgDependentFields[i]; + if ( dependentFieldPair[0] == name ) { + dependent_on_me.push(dependentFieldPair[1]); + } + } + + return dependent_on_me; + }, + /* + * Returns the name attribute of the field depending on + * whether it is a part of multiple instance template or not + * + * @param {HTMLElement} element + * + * @return {string} + * + */ + nameAttr: function( element ) { + return this.partOfMultiple( element ) ? "origname" : "name"; + }, + /* + * Checks whether the field is part of multiple instance template or not + * + * @param {HTMLElement} element + * + * @return {boolean} + * + */ + partOfMultiple: function( element ) { + return element.attr( "origname" ) != undefined ? true : false; + }, + /* + * Gives dependent field options which include + * property, base property and base value + * + * @param {string} dep_on + * + * @return {object} dep_field_opts + * + */ + getDependentFieldOpts: function( dep_on ) { + var input_id = "#" + this.id; + var dep_field_opts = {}; + if ( this.partOfMultiple($(input_id)) ) { + var base_element = $(input_id).closest( ".multipleTemplateInstance" ) + .find( '[origname ="' + dep_on + '" ]' ); + } else { + var base_element = $('[name ="' + dep_on + '" ]'); + } + dep_field_opts.base_value = base_element.val(); + dep_field_opts.base_prop = base_element.attr( "autocompletesettings" ); + dep_field_opts.prop = $(input_id).attr( "autocompletesettings" ); + + return dep_field_opts; + }, + /* + * Gives autocomplete options for a field + * + * + * @return {object} autocomplete_opts + * + */ + getAutocompleteOpts: function() { + var input_id = "#" + this.id; + var autocomplete_opts = {}; + autocomplete_opts.autocompletedatatype = $(input_id).attr( "autocompletedatatype" ); + autocomplete_opts.autocompletesettings = $(input_id).attr( "autocompletesettings" ); + + return autocomplete_opts; + }, + }; +} )( jQuery, mediaWiki, semanticforms ); \ No newline at end of file diff --git a/libs/ext.sf.select2.combobox.js b/libs/ext.sf.select2.combobox.js new file mode 100644 index 0000000..7665355 --- /dev/null +++ b/libs/ext.sf.select2.combobox.js @@ -0,0 +1,149 @@ +/* + * ext.sf.select2.js + * + * Javascript utility class to handle autocomplete + * for combobox input type using Select2 JS library + * + * @file + * + * @licence GNU GPL v2+ + * @author Jatin Mehta + */ + +( function( $, mw, sf ) { + 'use strict'; + + /** + * Inheritance class for the sf.select2 constructor + * + * + * @class + */ + sf.select2 = sf.select2 = sf.select2 || {}; + + /** + * Class constructor + * + * + * @class + * @constructor + */ + sf.select2.combobox = function() { + + }; + + var combobox_proto = new sf.select2.base(); + /* + * Returns data to be used by select2 for combobox autocompletion + * + * @param {string} autocompletesettings + * @return {associative array} values + * + */ + combobox_proto.getData = function( autocompletesettings ) { + var values = [{id: 0, text: ""}]; + var dep_on = this.dependentOn(); + if ( dep_on == null ) { + var sfgAutocompleteValues = mw.config.get( 'sfgAutocompleteValues' ); + var data = sfgAutocompleteValues[autocompletesettings]; + var i = 0; + //Convert data into the format accepted by Select2 + if (data != undefined) { + data.forEach(function() + { + values.push({ + id: i + 1, text: data[i] + }); + i++; + }); + } + } else { //Dependent field autocompletion + var dep_field_opts = this.getDependentFieldOpts( dep_on ); + var my_server = mw.config.get( 'wgScriptPath' ) + "/api.php"; + my_server += "?action=sfautocomplete&format=json&property=" + dep_field_opts.prop + "&baseprop=" + dep_field_opts.base_prop + "&basevalue=" + dep_field_opts.base_value; + $.ajax({ + url: my_server, + dataType: 'json', + async: false, + success: function(data) { + var id = 1; + //Convert data into the format accepted by Select2 + data.sfautocomplete.forEach( function(item) { + values.push({ + id: id++, text: item.title + }); + }); + return values; + } + }); + } + + return values; + }; + /* + * Returns ajax options to be used by select2 for + * remote autocompletion of combobox + * + * @return {object} ajaxOpts + * + */ + combobox_proto.getAjaxOpts = function() { + var input_id = "#" + this.id; + var autocomplete_opts = this.getAutocompleteOpts(); + var my_server = mw.util.wikiScript( 'api' ); + my_server += "?action=sfautocomplete&format=json&" + autocomplete_opts.autocompletedatatype + "=" + autocomplete_opts.autocompletesettings; + + var ajaxOpts = { + url: my_server, + dataType: 'jsonp', + data: function (term) { + return { + substr: term, // search term + }; + }, + results: function (data, page, query) { // parse the results into the format expected by Select2. + var id = 0; + data.sfautocomplete.forEach( function(item) { + item.id = id++; + item.text = item.title; + }); + return {results: data.sfautocomplete}; + } + }; + + return ajaxOpts; + }; + /* + * Used to set the value of the HTMLInputElement + * when there is a change in the select2 value + * + */ + combobox_proto.onChange = function() { + var self = this; + var data = $(this).select2( "data" ); + if (data != null) { + $(this).val( data.text ); + } else { + $(this).val( '' ); + } + + // Set the corresponding values for any other field + // in the form which is deoendent on this element + var cmbox = new sf.select2.combobox(); + var dep_on_me = cmbox.dependentOnMe( $(this) ); + dep_on_me.forEach( function( dependent_field_name ) { + if ( cmbox.partOfMultiple( $(self) ) ) { + var dependent_field = $(self).closest( ".multipleTemplateInstance" ) + .find( '[origname ="' + dependent_field_name + '" ]' ); + } else { + var dependent_field = $('[name ="' + dependent_field_name + '" ]'); + } + cmbox.destroy($(dependent_field)); + $(dependent_field).val( '' ); + cmbox.apply($(dependent_field)); + }); + }; + + sf.select2.combobox.prototype = combobox_proto; + +} )( jQuery, mediaWiki, semanticforms ); \ No newline at end of file diff --git a/libs/ext.sf.select2.tokens.js b/libs/ext.sf.select2.tokens.js new file mode 100644 index 0000000..f29f704 --- /dev/null +++ b/libs/ext.sf.select2.tokens.js @@ -0,0 +1,215 @@ +/* + * ext.sf.select2.js + * + * Javascript utility class to handle autocomplete + * for tokens input type using Select2 JS library + * + * @file + * + * @licence GNU GPL v2+ + * @author Jatin Mehta + */ + +( function( $, mw, sf ) { + 'use strict'; + + /** + * Inheritance class for the sf.select2 constructor + * + * + * @class + */ + sf.select2 = sf.select2 = sf.select2 || {}; + + /** + * Class constructor + * + * + * @class + * @constructor + */ + sf.select2.tokens = function() { + + }; + + var tokens_proto = new sf.select2.base(); + /* + * Returns options to be set by select2 + * + * @return {object} opts + * + */ + tokens_proto.setOptions = function() { + var input_id = this.id; + var opts = {}; + var input_id = "#" + input_id; + var input_tagname = $(input_id).prop( "tagName" ); + var autocomplete_opts = this.getAutocompleteOpts(); + + if ( autocomplete_opts.autocompletedatatype != undefined ) { + opts.ajax = this.getAjaxOpts(); + opts.minimumInputLength = 1; + opts.formatInputTooShort = mw.msg( "sf-select2-input-too-short", opts.minimumInputLength ); + opts.formatResult = this.formatResult; + opts.formatSelection = this.formatSelection; + opts.escapeMarkup = function (m) { return m; }; + } else if ( input_tagname == "INPUT" ) { + opts.data = this.getData( autocomplete_opts.autocompletesettings ); + } + var sfgAutocompleteOnAllChars = mw.config.get( 'sfgAutocompleteOnAllChars' ); + if ( !sfgAutocompleteOnAllChars ) { + opts.matcher = function( term, text ) { return text.toUpperCase().indexOf(term.toUpperCase())==0; }; + } + opts.formatSearching = mw.msg( "sf-select2-searching" ); + opts.formatNoMatches = mw.msg( "sf-select2-no-matches" ); + opts.placeholder = $(input_id).attr( "placeholder" ); + if ( $(input_id).attr( "existingvaluesonly" ) !== "true" && input_tagname == "INPUT" ) { + opts.createSearchChoice = function( term, data ) { if ( $(data).filter(function() { return this.text.localeCompare( term )===0; }).length===0 ) {return { id:term, text:term };} }; + } + if ( $(input_id).val() != "" && input_tagname == "INPUT" ) { + opts.initSelection = function ( element, callback ) { var data = {id: element.val(), text: element.val()}; callback(data); }; + } + opts.allowClear = true; + var size = $(input_id).attr("size"); + if ( size == undefined ) { + size = 35; //default value + } + opts.containerCss = { 'min-width': size * 6 }; + opts.containerCssClass = 'sf-select2-container'; + opts.dropdownCssClass = 'sf-select2-dropdown'; + + opts.multiple = true; + var maxtokens = $(input_id).attr( "maxtokens" ); + if ( maxtokens != undefined ) { + opts.maximumSelectionSize = maxtokens; + opts.formatSelectionTooBig = mw.msg( "sf-select2-selection-too-big", maxtokens ); + } + opts.adaptContainerCssClass = function( clazz ) { if (clazz == "mandatoryField") return ""; }; + + return opts; + }; + /* + * Returns data to be used by select2 for tokens autocompletion + * + * @param {string} autocompletesettings + * @return {associative array} values + * + */ + tokens_proto.getData = function( autocompletesettings ) { + var values = [{id: 0, text: ""}]; + var dep_on = this.dependentOn(); + if ( dep_on == null ) { + var sfgAutocompleteValues = mw.config.get( 'sfgAutocompleteValues' ); + var data = sfgAutocompleteValues[autocompletesettings]; + var i = 0; + //Convert data into the format accepted by Select2 + if (data != undefined) { + data.forEach(function() + { + values.push({ + id: i + 1, text: data[i] + }); + i++; + }); + } + } else { //Dependent field autocompletion + var dep_field_opts = this.getDependentFieldOpts( dep_on ); + var my_server = mw.config.get( 'wgScriptPath' ) + "/api.php"; + my_server += "?action=sfautocomplete&format=json&property=" + dep_field_opts.prop + "&baseprop=" + dep_field_opts.base_prop + "&basevalue=" + dep_field_opts.base_value; + $.ajax({ + url: my_server, + dataType: 'json', + async: false, + success: function(data) { + var id = 1; + //Convert data into the format accepted by Select2 + data.sfautocomplete.forEach( function(item) { + values.push({ + id: id++, text: item.title + }); + }); + return values; + } + }); + } + + return values; + }; + /* + * Returns ajax options to be used by select2 for + * remote autocompletion of tokens + * + * @return {object} ajaxOpts + * + */ + tokens_proto.getAjaxOpts = function() { + var input_id = "#" + this.id; + var autocomplete_opts = this.getAutocompleteOpts(); + var data_source = autocomplete_opts.autocompletesettings.split(',')[0]; + var my_server = mw.util.wikiScript( 'api' ); + my_server += "?action=sfautocomplete&format=json&" + autocomplete_opts.autocompletedatatype + "=" + data_source; + + var ajaxOpts = { + url: my_server, + dataType: 'jsonp', + data: function (term) { + return { + substr: term, // search term + }; + }, + results: function (data, page, query) { // parse the results into the format expected by Select2. + var id = 0; + data.sfautocomplete.forEach( function(item) { + item.id = id++; + item.text = item.title; + }); + return {results: data.sfautocomplete}; + } + }; + + return ajaxOpts; + }; + /* + * Used to set the value of the HTMLInputElement + * when there is a change in the select2 value + * + */ + tokens_proto.onChange = function() { + var self = this; + var data = $(this).select2( "data" ); + + var tokens = new sf.select2.tokens(); + var delim = tokens.getDelimiter( $(this) ); + + if (data != null) { + var tokens_value = ""; + data.forEach( function( token ) { + tokens_value += token.text + delim; + }); + $(this).val( tokens_value ); + } else { + $(this).val( '' ); + } + }; + /* + * Returns delimiter for the token field + * + * @return {string} delimiter + * + */ + tokens_proto.getDelimiter = function ( element ) { + var field_values = element.attr('autocompletesettings').split( ',' ); + var delimiter = null; + if (field_values[1] == 'list') { + delimiter = ","; + if (field_values[2] != null) { + delimiter = field_values[2]; + } + } + + return delimiter; + }; + + sf.select2.tokens.prototype = tokens_proto; + +} )( jQuery, mediaWiki, semanticforms ); \ No newline at end of file -- To view, visit https://gerrit.wikimedia.org/r/143598 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I51f2029e0f70f4aa1d99faadb9fd27b334e6ea3d Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/SemanticForms Gerrit-Branch: master Gerrit-Owner: Jatin <mehtajati...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits