| 1 |
/** |
| 2 |
* A modified version of country select for UWP needs. |
| 3 |
*/ |
| 4 |
// wrap in UMD - see https://github.com/umdjs/umd/blob/master/jqueryPlugin.js |
| 5 |
(function(factory) { |
| 6 |
if (typeof define === "function" && define.amd) { |
| 7 |
define([ "jquery" ], function($) { |
| 8 |
factory($, window, document); |
| 9 |
}); |
| 10 |
} else { |
| 11 |
factory(jQuery, window, document); |
| 12 |
} |
| 13 |
})(function($, window, document, undefined) { |
| 14 |
"use strict"; |
| 15 |
var pluginName = "countrySelect", id = 1, // give each instance its own ID for namespaced event handling |
| 16 |
defaults = { |
| 17 |
// Default country |
| 18 |
defaultCountry: "", |
| 19 |
// Position the selected flag inside or outside of the input |
| 20 |
defaultStyling: "inside", |
| 21 |
// Display only these countries |
| 22 |
onlyCountries: [], |
| 23 |
// The countries at the top of the list. Defaults to United States and United Kingdom |
| 24 |
preferredCountries: [ "us", "gb" ] |
| 25 |
}, keys = { |
| 26 |
UP: 38, |
| 27 |
DOWN: 40, |
| 28 |
ENTER: 13, |
| 29 |
ESC: 27, |
| 30 |
PLUS: 43, |
| 31 |
A: 65, |
| 32 |
Z: 90 |
| 33 |
}, windowLoaded = false; |
| 34 |
// keep track of if the window.load event has fired as impossible to check after the fact |
| 35 |
$(window).on('load', function() { |
| 36 |
windowLoaded = true; |
| 37 |
}); |
| 38 |
function Plugin(element, options) { |
| 39 |
this.element = element; |
| 40 |
this.options = $.extend({}, defaults, options); |
| 41 |
this._defaults = defaults; |
| 42 |
// event namespace |
| 43 |
this.ns = "." + pluginName + id++; |
| 44 |
this._name = pluginName; |
| 45 |
this.init(); |
| 46 |
} |
| 47 |
Plugin.prototype = { |
| 48 |
init: function() { |
| 49 |
// Process all the data: onlyCountries, preferredCountries, defaultCountry etc |
| 50 |
this._processCountryData(); |
| 51 |
// Generate the markup |
| 52 |
this._generateMarkup(); |
| 53 |
// Set the initial state of the input value and the selected flag |
| 54 |
this._setInitialState(); |
| 55 |
// Start all of the event listeners: input keyup, selectedFlag click |
| 56 |
this._initListeners(); |
| 57 |
}, |
| 58 |
/******************** |
| 59 |
* PRIVATE METHODS |
| 60 |
********************/ |
| 61 |
// prepare all of the country data, including onlyCountries, preferredCountries and |
| 62 |
// defaultCountry options |
| 63 |
_processCountryData: function() { |
| 64 |
// set the instances country data objects |
| 65 |
this._setInstanceCountryData(); |
| 66 |
// set the preferredCountries property |
| 67 |
this._setPreferredCountries(); |
| 68 |
}, |
| 69 |
// process onlyCountries array if present |
| 70 |
_setInstanceCountryData: function() { |
| 71 |
var that = this; |
| 72 |
if (this.options.onlyCountries.length) { |
| 73 |
var newCountries = []; |
| 74 |
$.each(this.options.onlyCountries, function(i, countryCode) { |
| 75 |
var countryData = that._getCountryData(countryCode, true); |
| 76 |
if (countryData) { |
| 77 |
newCountries.push(countryData); |
| 78 |
} |
| 79 |
}); |
| 80 |
this.countries = newCountries; |
| 81 |
} else { |
| 82 |
this.countries = allCountries; |
| 83 |
} |
| 84 |
}, |
| 85 |
// Process preferred countries - iterate through the preferences, |
| 86 |
// fetching the country data for each one |
| 87 |
_setPreferredCountries: function() { |
| 88 |
var that = this; |
| 89 |
this.preferredCountries = []; |
| 90 |
$.each(this.options.preferredCountries, function(i, countryCode) { |
| 91 |
var countryData = that._getCountryData(countryCode, false); |
| 92 |
if (countryData) { |
| 93 |
that.preferredCountries.push(countryData); |
| 94 |
} |
| 95 |
}); |
| 96 |
}, |
| 97 |
// generate all of the markup for the plugin: the selected flag overlay, and the dropdown |
| 98 |
_generateMarkup: function() { |
| 99 |
// Country input |
| 100 |
this.countryInput = $(this.element); |
| 101 |
// containers (mostly for positioning) |
| 102 |
var mainClass = "country-select"; |
| 103 |
if (this.options.defaultStyling) { |
| 104 |
mainClass += " " + this.options.defaultStyling; |
| 105 |
} |
| 106 |
this.countryInput.wrap($("<div>", { |
| 107 |
"class": mainClass |
| 108 |
})); |
| 109 |
var flagsContainer = $("<div>", { |
| 110 |
"class": "flag-dropdown" |
| 111 |
}).insertAfter(this.countryInput); |
| 112 |
// currently selected flag (displayed to left of input) |
| 113 |
var selectedFlag = $("<div>", { |
| 114 |
"class": "selected-flag" |
| 115 |
}).appendTo(flagsContainer); |
| 116 |
this.selectedFlagInner = $("<div>", { |
| 117 |
"class": "flag" |
| 118 |
}).appendTo(selectedFlag); |
| 119 |
// CSS triangle |
| 120 |
$("<div>", { |
| 121 |
"class": "arrow" |
| 122 |
}).appendTo(this.selectedFlagInner); |
| 123 |
// country list contains: preferred countries, then divider, then all countries |
| 124 |
this.countryList = $("<ul>", { |
| 125 |
"class": "country-list v-hide" |
| 126 |
}).appendTo(flagsContainer); |
| 127 |
if (this.preferredCountries.length) { |
| 128 |
this._appendListItems(this.preferredCountries, "preferred"); |
| 129 |
$("<li>", { |
| 130 |
"class": "divider" |
| 131 |
}).appendTo(this.countryList); |
| 132 |
} |
| 133 |
this._appendListItems(this.countries, ""); |
| 134 |
// Add the hidden input for the country code |
| 135 |
this.countryCodeInput = $("#"+this.countryInput.attr("id")+"_code"); |
| 136 |
if (!this.countryCodeInput) { |
| 137 |
this.countryCodeInput = $('<input type="hidden" id="'+this.countryInput.attr("id")+'_code" name="'+this.countryInput.attr("name")+'_code" value="" />'); |
| 138 |
this.countryCodeInput.insertAfter(this.countryInput); |
| 139 |
} |
| 140 |
// now we can grab the dropdown height, and hide it properly |
| 141 |
this.dropdownHeight = this.countryList.outerHeight(); |
| 142 |
this.countryList.removeClass("v-hide").addClass("hide"); |
| 143 |
// this is useful in lots of places |
| 144 |
this.countryListItems = this.countryList.children(".country"); |
| 145 |
}, |
| 146 |
// add a country <li> to the countryList <ul> container |
| 147 |
_appendListItems: function(countries, className) { |
| 148 |
// Generate DOM elements as a large temp string, so that there is only |
| 149 |
// one DOM insert event |
| 150 |
var tmp = ""; |
| 151 |
// for each country |
| 152 |
$.each(countries, function(i, c) { |
| 153 |
// open the list item |
| 154 |
tmp += '<li class="country ' + className + '" data-country-code="' + c.iso2 + '">'; |
| 155 |
// add the flag |
| 156 |
tmp += '<div class="flag ' + c.iso2 + '"></div>'; |
| 157 |
// and the country name |
| 158 |
tmp += '<span class="country-name">' + c.name + '</span>'; |
| 159 |
// close the list item |
| 160 |
tmp += '</li>'; |
| 161 |
}); |
| 162 |
this.countryList.append(tmp); |
| 163 |
}, |
| 164 |
// set the initial state of the input value and the selected flag |
| 165 |
_setInitialState: function() { |
| 166 |
var flagIsSet = false; |
| 167 |
// If the input is pre-populated, then just update the selected flag |
| 168 |
if (this.countryInput.val()) { |
| 169 |
flagIsSet = this._updateFlagFromInputVal(); |
| 170 |
} |
| 171 |
// If the country code input is pre-populated, update the name and the selected flag |
| 172 |
var selectedCode = this.countryCodeInput.val(); |
| 173 |
if (selectedCode) { |
| 174 |
this.selectCountry(selectedCode); |
| 175 |
} |
| 176 |
if (!flagIsSet) { |
| 177 |
// flag is not set, so set to the default country |
| 178 |
var defaultCountry; |
| 179 |
// check the defaultCountry option, else fall back to the first in the list |
| 180 |
if (this.options.defaultCountry) { |
| 181 |
defaultCountry = this._getCountryData(this.options.defaultCountry, false); |
| 182 |
// Did we not find the requested default country? |
| 183 |
if (!defaultCountry) { |
| 184 |
defaultCountry = this.preferredCountries.length ? this.preferredCountries[0] : this.countries[0]; |
| 185 |
} |
| 186 |
} else { |
| 187 |
defaultCountry = this.preferredCountries.length ? this.preferredCountries[0] : this.countries[0]; |
| 188 |
} |
| 189 |
this.selectCountry(defaultCountry.iso2); |
| 190 |
} |
| 191 |
}, |
| 192 |
// initialise the main event listeners: input keyup, and click selected flag |
| 193 |
_initListeners: function() { |
| 194 |
var that = this; |
| 195 |
// Update flag on keyup. |
| 196 |
// Use keyup instead of keypress because we want to update on backspace |
| 197 |
// and instead of keydown because the value hasn't updated when that |
| 198 |
// event is fired. |
| 199 |
// NOTE: better to have this one listener all the time instead of |
| 200 |
// starting it on focus and stopping it on blur, because then you've |
| 201 |
// got two listeners (focus and blur) |
| 202 |
this.countryInput.on("keyup" + this.ns, function() { |
| 203 |
that._updateFlagFromInputVal(); |
| 204 |
}); |
| 205 |
// toggle country dropdown on click |
| 206 |
var selectedFlag = this.selectedFlagInner.parent(); |
| 207 |
selectedFlag.on("click" + this.ns, function(e) { |
| 208 |
// only intercept this event if we're opening the dropdown |
| 209 |
// else let it bubble up to the top ("click-off-to-close" listener) |
| 210 |
// we cannot just stopPropagation as it may be needed to close another instance |
| 211 |
if (that.countryList.hasClass("hide") && !that.countryInput.prop("disabled")) { |
| 212 |
that._showDropdown(); |
| 213 |
} |
| 214 |
}); |
| 215 |
// Despite above note, added blur to ensure partially spelled country |
| 216 |
// with correctly chosen flag is spelled out on blur. Also, correctly |
| 217 |
// selects flag when field is autofilled |
| 218 |
this.countryInput.on("blur" + this.ns, function() { |
| 219 |
if (that.countryInput.val() != that.getSelectedCountryData().name) { |
| 220 |
that.setCountry(that.countryInput.val()); |
| 221 |
} |
| 222 |
that.countryInput.val(that.getSelectedCountryData().name); |
| 223 |
}); |
| 224 |
}, |
| 225 |
// Focus input and put the cursor at the end |
| 226 |
_focus: function() { |
| 227 |
this.countryInput.focus(); |
| 228 |
var input = this.countryInput[0]; |
| 229 |
// works for Chrome, FF, Safari, IE9+ |
| 230 |
if (input.setSelectionRange) { |
| 231 |
var len = this.countryInput.val().length; |
| 232 |
input.setSelectionRange(len, len); |
| 233 |
} |
| 234 |
}, |
| 235 |
// Show the dropdown |
| 236 |
_showDropdown: function() { |
| 237 |
this._setDropdownPosition(); |
| 238 |
// update highlighting and scroll to active list item |
| 239 |
var activeListItem = this.countryList.children(".active"); |
| 240 |
this._highlightListItem(activeListItem); |
| 241 |
// show it |
| 242 |
this.countryList.removeClass("hide"); |
| 243 |
this._scrollTo(activeListItem); |
| 244 |
// bind all the dropdown-related listeners: mouseover, click, click-off, keydown |
| 245 |
this._bindDropdownListeners(); |
| 246 |
// update the arrow |
| 247 |
this.selectedFlagInner.children(".arrow").addClass("up"); |
| 248 |
}, |
| 249 |
// decide where to position dropdown (depends on position within viewport, and scroll) |
| 250 |
_setDropdownPosition: function() { |
| 251 |
var inputTop = this.countryInput.offset().top, windowTop = $(window).scrollTop(), |
| 252 |
dropdownFitsBelow = inputTop + this.countryInput.outerHeight() + this.dropdownHeight < windowTop + $(window).height(), dropdownFitsAbove = inputTop - this.dropdownHeight > windowTop; |
| 253 |
// dropdownHeight - 1 for border |
| 254 |
var cssTop = !dropdownFitsBelow && dropdownFitsAbove ? "-" + (this.dropdownHeight - 1) + "px" : ""; |
| 255 |
this.countryList.css("top", cssTop); |
| 256 |
}, |
| 257 |
// we only bind dropdown listeners when the dropdown is open |
| 258 |
_bindDropdownListeners: function() { |
| 259 |
var that = this; |
| 260 |
// when mouse over a list item, just highlight that one |
| 261 |
// we add the class "highlight", so if they hit "enter" we know which one to select |
| 262 |
this.countryList.on("mouseover" + this.ns, ".country", function(e) { |
| 263 |
that._highlightListItem($(this)); |
| 264 |
}); |
| 265 |
// listen for country selection |
| 266 |
this.countryList.on("click" + this.ns, ".country", function(e) { |
| 267 |
that._selectListItem($(this)); |
| 268 |
}); |
| 269 |
// click off to close |
| 270 |
// (except when this initial opening click is bubbling up) |
| 271 |
// we cannot just stopPropagation as it may be needed to close another instance |
| 272 |
var isOpening = true; |
| 273 |
$("html").on("click" + this.ns, function(e) { |
| 274 |
if (!isOpening) { |
| 275 |
that._closeDropdown(); |
| 276 |
} |
| 277 |
isOpening = false; |
| 278 |
}); |
| 279 |
// Listen for up/down scrolling, enter to select, or letters to jump to country name. |
| 280 |
// Use keydown as keypress doesn't fire for non-char keys and we want to catch if they |
| 281 |
// just hit down and hold it to scroll down (no keyup event). |
| 282 |
// Listen on the document because that's where key events are triggered if no input has focus |
| 283 |
$(document).on("keydown" + this.ns, function(e) { |
| 284 |
// prevent down key from scrolling the whole page, |
| 285 |
// and enter key from submitting a form etc |
| 286 |
e.preventDefault(); |
| 287 |
if (e.which == keys.UP || e.which == keys.DOWN) { |
| 288 |
// up and down to navigate |
| 289 |
that._handleUpDownKey(e.which); |
| 290 |
} else if (e.which == keys.ENTER) { |
| 291 |
// enter to select |
| 292 |
that._handleEnterKey(); |
| 293 |
} else if (e.which == keys.ESC) { |
| 294 |
// esc to close |
| 295 |
that._closeDropdown(); |
| 296 |
} else if (e.which >= keys.A && e.which <= keys.Z) { |
| 297 |
// upper case letters (note: keyup/keydown only return upper case letters) |
| 298 |
// cycle through countries beginning with that letter |
| 299 |
that._handleLetterKey(e.which); |
| 300 |
} |
| 301 |
}); |
| 302 |
}, |
| 303 |
// Highlight the next/prev item in the list (and ensure it is visible) |
| 304 |
_handleUpDownKey: function(key) { |
| 305 |
var current = this.countryList.children(".highlight").first(); |
| 306 |
var next = key == keys.UP ? current.prev() : current.next(); |
| 307 |
if (next.length) { |
| 308 |
// skip the divider |
| 309 |
if (next.hasClass("divider")) { |
| 310 |
next = key == keys.UP ? next.prev() : next.next(); |
| 311 |
} |
| 312 |
this._highlightListItem(next); |
| 313 |
this._scrollTo(next); |
| 314 |
} |
| 315 |
}, |
| 316 |
// select the currently highlighted item |
| 317 |
_handleEnterKey: function() { |
| 318 |
var currentCountry = this.countryList.children(".highlight").first(); |
| 319 |
if (currentCountry.length) { |
| 320 |
this._selectListItem(currentCountry); |
| 321 |
} |
| 322 |
}, |
| 323 |
// Iterate through the countries starting with the given letter |
| 324 |
_handleLetterKey: function(key) { |
| 325 |
var letter = String.fromCharCode(key); |
| 326 |
// filter out the countries beginning with that letter |
| 327 |
var countries = this.countryListItems.filter(function() { |
| 328 |
return $(this).text().charAt(0) == letter && !$(this).hasClass("preferred"); |
| 329 |
}); |
| 330 |
if (countries.length) { |
| 331 |
// if one is already highlighted, then we want the next one |
| 332 |
var highlightedCountry = countries.filter(".highlight").first(), listItem; |
| 333 |
// if the next country in the list also starts with that letter |
| 334 |
if (highlightedCountry && highlightedCountry.next() && highlightedCountry.next().text().charAt(0) == letter) { |
| 335 |
listItem = highlightedCountry.next(); |
| 336 |
} else { |
| 337 |
listItem = countries.first(); |
| 338 |
} |
| 339 |
// update highlighting and scroll |
| 340 |
this._highlightListItem(listItem); |
| 341 |
this._scrollTo(listItem); |
| 342 |
} |
| 343 |
}, |
| 344 |
// Update the selected flag using the input's current value |
| 345 |
_updateFlagFromInputVal: function() { |
| 346 |
var that = this; |
| 347 |
// try and extract valid country from input |
| 348 |
var value = this.countryInput.val().replace(/(?=[() ])/g, '\\'); |
| 349 |
if (value) { |
| 350 |
var countryCodes = []; |
| 351 |
var matcher = new RegExp("^"+value, "i"); |
| 352 |
for (var i = 0; i < this.countries.length; i++) { |
| 353 |
if (this.countries[i].name.match(matcher)) { |
| 354 |
countryCodes.push(this.countries[i].iso2); |
| 355 |
} |
| 356 |
} |
| 357 |
// Check if one of the matching countries is already selected |
| 358 |
var alreadySelected = false; |
| 359 |
$.each(countryCodes, function(i, c) { |
| 360 |
if (that.selectedFlagInner.hasClass(c)) { |
| 361 |
alreadySelected = true; |
| 362 |
} |
| 363 |
}); |
| 364 |
if (!alreadySelected) { |
| 365 |
this._selectFlag(countryCodes[0]); |
| 366 |
this.countryCodeInput.val(countryCodes[0]).trigger("change"); |
| 367 |
} |
| 368 |
// Matching country found |
| 369 |
return true; |
| 370 |
} |
| 371 |
// No match found |
| 372 |
return false; |
| 373 |
}, |
| 374 |
// remove highlighting from other list items and highlight the given item |
| 375 |
_highlightListItem: function(listItem) { |
| 376 |
this.countryListItems.removeClass("highlight"); |
| 377 |
listItem.addClass("highlight"); |
| 378 |
}, |
| 379 |
// find the country data for the given country code |
| 380 |
// the ignoreOnlyCountriesOption is only used during init() while parsing the onlyCountries array |
| 381 |
_getCountryData: function(countryCode, ignoreOnlyCountriesOption) { |
| 382 |
var countryList = ignoreOnlyCountriesOption ? allCountries : this.countries; |
| 383 |
for (var i = 0; i < countryList.length; i++) { |
| 384 |
if (countryList[i].iso2 == countryCode) { |
| 385 |
return countryList[i]; |
| 386 |
} |
| 387 |
} |
| 388 |
return null; |
| 389 |
}, |
| 390 |
// update the selected flag and the active list item |
| 391 |
_selectFlag: function(countryCode) { |
| 392 |
if (! countryCode) { |
| 393 |
return false; |
| 394 |
} |
| 395 |
this.selectedFlagInner.attr("class", "flag " + countryCode); |
| 396 |
// update the title attribute |
| 397 |
var countryData = this._getCountryData(countryCode); |
| 398 |
this.selectedFlagInner.parent().attr("title", countryData.name); |
| 399 |
// update the active list item |
| 400 |
var listItem = this.countryListItems.children(".flag." + countryCode).first().parent(); |
| 401 |
this.countryListItems.removeClass("active"); |
| 402 |
listItem.addClass("active"); |
| 403 |
}, |
| 404 |
// called when the user selects a list item from the dropdown |
| 405 |
_selectListItem: function(listItem) { |
| 406 |
// update selected flag and active list item |
| 407 |
var countryCode = listItem.attr("data-country-code"); |
| 408 |
this._selectFlag(countryCode); |
| 409 |
this._closeDropdown(); |
| 410 |
// update input value |
| 411 |
this._updateName(countryCode); |
| 412 |
this.countryInput.trigger("change"); |
| 413 |
this.countryCodeInput.trigger("change"); |
| 414 |
// focus the input |
| 415 |
this._focus(); |
| 416 |
}, |
| 417 |
// close the dropdown and unbind any listeners |
| 418 |
_closeDropdown: function() { |
| 419 |
this.countryList.addClass("hide"); |
| 420 |
// update the arrow |
| 421 |
this.selectedFlagInner.children(".arrow").removeClass("up"); |
| 422 |
// unbind event listeners |
| 423 |
$(document).off("keydown" + this.ns); |
| 424 |
$("html").off("click" + this.ns); |
| 425 |
// unbind both hover and click listeners |
| 426 |
this.countryList.off(this.ns); |
| 427 |
}, |
| 428 |
// check if an element is visible within its container, else scroll until it is |
| 429 |
_scrollTo: function(element) { |
| 430 |
if (!element || !element.offset()) { |
| 431 |
return; |
| 432 |
} |
| 433 |
var container = this.countryList, containerHeight = container.height(), containerTop = container.offset().top, containerBottom = containerTop + containerHeight, elementHeight = element.outerHeight(), elementTop = element.offset().top, elementBottom = elementTop + elementHeight, newScrollTop = elementTop - containerTop + container.scrollTop(); |
| 434 |
if (elementTop < containerTop) { |
| 435 |
// scroll up |
| 436 |
container.scrollTop(newScrollTop); |
| 437 |
} else if (elementBottom > containerBottom) { |
| 438 |
// scroll down |
| 439 |
var heightDifference = containerHeight - elementHeight; |
| 440 |
container.scrollTop(newScrollTop - heightDifference); |
| 441 |
} |
| 442 |
}, |
| 443 |
// Replace any existing country name with the new one |
| 444 |
_updateName: function(countryCode) { |
| 445 |
this.countryCodeInput.val(countryCode).trigger("change"); |
| 446 |
this.countryInput.val(this._getCountryData(countryCode).name); |
| 447 |
}, |
| 448 |
/******************** |
| 449 |
* PUBLIC METHODS |
| 450 |
********************/ |
| 451 |
// get the country data for the currently selected flag |
| 452 |
getSelectedCountryData: function() { |
| 453 |
// rely on the fact that we only set 2 classes on the selected flag element: |
| 454 |
// the first is "flag" and the second is the 2-char country code |
| 455 |
var countryCode = this.selectedFlagInner.attr("class").split(" ")[1]; |
| 456 |
return this._getCountryData(countryCode); |
| 457 |
}, |
| 458 |
// update the selected flag |
| 459 |
selectCountry: function(countryCode) { |
| 460 |
countryCode = countryCode.toLowerCase(); |
| 461 |
// check if already selected |
| 462 |
if (!this.selectedFlagInner.hasClass(countryCode)) { |
| 463 |
this._selectFlag(countryCode); |
| 464 |
this._updateName(countryCode); |
| 465 |
} |
| 466 |
}, |
| 467 |
// set the input value and update the flag |
| 468 |
setCountry: function(country) { |
| 469 |
this.countryInput.val(country); |
| 470 |
this._updateFlagFromInputVal(); |
| 471 |
}, |
| 472 |
// remove plugin |
| 473 |
destroy: function() { |
| 474 |
// stop listeners |
| 475 |
this.countryInput.off(this.ns); |
| 476 |
this.selectedFlagInner.parent().off(this.ns); |
| 477 |
// remove markup |
| 478 |
var container = this.countryInput.parent(); |
| 479 |
container.before(this.countryInput).remove(); |
| 480 |
} |
| 481 |
}; |
| 482 |
// adapted to allow public functions |
| 483 |
// using https://github.com/jquery-boilerplate/jquery-boilerplate/wiki/Extending-jQuery-Boilerplate |
| 484 |
$.fn[pluginName] = function(options) { |
| 485 |
var args = arguments; |
| 486 |
// Is the first parameter an object (options), or was omitted, |
| 487 |
// instantiate a new instance of the plugin. |
| 488 |
if (options === undefined || typeof options === "object") { |
| 489 |
return this.each(function() { |
| 490 |
if (!$.data(this, "plugin_" + pluginName)) { |
| 491 |
$.data(this, "plugin_" + pluginName, new Plugin(this, options)); |
| 492 |
} |
| 493 |
}); |
| 494 |
} else if (typeof options === "string" && options[0] !== "_" && options !== "init") { |
| 495 |
// If the first parameter is a string and it doesn't start |
| 496 |
// with an underscore or "contains" the `init`-function, |
| 497 |
// treat this as a call to a public method. |
| 498 |
// Cache the method call to make it possible to return a value |
| 499 |
var returns; |
| 500 |
this.each(function() { |
| 501 |
var instance = $.data(this, "plugin_" + pluginName); |
| 502 |
// Tests that there's already a plugin-instance |
| 503 |
// and checks that the requested public method exists |
| 504 |
if (instance instanceof Plugin && typeof instance[options] === "function") { |
| 505 |
// Call the method of our plugin instance, |
| 506 |
// and pass it the supplied arguments. |
| 507 |
returns = instance[options].apply(instance, Array.prototype.slice.call(args, 1)); |
| 508 |
} |
| 509 |
// Allow instances to be destroyed via the 'destroy' method |
| 510 |
if (options === "destroy") { |
| 511 |
$.data(this, "plugin_" + pluginName, null); |
| 512 |
} |
| 513 |
}); |
| 514 |
// If the earlier cached method gives a value back return the value, |
| 515 |
// otherwise return this to preserve chainability. |
| 516 |
return returns !== undefined ? returns : this; |
| 517 |
} |
| 518 |
}; |
| 519 |
/******************** |
| 520 |
* STATIC METHODS |
| 521 |
********************/ |
| 522 |
// get the country data object |
| 523 |
$.fn[pluginName].getCountryData = function() { |
| 524 |
return allCountries; |
| 525 |
}; |
| 526 |
// set the country data object |
| 527 |
$.fn[pluginName].setCountryData = function(obj) { |
| 528 |
allCountries = obj; |
| 529 |
}; |
| 530 |
// Tell JSHint to ignore this warning: "character may get silently deleted by one or more browsers" |
| 531 |
// jshint -W100 |
| 532 |
// Array of country objects for the flag dropdown. |
| 533 |
// Each contains a name and country code (ISO 3166-1 alpha-2). |
| 534 |
// |
| 535 |
// Note: using single char property names to keep filesize down |
| 536 |
// n = name |
| 537 |
// i = iso2 (2-char country code) |
| 538 |
var ii = 0; |
| 539 |
var cc = []; |
| 540 |
var allCountries = $.each(uwp_country_data, function(i, c) { |
| 541 |
cc[ii] = {name:c,iso2:i}; |
| 542 |
ii++; |
| 543 |
}); |
| 544 |
|
| 545 |
allCountries = cc; |
| 546 |
}); |
| 547 |
|