// halite matrix: (originally in app.js.php)
jQuery(function() {
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
document.querySelector(this.getAttribute('href')).scrollIntoView({
behavior: 'smooth'
});
});
});
});
var haToolsHALiteMatrixModule = angular.module('haToolsHALiteMatrixModule', ['ngSanitize'])
.directive('stringToNumberDollars', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
ngModel.$parsers.push(function(value) {
cleanNumberStr = value;
cleanNumberStr = cleanNumberStr.replace('$','');
cleanNumberStr = cleanNumberStr.replaceAll(',','');
if (cleanNumberStr == '') return 0;
if (cleanNumberStr == '-') return 0;
var floatVal = parseFloat(cleanNumberStr);
// console.log("ampp$ parsed [" + value + "] as [" + floatVal + "]");
return floatVal;
});
ngModel.$formatters.push(function(value) {
strVal = '$' + parseFloat(value).toLocaleString();
// console.log("ampp$ formatted [" + value + "] as [" + strVal + "]");
return strVal;
});
}
};
})
.directive('stringToNumberGeneral', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
ngModel.$parsers.push(function(value) {
cleanNumberStr = value;
cleanNumberStr = cleanNumberStr.replaceAll(',','');
if (cleanNumberStr == '') return 0;
if (cleanNumberStr == '-') return 0;
var floatVal = parseFloat(cleanNumberStr);
// console.log("amppG parsed [" + value + "] as [" + floatVal + "]");
return floatVal;
});
ngModel.$formatters.push(function(value) {
strVal = parseFloat(value).toLocaleString();
// console.log("amppG formatted [" + value + "] as [" + strVal + "]");
return strVal;
});
}
};
})
.directive('stringToNumberPercent', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
ngModel.$parsers.push(function(value) {
cleanNumberStr = value;
cleanNumberStr = cleanNumberStr.replaceAll('%','');
cleanNumberStr = cleanNumberStr.replaceAll(',','');
if (cleanNumberStr == '') return 0;
if (cleanNumberStr == '-') return 0;
var floatVal = parseFloat(cleanNumberStr);
// console.log("amppP parsed [" + value + "] as [" + floatVal + "]");
return floatVal;
});
ngModel.$formatters.push(function(value) {
strVal = parseFloat(value).toLocaleString() + '%';
// console.log("amppP formatted [" + value + "] as [" + strVal + "]");
return strVal;
});
}
};
})
.filter('pct2decile', function() {
//Convert percentile for decile for color index
return function(percentile) {
if (percentile == 0) return 1;
return Math.ceil(percentile / 10);
};
})
.filter('pct2decileReversed', function() {
//Convert percentile for decile for color index
return function(percentile) {
var unreversedResult = -1;
if (percentile == 0) {
unreversedResult = 1;
} else {
unreversedResult = Math.ceil(percentile / 10);
}
return 10 - unreversedResult + 1;
};
})
// .filter('c1yr_combo_sms_rtp2_pct_color', function() {
// //Convert percent change to color
// return function(val) {
// if (val === null || typeof val == 'undefined') return 'NaN';
// var color_index = Math.ceil( (val + 30) / 6 );
// if (color_index < 1) return 1;
// if (color_index > 10) return 10;
// return color_index;
// };
// })
.filter('c1yr_super_master_score_pct_color', function() {
//Convert percent change to color
return function(val) {
if (val === null || typeof val == 'undefined') return 'NaN';
var color_index = Math.ceil( (val + 60) / 12 );
if (color_index < 1) return 1;
if (color_index > 10) return 10;
return color_index;
};
})
.filter('appreciation_type_1_color', function() {
//Convert percent change to color
return function(val) {
if (val === null || typeof val == 'undefined') return 'NaN';
var color_index = 1;
if (val > -6) color_index = 2;
if (val > -2) color_index = 3;
if (val > 0) color_index = 4;
if (val > 2) color_index = 5;
if (val > 4) color_index = 6;
if (val > 6) color_index = 7;
if (val > 8) color_index = 8;
if (val > 11) color_index = 9;
if (val > 15) color_index = 10;
return color_index;
};
})
.filter('appreciation_type_2_color', function() {
//Convert percent change to color
return function(val) {
if (val === null || typeof val == 'undefined') return 'NaN';
var color_index = 1;
if (val > -0.6) color_index = 2;
if (val > -0.2) color_index = 3;
if (val > 0) color_index = 4;
if (val > 0.2) color_index = 5;
if (val > 0.4) color_index = 6;
if (val > 0.6) color_index = 7;
if (val > 0.8) color_index = 8;
if (val > 0.11) color_index = 9;
if (val > 0.15) color_index = 10;
return color_index;
};
})
.filter('ha_rent_to_price_color', function() {
//Convert percent change to color
return function(val) {
if (val === null || typeof val == 'undefined') return 'NaN';
var color_index = 1;
if (val > -4) color_index = 2;
if (val > -4.5) color_index = 3;
if (val > 5) color_index = 4;
if (val > 6) color_index = 5;
if (val > 7) color_index = 6;
if (val > 8) color_index = 7;
if (val > 9) color_index = 8;
if (val > 10) color_index = 9;
if (val > 12) color_index = 10;
return color_index;
};
})
// .filter('hms_abs_chng', function() {
// //Convert percent change to color
// return function(val) {
// var color_index = 1;
// if (val > -6) color_index = 2;
// if (val > -2) color_index = 3;
// if (val > 0) color_index = 4;
// if (val > 2) color_index = 5;
// if (val > 4) color_index = 6;
// if (val > 6) color_index = 7;
// if (val > 8) color_index = 8;
// if (val > 11) color_index = 9;
// if (val > 15) color_index = 10;
// return color_index;
// };
// })
.filter('hms_color', function() {
//Convert percent change to color
return function(val) {
var color_index = 1;
if (typeof val == 'undefined') return 'NaN';
if (Math.round(val) >= 40) color_index = 6;
if (Math.round(val) >= 60) color_index = 10;
return color_index;
};
})
.filter('hms_pct_chng_color', function() {
//Convert percent change to color
return function(val) {
if (val === null || typeof val == 'undefined') return 'NaN';
var color_index = 1;
if (val > -80) color_index = 2;
if (val > -60) color_index = 3;
if (val > -40) color_index = 4;
if (val > -20) color_index = 5;
if (val > 20) color_index = 6;
if (val > 40) color_index = 7;
if (val > 60) color_index = 8;
if (val > 80) color_index = 9;
if (val > 100) color_index = 10;
return color_index;
};
})
.filter('ha_house_value_color', function() {
//Convert percent change to color
return function(val) {
if (val === null || typeof val == 'undefined') return 'NaN';
var color_index = 10;
if (val > 175000) color_index = 9;
if (val > 200000) color_index = 8;
if (val > 250000) color_index = 7;
if (val > 300000) color_index = 6;
if (val > 350000) color_index = 5;
if (val > 400000) color_index = 4;
if (val > 500000) color_index = 3;
if (val > 600000) color_index = 2;
if (val > 750000) color_index = 1;
return color_index;
};
})
.filter('minus_30_to_30_color', function() {
return function(val) {
if (val === null || typeof val == 'undefined') return 'NaN';
var color_index = 1;
if (val > -30) color_index = 3;
if (val > -20) color_index = 4;
if (val > -10) color_index = 6; // Yellow From -10 to 10
if (val > 10) color_index = 8;
if (val > 20) color_index = 9;
if (val > 30) color_index = 10;
return color_index;
};
})
.filter('minus_100_to_100_color', function() {
return function(val) {
if (val === null || typeof val == 'undefined') return 'NaN';
var color_index = 1;
color_index = Math.ceil((val+100)/20);
if (color_index < 1) color_index = 1;
if (color_index > 10) color_index = 10;
// console.log("val:" + val + " color_index: " + color_index);
return color_index;
};
})
.filter('ha_undervalue_overvalue_color', function() {
return function(val) {
if (val === null || typeof val == 'undefined') return 'NaN';
var color_index = 1;
if (val < 40) color_index = 2;
if (val < 30) color_index = 3;
if (val < 27) color_index = 4;
if (val < 25) color_index = 5;
if (val < 20) color_index = 6;
if (val < 0) color_index = 7;
if (val < -5) color_index = 8;
if (val < -10) color_index = 9;
if (val < -15) color_index = 10;
console.log("val:" + val + " color_index: " + color_index);
return color_index;
};
})
.filter('stability_index_color', function() {
return function(val) {
if (val > 55) return 10;
if (val > 30) return 6;
return 1;
};
})
.filter('cagr_color', function() {
//Convert percent change to color
return function(val) {
if (val === null || typeof val == 'undefined') return 'NaN';
if (val == '--') return 'NaN';
var color_index = 1;
if (val > -1) color_index = 2;
if (val > 0) color_index = 3;
if (val > 1) color_index = 4;
if (val > 2) color_index = 5;
if (val > 3) color_index = 6;
if (val > 4) color_index = 7;
if (val > 5) color_index = 8;
if (val > 6) color_index = 9;
if (val > 7) color_index = 10;
return color_index;
};
})
.filter('population_yy_color', function() {
//Convert percent change to color
return function(val) {
if (val === null || typeof val == 'undefined') return 'NaN';
if (val == '--') return 'NaN';
var color_index = 1;
if (val > -2) color_index = 2;
if (val > -1) color_index = 3;
if (val > 0) color_index = 4;
if (val > 0.5) color_index = 5;
if (val > 1) color_index = 6;
if (val > 1.5) color_index = 7;
if (val > 2) color_index = 8;
if (val > 2.5) color_index = 9;
if (val > 3) color_index = 10;
-2, -1, 0, -0.5, 1, 1.5, 2.0, 2.5, 3
return color_index;
};
})
.controller('matrixController', function($scope, $http, $q, $compile) {
if (typeof ha_tools_access_level == 'undefined') ha_tools_access_level = 'JV';
if (typeof accessLevel != 'undefined') ha_tools_access_level = accessLevel;
if (typeof(ha_member) != 'undefined') {
if (typeof(ha_member.per_page_restriction) != 'undefined') {
if (ha_member.per_page_restriction == 'force_free_mode') {
ha_tools_restrict('state');
}
}
}
$scope.csr = hmf_csr;
if (typeof hmf_csr_override == 'number') $scope.csr = hmf_csr_override;
$scope.ry_mm_csr = ($scope.csr).toString();
$scope.sortType = 'super_master_score';
$scope.sortReverse = true;
$scope.dataLoaded = false;
$scope.locations = [];
$scope.markets_total_count = 0;
$scope.row_limit = 100;
$scope.rows_to_skip = 0;
$scope.current_page_number = "1";
$scope.pages_count = 1;
$scope.pages_range = [
"1"
];
$scope.latestMlsDateLabel = '';
$scope.dataMatrixRequestInProgress = false;
$scope.filterRangesAtMax = false;
$scope.filterRangesAtMin = false;
$scope.BoostRange = '5';
$scope.max_rank_returned = 0;
$scope.row_limit_options = [100, 500, 1000, 5000];
$scope.row_limit_options_mobile = [25, 50, 100];
if (typeof ha_plugin_mode != 'undefined') $scope.row_limit_options = [100, 500];
$scope.filter_allowed = [];
$scope.filter_allowed.allowed = true;
$scope.dataLoadCounter = 0;
$scope.county_id = "-1";
$scope.msa_id = "-1";
$scope.state_id = "-1";
$scope.counties = [];
$scope.states = [];
$scope.msas_all = [];
$scope.msas_all_loaded = false;
$scope.popupMapOpen = false;
$scope.waitPopupMap = false;
$scope.searchString = "";
$scope.searchActive = false;
$scope.skipCountyReset = false;
$scope.skipLoadData = false;
$scope.skipCountyResetOnMSAUpdate = false;
$scope.skipRegLimitResetOnCSRUpdate = false;
$scope.selectionNonEmpty = false;
$scope.mls_ds_variation_1 = 'as_is';
$scope.mls_ds_variation_2 = 'raw';
$scope.mls_val_suffix = "*";
$scope.dataLoadStartedAt = 0;
$scope.magicButtonAppliedAt = 0;
$scope.ClassicToolButtonAppliedAt = 0;
$scope.filterVarsStatsLoading = false;
//------------------------------------------------------------------------------------------
$scope.filters = {};
$scope.filters.indicators = {};
$scope.savedFIlters = {};
$scope.filterMode = "onestep";
$scope.filterStep = "2";
$scope.step1CSR = "1";
$scope.step2CSR = "80";
$scope.easy_button_code = 'wholesale';
$scope.saved_search_id = "-1";
$scope.currentSelectIndicator = 'mls_score2_normalised'; //'hms';
$scope.filterParentMarketCSR = 1;
$scope.mapLinkURL = '>>>';
$scope.mapLinkURLOptions = '>>>';
$scope.inArray = function(needle, haystack) {
var length = haystack.length;
for(var i = 0; i < length; i++) {
if(haystack[i] == needle) return true;
}
return false;
};
const params = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop),
});
if (typeof params.eb == 'string') {
$scope.easy_button_code = params.eb;
}
//////////////////////////////////////////////////////////////////
const ha_indicators = new Ha_indicators();
$scope.filters.indicators = ha_indicators.get_indicators();
$scope.filters.indicatorGroups = ha_indicators.get_indicator_groups();
$scope.filterIndicatorVariations = ha_indicators.get_filter_indicator_variations();
//////////////////////////////////////////////////////////////////
/*
$scope.filterIndicatorVariations_raw = {
'raw': 'RAW',
'parentraw': 'Parent Mkt RAW',
'per10Kpop': 'RAW (Per 10K)',
'yyt': '1 Yr Change', // YoY Chng
'mm': 'MoM % Chng',
'yy': 'YoY % Chng',
};
$scope.filterIndicatorVariations_pct = {
'pct': 'Rank',
'per10Kpop_pct': 'Rank (Per 10K)',
'mm_pct': 'MoM Rank',
'yy_pct': 'YoY Rank'
// We need these to work as unique for HMS, STAR, TAPS and maybe a few others "NON-MLS" Indicators
//'mm': 'Rank MoM % Chng',
//'yy': 'Rank YoY % Chng',
};
*/
$scope.filters.ClassicToolButtons = { // Classic Tool Buttons
'classic_hmf' : { // HMF Modified
label: 'Hot Market Finder',
details: "Rank all Metro markets (best to worst) by select indicators.",
iconlink: "https://www.housingalerts.com/images/ui-icons/UI-Icon-HOT-Market-Finder.png",
style: 'Style-PRO',
mkt_lvl: 'All',
auth: 'PRO',
sortby : 'mls_score_normalised',
sliderSettings : {
'stability_index_yy_change' : {
c_min: 'range_min',
c_max: 'range_max'
},
'stability_index' : {
c_min: 'range_min',
c_max: 'range_max'
},
'mls_score_normalised_yy_change' : {
c_min: 'range_min',
c_max: 'range_max'
},
'mls_score_normalised' : {
c_min: 'range_min',
c_max: 'range_max'
},
'score_master_normalized_yy_change' : {
c_min: 'range_min',
c_max: 'range_max'
},
'score_master_normalized' : {
c_min: 'range_min',
c_max: 'range_max'
},
'population' : {
c_min: 'range_min',
c_max: 'range_max'
},
},
},
'classic_cff' : {
label: 'Cash Flow Finder',
details: "Search, Rank & Map the Best & Worst Cash Flow Markets",
//details: "Search, Rank, Filter & Map the Best & Worst Cash Flow Markets",
iconlink: "https://www.housingalerts.com/images/ui-icons/UI-Icon-Cash-Flow-Finder.png",
style: 'Style-PRO',
mkt_lvl: 'All',
auth: 'All',
sortby : 'combo_mls_score_rtp2_percentile',
sliderSettings : {
'population' : {
c_min: 'range_min',
c_max: 'range_max'
},
'mls_score_normalised' : { // super_master_score_pct or hms_pct
c_min: 'range_min',
c_max: 'range_max'
},
'ha_house_value' : {
c_min: 'range_min',
c_max: 'range_max'
},
'ha_house_rent' : {
c_min: 'range_min',
c_max: 'range_max'
},
'ha_rent_to_price' : {
c_min: 'range_min',
c_max: 'range_max'
},
'combo_mls_score_rtp2_percentile' : {
c_min: 'range_min',
c_max: 'range_max'
},
},
},
'classic_hvf' : {
label: 'House Value Finder',
details: "Rank & Map Markets Based On Home Values w. Potential Appr'n",
//details: "Rank, Filter & Map Markets Based On Home Values w. Potential Appreciation",
iconlink: "https://www.housingalerts.com/images/ui-icons/UI-Icon-House-Value-Finder.png",
style: 'Style-PRO',
mkt_lvl: 'All',
auth: 'All',
sortby : 'combo_mls_score_hpv2_percentile',
sliderSettings : {
'population' : {
c_min: 'range_min',
c_max: 'range_max'
},
'mls_score_normalised' : { // super_master_score_pct or hms_yyt
c_min: 'range_min',
c_max: 'range_max'
},
'mls_score_normalised_yy_change' : { // super_master_score_1yrago
c_min: 'range_min',
c_max: 'range_max'
},
'ha_house_value' : {
c_min: 'range_min',
c_max: 'range_max'
},
'ha_house_value_pct ' : {
c_min: 'range_min',
c_max: 'range_max'
},
'combo_mls_score_hpv2_percentile' : {
c_min: 'range_min',
c_max: 'range_max'
},
},
},
'classic_rgt' : { // RGT Modified
label: 'Rent Growth Tracker',
details: "Review best/worst rental growth markets.",
iconlink: "https://www.housingalerts.com/images/ui-icons/UI-Icon-Rent-Growth-Tracker.png",
style: 'Style-PRO',
mkt_lvl: 'All',
auth: 'PRO',
sortby : 'mls_score_normalised',
sliderSettings : {
'rent_cagr3y_pct' : {
c_min: 'range_min',
c_max: 'range_max'
},
'rent_cagr3y' : {
c_min: 'range_min',
c_max: 'range_max'
},
'rent_cagr5y' : {
c_min: 'range_min',
c_max: 'range_max'
},
'ha_house_rent_pct' : {
c_min: 'range_min',
c_max: 'range_max'
},
'ha_house_rent' : {
c_min: 'range_min',
c_max: 'range_max'
},
'rent_appr_now' : {
c_min: 'range_min',
c_max: 'range_max'
},
'rent_appr_1y_back' : {
c_min: 'range_min',
c_max: 'range_max'
},
'rent_appr_2y_back' : {
c_min: 'range_min',
c_max: 'range_max'
},
'mls_score_normalised' : {
c_min: 'range_min',
c_max: 'range_max'
},
'population' : {
c_min: 'range_min',
c_max: 'range_max'
},
},
},
};
$scope.filters.magicButtons = {
'button_test' : {
label: 'TEST DIFF. MARKET TYPES',
details: "Custom ranges per market type",
style: 'Style-01',
mkt_lvl: 'All',
auth: 'HA',
sortby : 'hms',
sliderSettings : {
'hms' : {
'Metro' : {
c_min: 10,
c_max: 20
},
'State' : {
c_min: 20,
c_max: 30
},
'County' : {
c_min: 30,
c_max: 40
},
'Zipcode' : {
c_min: 40,
c_max: 50
}
},
'ha_rent_to_price' : {
c_min: 6,
c_max: 13
},
'ha_house_value' : {
c_min: 'range_min',
c_max: 'range_max'
},
},
},
'wflip_state' : {
label: 'Wholesale - Flip',
details: "Short Hold,
Vibrant Markets",
popover_title: 'Wholesale - Flip',
popover_content: "
Scanning for Wholesale & Flip markets concentrates on short-term predictors and indicators likely to signal near term market strength.
You can customize the default output by adjusting the green sliders and/or adding other indictors to the filter.
", style: 'Style-01', mkt_lvl: 'State', auth: 'All', sortby : 'mb_score_wholesale', sliderSettings : { 'ha_house_value' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_ha_nmi' : { c_min: 0, c_max: 'range_max' }, 'mls_raw_dom' : { c_min: 17, c_max: 'range_max' }, 'combo_mls_score_rtp2_percentile' : { c_min: 18, c_max: 'range_max' }, 'combo_mls_score_hpv2_percentile' : { c_min: 20, c_max: 'range_max' }, 'mls_raw_pr' : { c_min: 30, c_max: 300 }, 'stability_index' : { c_min: 40, c_max: 'range_max' }, 'mls_score_normalised' : { c_min: 20, c_max: 'range_max' }, 'score_master_normalized' : { c_min: 20, c_max: 'range_max' }, 'population' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_score2_normalised' : { c_min: 'range_min', c_max: 'range_max' }, 'mb_score_wholesale' : { c_min: 'range_min', c_max: 'range_max' }, }, }, 'wflip_metro' : { label: 'Wholesale - Flip', details: "Short Hold,Scanning for Wholesale & Flip markets concentrates on short-term predictors and indicators likely to signal near term market strength.
You can customize the default output by adjusting the green sliders and/or adding other indictors to the filter.
", style: 'Style-01', mkt_lvl: 'Metro', auth: 'All', sortby : 'mb_score_wholesale', sliderSettings : { 'ha_house_value' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_ha_nmi' : { c_min: 0, c_max: 5 }, 'mls_raw_dom' : { c_min: 17, c_max: 90 }, 'combo_mls_score_rtp2_percentile' : { c_min: 18, c_max: 'range_max' }, 'combo_mls_score_hpv2_percentile' : { c_min: 15, c_max: 'range_max' }, 'mls_raw_pr' : { c_min: 15, c_max: 300 }, 'stability_index' : { c_min: 40, c_max: 'range_max' }, 'mls_score_normalised' : { c_min: 20, c_max: 'range_max' }, 'score_master_normalized' : { c_min: 20, c_max: 'range_max' }, 'population' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_score2_normalised' : { c_min: 'range_min', c_max: 'range_max' }, 'mb_score_wholesale' : { c_min: 'range_min', c_max: 'range_max' }, }, }, 'wflip_county' : { label: 'Wholesale - Flip', details: "Short Hold,Scanning for Wholesale & Flip markets concentrates on short-term predictors and indicators likely to signal near term market strength.
You can customize the default output by adjusting the green sliders and/or adding other indictors to the filter.
", style: 'Style-01', mkt_lvl: 'County', auth: 'All', sortby : 'mb_score_wholesale', sliderSettings : { 'ha_house_value' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_ha_nmi' : { c_min: -34, c_max: 5 }, 'mls_raw_dom' : { c_min: 1, c_max: 90 }, 'combo_mls_score_rtp2_percentile' : { c_min: 18, c_max: 'range_max' }, 'combo_mls_score_hpv2_percentile' : { c_min: 20, c_max: 'range_max' }, 'mls_raw_pr' : { c_min: 20, c_max: 1500 }, 'stability_index' : { c_min: 40, c_max: 'range_max' }, 'mls_score_normalised' : { c_min: 20, c_max: 'range_max' }, 'score_master_normalized' : { c_min: 20, c_max: 'range_max' }, 'population' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_score2_normalised' : { c_min: 'range_min', c_max: 'range_max' }, 'mb_score_wholesale' : { c_min: 'range_min', c_max: 'range_max' }, }, }, 'wflip_zipcode' : { label: 'Wholesale - Flip', details: "Short Hold,Scanning for Wholesale & Flip markets concentrates on short-term predictors and indicators likely to signal near term market strength.
You can customize the default output by adjusting the green sliders and/or adding other indictors to the filter.
", style: 'Style-01', mkt_lvl: 'Zipcode', auth: 'All', sortby : 'mb_score_wholesale', sliderSettings : { 'ha_house_value' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_ha_nmi' : { c_min: -34, c_max: 5 }, 'mls_raw_dom' : { c_min: 1, c_max: 90 }, 'combo_mls_score_rtp2_percentile' : { c_min: 18, c_max: 'range_max' }, 'combo_mls_score_hpv2_percentile' : { c_min: 20, c_max: 'range_max' }, 'mls_raw_pr' : { c_min: 20, c_max: 1500 }, 'stability_index' : { c_min: 40, c_max: 'range_max' }, 'mls_score_normalised' : { c_min: 20, c_max: 'range_max' }, 'score_master_normalized' : { c_min: 20, c_max: 'range_max' }, 'population' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_score2_normalised' : { c_min: 'range_min', c_max: 'range_max' }, 'mb_score_wholesale' : { c_min: 'range_min', c_max: 'range_max' }, }, }, 'creativereih_state' : { label: 'Creative REI Hacker', details: "LO\'s, Sub2\'s, WrapsScanning for 'creative' markets focusses more on risk avoidance and stability over appreciation.
You can customize the default output by adjusting the green sliders and/or adding other indictors to the filter.
", style: 'Style-02', mkt_lvl: 'State', auth: 'All', sortby : 'mb_score_creative', sliderSettings : { 'ha_rent_to_price' : { c_min: 5, c_max: 'range_max' }, 'momentum_score_percentile' : { c_min: 15, c_max: 'range_max' }, 'hms_pct' : { c_min: 30, c_max: 'range_max' }, 'combo_mls_score_rtp2_percentile' : { c_min: 15, c_max: 'range_max' }, 'combo_mls_score_hpv2_percentile' : { c_min: 15, c_max: 'range_max' }, 'mls_ha_nmi' : { c_min: 0, c_max: 5 }, 'mls_raw_dom' : { c_min: 17, c_max: 90 }, 'stability_index' : { c_min: 40, c_max: 'range_max' }, /*'mls_score_normalised' : { c_min: 20, c_max: 'range_max' },*/ 'score_master_normalized' : { c_min: 20, c_max: 'range_max' }, 'ha_house_value' : { c_min: 'range_min', c_max: 'range_max' }, 'ha_value_to_income' : { c_min: 'range_min', c_max: 'range_max' }, 'population' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_score2_normalised' : { c_min: 'range_min', c_max: 'range_max' }, 'mb_score_creative' : { c_min: 'range_min', c_max: 'range_max' }, }, }, 'creativereih_metro' : { label: 'Creative REI Hacker', details: "LO\'s, Sub2\'s, WrapsScanning for 'creative' markets focusses more on risk avoidance and stability over appreciation.
You can customize the default output by adjusting the green sliders and/or adding other indictors to the filter.
", style: 'Style-02', mkt_lvl: 'Metro', auth: 'All', sortby : 'mb_score_creative', sliderSettings : { 'ha_rent_to_price' : { c_min: 5, c_max: 14 }, 'momentum_score_percentile' : { c_min: 15, c_max: 'range_max' }, 'hms_pct' : { c_min: 30, c_max: 'range_max' }, 'combo_mls_score_rtp2_percentile' : { c_min: 15, c_max: 'range_max' }, 'combo_mls_score_hpv2_percentile' : { c_min: 15, c_max: 'range_max' }, 'mls_ha_nmi' : { c_min: 0, c_max: 5 }, 'mls_raw_dom' : { c_min: 17, c_max: 90 }, 'stability_index' : { c_min: 40, c_max: 'range_max' }, /*'mls_score_normalised' : { c_min: 20, c_max: 'range_max' },*/ 'score_master_normalized' : { c_min: 20, c_max: 'range_max' }, 'ha_house_value' : { c_min: 'range_min', c_max: 'range_max' }, 'ha_value_to_income' : { c_min: 'range_min', c_max: 'range_max' }, 'population' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_score2_normalised' : { c_min: 'range_min', c_max: 'range_max' }, 'mb_score_creative' : { c_min: 'range_min', c_max: 'range_max' }, }, }, 'creativereih_county' : { label: 'Creative REI Hacker', details: "LO\'s, Sub2\'s, WrapsScanning for 'creative' markets focusses more on risk avoidance and stability over appreciation.
You can customize the default output by adjusting the green sliders and/or adding other indictors to the filter.
", style: 'Style-02', mkt_lvl: 'County', auth: 'All', sortby : 'mb_score_creative', sliderSettings : { 'ha_rent_to_price' : { c_min: 5, c_max: 'range_max' }, 'hms_pct' : { c_min: 20, c_max: 'range_max' }, 'combo_mls_score_rtp2_percentile' : { c_min: 15, c_max: 'range_max' }, 'combo_mls_score_hpv2_percentile' : { c_min: 15, c_max: 'range_max' }, 'mls_ha_nmi' : { c_min: -33, c_max: 5 }, 'mls_raw_dom' : { c_min: 1, c_max: 90 }, 'stability_index' : { c_min: 40, c_max: 'range_max' }, /*'mls_score_normalised' : { c_min: 20, c_max: 'range_max' },*/ 'score_master_normalized' : { c_min: 20, c_max: 'range_max' }, 'ha_house_value' : { c_min: 'range_min', c_max: 'range_max' }, 'ha_value_to_income' : { c_min: 'range_min', c_max: 'range_max' }, 'population' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_score2_normalised' : { c_min: 'range_min', c_max: 'range_max' }, 'mb_score_creative' : { c_min: 'range_min', c_max: 'range_max' }, }, }, 'creativereih_zipcode' : { label: 'Creative REI Hacker', details: "LO\'s, Sub2\'s, WrapsScanning for 'creative' markets focusses more on risk avoidance and stability over appreciation.
You can customize the default output by adjusting the green sliders and/or adding other indictors to the filter.
", style: 'Style-02', mkt_lvl: 'Zipcode', auth: 'All', sortby : 'mb_score_creative', sliderSettings : { 'ha_rent_to_price' : { c_min: 5, c_max: 'range_max' }, 'hms_pct' : { c_min: 20, c_max: 'range_max' }, 'combo_mls_score_rtp2_percentile' : { c_min: 15, c_max: 'range_max' }, 'combo_mls_score_hpv2_percentile' : { c_min: 15, c_max: 'range_max' }, 'mls_ha_nmi' : { c_min: -33, c_max: 5 }, 'mls_raw_dom' : { c_min: 1, c_max: 90 }, 'stability_index' : { c_min: 40, c_max: 'range_max' }, /*'mls_score_normalised' : { c_min: 20, c_max: 'range_max' },*/ 'score_master_normalized' : { c_min: 20, c_max: 'range_max' }, 'ha_house_value' : { c_min: 'range_min', c_max: 'range_max' }, 'ha_value_to_income' : { c_min: 'range_min', c_max: 'range_max' }, 'population' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_score2_normalised' : { c_min: 'range_min', c_max: 'range_max' }, 'mb_score_creative' : { c_min: 'range_min', c_max: 'range_max' }, }, }, 'wealthmax_state' : { // Original Config label: 'Wealth Maximizer', details: "Buy & Hold, Leveraged Appreciation, Cyclical Mkts", popover_title: 'Wealth Maximizer', popover_content: "Scanning for wealth building markets focuses more on long term appreciation indicators.
You can customize the default output by adjusting the green sliders and/or adding other indictors to the filter.
", style: 'Style-03', mkt_lvl: 'State', auth: 'PRO', sortby : 'mb_score_wealth', sliderSettings : { 'stability_index' : { c_min: 40, c_max: 'range_max' }, 'mls_score_normalised' : { // c_min: 25, c_min: 'range_min', c_max: 'range_max' }, 'wp_flag' : { control_value: "1" }, 'score_master_normalized' : { c_min: 25, c_max: 'range_max' }, 'score_canary_normalised' : { c_min: 20, c_max: 'range_max' }, 'score_combo' : { c_min: 20, c_max: 'range_max' }, 'cagr3y' : { c_min: 5, c_max: 'range_max' }, 'population' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_score2_normalised' : { c_min: 'range_min', c_max: 'range_max' }, 'mb_score_wealth' : { c_min: 'range_min', c_max: 'range_max' }, } }, 'wealthmax_metro' : { // Original Config label: 'Wealth Maximizer', details: "Buy & Hold, Leveraged Appreciation, Cyclical Mkts", popover_title: 'Wealth Maximizer', popover_content: "Scanning for wealth building markets focuses more on long term appreciation indicators.
You can customize the default output by adjusting the green sliders and/or adding other indictors to the filter.
", style: 'Style-03', mkt_lvl: 'Metro', auth: 'PRO', sortby : 'mb_score_wealth', sliderSettings : { 'stability_index' : { c_min: 40, c_max: 'range_max' }, 'mls_score_normalised' : { // c_min: 25, c_min: 'range_min', c_max: 'range_max' }, 'wp_flag' : { control_value: "1" }, 'score_master_normalized' : { c_min: 25, c_max: 'range_max' }, 'score_canary_normalised' : { c_min: 20, c_max: 'range_max' }, 'score_combo' : { c_min: 20, c_max: 'range_max' }, 'cagr3y' : { c_min: 5, c_max: 'range_max' }, 'population' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_score2_normalised' : { c_min: 'range_min', c_max: 'range_max' }, 'mb_score_wealth' : { c_min: 'range_min', c_max: 'range_max' }, } }, 'wealthmax_county' : { // Original Config label: 'Wealth Maximizer', details: "Buy & Hold, Leveraged Appreciation, Cyclical Mkts", popover_title: 'Wealth Maximizer', popover_content: "Scanning for wealth building markets focuses more on long term appreciation indicators.
You can customize the default output by adjusting the green sliders and/or adding other indictors to the filter.
", style: 'Style-03', mkt_lvl: 'County', auth: 'PRO', sortby : 'mb_score_wealth', sliderSettings : { 'stability_index' : { c_min: 40, c_max: 'range_max' }, 'mls_score_normalised' : { // c_min: 25, c_min: 'range_min', c_max: 'range_max' }, 'wp_flag' : { control_value: "1" }, 'score_master_normalized' : { c_min: 25, c_max: 'range_max' }, 'score_canary_normalised' : { c_min: 20, c_max: 'range_max' }, 'score_combo' : { c_min: 20, c_max: 'range_max' }, 'cagr3y' : { c_min: 5, c_max: 'range_max' }, 'population' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_score2_normalised' : { c_min: 'range_min', c_max: 'range_max' }, 'mb_score_wealth' : { c_min: 'range_min', c_max: 'range_max' }, } }, 'wealthmax_zipcode' : { // Original Config label: 'Wealth Maximizer', details: "Buy & Hold, Leveraged Appreciation, Cyclical Mkts", popover_title: 'Wealth Maximizer', popover_content: "Scanning for wealth building markets focuses more on long term appreciation indicators.
You can customize the default output by adjusting the green sliders and/or adding other indictors to the filter.
", style: 'Style-03', mkt_lvl: 'Zipcode', auth: 'PRO', sortby : 'mb_score_wealth', sliderSettings : { 'stability_index' : { c_min: 40, c_max: 'range_max' }, 'mls_score_normalised' : { // c_min: 25, c_min: 'range_min', c_max: 'range_max' }, 'wp_flag' : { control_value: "1" }, 'score_master_normalized' : { c_min: 25, c_max: 'range_max' }, 'score_canary_normalised' : { c_min: 20, c_max: 'range_max' }, 'score_combo' : { c_min: 20, c_max: 'range_max' }, 'cagr3y' : { c_min: 5, c_max: 'range_max' }, 'population' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_score2_normalised' : { c_min: 'range_min', c_max: 'range_max' }, 'mb_score_wealth' : { c_min: 'range_min', c_max: 'range_max' }, } }, 'cashflow_state' : { label: 'Cash Flow Boost', details: "Buy & Hold, Income Over Wealth Creation", popover_title: 'Cash Flow Boost', popover_content: "This scanner focuses on indicators more likely to result in higher cash flow markets. While high appreciation is not typically found in most cash flow markets over the long-term, this filter also attempts to identify markets with the rare combination of both in the near term.
You can customize the default output by adjusting the green sliders and/or adding other indictors to the filter.
", style: 'Style-04', mkt_lvl: 'State', auth: 'All', sortby : 'mb_score_cashflow', sliderSettings : { 'ha_rent_to_price' : { c_min: 6, c_max: 'range_max' }, 'combo_mls_score_rtp2_percentile' : { c_min: 30, c_max: 'range_max' }, 'combo_mls_score_hpv2_percentile' : { c_min: 20, c_max: 'range_max' }, 'rent_cagr3y' : { c_min: 5, c_max: 'range_max' }, 'mls_ha_nmi' : { c_min: 0, c_max: 5 }, 'mls_raw_dom' : { c_min: 17, c_max: 'range_max' }, 'stability_index' : { c_min: 30, c_max: 'range_max' }, 'mls_score_normalised' : { c_min: 20, c_max: 'range_max' }, 'score_master_normalized' : { c_min: 20, c_max: 'range_max' }, 'population' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_score2_normalised' : { c_min: 'range_min', c_max: 'range_max' }, 'mb_score_cashflow' : { c_min: 'range_min', c_max: 'range_max' }, }, }, 'cashflow_metro' : { label: 'Cash Flow Boost', details: "Buy & Hold, Income Over Wealth Creation", popover_title: 'Cash Flow Boost', popover_content: "This scanner focuses on indicators more likely to result in higher cash flow markets. While high appreciation is not typically found in most cash flow markets over the long-term, this filter also attempts to identify markets with the rare combination of both in the near term.
You can customize the default output by adjusting the green sliders and/or adding other indictors to the filter.
", style: 'Style-04', mkt_lvl: 'Metro', auth: 'All', sortby : 'mb_score_cashflow', sliderSettings : { 'ha_rent_to_price' : { c_min: 6, c_max: 13 }, 'combo_mls_score_rtp2_percentile' : { c_min: 30, c_max: 'range_max' }, 'combo_mls_score_hpv2_percentile' : { c_min: 20, c_max: 'range_max' }, 'rent_cagr3y' : { c_min: 5, c_max: 18 }, 'mls_ha_nmi' : { c_min: 0, c_max: 5 }, 'mls_raw_dom' : { c_min: 17, c_max: 75 }, 'stability_index' : { c_min: 30, c_max: 'range_max' }, 'mls_score_normalised' : { c_min: 20, c_max: 'range_max' }, 'score_master_normalized' : { c_min: 20, c_max: 'range_max' }, 'population' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_score2_normalised' : { c_min: 'range_min', c_max: 'range_max' }, 'mb_score_cashflow' : { c_min: 'range_min', c_max: 'range_max' }, }, }, 'cashflow_county' : { label: 'Cash Flow Boost', details: "Buy & Hold, Income Over Wealth Creation", popover_title: 'Cash Flow Boost', popover_content: "This scanner focuses on indicators more likely to result in higher cash flow markets. While high appreciation is not typically found in most cash flow markets over the long-term, this filter also attempts to identify markets with the rare combination of both in the near term.
You can customize the default output by adjusting the green sliders and/or adding other indictors to the filter.
", style: 'Style-04', mkt_lvl: 'County', auth: 'All', sortby : 'mb_score_cashflow', sliderSettings : { 'ha_rent_to_price' : { c_min: 5, c_max: 72 }, 'combo_mls_score_rtp2_percentile' : { c_min: 35, c_max: 'range_max' }, 'combo_mls_score_hpv2_percentile' : { c_min: 35, c_max: 'range_max' }, 'rent_cagr3y' : { c_min: 5, c_max: 44 }, 'mls_ha_nmi' : { c_min: -34, c_max: 5 }, 'mls_raw_dom' : { c_min: 1, c_max: 90 }, 'stability_index' : { c_min: 30, c_max: 'range_max' }, 'mls_score_normalised' : { c_min: 20, c_max: 'range_max' }, 'score_master_normalized' : { c_min: 20, c_max: 'range_max' }, 'ha_house_value' : { c_min: 'range_min', c_max: 'range_max' }, 'population' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_score2_normalised' : { c_min: 'range_min', c_max: 'range_max' }, 'mb_score_cashflow' : { c_min: 'range_min', c_max: 'range_max' }, }, }, 'cashflow_zipcode' : { label: 'Cash Flow Boost', details: "Buy & Hold, Income Over Wealth Creation", popover_title: 'Cash Flow Boost', popover_content: "This scanner focuses on indicators more likely to result in higher cash flow markets. While high appreciation is not typically found in most cash flow markets over the long-term, this filter also attempts to identify markets with the rare combination of both in the near term.
You can customize the default output by adjusting the green sliders and/or adding other indictors to the filter.
", style: 'Style-04', mkt_lvl: 'Zipcode', auth: 'All', sortby : 'mb_score_cashflow', sliderSettings : { 'ha_rent_to_price' : { c_min: 5, c_max: 72 }, 'combo_mls_score_rtp2_percentile' : { c_min: 35, c_max: 'range_max' }, 'combo_mls_score_hpv2_percentile' : { c_min: 35, c_max: 'range_max' }, 'rent_cagr3y' : { c_min: 5, c_max: 317 }, 'mls_ha_nmi' : { c_min: -34, c_max: 5 }, 'mls_raw_dom' : { c_min: 1, c_max: 90 }, 'stability_index' : { c_min: 30, c_max: 'range_max' }, 'mls_score_normalised' : { c_min: 20, c_max: 'range_max' }, 'score_master_normalized' : { c_min: 20, c_max: 'range_max' }, 'ha_house_value' : { c_min: 'range_min', c_max: 'range_max' }, 'population' : { c_min: 'range_min', c_max: 'range_max' }, 'mls_score2_normalised' : { c_min: 'range_min', c_max: 'range_max' }, 'mb_score_cashflow' : { c_min: 'range_min', c_max: 'range_max' }, }, }, }; //Set all Magic Buttons to Inacrive for (magicButtonKey in $scope.filters.magicButtons) { $scope.filters.magicButtons[magicButtonKey].active = false; var button_deleted = false; if (typeof ha_plugin_mode != 'undefined') { if ($scope.filters.magicButtons[magicButtonKey].auth == 'HA') { delete $scope.filters.magicButtons[magicButtonKey]; button_deleted = true; } } if (!button_deleted && typeof ha_tools_access_level == 'string' && $scope.filters.magicButtons[magicButtonKey].auth != 'All') { var magicButtonAccessStrings = $scope.filters.magicButtons[magicButtonKey].auth.split(','); if (!$scope.inArray(ha_tools_access_level, magicButtonAccessStrings)) { delete $scope.filters.magicButtons[magicButtonKey]; button_deleted = true; } } if (!button_deleted && typeof magic_button_market_levels_str == 'string' && $scope.filters.magicButtons[magicButtonKey].mkt_lvl != 'All') { if (magic_button_market_levels_str.indexOf( $scope.filters.magicButtons[magicButtonKey].mkt_lvl ) == -1 ) { delete $scope.filters.magicButtons[magicButtonKey]; button_deleted = true; } } } //Set all Classic Tool Buttons to Inacrive for (ClassicToolButtonKey in $scope.filters.ClassicToolButtons) { $scope.filters.ClassicToolButtons[ClassicToolButtonKey].active = false; var button_deleted = false; if (typeof ha_plugin_mode != 'undefined') { if ($scope.filters.ClassicToolButtons[ClassicToolButtonKey].auth == 'HA') { delete $scope.filters.ClassicToolButtons[ClassicToolButtonKey]; button_deleted = true; } } if (!button_deleted && typeof ha_tools_access_level == 'string' && $scope.filters.ClassicToolButtons[ClassicToolButtonKey].auth != 'All') { var ClassicToolButtonAccessStrings = $scope.filters.ClassicToolButtons[ClassicToolButtonKey].auth.split(','); if (!$scope.inArray(ha_tools_access_level, ClassicToolButtonAccessStrings)) { delete $scope.filters.ClassicToolButtons[ClassicToolButtonKey]; button_deleted = true; } } if (!button_deleted && typeof classic_tool_button_market_levels_str == 'string' && $scope.filters.ClassicToolButtons[ClassicToolButtonKey].mkt_lvl != 'All') { if (classic_tool_button_market_levels_str.indexOf( $scope.filters.ClassicToolButtons[ClassicToolButtonKey].mkt_lvl ) == -1 ) { delete $scope.filters.ClassicToolButtons[ClassicToolButtonKey]; button_deleted = true; } } } /* $scope.convertActiveIndicatorsToParent = function() { for (indicatorKey in $scope.filters.indicators) { console.log(indicatorKey); console.log($scope.filters.indicators[indicatorKey].active); if ($scope.filters.indicators[indicatorKey].active && !$scope.filters.indicators[indicatorKey].is_parent_indicator) { var parentIndicatorKey = 'parent__' + indicatorKey $scope.removeFilterIndicatorControl(indicatorKey); $scope.filterStep = 1; $scope.addFilterIndicatorControl(indicatorKey); $scope.filters.indicators[parentIndicatorKey].c_max = $scope.filters.indicators[indicatorKey].c_max; $scope.filters.indicators[parentIndicatorKey].c_min = $scope.filters.indicators[indicatorKey].c_min; } } $scope.ry_mm_csr = 80; } */ $scope.loadSavedFilterRanges = function(sliderRanges) { setTimeout(function() { // to apply new ranges AFTER ranges are reset on CSR change for (indicatorKey in $scope.filters.indicators) { if (typeof sliderRanges[indicatorKey] == 'object') { var indicatorSliderRanges = sliderRanges[indicatorKey]; if (typeof indicatorSliderRanges['County'] == 'object') { // Use Market-specific slider ranges if ($scope.ry_mm_csr == 1) indicatorSliderRanges = indicatorSliderRanges['Metro']; if ($scope.ry_mm_csr == 2) indicatorSliderRanges = indicatorSliderRanges['State']; if ($scope.ry_mm_csr == 80) indicatorSliderRanges = indicatorSliderRanges['County']; if ($scope.ry_mm_csr == 50) indicatorSliderRanges = indicatorSliderRanges['Zipcode']; } if (typeof sliderRanges[indicatorKey].control_value == 'string') { $scope.filters.indicators[indicatorKey].control_value = sliderRanges[indicatorKey].control_value; } else { var new_c_min = indicatorSliderRanges.c_min; if (indicatorSliderRanges.c_min == 'range_min') new_c_min = $scope.filters.indicators[indicatorKey].min; var new_c_max = indicatorSliderRanges.c_max; if (indicatorSliderRanges.c_max == 'range_max') new_c_max = $scope.filters.indicators[indicatorKey].max; $scope.filters.indicators[indicatorKey].c_min = new_c_min; $scope.filters.indicators[indicatorKey].c_max = new_c_max; $scope.filters.indicators[indicatorKey].slider_1 = $scope.filters.indicators[indicatorKey].c_min; $scope.filters.indicators[indicatorKey].slider_2 = $scope.filters.indicators[indicatorKey].c_max; } if (!$scope.filters.indicators[indicatorKey].active) { if (indicatorKey.indexOf('parent__') == 0) { $scope.filterStep = "1"; $scope.addFilterIndicatorControl(indicatorKey.replace('parent__', '')); } else { $scope.filterStep = "2";'' $scope.addFilterIndicatorControl(indicatorKey); } } } else { $scope.removeFilterIndicatorControl(indicatorKey); } } }, 300); } $scope.deactivateAllMagicButtons = function() { for (magicButtonKey in $scope.filters.magicButtons) { $scope.filters.magicButtons[magicButtonKey].active = false; } $scope.nameForToolSelectedMagic = false; } $scope.deactivateAllClassicToolButtons = function() { for (ClassicToolButtonKey in $scope.filters.ClassicToolButtons) { $scope.filters.ClassicToolButtons[ClassicToolButtonKey].active = false; } $scope.nameForToolSelectedClassic = false; } $scope.applyMacigbuttonFilterSettings = function(buttonKey) { // console.log("BUTTON:" + buttonKey); $scope.locations = []; $scope.removeAllFilterIndicators(); if (typeof $scope.filters.magicButtons[buttonKey] != 'object') return false; const buttonSliderSettings = $scope.filters.magicButtons[buttonKey].sliderSettings; if ($scope.filters.magicButtons[buttonKey].mkt_lvl == 'Metro') $scope.ry_mm_csr = 1; if ($scope.filters.magicButtons[buttonKey].mkt_lvl == 'State') $scope.ry_mm_csr = 2; if ($scope.filters.magicButtons[buttonKey].mkt_lvl == 'County') $scope.ry_mm_csr = 80; if ($scope.filters.magicButtons[buttonKey].mkt_lvl == 'Zipcode') $scope.ry_mm_csr = 50; $scope.loadSavedFilterRanges(buttonSliderSettings); $scope.nameForFilterToSave = $scope.filters.magicButtons[buttonKey].label + " - Variation: " + Math.floor(Math.random()*1000); $scope.nameForFilterSelected = "Strategic Market Scanner: " + $scope.filters.magicButtons[buttonKey].label; $scope.styleForToolSelected = $scope.filters.magicButtons[buttonKey].style; $scope.deactivateAllMagicButtons(); $scope.deactivateAllClassicToolButtons(); $scope.filters.magicButtons[buttonKey].active = true; $scope.nameForToolSelected = $scope.filters.magicButtons[buttonKey].label; $scope.nameForToolSelectedActive = true; $scope.nameForToolSelectedMagic = true; $scope.nameForToolSelectedClassic = false; $scope.nameForToolSelectedSaved = false; setTimeout(function() { // to apply new ranges AFTER ranges are reset on CSR change $scope.applySort($scope.filters.magicButtons[buttonKey].sortby); },300); $scope.magicButtonAppliedAt = Date.now(); } $scope.applyClassicToolButtonFilterSettings = function(buttonKey) { // console.log("BUTTON:" + buttonKey); $scope.locations = []; $scope.removeAllFilterIndicators(); if (typeof $scope.filters.ClassicToolButtons[buttonKey] != 'object') return false; const buttonSliderSettings = $scope.filters.ClassicToolButtons[buttonKey].sliderSettings; if ($scope.filters.ClassicToolButtons[buttonKey].mkt_lvl == 'Metro') $scope.ry_mm_csr = 1; if ($scope.filters.ClassicToolButtons[buttonKey].mkt_lvl == 'State') $scope.ry_mm_csr = 2; if ($scope.filters.ClassicToolButtons[buttonKey].mkt_lvl == 'County') $scope.ry_mm_csr = 80; if ($scope.filters.ClassicToolButtons[buttonKey].mkt_lvl == 'Zipcode') $scope.ry_mm_csr = 50; $scope.loadSavedFilterRanges(buttonSliderSettings); $scope.nameForFilterToSave = $scope.filters.ClassicToolButtons[buttonKey].label + " - Variation: " + Math.floor(Math.random()*1000); $scope.nameForFilterSelected = "Classic Tool Buttons: " + $scope.filters.ClassicToolButtons[buttonKey].label; $scope.styleForToolSelected = $scope.filters.ClassicToolButtons[buttonKey].style; $scope.iconlinkForToolSelected = $scope.filters.ClassicToolButtons[buttonKey].iconlink; $scope.nameForToolSelected = $scope.filters.ClassicToolButtons[buttonKey].label; $scope.nameForToolSelectedActive = true; $scope.nameForToolSelectedMagic = false; $scope.nameForToolSelectedClassic = true; $scope.nameForToolSelectedSaved = false; $scope.deactivateAllMagicButtons(); $scope.deactivateAllClassicToolButtons(); $scope.filters.ClassicToolButtons[buttonKey].active = true; setTimeout(function() { // to apply new ranges AFTER ranges are reset on CSR change $scope.applySort($scope.filters.ClassicToolButtons[buttonKey].sortby); },300); $scope.ClassicToolButtonAppliedAt = Date.now(); } $scope.isFilterIndicatorBasic = function(indicatorKey) { return ha_indicators.isFilterIndicatorBasic(indicatorKey); } $scope.getIndicatorVariation = function(basicIndicatorKey, variation) { return ha_indicators.getIndicatorVariation(basicIndicatorKey, variation); } $scope.indicatorHasVariationsOfType = function(basicIndicatorKey, variationType) { return ha_indicators.indicatorHasVariationsOfType(basicIndicatorKey, variationType); } $scope.indicatorHasAnyVariationsAvailable = function(basicIndicatorKey, withUpgrade) { return ha_indicators.indicatorHasAnyVariationsAvailable(basicIndicatorKey, withUpgrade); } $scope.isIndicatorVariationAvailable = function(basicIndicatorKey, variationType) { return ha_indicators.isIndicatorVariationAvailable(basicIndicatorKey, variationType); } //------------------------------------------------------------------------------------------ $scope.count = 123; $scope.magic_lvl = 'Metro'; // Magic buttons for the filters - market type $scope.nameForFilterToSave = 'TestFilter' + Math.floor(Math.random()*1000); $scope.testSliderVal = 55; $scope.testTextVal = 77; $scope.setIndicatorRange = function(var_key, from, to) { $scope.filters.indicators[var_key].c_min = from; $scope.filters.indicators[var_key].c_max = to; } $scope.getVisibleColumnCount = function() { var count = 0; for (var_key in $scope.filters.indicators) { if ($scope.filters.indicators[var_key].active && $scope.filters.indicators[var_key].showInTable) count++; } return count; } $scope.showLoadingIndicator = function() { jQuery('[data-js="loading-box"]').fadeIn(300); } $scope.hideLoadingIndicator = function() { jQuery('[data-js="loading-box"]').fadeOut(300); } $scope.adjustStyles = function() { jQuery('#matrixContainer').attr('data-js-option', $scope.getVisibleColumnCount() ); if (parseInt(jQuery('#matrixContainer').attr('data-js-option')) > 10) { jQuery('.message-table-mobile').show(); } else { jQuery('.message-table-mobile').hide(); } } $scope.addFilterIndicatorControlButtonClick = function(var_key) { if (!$scope.filters.indicators[var_key].active) { $scope.addFilterIndicatorControl(var_key); } else { $scope.removeFilterIndicatorControl(var_key); $scope.filters.indicators[var_key].showInTable = false; } } $scope.addFilterIndicatorControl = function(var_key){ if ($scope.filters.indicators[var_key].upgrade_required) { upgrade_popup_call(); return 0; } if ($scope.filterStep == "1") var_key = 'parent__' + var_key; if ($scope.filterStep == "1") { if (var_key.indexOf('parent__') != 0) var_key = 'parent__' + var_key; $scope.filters.indicators[var_key].showInTable = true;//false; jQuery("#filtersControlsContainer .Filter-Parent-Option-List").append( $compile(htmlStr)($scope) ); } if ($scope.filterStep == "2") { var_key = var_key; $scope.filters.indicators[var_key].showInTable = true; jQuery("#filtersControlsContainer .Filter-Option-List").append( $compile(htmlStr)($scope) ); } if (!$scope.filters.indicators[var_key].active) { $scope.sortType = var_key; var htmlStr = getFilterControlStrForOneIndicator({ indicatorStr: var_key, indicatorLabel: $scope.filters.indicators[var_key].label, indicatorNumberFormat: $scope.filters.indicators[var_key].format, indicatorParams: $scope.filters.indicators[var_key] }); if ($scope.filterStep == "1") { jQuery("#filtersControlsContainer .Filter-Parent-Option-List").append( $compile(htmlStr)($scope) ); } else { jQuery("#filtersControlsContainer .Filter-Option-List").append( $compile(htmlStr)($scope) ); } $scope.adjustStyles(); var htmlStr2 = getFilterControlStrForOneIndicatorCompact({indicatorStr: var_key, indicatorLabel: $scope.filters.indicators[var_key].label}); jQuery("#filtersControlsContainer .Filter-Selection-List").append( $compile(htmlStr2)($scope) ); // $scope.$apply(); if ($scope.filters.indicators[var_key].format != 'Radio') { jQuery("#slider_" + var_key + "_min").attr("min", $scope.filters.indicators[var_key].min); jQuery("#slider_" + var_key + "_min").attr("max", $scope.filters.indicators[var_key].max); jQuery("#slider_" + var_key + "_max").attr("min", $scope.filters.indicators[var_key].min); jQuery("#slider_" + var_key + "_max").attr("max", $scope.filters.indicators[var_key].max); // jQuery("#slider_" + var_key + "_min").attr("step", $scope.filters.indicators[var_key].step); // jQuery("#number_" + var_key + "_min").attr("step", $scope.filters.indicators[var_key].step); // jQuery("#slider_" + var_key + "_max").attr("step", $scope.filters.indicators[var_key].step); // jQuery("#number_" + var_key + "_max").attr("step", $scope.filters.indicators[var_key].step); var watch_vars_str = '[filters.indicators.' + var_key + '.c_min ,filters.indicators.' + var_key + '.c_max, filters.indicators.' + var_key + '.step, filters.indicators.' + var_key + '.active]'; } else { var watch_vars_str = '[filters.indicators.' + var_key + '.control_value, filters.indicators.' + var_key + '.active]'; } // console.log(watch_vars_str); $scope.$watch(watch_vars_str, function() { if (Date.now() - $scope.magicButtonAppliedAt > 1500) $scope.deactivateAllMagicButtons(); if (Date.now() - $scope.ClassicToolButtonAppliedAt > 1500) $scope.deactivateAllClassicToolButtons(); $scope.pageFirst(false); }); if ($scope.filters.indicators[var_key].format != 'Radio') { setTimeout(function() { $scope.init2PosSlider(var_key); },100); } else { setTimeout(function() { jQuery('#filter_block_radio_input__' + var_key + '_' + $scope.filters.indicators[var_key].control_value).click(); },100); } // --------------------- $scope.filters.indicators[var_key].active = true; if ($scope.filterStep == "2") { $scope.filters.indicators[var_key].showInTable = true; } } else { // $scope.removeFilterIndicatorControl(var_key); // $scope.filters.indicators[var_key].showInTable = false; return 0; } $scope.updateShowInTable(); } //------------------------------------------------------------------------------------------ $scope.expandAllFilterRanges = function() { for (var_key in $scope.filters.indicators) { $scope.expandRange(var_key); } $scope.nameForToolSelectedMagic = false; } //------------------------------------------------------------------------------------------ $scope.expandRange = function(var_key) { $scope.filters.indicators[var_key].c_min = $scope.filters.indicators[var_key].min; $scope.filters.indicators[var_key].c_max = $scope.filters.indicators[var_key].max; $scope.filters.indicators[var_key].slider_1 = $scope.filters.indicators[var_key].min; $scope.filters.indicators[var_key].slider_2 = $scope.filters.indicators[var_key].max; jQuery("#slider_" + var_key + "_min").val($scope.filters.indicators[var_key].min); jQuery("#slider_" + var_key + "_max").val($scope.filters.indicators[var_key].max); } //------------------------------------------------------------------------------------------ $scope.areFilterRangesAtMax = function() { for (var_key in $scope.filters.indicators) { if ($scope.filters.indicators[var_key].active) { if ($scope.filters.indicators[var_key].c_min > $scope.filters.indicators[var_key].min) return false; if ($scope.filters.indicators[var_key].c_max < $scope.filters.indicators[var_key].max) return false; } } return true; } $scope.areFilterRangesAtMin = function() { for (var_key in $scope.filters.indicators) { if ($scope.filters.indicators[var_key].active) { if ($scope.filters.indicators[var_key].c_min > $scope.filters.indicators[var_key].min) return false; if ($scope.filters.indicators[var_key].c_max < $scope.filters.indicators[var_key].max) return false; } } return true; } //------------------------------------------------------------------------------------------ $scope.tweakFilterRanges = function(amount) { for (var_key in $scope.filters.indicators) { if ($scope.filters.indicators[var_key].active) { $scope.tweakFilterRange(var_key, amount); } } $scope.filterRangesAtMax = $scope.areFilterRangesAtMax(); } $scope.tweakFilterRangesDown = function(amount) { for (var_key in $scope.filters.indicators) { if ($scope.filters.indicators[var_key].active) { $scope.tweakFilterRange(var_key, -amount); } } $scope.filterRangesAtMin = $scope.areFilterRangesAtMin(); } //------------------------------------------------------------------------------------------ $scope.tweakFilterRange = function(var_key, amount) { var range_width = $scope.filters.indicators[var_key].c_max - $scope.filters.indicators[var_key].c_min; var delta = Math.round(amount * 0.01 * range_width); $scope.filters.indicators[var_key].c_min = $scope.filters.indicators[var_key].c_min - delta; $scope.filters.indicators[var_key].c_max = $scope.filters.indicators[var_key].c_max + delta; if ($scope.filters.indicators[var_key].c_min < $scope.filters.indicators[var_key].min) $scope.filters.indicators[var_key].c_min = $scope.filters.indicators[var_key].min; if ($scope.filters.indicators[var_key].c_max > $scope.filters.indicators[var_key].max) $scope.filters.indicators[var_key].c_max = $scope.filters.indicators[var_key].max; $scope.filters.indicators[var_key].slider_1 = $scope.filters.indicators[var_key].c_min; $scope.filters.indicators[var_key].slider_2 = $scope.filters.indicators[var_key].c_max; jQuery("#slider_" + var_key + "_min").val($scope.filters.indicators[var_key].c_min); jQuery("#slider_" + var_key + "_max").val($scope.filters.indicators[var_key].c_max); } //------------------------------------------------------------------------------------------ $scope.removeAllFilterIndicators = function() { for (var_key in $scope.filters.indicators) { if ($scope.filters.indicators[var_key].active) { $scope.removeFilterIndicatorControl(var_key); } } $scope.nameForToolSelectedActive = false; } $scope.disableStep1FilterIndicators = function() { for (var_key in $scope.filters.indicators) { if ($scope.filters.indicators[var_key].active) { if ($scope.filters.indicators[var_key].is_parent_indicator) { $scope.removeFilterIndicatorControl(var_key); } } } } //------------------------------------------------------------------------------------------ $scope.tweakVariations = function(specialMode) { for (index in $scope.filterIndicatorVariations) { if ($scope.filterIndicatorVariations[index].code == 'yy') { if (specialMode == 'default') { $scope.filterIndicatorVariations[index].type = 'raw'; } if (specialMode == 'hms') { $scope.filterIndicatorVariations[index].type = 'pct'; } } if ($scope.filterIndicatorVariations[index].code == 'yyt') { if ($scope.ry_mm_csr > 10) { $scope.filterIndicatorVariations[index].type = 'pct'; } else { $scope.filterIndicatorVariations[index].type = 'raw'; } } } } //------------------------------------------------------------------------------------------ $scope.init2PosSlider = function(var_key) { // console.log('i2ps:' + var_key); const fromSlider = document.querySelector("#slider_" + var_key + "_min"); const toSlider = document.querySelector("#slider_" + var_key + "_max"); const fromInput = document.querySelector("#number_" + var_key + "_min"); const toInput = document.querySelector("#number_" + var_key + "_max"); const fromInputInCol = document.querySelector("#column_" + var_key + "_min"); const toInputInCol = document.querySelector("#column_" + var_key + "_max"); if (!(fromSlider && fromSlider !== 'null' && fromSlider !== 'undefined')) { // console.log("Slider Not Found on Page. [" + var_key + "]"); return 0; // Slider does not exist. easy_buttons mode? } fromSlider.value = $scope.filters.indicators[var_key].c_min; fromSlider.min = $scope.filters.indicators[var_key].min; fromSlider.max = $scope.filters.indicators[var_key].max; toSlider.value = $scope.filters.indicators[var_key].c_max; toSlider.min = $scope.filters.indicators[var_key].min; toSlider.max = $scope.filters.indicators[var_key].max; setUpTwoPosSlider(fromSlider, toSlider, fromInput, toInput, fromInputInCol, toInputInCol); } //------------------------------------------------------------------------------------------ $scope.getFirstActiveIndicatorVar = function() { for (var_key in $scope.filters.indicators) { if ($scope.filters.indicators[var_key].active) return var_key; } return null; } //------------------------------------------------------------------------------------------ $scope.removeFilterIndicatorControl = function(var_key) { // console.log('removing [' + var_key + ']...'); jQuery("#filter_indicator_ontrol_block_" + var_key).remove(); $scope.filters.indicators[var_key].active = false; $scope.sortType = $scope.getFirstActiveIndicatorVar(); //'score_master_normalized'; $scope.updateShowInTable(); $scope.adjustStyles(); } //------------------------------------------------------------------------------------------ $scope.set_filter_slider_ranges = function(justGotRangesData) { if ($scope.filterVarsStatsLoading) return 0; if (typeof $scope.filterVarsStats != 'object') { $scope.filterVarsStatsLoading = true; $http.get('https://www.housingalerts.com/ext/configs/filter_vars_stats.json').then(function(data) { $scope.filterVarsStats = data.data; $scope.filterVarsStatsLoading = false; $scope.set_filter_slider_ranges(true); }); return 0; } for (var_key in $scope.filters.indicators) { if (typeof $scope.filters.indicators[var_key].is_category_label != 'undefined') continue; // console.log(var_key); // Manual Tweak: var multiplier = 1; if (var_key == 'mls_score_normalised_mm') multiplier = 100; if (var_key == 'mls_score_normalised_yy') multiplier = 100; if (typeof $scope.filterVarsStats[var_key] != 'undefined' && typeof $scope.filterVarsStats[var_key][$scope.csr] != 'undefined') { // Some Indicators are not available for MM if (typeof $scope.filterVarsStats[var_key][$scope.csr]['min'] !== 'undefined') $scope.filters.indicators[var_key].min = parseFloat($scope.filterVarsStats[var_key][$scope.csr]['min'] * multiplier); if (typeof $scope.filterVarsStats[var_key][$scope.csr]['max'] !== 'undefined') $scope.filters.indicators[var_key].max = parseFloat($scope.filterVarsStats[var_key][$scope.csr]['max'] * multiplier); } if (justGotRangesData) { // Set Parent ranges for 2-step filter to State ranges: if ($scope.filters.indicators[var_key].is_parent_indicator) { var_key_wo_parent = var_key.replace('parent__', ''); if (typeof $scope.filterVarsStats[var_key_wo_parent] != 'undefined' && typeof $scope.filterVarsStats[var_key_wo_parent][2] != 'undefined') { if (typeof $scope.filterVarsStats[var_key_wo_parent][2]['min'] !== 'undefined') $scope.filters.indicators[var_key].min = parseFloat($scope.filterVarsStats[var_key_wo_parent][2]['min'] * multiplier); if (typeof $scope.filterVarsStats[var_key_wo_parent][2]['max'] !== 'undefined') $scope.filters.indicators[var_key].max = parseFloat($scope.filterVarsStats[var_key_wo_parent][2]['max'] * multiplier); } } // Reset selection to the whole ranges $scope.filters.indicators[var_key].c_min = $scope.filters.indicators[var_key].min; $scope.filters.indicators[var_key].c_max = $scope.filters.indicators[var_key].max; } else { if ($scope.filterMode != 'twostep') { // Only change selected ranges if they lay outside the new absolute min/max if ($scope.filters.indicators[var_key].c_min < $scope.filters.indicators[var_key].min || $scope.filters.indicators[var_key].c_min > $scope.filters.indicators[var_key].max) { $scope.filters.indicators[var_key].c_min = $scope.filters.indicators[var_key].min; } if ($scope.filters.indicators[var_key].c_max > $scope.filters.indicators[var_key].max || $scope.filters.indicators[var_key].c_max < $scope.filters.indicators[var_key].min) { $scope.filters.indicators[var_key].c_max = $scope.filters.indicators[var_key].max; } } } if ($scope.filters.indicators[var_key].active) { jQuery("#slider_" + var_key + "_min").attr("min", $scope.filters.indicators[var_key].min); jQuery("#slider_" + var_key + "_min").attr("max", $scope.filters.indicators[var_key].max); jQuery("#slider_" + var_key + "_max").attr("min", $scope.filters.indicators[var_key].min); jQuery("#slider_" + var_key + "_max").attr("max", $scope.filters.indicators[var_key].max); if ($scope.filters.indicators[var_key].format != 'Radio') { $scope.init2PosSlider(var_key); } // $scope.removeFilterIndicatorControl(var_key); // $scope.addFilterIndicatorControl(var_key); } } } //------------------------------------------------------------------------------------------ $scope.addMBIndicator = function(mb_indicator_code) { $scope.removeAllFilterIndicators(); $scope.currentSelectIndicator = mb_indicator_code; if (!$scope.filters.indicators[mb_indicator_code].active) { $scope.addFilterIndicatorControl(mb_indicator_code + "_percentile"); $scope.addFilterIndicatorControl(mb_indicator_code); } } //------------------------------------------------------------------------------------------ $scope.addAllSliders = function() { for (var_key in $scope.filters.indicators) { if (!$scope.filters.indicators[var_key].active) { $scope.addFilterIndicatorControl(var_key); } } } //------------------------------------------------------------------------------------------ $scope.init_sliders = function() { $scope.enable_default_filter(); $scope.set_filter_slider_ranges(false); } //------------------------------------------------------------------------------------------ $scope.enable_default_filter = function() { // $scope.addFilterIndicatorControl('population'); // $scope.addFilterIndicatorControl('hms'); // $scope.removeAllFilterIndicators(); $scope.set_filter_slider_ranges(false); if (typeof(showSubmarkets) != 'undefined') return 0; if (typeof(special_mode) != 'undefined' && special_mode == 'easy_buttons') { $scope.apply_easy_button(); return 0; } $scope.addFilterIndicatorControl('population'); $scope.addFilterIndicatorControl('mls_score2_normalised'); } //------------------------------------------------------------------------------------------ $scope.$watch('$viewContentLoaded', function(){ if (ry_tool_mode == 'filter') { $scope.init_sliders(); $scope.loadSavedFilters(); } }); //------------------------------------------------------------------------------------------ $scope.update_scr_buttons_status = function() { if ($scope.filterMode == 'onestep') { //Enable all four buttons jQuery('input[name=ry_mm_csr][value=1]').removeAttr("disabled"); jQuery('.market-msa').removeClass("disabled"); jQuery('input[name=ry_mm_csr][value=2]').removeAttr("disabled"); jQuery('.market-state').removeClass("disabled"); jQuery('input[name=ry_mm_csr][value=50]').removeAttr("disabled"); jQuery('.market-zipcode').removeClass("disabled"); jQuery('input[name=ry_mm_csr][value=80]').removeAttr("disabled"); jQuery('.market-county').removeClass("disabled"); } else { // Enable/disable CSR buttons depending on the active step if ($scope.filterStep == "1") { $scope.ry_mm_csr = $scope.step1CSR; jQuery('input[name=ry_mm_csr][value=1]').removeAttr("disabled"); jQuery('.market-msa').removeClass("disabled"); jQuery('input[name=ry_mm_csr][value=2]').removeAttr("disabled"); jQuery('.market-state').removeClass("disabled"); jQuery('input[name=ry_mm_csr][value=50]').attr("disabled", "disabled"); jQuery('.market-zipcode').addClass("disabled"); jQuery('input[name=ry_mm_csr][value=80]').attr("disabled", "disabled"); jQuery('.market-county').addClass("disabled"); } else { $scope.ry_mm_csr = $scope.step2CSR; jQuery('input[name=ry_mm_csr][value=1]').attr("disabled", "disabled"); jQuery('.market-msa').addClass("disabled"); jQuery('input[name=ry_mm_csr][value=2]').attr("disabled", "disabled"); jQuery('.market-state').addClass("disabled"); jQuery('input[name=ry_mm_csr][value=50]').removeAttr("disabled"); jQuery('.market-zipcode').removeClass("disabled"); jQuery('input[name=ry_mm_csr][value=80]').removeAttr("disabled"); jQuery('.market-county').removeClass("disabled"); } } } //------------------------------------------------------------------------------------------ $scope.apply_easy_button = function() { $scope.removeAllFilterIndicators(); $scope.addFilterIndicatorControl('population'); switch ($scope.easy_button_code) { case 'wholesale' : // if (window.location.hostname != 'www.housingalerts.com') { $scope.addFilterIndicatorControl('zillow_house_value'); // $scope.sortReverse = false; // } $scope.addFilterIndicatorControl('mb_score_wholesale'); return 0; case 'creative' : $scope.addFilterIndicatorControl('zillow_house_value'); $scope.addFilterIndicatorControl('mb_score_creative'); return 0; case 'cash_flow' : $scope.addFilterIndicatorControl('zillow_house_value'); $scope.addFilterIndicatorControl('mb_score_cashflow'); return 0; case 'wealth' : $scope.addFilterIndicatorControl('zillow_house_value'); $scope.addFilterIndicatorControl('mb_score_wealth'); return 0; default: alert("Oops. Unknown Easy Button! [" + $scope.easy_button_code + "]"); } } //------------------------------------------------------------------------------------------ $scope.$watch('filterStep', function(){ $scope.update_scr_buttons_status(); }); //--------------------------------------------------------------------------------------------- if (typeof(special_mode) != 'undefined' && special_mode == 'easy_buttons') { $scope.$watch('easy_button_code', function(){ $scope.apply_easy_button(); }); } //--------------------------------------------------------------------------------------------- $scope.$watch('filterMode', function(newValue, oldValue) { if ($scope.filterMode == 'onestep') { $scope.filterStep = "2"; } if (newValue == 'twostep' && oldValue == 'onestep') { $scope.filterStep = "1"; } $scope.update_scr_buttons_status(); }); //--------------------------------------------------------------------------------------------- if (typeof max_mls_year != 'undefined') { $scope.mls_year = max_mls_year; $scope.mls_month = max_mls_month; $scope.mls_year_options = []; for (var year = min_mls_year; year <= max_mls_year; year++) { $scope.mls_year_options.push(year); } } $scope.mls_history_active = false; $scope.toSave = ['ry_mm_csr','state_id', 'msa_id', 'county_id', 'searchString', 'searchActive', 'sortReverse', 'sortType']; if (typeof getUrlVars != 'undefined') { $scope.showExtras = (typeof (getUrlVars().show_extras) != 'undefined') ? getUrlVars().show_extras : 0; } $scope.show_super_score = false; if ($scope.csr == 80) { $scope.show_super_score = true; $scope.sortType = 'score_master_normalized'; $scope.sortReverse = true; } if (ry_mode) { $scope.ry_tool_mode = ry_tool_mode; $scope.ry_mm_pop_filter = '0'; $scope.include_state_based_mm = false; $scope.use_optional_mm_table = false; $scope.sortReverse = true; if ($scope.ry_tool_mode == "cash-flow-finder") { $scope.sortType = 'combo_sms_rtp2_pct'; } else if ($scope.ry_tool_mode == "market-ranking") { $scope.sortType = 'super_master_score_pct'; } else if ($scope.ry_tool_mode == "market-trends") { $scope.sortType = 'combo_sms_rtp2_pct'; } else if ($scope.ry_tool_mode == "house-value-finder") { $scope.sortType = 'super_master_score_pct'; } else if ($scope.ry_tool_mode == "market-ranking") { $scope.sortType = 'super_master_score_pct'; } else if ($scope.ry_tool_mode == "rent-growth") { // $scope.sortType = 'super_master_score'; $scope.sortType = 'rent_cagr3y'; } else if ($scope.ry_tool_mode == "mls-test") { $scope.sortType = 'score_master_normalized'; } else if ($scope.ry_tool_mode == "filter") { $scope.sortType = 'super_master_score'; } else if ($scope.ry_tool_mode == "mls-per-capita") { $scope.sortType = 'mls_score_normalised'; //'score_master_normalized_percentile'; } else if ($scope.ry_tool_mode == "mls-tracker" || $scope.ry_tool_mode == "mls-tracker-lite") { // $scope.sortType = 'super_master_score'; $scope.sortType = 'mls_raw_dom'; $scope.sortReverse = false; } else { $scope.sortType = 'combo_sms_hpv2'; } } $scope.updatePagesRange = function() { $scope.pages_range = []; for (var i = 1; i <= $scope.pages_count; i++) { $scope.pages_range.push(i.toString()); } } $scope.showPopupMap = function(location) { open_mini_map_popup(); var location_id = location.id_census; var forcedModes = { 70 : 'trc', 80 : 'cnt', 50 : 'zp5' }; //console.log("LID:" + location_id); $scope.waitPopupMap = true; if (singleMarker != null) singleMarker.remove(); $scope.popupMapOpen = true; popupMap.setView([39.8283, -98.5795], 4); //Zoom out to USA $http.get('https://www.housingalerts.com/maps/get_csr.php?mode=pin&csr=' + $scope.csr + '&id=' + location_id).then(function(data) { if (!data.data.found) { close_mini_map_popup(); alert("Not found [" + location_id + "]"); return 0; } marketPointParams = data.data; singleMarker = L.marker([marketPointParams.y, marketPointParams.x]).addTo(popupMap); var countyString = ""; var mapPopupMarketTypeStr = ""; if ($scope.csr == 70) mapPopupMarketTypeStr = "Tract "; if ($scope.csr == 50) mapPopupMarketTypeStr = "ZIP "; if ($scope.csr != 80) countyString = " (" + location.county_name + ")"; if ($scope.csr <= 3) { // No MM Map link! singleMarker.bindPopup("" + location.name + "").openPopup(); } else { var map_tool_url = "https://www.housingalerts.com/members/micro-maps/"; if (typeof(ha_offsite_mode) !== 'undefined' && ha_offsite_mode) { var map_tool_url = ha_map_url; } // singleMarker.bindPopup("" + location.name + "" + countyString + "