302 lines
9.4 KiB
JavaScript
302 lines
9.4 KiB
JavaScript
(function (context, $) {
|
|
|
|
"use strict";
|
|
|
|
context.JK = context.JK || {};
|
|
|
|
context.JK.SelectLocation = Class.extend({
|
|
|
|
init: function ($countries, $regions, $cities, app, useEasyDropdown) {
|
|
this.api = context.JK.Rest();
|
|
this.logger = context.JK.logger;
|
|
this.loadingCitiesData = false;
|
|
this.loadingRegionsData = false;
|
|
this.loadingCountriesData = false;
|
|
this.nilOptionStr = '<option value=""></option>';
|
|
this.nilOptionText = 'n/a';
|
|
this.countriesLoaded = false;
|
|
this.$countries = $countries;
|
|
this.$regions = $regions;
|
|
this.$cities = $cities;
|
|
this.$deferred = null;
|
|
this.useEasyDropdown = useEasyDropdown === undefined ? true : useEasyDropdown;
|
|
this.app = app;
|
|
|
|
$countries.on('change', function (evt) {
|
|
evt.stopPropagation();
|
|
this.handleCountryChanged();
|
|
return false;
|
|
}.bind(this));
|
|
if($regions) {
|
|
$regions.on('change', function (evt) {
|
|
evt.stopPropagation();
|
|
this.handleRegionChanged();
|
|
return false;
|
|
}.bind(this));
|
|
}
|
|
},
|
|
selectCountry: function (country) {
|
|
if(this.useEasyDropdown) {
|
|
this.$countries.easyDropDown('select', country, true)
|
|
}
|
|
else {
|
|
this.$countries.val(country)
|
|
}
|
|
},
|
|
ready: function() {
|
|
return this.$deferred;
|
|
},
|
|
load: function (country, region, city) {
|
|
|
|
this.country = country;
|
|
this.region = region;
|
|
this.city = city;
|
|
|
|
if (!country) {
|
|
// this case shouldn't happen because sign up makes you pick a location. This is just 'in case', so that the UI is more error-resilient
|
|
this.logger.debug("user has no specified country: " + country)
|
|
country = 'US';
|
|
}
|
|
|
|
// make the 3 slower requests, which only matter if the user wants to affect their ISP or location
|
|
this.loadingCountriesData = true;
|
|
this.$deferred = this.api.getCountries()
|
|
.done(function (countriesx) {
|
|
this.populateCountriesx(countriesx["countriesx"], country);
|
|
}.bind(this))
|
|
.fail(this.app.ajaxError)
|
|
.always(function () {
|
|
this.loadingCountriesData = false;
|
|
}.bind(this))
|
|
|
|
|
|
if (country && this.$regions) {
|
|
this.loadingRegionsData = true;
|
|
this.api.getRegions({ country: country })
|
|
.done(function (regions) {
|
|
this.populateRegions(regions["regions"], region);
|
|
}.bind(this))
|
|
.fail(this.regionListFailure.bind(this))
|
|
.always(function () {
|
|
this.loadingRegionsData = false;
|
|
}.bind(this))
|
|
|
|
if (region && this.$cities) {
|
|
this.loadingCitiesData = true;
|
|
this.api.getCities({ country: country, region: region })
|
|
.done(function (cities) {
|
|
this.populateCities(cities["cities"], this.city)
|
|
}.bind(this))
|
|
.fail(this.cityListFailure.bind(this))
|
|
.always(function () {
|
|
this.loadingCitiesData = false;
|
|
}.bind(this))
|
|
}
|
|
}
|
|
return this.$deferred;
|
|
},
|
|
handleCountryChanged: function () {
|
|
var selectedCountry = this.$countries.val()
|
|
|
|
if(!this.$regions) {
|
|
return;
|
|
}
|
|
|
|
var selectedRegion = this.$regions.val()
|
|
var cityElement = this.$cities
|
|
|
|
this.updateRegionList(selectedCountry, this.$regions);
|
|
this.updateCityList(selectedCountry, null, cityElement);
|
|
},
|
|
handleRegionChanged: function () {
|
|
var selectedCountry = this.$countries.val()
|
|
var selectedRegion = this.$regions.val()
|
|
var cityElement = this.$cities;
|
|
|
|
this.updateCityList(selectedCountry, selectedRegion, cityElement);
|
|
},
|
|
updateRegionList: function (selectedCountry, regionElement) {
|
|
// only update region
|
|
if (selectedCountry) {
|
|
// set city disabled while updating
|
|
regionElement.attr('disabled', true).easyDropDown('disable');
|
|
this.loadingRegionsData = true;
|
|
|
|
regionElement.children().remove()
|
|
regionElement.append($(this.nilOptionStr).text('loading...'))
|
|
|
|
this.api.getRegions({ country: selectedCountry })
|
|
.done(this.getRegionsDone.bind(this))
|
|
.error(function (err) {
|
|
regionElement.children().remove()
|
|
regionElement.append($(this.nilOptionStr).text(this.nilOptionText))
|
|
}.bind(this))
|
|
.always(function () {
|
|
console.log("regions load: this.loadingRegionsData; " + this.loadingRegionsData)
|
|
this.loadingRegionsData = false;
|
|
}.bind(this))
|
|
}
|
|
else {
|
|
regionElement.children().remove()
|
|
regionElement.append($(this.nilOptionStr).text(this.nilOptionText))
|
|
}
|
|
},
|
|
updateCityList: function (selectedCountry, selectedRegion, cityElement) {
|
|
|
|
// only update cities
|
|
if (selectedCountry && selectedRegion) {
|
|
// set city disabled while updating
|
|
cityElement.attr('disabled', true).easyDropDown('disable');
|
|
this.loadingCitiesData = true;
|
|
|
|
cityElement.children().remove()
|
|
cityElement.append($(this.nilOptionStr).text('loading...'))
|
|
|
|
this.api.getCities({ country: selectedCountry, region: selectedRegion })
|
|
.done(this.getCitiesDone.bind(this))
|
|
.error(function (err) {
|
|
cityElement.children().remove()
|
|
cityElement.append($(this.nilOptionStr).text(this.nilOptionText))
|
|
}.bind(this))
|
|
.always(function () {
|
|
this.loadingCitiesData = false;
|
|
}.bind(this))
|
|
}
|
|
else {
|
|
cityElement.children().remove();
|
|
cityElement.append($(this.nilOptionStr).text(this.nilOptionText));
|
|
if(this.useEasyDropdown) {
|
|
context.JK.dropdown(cityElement);
|
|
}
|
|
}
|
|
},
|
|
|
|
getCitiesDone: function (data) {
|
|
this.populateCities(data['cities'], this.city);
|
|
},
|
|
getRegionsDone: function (data) {
|
|
this.populateRegions(data['regions'], this.region);
|
|
this.updateCityList(this.$countries.val(), this.$regions.val(), this.$cities);
|
|
},
|
|
writeCountry: function (index, countryx) {
|
|
if (!countryx.countrycode) return;
|
|
|
|
var option = $(this.nilOptionStr);
|
|
option.text(countryx.countryname ? countryx.countryname : countryx.countrycode);
|
|
option.attr("value", countryx.countrycode);
|
|
|
|
if (countryx.countrycode == this.country) {
|
|
this.foundCountry = true;
|
|
}
|
|
|
|
this.$countries.append(option);
|
|
},
|
|
populateCountriesx: function (countriesx) {
|
|
|
|
this.countriesLoaded = true;
|
|
|
|
// countriesx has the format [{countrycode: "US", countryname: "United States"}, ...]
|
|
|
|
this.foundCountry = false;
|
|
this.$countries.children().remove();
|
|
|
|
var nilOption = $(this.nilOptionStr);
|
|
nilOption.text(this.nilOptionText);
|
|
this.$countries.append(nilOption);
|
|
|
|
$.each(countriesx, this.writeCountry.bind(this));
|
|
|
|
if (!this.foundCountry) {
|
|
this.logger.warn("user has no country in the database. user's country:" + this.country)
|
|
// in this case, the user has a country that is not in the database
|
|
// this can happen in a development/test scenario, but let's assume it can
|
|
// happen in production too.
|
|
var option = $(this.nilOptionStr);
|
|
option.text(this.country);
|
|
option.attr("value", this.country);
|
|
this.$countries.append(option);
|
|
}
|
|
|
|
this.$countries.val(this.country);
|
|
this.$countries.attr("disabled", null).easyDropDown('enable');
|
|
if(this.useEasyDropdown) {
|
|
context.JK.dropdown(this.$countries);
|
|
}
|
|
},
|
|
|
|
writeRegion: function (index, region) {
|
|
if (!region) return;
|
|
|
|
var option = $(this.nilOptionStr)
|
|
option.text(region['name'])
|
|
option.attr("value", region['region'])
|
|
|
|
this.$regions.append(option)
|
|
},
|
|
|
|
populateRegions: function (regions, userRegion) {
|
|
this.$regions.children().remove()
|
|
|
|
var nilOption = $(this.nilOptionStr);
|
|
nilOption.text(this.nilOptionText);
|
|
this.$regions.append(nilOption);
|
|
|
|
$.each(regions, this.writeRegion.bind(this))
|
|
|
|
this.$regions.val(userRegion)
|
|
this.$regions.attr("disabled", null).easyDropDown('enable');
|
|
|
|
if(this.useEasyDropdown) {
|
|
context.JK.dropdown(this.$regions);
|
|
}
|
|
},
|
|
|
|
writeCity: function (index, city) {
|
|
if (!city) return;
|
|
|
|
var option = $(this.nilOptionStr)
|
|
option.text(city)
|
|
option.attr("value", city)
|
|
|
|
this.$cities.append(option)
|
|
},
|
|
|
|
populateCities: function (cities, userCity) {
|
|
this.$cities.children().remove();
|
|
|
|
var nilOption = $(this.nilOptionStr);
|
|
nilOption.text(this.nilOptionText);
|
|
this.$cities.append(nilOption);
|
|
|
|
$.each(cities, this.writeCity.bind(this))
|
|
|
|
this.$cities.val(userCity)
|
|
this.$cities.attr("disabled", null).easyDropDown('enable');
|
|
|
|
if(this.useEasyDropdown) {
|
|
context.JK.dropdown(this.$cities);
|
|
}
|
|
},
|
|
|
|
regionListFailure: function (jqXHR, textStatus, errorThrown) {
|
|
if (jqXHR.status == 422) {
|
|
this.logger.debug("no regions found for country: " + this.country);
|
|
}
|
|
else {
|
|
this.app.ajaxError(arguments);
|
|
}
|
|
},
|
|
|
|
cityListFailure: function (jqXHR, textStatus, errorThrown) {
|
|
if (jqXHR.status == 422) {
|
|
this.logger.debug("no cities found for country/region: " + this.country + "/" + this.region);
|
|
}
|
|
else {
|
|
this.app.ajaxError(arguments);
|
|
}
|
|
}
|
|
});
|
|
|
|
})(window, jQuery);
|
|
|