// Constants ----------------------------------------------- var API_PAGE_SIZE = 100 var LIVE_IMAGE_UPLOAD_URL = '/common/live-image-upload/create/' var STUB_IMAGE_URL = '/static/img/profile.jpg' // Plugins init -------------------------------------------- $('.datepicker').datepicker() $('[data-tooltip]').tooltip({ container: 'body', // Remove unwanted side-effects trigger : 'hover', // Disable tooltip remaining visible after a click }) // Specialization select ----------------------------------- ;(function() { var specSelectOptions = { language: 'ru', //minimumInputLength: 1, // Commented out to immediately load remote data placeholder: 'Выберите специализацию', // Required by `allowClear` allowClear: true, ajax: { url: null, dataType: 'json', quietMillis: 250, cache: true, data: function(term, page) { return { name__icontains: term, page: page, } }, results: function(data, page) { return { results: _.map(function(item) { return { id: item.id, text: _.repeat(item.level-1, '  ') + item.name, origItem: item, } }, data.results), more: (page * API_PAGE_SIZE) < data.count, } }, }, } $('.-spec-work-type-combo-container').each(function(i, container) { var $container = $(container) var $specSelects = $container.find('.-spec-select') var $chosenSpecId = $container.find('.-chosen-spec-id').first() var $specSelect1 = $container.find('.-spec-select-level-1').first() window.select = $specSelect1 var $specSelect2 = $container.find('.-spec-select-level-2').first() var $specSelect3 = $container.find('.-spec-select-level-3').first() var $specSelect4 = $container.find('.-spec-select-level-4').first() var specSelects = [$specSelect1, $specSelect2, $specSelect3, $specSelect4] var $workTypeSelect = $container.find('.-project-work-type-select-field').first() if (!_.isEmpty($workTypeSelect)) { var workTypeId = Number($workTypeSelect.find('option:selected').first().val()) || 1 $workTypeSelect.on('change', function($evt) { var $that = $(this) var workTypeId = Number($that.val()) reinitSpecializationsByWorkType(specSelects, workTypeId).then(function(rootSpec) { updateSpecializationWidgets(rootSpec.id, $container, $chosenSpecId, specSelects) }) }) } else { var $workTypeRadios = $container.find('.-project-work-type-radios-container').first().find('input[type=radio]') if (!_.isEmpty($workTypeRadios)) { var workTypeId = Number($workTypeRadios.filter(':checked').val()) || 1 $workTypeRadios.on('change', function($evt) { var $that = $(this) var workTypeId = Number($that.val()) reinitSpecializationsByWorkType(specSelects, workTypeId).then(function(rootSpec) { updateSpecializationWidgets(rootSpec.id, $container, $chosenSpecId, specSelects) }) }) } else { var workTypeId = 1 } } reinitSpecializationsByWorkType(specSelects, workTypeId).then(function(rootSpec_) { updateSpecializationWidgets(null, $container, $chosenSpecId, specSelects) }) var chosenSpecId = $chosenSpecId.val() if (chosenSpecId) updateSpecializationWidgets(chosenSpecId, $container, $chosenSpecId, specSelects) $specSelects.on('change', function($evt) { var specId = $evt.added ? $evt.added.id : null updateSpecializationWidgets(specId, $container, $chosenSpecId, specSelects) }) }) function reinitSpecializationsByWorkType(specSelects, workTypeId) { return $.get('/api/specializations/?parent__name=_root') .then(function(res) { var rootSpecs = res.results if (workTypeId == null) { var url = '/api/specializations/' var specId = null } else { var rootSpec = ({1: rootSpecs[0], 2: rootSpecs[1], 3: rootSpecs[2]})[workTypeId] var specId = rootSpec.id var url = format('/api/specializations/?lft__gte=%s&rght__lte=%s', rootSpec.lft, rootSpec.rght) } specSelects[0].select2(_.merge(specSelectOptions, {ajax: {url: url}})) specSelects[1].select2(_.merge(specSelectOptions, {ajax: {url: null}})) specSelects[2].select2(_.merge(specSelectOptions, {ajax: {url: null}})) specSelects[3].select2(_.merge(specSelectOptions, {ajax: {url: null}})) // TODO: Hardcoded: specSelects[0].select2('container').closest('.-single-spec-select').css('display', workTypeId === 2 ? 'none' : 'block') specSelects[1].select2('container').closest('.-single-spec-select').find('.-dynamic-label').first().text(workTypeId === 2 ? 'Перечень услуг' : 'Стадия проекта') return rootSpec }) } function updateSpecializationWidgets(specId, $container, $chosenSpecId, specSelects) { return getSpecializationTree(specId).then(function(specs) { var spec = specs.spec specSelects[1].select2(_.merge(specSelectOptions, {ajax: {url: specs.urlLevel2}})) specSelects[2].select2(_.merge(specSelectOptions, {ajax: {url: specs.urlLevel3}})) specSelects[3].select2(_.merge(specSelectOptions, {ajax: {url: specs.urlLevel4}})) var specLevel1 = specs.specLevel1; var specLevel2 = specs.specLevel2; var specLevel3 = specs.specLevel3; var specLevel4 = specs.specLevel4; specSelects[0].select2('data', specLevel1 ? {id: specLevel1.id, text: specLevel1.name, origItem: specLevel1} : null) specSelects[1].select2('data', specLevel2 ? {id: specLevel2.id, text: specLevel2.name, origItem: specLevel2} : null) specSelects[2].select2('data', specLevel3 ? {id: specLevel3.id, text: specLevel3.name, origItem: specLevel3} : null) specSelects[3].select2('data', specLevel4 ? {id: specLevel4.id, text: specLevel4.name, origItem: specLevel4} : null) $chosenSpecId.val(specId) specSelects[1].select2('enable', Boolean(specLevel1 && !_.isEmpty(specLevel1.children))) specSelects[2].select2('enable', Boolean(specLevel2 && !_.isEmpty(specLevel2.children))) specSelects[3].select2('enable', Boolean(specLevel3 && !_.isEmpty(specLevel3.children))) specializationTreeHasLevels(specId).then(function(haveLevels) { specSelects[1].select2('container').closest('.-single-spec-select').css('display', haveLevels.level2 ? 'block' : 'none') specSelects[2].select2('container').closest('.-single-spec-select').css('display', haveLevels.level3 ? 'block' : 'none') specSelects[3].select2('container').closest('.-single-spec-select').css('display', haveLevels.level4 ? 'block' : 'none') }) }) } }()) // Specialization select (simple) ------------------------------- ;(function() { var simpleSpecSelectsOptions = { language: 'ru', placeholder: 'Выберите специализацию', // Required by `allowClear` allowClear: true, ajax: { url: '/api/specializations/', dataType: 'json', quietMillis: 250, cache: true, data: function(term, page) { return { name__icontains: term, page: page, } }, results: function(data, page) { return { results: _.map(function(item) { return { id: item.id, text: _.repeat(item.level-1, '  ') + item.name, origItem: item, } }, data.results), more: (page * API_PAGE_SIZE) < data.count, } }, }, //initSelection: function(element, callback) { // var id = $(element).val() // // if (id !== '') { // $.ajax({url: '/api/specializations/' + id + '/', method: 'GET', dataType: 'json'}) // .then(function(data) {callback(data)}) // } //} } var $simpleSpecContainer = $('#simpleSpecContainer') var $emptySimpleSpecWidget = $simpleSpecContainer.find('.-simple-spec-widget').first() $simpleSpecContainer.find('.-chosen-simple-spec-id').each(function(i, el) { var $el = $(el) var specId = Number($el.val()) if (specId) initSimpleSpecSelect2($el.closest('.-simple-spec-widget').find('.-simple-spec-select').first(), specId) }) $('#addSpec').on('click', function($evt) { var $newSimpleSpecWidget = $emptySimpleSpecWidget.clone() $simpleSpecContainer.append($newSimpleSpecWidget) var $newSimpleSpecSelect = $newSimpleSpecWidget.find('.-simple-spec-select').first() initSimpleSpecSelect2($newSimpleSpecSelect).then(function() { $newSimpleSpecWidget.css('display', 'block') }) }) $simpleSpecContainer.on('change', '.-simple-spec-select', function($evt) { if ($evt.added) $(this).parent().children('.-chosen-simple-spec-id').first().val($evt.added.id) }) function initSimpleSpecSelect2($select, specId) { $select.select2(simpleSpecSelectsOptions) if (specId) { return $.get(format('/api/specializations/%s/', specId)) .then(function(spec) { $select.select2('data', { id: spec.id, text: _.repeat(spec.level-1, '  ') + spec.name, origItem: spec, }) }) } else { return $.when() } } }()) // Team invitation contractor select ------------------------------- ;(function() { var contractorSelectOptions = { language: 'ru', placeholder: 'Выберите пользователя', // Required by `allowClear` allowClear: true, ajax: { url: '/api/users/', dataType: 'json', quietMillis: 250, cache: true, data: function(term, page) { return { username__icontains: term, page: page, is_contractor: 'true', } }, results: function(data, page) { return { results: _.map(function(item) { return { id: item.id, text: format('%s (%s)', item.username, item.get_full_name), origItem: item, } }, data.results), more: (page * API_PAGE_SIZE) < data.count, } }, }, } function initContractorSelect($select, excludeIds) { contractorSelectOptions.ajax.url = format('%s?id__in!=%s', contractorSelectOptions.ajax.url, excludeIds.join(',')) return $select.select2(contractorSelectOptions) } window.initContractorSelect = initContractorSelect }()) // Order offer project select --------------------------------------------- ;(function() { var projectSelectOptions = { language: 'ru', placeholder: 'Выберите проект', // Required by `allowClear` allowClear: true, } function initProjectSelect($select, customerId, contractorId) { var urlObj = new URI('/api/projects/') urlObj.setQuery({ state: 'active', customer: customerId, order__contractor__isnull: true, order__team__isnull: true, x_no_contractor_answer: contractorId, }) return $.get(urlObj.href()).then(function(res) { var projects = res.results $select.select2(_.merge(projectSelectOptions, { data: _.map(function(project) { return { id: project.id, //text: project.name, text: format('%s (%s)', project.name, project.id), // Tmp origItem: project, } }, projects), })) }) } window.initProjectSelect = initProjectSelect }()) // Location select ---------------------------------------------- ;(function() { var $locationSelects = $('.-location-select') var locationSelectOptions = { language: 'ru', placeholder: 'Выберите местоположение', // Required by `allowClear` allowClear: true, } var $countrySelect = $('.-location-select-country') var $regionSelect = $('.-location-select-region') var $citySelect = $('.-location-select-city') // Initialize: getLocationTree(null).then(function(locs) { $countrySelect.select2(_.merge(locationSelectOptions, {data: locs.countries})) $regionSelect.select2(_.merge(locationSelectOptions, {data: locs.regions})) $citySelect.select2(_.merge(locationSelectOptions, {data: locs.cities})) var chosenLocId = $('#chosenLocationId').val() if (chosenLocId) updateLocationWidgets(chosenLocId) }) $locationSelects.on('change', function($evt) { updateLocationWidgets($evt.added ? $evt.added.id : null) }) function updateLocationWidgets(locId) { return getLocationTree(locId).then(function(locs) { $countrySelect.select2({data: locs.countries}) $regionSelect.select2({data: locs.regions}) $citySelect.select2({data: locs.cities}) var loc = locs.location if (loc && loc.level === 1) { $countrySelect.select2('val', locs.country.id) } else if (loc && loc.level === 2) { $regionSelect.select2('val', locs.region.id) $countrySelect.select2('val', locs.country.id) } else if (loc && loc.level === 3) { $citySelect.select2('val', locs.city.id) $regionSelect.select2('val', locs.region.id) $countrySelect.select2('val', locs.country.id) } if (loc) $('#chosenLocationId').val(loc.id) }) } $('#realtyId').on('change', function($evt) { var realtyId = Number($(this).val()) if (realtyId) { loadRealtyDetails(realtyId).then(function(res) { $('#realtyName').val(res.name) $('#realtyBuildingClassificationId').val(res.building_classification.id).change() $('#realtyConstructionTypeId').val(res.construction_type.id).change() updateLocationWidgets(res.location.id) }) } else { $('#realtyName').val('') $('#realtyBuildingClassificationId').val('').change() $('#realtyConstructionTypeId').val('').change() updateLocationWidgets(null) } }) function loadRealtyDetails(realtyId) { return $.ajax({ url: '/api/realties/' + realtyId + '/', method: 'GET', dataType: 'json', }) .then(function(res) {return res}) } }()) // File uploading --------------------------------------- // TODO: Add file number and overall size limit support ;(function() { var $fileUploadContainer = $('#fileUploadContainer') $('#fileUploadAddBtn').on('click', function($evt) { $fileUploadContainer.find('.file-upload-widget').last().find('.file-upload-input').click() }) $fileUploadContainer.on('change', '.file-upload-input', function($evt) { var $fileInput = $(this) var $fileUploadWidget = $fileInput.closest('.file-upload-widget') var filePath = $fileInput.val().replace(/\\/g, '/') var fileName = path.basename(filePath) //var fileExt = path.extname(filePath) var fileSize = $fileInput.get(0).files && humanFileSize($fileInput.get(0).files[0].size) if (fileName) { $fileUploadWidget.find('.file-upload-label').text(fileName + ' ' + fileSize) var $newFileUploadWidget = $fileUploadWidget.clone() $newFileUploadWidget.find('.file-upload-label').text('') $fileUploadContainer.find('ul').first().append($newFileUploadWidget) $fileUploadWidget.css('display', 'block') } }) $fileUploadContainer.on('click', '.file-upload-remove-btn', function($evt) { var $btn = $(this) $btn.closest('.file-upload-widget').remove() }) $fileUploadContainer.on('click', '.existing-file-remove-btn', function($evt) { var $btn = $(this) $btn.closest('.existing-file-widget').remove() }) }()) // Project answer portfolio selection ---------------------- $('input[type="checkbox"].answer-portfolio-select').on('change', function($evt) { var $that = $(this) if ($('input[type="checkbox"].answer-portfolio-select:checked').length > 4) { $that.prop('checked', false) return } var portfId = $that.val() var $container = $('#answer-portfolio-photo-widget-container') if ($that.prop('checked')) { $.ajax({url: '/api/portfolios/' + portfId + '/', method: 'GET', dataType: 'json'}) .then(function(portf) { var photoUrl = portf.photos[0].img var $newWidget = $container.find('.answer-portfolio-photo-widget').first().clone() $newWidget.data('portf-id', portfId) var $newWidgetPhotoCont = $newWidget.find('.answer-portfolio-photo-widget-photo-cont').first() $newWidgetPhotoCont.css('background', 'url("' + photoUrl + '") no-repeat center') $container.append($newWidget) $newWidget.css('display', 'block') }) } else { var $widgets = $container.find('.answer-portfolio-photo-widget') var $widget = _.find(function(el) {return $(el).data('portf-id') === portfId}, $widgets) $widget.remove() } }) var initialPortfIds = $('input[type="checkbox"]:checked.answer-portfolio-select').map(function(i, el) {return $(el).val()}) loadAllPhotos(initialPortfIds) function loadAllPhotos(portfIds) { var $container = $('#answer-portfolio-photo-widget-container') _.each(function(portfId) { $.ajax({url: '/api/portfolios/' + portfId + '/', method: 'GET', dataType: 'json'}) .then(function(portf) { var photoUrl = portf.photos[0].img var $newWidget = $container.find('.answer-portfolio-photo-widget').first().clone() $newWidget.data('portf-id', portfId) var $newWidgetPhotoCont = $newWidget.find('.answer-portfolio-photo-widget-photo-cont').first() $newWidgetPhotoCont.css('background', 'url("' + photoUrl + '") no-repeat center') $container.append($newWidget) $newWidget.css('display', 'block') }) }, portfIds) } // Live image upload -------------------------------------------- ;(function() { var $container = $('.-live-image-upload-container').first() var $liveImageUploadField = $container.find('.-live-image-upload-field').first() var liveImageDeleteClass = '.-live-image-delete' var $imageDeleteBtns = $('.-image-delete') var templ = _.template($container.find('.-templ').first().html()) var $res = $container.find('.-res').first() var images = [] $liveImageUploadField.fileupload({ url: LIVE_IMAGE_UPLOAD_URL, dataType: 'json', done: function($evt, data) { var image = data.result images.push(image) render() } }) $container.on('click', liveImageDeleteClass, function($evt) { var $that = $(this) var image = _.find({id: $that.data('imageId')}, images) $.post(image.deleteUrl).then(function(res) { if (res.status == 'success') { remove(images, image) render() } }) }) $imageDeleteBtns.on('click', function($evt) { $(this).closest('.-image-widget').remove() }) // Helpers -------------------------------- function render() { $res.html(templ({images: images})) } }()) // Live image avatar (single) upload --------------------------------- ;(function() { var $container = $('.-live-image-avatar-upload-container').first() var $avatarImage = $container.find('.-avatar-image').first() var $liveImageUpload = $container.find('.-live-image-upload').first() var $liveImageId = $container.find('.-live-image-id').first() var $liveImageDelete = $container.find('.-live-image-delete').first() $avatarImage.attr('orig-src', $avatarImage.attr('src')) $liveImageUpload.fileupload({ url: LIVE_IMAGE_UPLOAD_URL, dataType: 'json', done: function($evt, data) { var image = data.result $avatarImage.attr('src', image.thumbnailUrl) $liveImageId.val(image.id) $liveImageDelete.data('url', image.deleteUrl) $liveImageDelete.css('display', 'block') } }) $liveImageDelete.on('click', function($evt) { var $that = $(this) $.post($that.data('url')).then(function(res) { if (res.status == 'success') { $avatarImage.attr('src', $avatarImage.attr('orig-src') || STUB_IMAGE_URL) $liveImageId.val('') $that.css('display', 'none') } }) }) }()) // Helpers --------------------------------------------- function getSpecializationTree(specId) { var specs = { spec: null, specLevel1: null, specLevel2: null, specLevel3: null, specLevel4: null, urlLevel2: null, urlLevel3: null, urlLevel4: null, } if (specId === null) { return $.when(specs) } else { return $.ajax({url: '/api/specializations/' + specId + '/', method: 'GET', dataType: 'json'}) .then(function(spec) { if (spec.level === 1) { return _.merge(specs, { spec: spec, specLevel1: spec, urlLevel2: format('/api/specializations/?lft__gt=%s&rght__lte=%s', spec.lft, spec.rght), }) } else if (spec.level === 2) { var specLevel2 = spec return $.ajax({url: '/api/specializations/' + specLevel2.parent.id + '/', method: 'GET', dataType: 'json'}) .then(function(spec) { var specLevel1 = spec return _.merge(specs, { spec: specLevel2, specLevel1: specLevel1, urlLevel2: format('/api/specializations/?lft__gt=%s&rght__lte=%s', specLevel1.lft, specLevel1.rght), specLevel2: specLevel2, urlLevel3: format('/api/specializations/?lft__gt=%s&rght__lte=%s', specLevel2.lft, specLevel2.rght), }) }) } else if (spec.level === 3) { var specLevel3 = spec return $.ajax({url: '/api/specializations/' + specLevel3.parent.id + '/', method: 'GET', dataType: 'json'}) .then(function(spec) { var specLevel2 = spec return $.ajax({url: '/api/specializations/' + specLevel2.parent.id + '/', method: 'GET', dataType: 'json'}) .then(function(spec) { var specLevel1 = spec return _.merge(specs, { spec: specLevel3, specLevel1: specLevel1, urlLevel2: format('/api/specializations/?lft__gt=%s&rght__lte=%s', specLevel1.lft, specLevel1.rght), specLevel2: specLevel2, urlLevel3: format('/api/specializations/?lft__gt=%s&rght__lte=%s', specLevel2.lft, specLevel2.rght), specLevel3: specLevel3, urlLevel4: format('/api/specializations/?lft__gt=%s&rght__lte=%s', specLevel3.lft, specLevel3.rght), }) }) }) } else if (spec.level === 4) { var specLevel4 = spec return $.ajax({url: '/api/specializations/' + specLevel4.parent.id + '/', method: 'GET', dataType: 'json'}) .then(function(spec) { var specLevel3 = spec return $.ajax({url: '/api/specializations/' + specLevel3.parent.id + '/', method: 'GET', dataType: 'json'}) .then(function(spec) { var specLevel2 = spec return $.ajax({url: '/api/specializations/' + specLevel2.parent.id + '/', method: 'GET', dataType: 'json'}) .then(function(spec) { var specLevel1 = spec return _.merge(specs, { spec: specLevel4, specLevel1: specLevel1, urlLevel2: format('/api/specializations/?lft__gt=%s&rght__lte=%s', specLevel1.lft, specLevel1.rght), specLevel2: specLevel2, urlLevel3: format('/api/specializations/?lft__gt=%s&rght__lte=%s', specLevel2.lft, specLevel2.rght), specLevel3: specLevel3, urlLevel4: format('/api/specializations/?lft__gt=%s&rght__lte=%s', specLevel3.lft, specLevel3.rght), specLevel4: specLevel4, }) }) }) }) } }) } } function getLocationTree(locId) { var locations = { location: null, country: null, region: null, city: null, countries: [], regions: [], cities: [], } if (locId === null) { return $.ajax({url: '/api/locations/?level=1', method: 'GET', dataType: 'json'}) .then(function(res) { return _.merge(locations, { countries: _.map(function(item) {return {text: item.name, id: item.id, origItem: item}}, res.results), }) }) } else { return $.ajax({url: '/api/locations/' + locId + '/', method: 'GET', dataType: 'json'}).then(function(loc) { locations = _.merge(locations, {location: loc}) if (loc.level === 1) { var country = loc return $.when( $.ajax({url: '/api/locations/?level=1', method: 'GET', dataType: 'json'}) .then(function(res) {return res.results}), // Countries $.ajax({url: '/api/locations/?level=2&parent=' + country.id, method: 'GET', dataType: 'json'}) .then(function(res) {return res.results}) // Regions ) .then(function(countries, regions) { return _.merge(locations, { country: country, countries: _.map(function(item) {return {text: item.name, id: item.id, origItem: item}}, countries), regions: _.map(function(item) {return {text: item.name, id: item.id, origItem: item}}, regions), }) }) } else if (loc.level === 2) { var region = loc return $.when( $.ajax({url: '/api/locations/?level=1', method: 'GET', dataType: 'json'}) .then(function(res) {return res.results}), // Countries $.ajax({url: '/api/locations/?level=2&parent=' + region.parent.id, method: 'GET', dataType: 'json'}) .then(function(res) {return res.results}), // Regions $.ajax({url: '/api/locations/' + region.parent.id + '/', method: 'GET', dataType: 'json'}) .then(function(res) {return res}), // Country $.ajax({url: '/api/locations/?level=3&parent=' + region.id, method: 'GET', dataType: 'json'}) .then(function(res) {return res.results}) // Cities ) .then(function(countries, regions, country, cities) { return _.merge(locations, { country: country, region: region, countries: _.map(function(item) {return {text: item.name, id: item.id, origItem: item}}, countries), regions: _.map(function(item) {return {text: item.name, id: item.id, origItem: item}}, regions), cities: _.map(function(item) {return {text: item.name, id: item.id, origItem: item}}, cities), }) }) } else if (loc.level === 3) { var city = loc return $.when( $.ajax({url: '/api/locations/?level=1', method: 'GET', dataType: 'json'}) .then(function(res) {return res.results}), // Countries $.ajax({url: '/api/locations/' + city.parent.id + '/', method: 'GET', dataType: 'json'}) .then(function(res) {return res}), // Region $.ajax({url: '/api/locations/?level=3&parent=' + city.parent.id, method: 'GET', dataType: 'json'}) .then(function(res) {return res.results}) // Cities ) .then(function(countries, region, cities) { locations = _.merge(locations, { region: region, city: city, countries: _.map(function(item) {return {text: item.name, id: item.id, origItem: item}}, countries), cities: _.map(function(item) {return {text: item.name, id: item.id, origItem: item}}, cities), }) return $.when( $.ajax({url: '/api/locations/?level=2&parent=' + region.parent.id, method: 'GET', dataType: 'json'}) .then(function(res) {return res.results}), // Regions $.ajax({url: '/api/locations/' + region.parent.id + '/', method: 'GET', dataType: 'json'}) .then(function(res) {return res}) // Country ) .then(function(regions, country) { return _.merge(locations, { country: country, regions: _.map(function(item) {return {text: item.name, id: item.id, origItem: item}}, regions), }) }) }) } }) } } function specializationTreeHasLevels(specId) { if (specId == null) { var haveLevels = { level2: true, level3: true, level4: true, } return $.when(haveLevels) } else { return $.get(format('/api/specializations/%s/', specId)).then(function(spec) { return $.get(format('/api/specializations/?level=1&lft__lte=%s&rght__gte=%s', spec.lft, spec.rght)).then(function(res) { var specTreeRoot = res.results[0] var url_ = format('/api/specializations/?lft__gt=%s&rght__lt=%s&level=%s', specTreeRoot.lft, specTreeRoot.rght) return $.when( $.get(format(url_, 2)).then(function(res) {return res}), $.get(format(url_, 3)).then(function(res) {return res}), $.get(format(url_, 4)).then(function(res) {return res}) ) .then(function(resLvl1, resLvl2, resLvl3) { var haveLevels = { level2: !_.isEmpty(resLvl1.results), level3: !_.isEmpty(resLvl2.results), level4: !_.isEmpty(resLvl3.results), } return haveLevels }) }) }) } } // Utils ----------------------------------------------- var _call = Function.prototype.call var _splice = _call.bind(Array.prototype.splice) function humanFileSize(bytes, si) { var thresh = si ? 1000 : 1024 if (Math.abs(bytes) < thresh) return bytes + ' B' var units = si ? ['kB','MB','GB','TB','PB','EB','ZB','YB'] : ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'] var u = -1 do { bytes /= thresh ++u } while (Math.abs(bytes) >= thresh && u < units.length-1) return bytes.toFixed(1) + ' ' + units[u] } function format() { var str = _.head(arguments) var args = _.tail(arguments) var arg while (true) { arg = args.shift() if (arg != null && str.search('%s') !== -1) str = str.replace('%s', arg) else break } return str } function remove(coll, item) { _splice(coll, _.indexOf(item, coll), 1) return coll } function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie != '') { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); if (cookie.substring(0, name.length + 1) == (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; }