public/javascripts/map_script.js
//defines map and oTable as global variables that will be used in various places
var map, oTable;
//initiates an empty object to store the data for internships
var internship_data = {'countries':{},'regions':{}};
//initiates the internship_locations object which stores the x,y coordinates for the map for both countries and regions
var internship_locations = {
'countries':{
'USA':{'x':245, 'y':260},
'CAN':{'x':220, 'y':210},
'GRL':{'x':442, 'y':68},
'NIC':{'x':302, 'y':362},
'PRI':{'x':360, 'y':343},
'VGB':{'x':369, 'y':338},
'CUB':{'x':314, 'y':329},
'BHS':{'x':326, 'y':321},
'TCA':{'x':348, 'y':332},
'DOM':{'x':350, 'y':339},
'JAM':{'x':323, 'y':345},
'HTI':{'x':338, 'y':340},
'TTO':{'x':377, 'y':370},
'KNA':{'x':371, 'y':347},
'BRB':{'x':383, 'y':361},
'GRD':{'x':375, 'y':364},
'VCT':{'x':371, 'y':359},
'DMA':{'x':376, 'y':353},
'HND':{'x':292, 'y':356},
'MEX':{'x':243, 'y':318},
'CRI':{'x':302, 'y':373},
'BLZ':{'x':293, 'y':347},
'SLV':{'x':284, 'y':362},
'GTM':{'x':280, 'y':355},
'PAN':{'x':317, 'y':376},
'BRA':{'x':405, 'y':422},
'ARG':{'x':366, 'y':517},
'VEN':{'x':359, 'y':375},
'FLK':{'x':383, 'y':592},
'GUY':{'x':385, 'y':382},
'PER':{'x':339, 'y':446},
'COL':{'x':338, 'y':388},
'SUR':{'x':394, 'y':396},
'GUF':{'x':405, 'y':388},
'ECU':{'x':317, 'y':405},
'BOL':{'x':367, 'y':464},
'PRY':{'x':381, 'y':476},
'URY':{'x':397, 'y':524},
'CHL':{'x':337, 'y':570},
'GBR':{'x':575, 'y':207},
'FIN':{'x':661, 'y':171},
'SWE':{'x':638, 'y':152},
'NOR':{'x':609, 'y':169},
'SRB':{'x':646, 'y':248},
'SVK':{'x':643, 'y':230},
'HUN':{'x':642, 'y':237},
'BGR':{'x':662, 'y':254},
'RUS':{'x':730, 'y':164},
'POL':{'x':643, 'y':212},
'DNK':{'x':609, 'y':196},
'MKD':{'x':650, 'y':259},
'GRC':{'x':655, 'y':274},
'NLD':{'x':594, 'y':213},
'LUX':{'x':599, 'y':226},
'BEL':{'x':673, 'y':204},
'ESP':{'x':567, 'y':262},
'PRT':{'x':551, 'y':274},
'DEU':{'x':613, 'y':212},
'TUR':{'x':682, 'y':269},
'BIH':{'x':637, 'y':249},
'SVN':{'x':627, 'y':241},
'HRV':{'x':634, 'y':242},
'MNE':{'x':642, 'y':254},
'ALB':{'x':644, 'y':262},
'CZE':{'x':629, 'y':226},
'AUT':{'x':627, 'y':234},
'MDA':{'x':675, 'y':238},
'ROU':{'x':661, 'y':237},
'FRA':{'x':587, 'y':231},
'CHE':{'x':606, 'y':238},
'UKR':{'x':691, 'y':230},
'ITA':{'x':625, 'y':258},
'MLT':{'x':629, 'y':285},
'IRL':{'x':548, 'y':207},
'ISL':{'x':518, 'y':148},
'EST':{'x':664, 'y':184},
'LTU':{'x':657, 'y':200},
'LVA':{'x':661, 'y':193},
'CYP':{'x':688, 'y':284},
'BLR':{'x':673, 'y':205},
'KOR':{'x':997, 'y':285},
'AZE':{'x':740, 'y':260},
'KAZ':{'x':802, 'y':226},
'TKM':{'x':771, 'y':263},
'IDN':{'x':954, 'y':413},
'SGP':{'x':929, 'y':407},
'TLS':{'x':999, 'y':430},
'VNM':{'x':924, 'y':327},
'TJK':{'x':818, 'y':273},
'PRK':{'x':1003, 'y':260},
'MNG':{'x':920, 'y':232},
'JPN':{'x':1043, 'y':267},
'MYS':{'x':948, 'y':397},
'LAO':{'x':917, 'y':342},
'KHM':{'x':925, 'y':359},
'THA':{'x':910, 'y':356},
'PAK':{'x':798, 'y':314},
'BTN':{'x':876, 'y':311},
'NPL':{'x':849, 'y':303},
'IRN':{'x':761, 'y':290},
'AFG':{'x':799, 'y':284},
'KGZ':{'x':828, 'y':258},
'UZB':{'x':792, 'y':262},
'IRQ':{'x':720, 'y':289},
'ARE':{'x':756, 'y':325},
'GEO':{'x':723, 'y':255},
'SYR':{'x':707, 'y':282},
'OMN':{'x':762, 'y':342},
'KWT':{'x':735, 'y':304},
'JOR':{'x':704, 'y':295},
'LBN':{'x':695, 'y':287},
'ARM':{'x':726, 'y':263},
'QAT':{'x':748, 'y':318},
'CHN':{'x':904, 'y':276},
'YEM':{'x':735, 'y':357},
'BGD':{'x':875, 'y':327},
'IND':{'x':839, 'y':332},
'LKA':{'x':845, 'y':381},
'PHL':{'x':978, 'y':348},
'TWN':{'x':977, 'y':322},
'SAU':{'x':726, 'y':320},
'ISR':{'x':691, 'y':296},
'NCL':{'x':1126, 'y':476},
'SLB':{'x':1103, 'y':431},
'MHL':{'x':1142, 'y':365},
'KIR':{'x':1174, 'y':407},
'FSM':{'x':1085, 'y':364},
'PLW':{'x':1025, 'y':367},
'TON':{'x':1195, 'y':473},
'FJI':{'x':1169, 'y':450},
'VUT':{'x':1133, 'y':464},
'TUV':{'x':1172, 'y':420},
'ASM':{'x':1195, 'y':458},
'WSM':{'x':1196, 'y':437},
'AUS':{'x':1024, 'y':484},
'NZL':{'x':1144, 'y':555},
'PNG':{'x':1054, 'y':417},
'PYF':{'x':1235, 'y':463},
'SHN':{'x':560, 'y':458},
'TUN':{'x':610, 'y':283},
'SLE':{'x':539, 'y':377},
'GNB':{'x':525, 'y':366},
'UGA':{'x':684, 'y':403},
'KEN':{'x':706, 'y':398},
'TZA':{'x':699, 'y':431},
'RWA':{'x':677, 'y':410},
'EGY':{'x':676, 'y':316},
'SDN':{'x':677, 'y':351},
'MOZ':{'x':703, 'y':447},
'SOM':{'x':737, 'y':372},
'COD':{'x':654, 'y':401},
'MDG':{'x':732, 'y':471},
'CMR':{'x':618, 'y':393},
'NGA':{'x':602, 'y':377},
'AGO':{'x':638, 'y':454},
'GAB':{'x':613, 'y':411},
'MRT':{'x':548, 'y':346},
'GNQ':{'x':608, 'y':399},
'GIN':{'x':543, 'y':368},
'CAF':{'x':651, 'y':381},
'TCD':{'x':639, 'y':352},
'NAM':{'x':635, 'y':479},
'ZWE':{'x':678, 'y':473},
'MWI':{'x':691, 'y':447},
'BWA':{'x':656, 'y':483},
'ZMB':{'x':662, 'y':457},
'SWZ':{'x':683, 'y':494},
'BDI':{'x':678, 'y':416},
'ETH':{'x':707, 'y':373},
'CIV':{'x':560, 'y':384},
'BFA':{'x':575, 'y':364},
'NER':{'x':610, 'y':341},
'COG':{'x':626, 'y':416},
'LBR':{'x':547, 'y':385},
'LSO':{'x':672, 'y':505},
'SEN':{'x':529, 'y':354},
'GHA':{'x':575, 'y':375},
'MLI':{'x':572, 'y':339},
'DZA':{'x':585, 'y':305},
'MAR':{'x':558, 'y':293},
'ESH':{'x':534, 'y':318},
'LBY':{'x':636, 'y':317},
'ZAF':{'x':653, 'y':516}
},
'regions':{
'African_Countries': {'x':635, 'y':350},
'Australia_Countries': {'x':1010, 'y':490},
'Asian_Countries': {'x':900, 'y':275},
'European_Countries': {'x':625, 'y':225},
'South_American_Countries': {'x':385, 'y':450},
'North_American_countries': {'x':250, 'y':225},
'Oceanian_Countries': {'x':0, 'y':0}
}
};
//models and booleans are defined to make the code more dynamic. they represent the filters and can be added to or taken from as filters change.
var models = ['languages','fields','industries','providers','academic_focuses'];
var booleans = ['for_credit','part_time','full_time','us_citizenship','paid'];
//This object stores and keeps track of the filters so they can be sent via ajax to the server when filters are applied
var filters = {'filters': true, 'languages':null, 'fields':null, 'industries':null, 'providers':null, 'locations':null, 'academic_focuses':null, 'for_credit': null, 'full_time': null, 'part_time': null, 'us_citizenship': null, 'paid': null};
//These booleans default to false and help the WaitUntilTheMapAndDataAreLoaded function function properly according to its definition
var mapIsLoaded = false, dataIsLoaded = false;
/***********************************************************************************
This function executes when the page is loaded and it does some basic setup
like setting div sizes and sets some button and div click listeners
and finally calls some functions to do get the default data for the map and
the internships.
***********************************************************************************/
$(function(){
//Initial width and height set for main divs based on the size of the user screen
$('#svg').width($(window).width());
$('#svg').height($(window).height()-50);
$('#list').width($(window).width());
$('#list').height($(window).height()-50);
//$('#dropdown').height($(window).height()-50);
$("#dropdown").qvivoScroll();
//Set the click listener for the View Map/View List Button
$("#MapListToggle").click(function(){
toggleMapListView();
});
//Set the click listener for the Filter Button
$("#FilterToggle").click(function(){
//$("#filters").fadeToggle(250);
$("#filters").toggle();
$('select.chosen').chosen();
$("#FilterToggle span").toggleClass('triangle_down');
$("#FilterToggle span").toggleClass('triangle_up');
});
$("#filters #close_button").click(function(){
$("#FilterToggle").trigger("click");
});
//Set the click listener for the svg and list divs to close the filter div if its open
$("#svg, #list").click(function(){
if($('#filters').is(':visible')){
$('#FilterToggle').trigger('click');
}
});
//load the initial data from the server (Asynchronously)
getInternshipData();
//Load the svg data from the server (Asynchronously)
getMapData();
//setup the filters
initFilters();
//calls a function that makes sure the Asynchronous calls are both done before continuing
WaitUntilTheMapAndDataAreLoaded();
});
/***********************************************************************************
This function sets up the svg details and is called after the svg data is loaded
into the DOM.
***********************************************************************************/
function initMap(){
//load the svg data into the svg-map div
map = $('#svg-map').svg('get');
//add the id to the svg map object
map.configure({id:'map'}, false);
//do an initial window zoom based on the width and height of the screen and the map deminsions
var boundingBox = map.getElementById('map').getBBox();
var base_view = parseInt(boundingBox.x) + ', ' + parseInt(boundingBox.y) + ', ' + parseInt(boundingBox.width) + ', ' + parseInt(boundingBox.height);
//animates the view change.
/* The Animation Code
$("#map").fadeOut(500,function(){
$("#map").animate({svgViewBox: base_view}, 0, function(){
$("#map").fadeIn(500);
});
});
*/
$("#map").animate({svgViewBox: base_view}, 0);
//the zoom out icon sits at the bottom right of the page and a click on it shoud zoom out to the original zoom position
$("#zoomout").click(function(){
/* The Animation Code
$("#map").fadeOut(500,function(){
resetMap();
map.change(map.getElementById("Country_names_Lines"), {display: 'none'});
$("#map").animate({svgViewBox: base_view}, 0, function(){
$("#map").fadeIn(500);
});
});
*/
resetMap();
map.change(map.getElementById("Country_names_Lines"), {display: 'none'});
$("#map").animate({svgViewBox: base_view}, 0);
});
$("#map").children('g').each(function(){
var id = $(this).attr('id');
if(id == 'Country_names_Lines'){
return;
}
if(id == 'internships'){
return;
}
//The region - as defined as the label name on the map (with underscores for spaces) is the key with an array of UN Codes as the value
internship_data.regions[id] = new Array();
$(this).children('g').each(function(){
internship_data.regions[id].push($(this).attr('id'));
});
//Sets the class clickable as to show the pointer
map.change(map.getElementById($(this).attr('id')), {class: 'clickable'});
//sets up the action to take on click
$(this).click(function(){
$('#dropdown').hide( 'fade', {}, 0);
boundingBox = map.getElementById($(this).attr('id')).getBBox();
//viewBox numbers => <min-x>, <min-y>, <width> and <height>
var view = parseInt(boundingBox.x) + ', ' + parseInt(boundingBox.y) + ', ' + parseInt(boundingBox.width) + ', ' + parseInt(boundingBox.height);
//animates the view change. Maybe we should just fade out, move, and fade back in
/* The Animation stuff
$("#map").fadeOut(500,function(){
$("#map").animate({svgViewBox: view}, 0, function(){
$("#map").fadeIn(500);
});
});
*/
$("#map").animate({svgViewBox: view}, 0);
//Shows the Country Names
map.change(map.getElementById("Country_names_Lines"), {display: ''});
resetGroup('internships');
$('#'+$(this).attr('id')).children('g').each(function(){
displayInternships($(this).attr('id'), true);
});
});
});
//setup the group to handle interships
map.group(null, 'internships');
resetMap();
}
/***********************************************************************************
This function removes the list of internships from the screen, resets the
internship group, and displays the internship numbers for each continent
***********************************************************************************/
function resetMap(){
$('#dropdown').hide( 'fade', {}, 0);
resetGroup('internships');
$('#map').children('g').each(function(){
displayInternships($(this).attr('id'), false);
});
}
/***********************************************************************************
***********************************************************************************/
function displayInternships(id, country_level){
$('#dropdown').css('height','auto');
var element = map.getElementById(id);
var parent = map.getElementById('internships');
//find the count for this id
var count = 0;
var midPointX, midPointY, radiusOfCircle;
if(internship_data.regions[id]){
jQuery.each(internship_data.regions[id], function(index){
count += getCountryCount(internship_data.regions[id][index]);
});
midPointX = internship_locations.regions[id].x;
midPointY = internship_locations.regions[id].y;
radiusOfCircle = 40;
} else if(internship_data.countries[id]) {
count = getCountryCount(id);
midPointX = internship_locations.countries[id].x;
midPointY = internship_locations.countries[id].y;
//Mutalate coordinates
//midPointX = ( midPointX - 29.986 ) * ( 1425 / 440 );
//midPointX = ( midPointX - 40 ) * ( 1425 / 440 );
//midPointY = ( ( midPointY - 320.103 ) * -1 ) * ( 671 / 222 );
/*midPointX = (midPointX - 29.986) * (2.834);
midPointY = -1 * (midPointY - 310.103) * (2.9);*/
//alert(midPointX + ", " + midPointY);
radiusOfCircle = 10;
} else {
return;
}
if(count <= 0) {
return;
}
var divisorXoffset = 0;
if(count < 10) {
divisorXoffset = 4;
} else {
divisorXoffset = 2;
}
map.circle(parent, midPointX, midPointY, radiusOfCircle, {stroke: 'transparent', color: 'red',strokeWidth: 1, fill: 'transparent', id: "clickable_circle_"+id});
map.text(parent, midPointX - (radiusOfCircle/divisorXoffset), midPointY + (radiusOfCircle/3), ''+count+'', {fontSize: radiusOfCircle, fill: 'black', id: "clickable_number_"+id});
//this imitates a click on the circle
$("#clickable_number_"+id).click(function(){
$("#clickable_circle_"+id).trigger('click');
});
$("#clickable_circle_"+id).click(function(){
$('#dropdown').hide( 'fade', {}, 1000);
$('#dropdown ul').html('');
if(country_level){
var country_code = id;
$('#dropdown ul').append(
'<li class="country_group_title">' + internship_data.countries[country_code][0].country + '</li>'
);
var included_internships = new Array();
jQuery.each(internship_data.countries[country_code], function(index){
var internship = internship_data.countries[country_code][index];
if (included_internships.indexOf(internship.id) < 0){
$('#dropdown ul').append(
'<li id="click-'+internship.id+'">' + internship.name + ' (' + internship.provider_name + ') </li>'
);
$('#dropdown ul li:last').click(function(){
setupDialogBox(internship.id);
});
included_internships.push(internship.id);
}
});
} else {
$('#'+id).trigger('click');
$.each(internship_data.regions[id], function(i){
var country_code = internship_data.regions[id][i];
if(internship_data.countries[country_code]){
$('#dropdown ul').append(
'<li class="country_group_title">' + internship_data.countries[country_code][0].country + '</li>'
);
var included_internships = new Array();
$.each(internship_data.countries[country_code], function(index){
var internship = internship_data.countries[country_code][index];
if (included_internships.indexOf(internship.id) < 0){
$('#dropdown ul').append(
'<li id="click-'+internship.id+'">' + internship.name + ' (' + internship.provider_name + ') </li>'
);
$('#dropdown ul li:last').click(function(){
setupDialogBox(internship.id);
});
included_internships.push(internship.id);
}
});
}
});
}
$('#dropdown').show( 'fade', {}, 1000);
if(($('#dropdown').height()) > ($(window).height()-150)){
$('#dropdown').height($(window).height()-150);
}
});
}
/***********************************************************************************
This function returns the number of internships in the given country where the
country_code is the id
***********************************************************************************/
function getCountryCount(id){
if(typeof internship_data.countries[id] == 'undefined'){
return 0;
}
return internship_data.countries[id].length;
}
/***********************************************************************************
This function removes the group with the given id from the svg map object and
sets the group class to clickable
***********************************************************************************/
function resetGroup(id){
map.remove(map.getElementById(id));
map.group(null, id, {class: 'clickable'});
}
/***********************************************************************************
This function pulls in the html for the dialog box from an ejs file and upon
success the resutls are appended to the dialogs div where all of the dialogs
are kept in the DOM for faster loaded if they are reopened during the same
session. The jquery tabs are initialized with the 0 index selected. The
dialog is then initiated.
***********************************************************************************/
function setupDialogBox(id){
startLoadingIndicator();
if($('#dialog-'+id).html() == null){
$.ajax({
url: '/internships/' + id + '.json',
dataType: 'json',
success: function(data){
var html = new EJS({ url: 'javascripts/templates/modal_view.ejs'}).render(data);
$('#dialogs').append(html);
$('#tabs-' + id).tabs({ selected: 0});
initDialog(id);
stopLoadingIndicator();
}
});
} else {
initDialog(id);
stopLoadingIndicator();
}
}
/***********************************************************************************
This function sets up the view for the dialog popup for the given internship
id as it is identified on the server.
***********************************************************************************/
function initDialog(id){
$('#dialog-'+id).dialog({
height: $(window).height()-($(window).height()*0.2),
width: $(window).width()-($(window).width()*0.2),
modal: true,
close: function() { $(this).dialog("destroy"); }
});
}
/***********************************************************************************
This function toggles the visible div between list and svg
***********************************************************************************/
function toggleMapListView(){
if($("#svg").css('z-index') == '1'){
$("#list").css('z-index','1');
$("#svg").css('z-index','0');
$("#MapListToggle").html("View Map");
} else {
$("#list").css('z-index','0');
$("#svg").css('z-index','1');
$("#MapListToggle").html("View List");
}
}
/***********************************************************************************
This function sets up the 'table view' view
***********************************************************************************/
function initList(){
if(dataTableIsLoaded()){
destoryDataTable();
}
var html = new EJS({url: 'javascripts/templates/list_view.ejs'}).render(internship_data);
$("#list_view_body").html(html);
initDataTable();
}
/***********************************************************************************
This function configures the user interface functionality and interaction
with the filters object.
***********************************************************************************/
function initFilters(){
var settings = {
"selectedValuesProp":"value",
"searchObjProps":"name",
"queryParam":"query",
"neverSubmit":"true",
"selectedItemProp":"name",
"startText": "Begin Typing..."
};
//Sets the operations to apply the current filters
$("#apply_filters").click(function(){
//Update the global filters object
$.each(models, function(index,model){
var list = $("#"+model).val();
if(list != null){
list = list.join(",");
}
filters[model] = list;
});
$.each(booleans, function(index,bool){
filters[bool] = $('input:radio[name='+bool+']:checked').val();
});
//send the filters to the server and update the page
filterInternshipData();
});
//Sets the operations to reset and apply the current reset filters
$("#reset_filters").click(function(){
//reset the filters object to its default values
filters = {'filters': true, 'languages':null, 'fields':null, 'industries':null, 'providers':null, 'locations':null, 'academic_focuses':null, 'for_credit': null, 'full_time': null, 'part_time': null, 'us_citizenship': null, 'paid': null};
//reset all multi select fields to none
$.each(models, function(index,model){
$("#as-selections-" + model + " li a").trigger('click');
$("#as-values-" + model).attr('value','');
});
//reset all boolean options to either
$.each(booleans, function(index,bool){
$('input:radio[name='+bool+'][value=null]').attr('checked','checked');
});
//send the filters to the server and update the page
filterInternshipData();
});
}
/***********************************************************************************
This calls functions that are called when the page is loaded
***********************************************************************************/
function filterInternshipData(){
//This takes any action that is bound to clicking the filter button with intent to close it
$('#FilterToggle').trigger('click');
getInternshipData();
getMapData();
WaitUntilTheMapAndDataAreLoaded();
}
/***********************************************************************************
This function is a polling function that checks to see if both the internship
data and the svg data are loaded before proceeding. it then fires off functions
that complete the setup process for the map and reset the booleans that determine
whther or not the data has successfully loaded in both objects. It also shows
and hides a loading indicator for the user to let them know it is loading.
***********************************************************************************/
function WaitUntilTheMapAndDataAreLoaded(){
startLoadingIndicator();
if(mapIsLoaded && dataIsLoaded){
//setup the list view
initList();
//setup the map view
initMap();
//reset the loading flags
dataIsLoaded = false;
mapIsLoaded = false;
stopLoadingIndicator();
} else {
setTimeout("WaitUntilTheMapAndDataAreLoaded()",250);
}
}
/***********************************************************************************
This function is called to initiate the data table javascript plugin with
settings and window binidng.
***********************************************************************************/
function initDataTable(){
// DATATABLES =============================================================
// DataTables Config (more info can be found at http://www.datatables.net/)
oTable = $('.datatable').dataTable({
"bJQueryUI": true,
"sScrollX": "",
"bSortClasses": false,
"aaSorting": [[0,'asc']],
"bAutoWidth": true,
"bInfo": true,
"sScrollY": "100%",
"sScrollX": "100%",
"bScrollCollapse": true,
"sPaginationType": "full_numbers",
"bRetrieve": true
});
$(window).bind('resize', function(){
oTable.fnAdjustColumnSizing();
});
}
/***********************************************************************************
This function is called to destory an active and initiated data table as
defined in initDataTable()
***********************************************************************************/
function destoryDataTable(){
oTable.fnDestroy();
// destroy doesn't really work. This next line removes extra html that gets inserted when the datatable
// is initialized multiple times.
$('#list table tr th').each(function(){
$(this).html($(this).children('div').html());
});
}
/***********************************************************************************
This function checks to see if the dataTabe is currently loaded and returns
a boolean as a result.
***********************************************************************************/
function dataTableIsLoaded(){
if($('#list .dataTables_wrapper').size() == 1){
return true;
}
return false;
}
/***********************************************************************************
This function queries the server for the initial internship data and loads it
into the global internship_data object to be used thoughout the script.
***********************************************************************************/
function getInternshipData(){
$.ajax({
url: '/internships.json',
data: filters,
dataType: 'json',
success: function(data){
internship_data.countries = data;
dataIsLoaded = true;
}
});
}
/***********************************************************************************
This function queries the server for the svg data so the map can be drawn for
the user. it then loads that data into the div with id 'svg-map'
***********************************************************************************/
function getMapData(){
$("#svg-map").svg('destroy');
$("#svg-map").svg({
loadURL: '/images/map.svg',
onLoad: function(){
mapIsLoaded = true;
}
});
}
/***********************************************************************************
This function shows the loading indicator for the user
***********************************************************************************/
function startLoadingIndicator(){
$('#svg').showLoading();
$('#list').showLoading();
}
/***********************************************************************************
This function hides the loading indicator for the user
***********************************************************************************/
function stopLoadingIndicator(){
$('#svg').hideLoading();
$('#list').hideLoading();
}