Created
September 15, 2022 11:36
-
-
Save 1234ru/85d64980510ac8a3bb370272fdf00a81 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// IE11 friendly syntax | |
var _Local = _Local || {}; | |
_Local.FIAS = function() {}; | |
/** | |
* @typedef {Object} FIAS~fieldsConfigItem | |
* @property {string} type - $.fias.types.city|street|etc. | |
* @property {string|void} selector - input[name="street"] | |
* @property {jQuery|void} fieldObject | |
* @property {Node|void} parentInput | |
* @property {Object} properties | |
* | |
*/ | |
/** | |
* @param {FIAS~fieldsConfigItem[]} fieldsConfig | |
* @param {object} fiasOptions // https://github.com/fias-api/jquery#%D1%81%D0%B2%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%B0-%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%B0-fias | |
* @param {jQuery|void} container // An element to search fields within | |
*/ | |
_Local.FIAS.prototype.setAutoComplete = function( | |
fieldsConfig, | |
fiasOptions, | |
container | |
) { | |
container = container || $(document.body); | |
var fields = this.initializeFields(fieldsConfig, container); | |
var fiasObject = this.createFIASobject(fields, fiasOptions); | |
this.updateFieldsFias(fields); | |
return fiasObject; | |
} | |
_Local.FIAS.prototype.initializeFields = function( | |
fieldsConfig, | |
fieldsContainer | |
) { | |
var i, cfg, field, parentInput, selector, | |
fields = []; | |
for (i = 0; i < fieldsConfig.length; i++) { | |
cfg = fieldsConfig[i]; | |
if (cfg.fieldObject) { | |
field = cfg.fieldObject; | |
} else { | |
selector = cfg.selector || 'input[name="' + cfg.type + '"]'; | |
field = fieldsContainer.find(selector); | |
} | |
// fiasObject = fiasObject.add(field); | |
field.fias('type', $.fias.type[cfg.type]); | |
if (parentInput = cfg.parentInput || fields[i - 1]) { | |
// Надо устанавливать и parentType, и parentInput, | |
// что странно, т.к. библиотека могла бы взять | |
// первое из второго. | |
field.fias('parentType', parentInput.fias('type')); | |
field.fias('parentInput', parentInput); | |
} | |
field.fias(cfg.properties || {}); | |
fields.push(field); | |
} | |
return fields; | |
} | |
_Local.FIAS.prototype.createFIASobject = function(fields, fiasOptions) { | |
var obj = $(); | |
for (var i = 0; i < fields.length; i++) { | |
obj = obj.add(fields[i]); | |
} | |
obj.fias(fiasOptions || {}); | |
return obj; | |
} | |
_Local.FIAS.prototype.updateFieldsFias = function(fields) { | |
var chain = new Promise(function (resolve) { | |
resolve(); | |
}); | |
for (var i = 0; i < fields.length; i++) { | |
chain = chain.then( | |
this.makeResolutionFunction(fields, i) | |
) | |
} | |
} | |
_Local.FIAS.prototype.makeResolutionFunction = function(fields, i) { | |
var obj = this; | |
// Помимо самого поля нужно еще дочернее и родительское: | |
// - дочернее - чтобы установить ему parentId | |
// (понадобится, когда придет время делать запрос | |
// для дочернего поля) | |
// - родительское - чтобы установить запросу parentType | |
// из type родительского (аналогичным образом получить id | |
// из родительского нельзя, т.к. id не сохраняется | |
// в свойствах fias). | |
return function(promiseResolutionResult) { | |
return obj.makeRequestPromise( | |
fields[i], | |
fields[i + 1], | |
promiseResolutionResult | |
); | |
}; | |
} | |
_Local.FIAS.prototype.makeRequestPromise = function( | |
input, | |
childInput, | |
parentResponseItem | |
) { | |
return new Promise(function(resolve, reject) { | |
var value = input.val(); | |
if (!value) { | |
return ; | |
} | |
var query = { | |
'type': input.fias('type'), | |
'name': value, | |
'limit': 1, // нужен только один элемент | |
}; | |
if (parentResponseItem) { | |
query.parentType = parentResponseItem.contentType; | |
query.parentId = parentResponseItem.id; | |
} | |
$.fias.api(query, function (response) { | |
// В бесплатной версии первым пунктом всегда приходит | |
// "Бесплатная версия...", независимо от limit, | |
// поэтому берем последний элемент. | |
// var item = Array.at(-1); // Это для ES-2022 | |
var responseItem = response[ response.length - 1]; | |
// Проверяем, что совпадение точное, а не по левой части. | |
if (responseItem && responseItem.name == query.name) { | |
if (childInput) { | |
childInput.fias('parentId', responseItem.id); | |
} | |
resolve(responseItem); | |
} | |
}); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment