PageSourceSearch

https://dadis-transboundary-breed-ws.web.app/assets/js/main.js

js dadis-transboundary-breed-ws.web.app collected 2026-10-03 12:20:41 UTC 19,378 bytes, 463 lines download raw bytes

1$(document).ready(function () {
2    /*     $('#faoHeader').show();
3    
4        var headingHTML = `
5            <div id="transboundaryListTitle" class="bg-white border-bottom shadow-sm mb-4 py-3">
6            <h1 class="text-center m-0 text-primary fw-normal fs-4">
7                Transboundary Breed Summary
8            </h1>
9            </div>
10        `;
11        $('#faoHeader').after(headingHTML); */
12
13    // Inizializza i Tooltip nativi di Bootstrap 5
14    var tooltipTriggerList = [].slice.call(document.querySelectorAll('[title]'))
15    var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
16        return new bootstrap.Tooltip(tooltipTriggerEl)
17    });
18
19    startup();
20});
21
22var i18nData = {};
23var speciesMap = new Map();
24
25//** WS **
26//** WS **
27const ENVIRONMENT_DADIS = "https://dadis-ws.firebaseio.com";
28const ENVIRONMENT_TABLEAU = "https://dadis-ws-tableau.firebaseio.com";
29//const BREED_DATA_SHEET_URL = "https://dadis-tools-ws.web.app/breed-data-sheet";
30//const SINGLE_TRANSBOUNDARY_CALLBACK = 'https://dadis-tools-ws.web.app/transboundary-breed-details';
31const BREED_DATA_SHEET_URL = 'https://dadis-breed-datasheet-ws.firebaseapp.com/';
32//const BREED_DATA_SHEET_URL = "https://dadis-tools-ws.web.app/breed-data-sheet";
33const SINGLE_TRANSBOUNDARY_CALLBACK = "https://dadis-transboundary-breed-ws.web.app";
34//const SINGLE_TRANSBOUNDARY_CALLBACK = 'https://dadis-tools-ws.web.app/transboundary-breed-details';
35/////////////////////////*/
36
37/*//** TARINING **
38  const ENVIRONMENT_DADIS = "https://dadis-training.firebaseio.com";
39  const ENVIRONMENT_TABLEAU = "https://dadis-training-tableau.firebaseio.com"; 
40  const BREED_DATA_SHEET_URL = "https://dadis-tools-qa.web.app/breed-data-sheet";
41  const SINGLE_TRANSBOUNDARY_CALLBACK = 'https://dadis-tools-qa.web.app/transboundary-breed-details';
42/////////////////////////*/
43
44//** DEV **
45/* const ENVIRONMENT_DADIS = "https://fao-dadis-dev.firebaseio.com";
46 const ENVIRONMENT_TABLEAU = "https://dadis-training-tableau.firebaseio.com"; 
47 const BREED_DATA_SHEET_URL = "https://dadis-tools-dev.web.app/breed-data-sheet"; 
48 const SINGLE_TRANSBOUNDARY_CALLBACK = "https://dadis-transboundary-breed-dev.web.app";
49/////////////////////////*/
50
51
52var LANG = 'en';
53var TARGET_LANG = 'en';
54var isExternal = false;
55var specieVal = "";
56var transboundaryVal = "";
57var countryMap = new Map();
58
59var getCountryIsoNameMap = function () {
60    return new Promise(function (resolve, reject) {
61        var url = ENVIRONMENT_DADIS + '/Data/countries.json';
62        $.getJSON(url, function (countries) {
63            if (countries == null || typeof countries === 'undefined') reject('Country Node Not Found!!!');
64            else {
65                for (let ISO in countries) {
66                    countryMap.set(ISO, countries[ISO]['names'][LANG]);
67                }
68                resolve(countryMap);
69            }
70        });
71    });
72}
73
74var startup = function () {
75    isExternal = get("external") == "1" ? true : false;
76    specieVal = get("species") == "all" ? "" : get("species");
77    transboundaryVal = get("transboundary") == "all" ? "" : get("transboundary");
78    LANG = get("lang") ? get("lang") : 'en';
79
80    if (LANG != 'en' && LANG != 'es' && LANG != 'fr' && LANG != 'ru' && LANG != 'ch') LANG = 'en';
81
82    loadBundles(LANG);
83
84    loadI18nLocalData().then((data) => { i18nData = data; });
85
86    $.when(getCountryIsoNameMap(), getSpeciesNameMap())
87        .done(function () { getSpecies(); })
88        .fail(function (error) { console.log(error); });
89
90    if (isExternal) {
91        $('#breedSearchForm').remove();
92        $('#faoHeader').show();
93        getTransboundaryRisk();
94    }
95}
96
97function get(name) {
98    if (name = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(location.search))
99        return decodeURIComponent(name[1]);
100}
101
102function loadBundles(lang) {
103    jQuery.i18n.properties({
104        name: 'message',
105        path: 'assets/locale/messages/',
106        mode: 'both',
107        language: lang,
108        callback: function () { translateLabels(); }
109    });
110}
111
112var getSpecies = function () {
113    var url = ENVIRONMENT_DADIS + '/Data/Transboundary/species.json';
114    $.getJSON(url, function (species) {
115        if (species == null || species.lenght == 0) {
116            $('#spinner').hide();
117            $('#generalError').show();
118        } else {
119            var specieSelect = $('#specieSelect');
120            for (var specie in species) {
121                specieSelect.append('<option value="' + specie + '">' + speciesMap.get(specie)[LANG] + '</option>');
122                specieSelect.select2({
123                    theme: 'bootstrap-5',
124                    width: '100%',
125                });
126            }
127
128            if (!isExternal) {
129                $('#spinner').hide();
130                $('#profileCard').hide();
131                $('#transboundaryTableFields').hide();
132                $('#breedSearchForm').show();
133                $('#searchBreedMessage').show();
134            }
135        }
136    });
137}
138
139var speciesListOrdered = []
140var getSpeciesNameMap = function () {
141    speciesListOrdered = []
142    return new Promise(function (resolve, reject) {
143        var url = ENVIRONMENT_DADIS + '/Data/species.json?callback=?';
144        $.getJSON(url, function (species) {
145            if (species == null || typeof species === 'undefined') reject('Species Node Not Found!!!');
146            else {
147                for (let speciesItem in species) {
148                    speciesMap.set(speciesItem, species[speciesItem]['names']);
149                }
150                resolve(speciesMap);
151            }
152        });
153    });
154}
155
156function reorderObjectMapToArray(map, lang) {
157    var newList = [];
158    var keys = Object.keys(map);
159    for (let key in keys) newList.push(map[keys[key]]);
160    newList.sort(function (a, b) {
161        try { return a.names[lang].localeCompare(b.names[lang]); }
162        catch (error) { console.error(error); }
163    });
164    return newList;
165}
166
167var getTransboundary = function () {
168    $('#profileCard').hide();
169    $('#transboundaryTableFields').hide();
170    $('#transboundarySelect').find('option').remove().end().append('<option value="" selected>Choose a transboundary</option>');
171
172    var selectedTransboundary = $('#specieSelect').val();
173    if (!selectedTransboundary) return;
174
175    var url = ENVIRONMENT_DADIS + '/Data/Transboundary/species/' + selectedTransboundary + '.json';
176    $.getJSON(url, function (transboundary) {
177        if (transboundary == null || transboundary.lenght == 0) {
178            $('#spinner').hide();
179            $('#generalError').show();
180        } else {
181            var transboundarySelect = $('#transboundarySelect');
182            for (var transb in transboundary) {
183                transboundarySelect.append('<option value="' + transb + '">' + transb + '</option>');
184            }
185            transboundarySelect.select2({
186                theme: 'bootstrap-5',
187                width: '100%',
188            });
189            if (!isExternal) {
190                $('#spinner').hide();
191                $('#breedSearchForm').show();
192                $('#searchBreedMessage').show();
193            }
194        }
195    });
196}
197
198var doBreedSearch = function () {
199    // Logica di instradamento originale (anche se qui viene guidata dai select individualmente)
200    $('#spinner').show();
201    $('#profileCard').hide();
202    $('#missingBreeds').hide();
203    $("#renderBreedsList").empty();
204    $('#searchBreedMessage').hide();
205}
206
207var getTransboundaryRisk = function () {
208    $('#spinner').show();
209    $('#profileCard').hide();
210    $('#transboundaryTableFields').hide();
211    $('#missingBreeds').hide();
212    $('#transboundaryTable').hide();
213
214    var selectedSpecies = $('#specieSelect').val();
215    var selectedTransboundary = $('#transboundarySelect').val();
216
217    if (specieVal != 'all' && specieVal != undefined && specieVal != '') selectedSpecies = specieVal;
218    if (transboundaryVal != 'all' && transboundaryVal != undefined && transboundaryVal != '') selectedTransboundary = transboundaryVal;
219
220    if (!selectedSpecies || !selectedTransboundary) {
221        $('#spinner').hide();
222        return;
223    }
224
225    const FIREBASE_ENTRY_POINT = ENVIRONMENT_TABLEAU + "/RiskStatusAndTrendTransboundary/RiskStatus.json";
226
227    $.getJSON(FIREBASE_ENTRY_POINT, function (trendArray) {
228        var table = $('#transboundaryTable');
229        table.empty();
230
231        var count = 0;
232        var numbCountriesReportingBreeds = 0;
233        var numberCountriesReportingPopulationData = 0;
234
235        for (var i in trendArray) {
236            if (trendArray.hasOwnProperty(i)) {
237                if (selectedSpecies == trendArray[i]["SPECIES"] && selectedTransboundary == trendArray[i]["TRANSBOUNDARY"]) {
238
239                    numbCountriesReportingBreeds++;
240
241                    if (trendArray[i]["LOCALBREEDPOPULATIONMINSIZE"] != "" || trendArray[i]["LOCALBREEDPOPULATIONMAXSIZE"] != "" || trendArray[i]["LOCALBREEDINGFEMALE"] != "" || trendArray[i]["LOCALBREEDINGMALE"] != "" || trendArray[i]["LOCALBREEDPERCENTAGEOFFEMALEBREDPURE"] != "") {
242                        numberCountriesReportingPopulationData++;
243                    }
244
245                    var transboundaryRisk = calculateRisk(trendArray[i]["RISK"]);
246                    var breedRisk = calculateRisk(trendArray[i]["LOCALBREEDRISK"]);
247                    var trend = calculateRiskTrend(trendArray[i]["LOCALBREEDTREND"]);
248
249                    setField('card_transboundary_breed', trendArray[i]["TRANSBOUNDARY"]);
250                    setField('card_species', trendArray[i]["SPECIES"]);
251                    setField('card_breed_type', trendArray[i]["TYPE"]);
252                    setField('card_geo_classification', trendArray[i]["GEOCLASSIFICATION"]);
253                    setField('card_number_of_countries_reporting_the_breed', numbCountriesReportingBreeds);
254                    setField('card_number_of_countries_reporting_the_population_data', numberCountriesReportingPopulationData);
255
256                    var estimatePopulationSize = "NA";
257                    if (trendArray[i]["POPULATION"] > -1) {
258                        estimatePopulationSize = trendArray[i]["POPULATION"];
259                        if (!isNaN(estimatePopulationSize)) estimatePopulationSize = Math.round(estimatePopulationSize);
260                    }
261                    setField('card_estimated_population_size', estimatePopulationSize);
262
263                    var breed_data_sheet_url_local = BREED_DATA_SHEET_URL + "?country=" + trendArray[i]["COUNTRY"] + "&specie=" + trendArray[i]["SPECIES"] + "&breed=" + trendArray[i]["MOSTCOMMONNAME"] + "&callback=transboundarylist&lang=" + LANG;
264
265                    table.append(
266                        '<tr><td><a href="' + breed_data_sheet_url_local + '" target="_blank" class="fw-bold text-decoration-none">' + trendArray[i]["MOSTCOMMONNAME"] + '</a></td>' +
267                        '<td>' + countryMap.get(trendArray[i]["COUNTRY"]) + '</td>' +
268                        '<td>' + renameRiskStatus(trendArray[i]["LOCALBREEDRISK"]) + '</td>' +
269                        '<td>' +
270                        '<div class="risk-outer-circle ' + transboundaryRisk + '">' +
271                        '<div class="risk-inner-circle ' + breedRisk + '">' +
272                        '<i class="material-icons">' + trend + '</i>' +
273                        '</div></div>' +
274                        '</td>' +
275                        '<td>' + trendArray[i]["LOCALBREEDPOPULATIONMINSIZE"] + '</td>' +
276                        '<td>' + trendArray[i]["LOCALBREEDPOPULATIONMAXSIZE"] + '</td>' +
277                        '<td>' + trendArray[i]["LOCALBREEDINGFEMALE"] + '</td>' +
278                        '<td>' + trendArray[i]["LOCALBREEDINGMALE"] + '</td>' +
279                        '<td>' + trendArray[i]["LOCALBREEDPERCENTAGEOFFEMALEBREDPURE"] + '</td></tr>'
280                    );
281                    count++;
282                }
283            }
284        }
285
286        if (count === 0) {
287            $('#missingBreeds').show();
288        } else {
289            $('#profileCard').show();
290            $('#transboundaryTableFields').show();
291            $('#transboundaryTable').show();
292            $('#searchBreedMessage').hide();
293        }
294        $('#spinner').hide();
295    });
296}
297
298var setField = function (id, value) {
299    var str = checkValue(value) ? value : "-";
300    $('#' + id).text(str);
301}
302
303var checkValue = function (value) {
304    return (!!value && value != "" && typeof value != "undefined");
305}
306
307var renameRiskStatus = function (valRisk) {
308    if (valRisk) {
309        switch (valRisk) {
310            case "notAtRisk": return i18nData[LANG]?.['RiskStatus']?.['notAtRisk'] || "Not at Risk";
311            case "atRisk": return i18nData[LANG]?.['RiskStatus']?.['atRisk'] || "At Risk";
312            case "critical": return i18nData[LANG]?.['RiskStatus']?.['critical'] || "Critical";
313            case "endangered": return i18nData[LANG]?.['RiskStatus']?.['endangered'] || "Endangered";
314            case "vulnerable": return i18nData[LANG]?.['RiskStatus']?.['vulnerable'] || "Vulnerable";
315            case "unknown": return i18nData[LANG]?.['RiskStatus']?.['unknown'] || "Unknown";
316            case "extinct": return i18nData[LANG]?.['RiskStatus']?.['extinct'] || "Extinct";
317            default: return i18nData[LANG]?.['RiskStatus']?.['unknown'] || "Unknown";
318        }
319    }
320}
321
322var calculateRisk = function (risk) {
323    if (risk) {
324        switch (risk) {
325            case "notAtRisk": return "green";
326            case "atRisk": return "amber darken-4";
327            case "critical": return "amber darken-4";
328            case "endangered": return "amber darken-4";
329            case "vulnerable": return "amber darken-4";
330            case "unknown": return "grey";
331            case "extinct": return "black";
332            default: return "grey";
333        }
334    }
335}
336
337var calculateRiskTrend = function (trend) {
338    if (trend) {
339        switch (trend) {
340            case "increasing": return "trending_up";
341            case "decreasing": return "trending_down";
342            case "stable": return "trending_flat";
343            case "unknown": return "";
344            default: return "";
345        }
346    }
347}
348
349function getURL() {
350    var species = $('#specieSelect').val();
351    var transboundary = $('#transboundarySelect').val();
352    var param = `?species=${species}&transboundary=${encodeURIComponent(transboundary)}&external=1&lang=${LANG}`;
353    var url = SINGLE_TRANSBOUNDARY_CALLBACK + param;
354    window.open(url, "_blank");
355}
356
357function translateLabels() {
358    // SEARCH FILTERS
359    $('#specieSelect option:first').text(jQuery.i18n.prop('choose_species'));
360    $('#transboundarySelect option:first').text(jQuery.i18n.prop('choose_transboundary'));
361    $("#speciesLabel").text(`${jQuery.i18n.prop('species')}
361`);
362    $("#transboundaryLabel").text(`${jQuery.i18n.prop('transboundary')}`);
363
364    // title
365    $("#titleLabel").text(`${jQuery.i18n.prop('transboundary_breed_summary')}`);
366
367    // main dialog
368    $("#transboundaryBreed").text(`${jQuery.i18n.prop('transboundary_breed')}:`);
369    $("#species").text(`${jQuery.i18n.prop('species')}:`);
370    $("#breedType").text(`${jQuery.i18n.prop('breed_type')}:`);
371    $("#geoClassification").text(`${jQuery.i18n.prop('geo_classification')}:`);
372    $("#nmbCountriesReporting").text(`${jQuery.i18n.prop('nmb_countries_reporting')}:`);
373    $("#nmbCountriesReportingPopulation").text(`${jQuery.i18n.prop('nmb_countries_reporting_population')}:`);
374    $("#estimatedPopulationSize").text(`${jQuery.i18n.prop('estimated_population_size')}:`);
375
376    $("#mostCommonName").text(`${jQuery.i18n.prop('most_common_name')}`);
377    $("#country").text(`${jQuery.i18n.prop('country')}`);
378    $("#nationalRiskStatus").text(`${jQuery.i18n.prop('national_risk_status')}`);
379    $("#riskLevel").text(`${jQuery.i18n.prop('risk_level')}`);
380    $("#populationSizeMin").text(`${jQuery.i18n.prop('population_size_min')}`);
381    $("#populationSizeMax").text(`${jQuery.i18n.prop('population_size_max')}`);
382    $("#breedingFemale").text(`${jQuery.i18n.prop('breeding_female')}`);
383    $("#breedingMale").text(`${jQuery.i18n.prop('breeding_male')}`);
384    $("#femaleBreedPure").text(`${jQuery.i18n.prop('female_breed_pure')}`);
385
386    // messages
387    $("#selectSpeciesMessage").text(`${jQuery.i18n.prop('select_species_message')}`);
388    $("#noTransboundaryBreedsFound").text(`${jQuery.i18n.prop('no_transboundary_breeds_found')}`);
389    $("#error").text(`${jQuery.i18n.prop('error')}`);
390    $("#profileNotFound").text(`${jQuery.i18n.prop('profile_not_found')}`);
391
392    // modal
393    $("#help").text(`${jQuery.i18n.prop('help')}`);
394    $("#help1").text(`${jQuery.i18n.prop('help_1')}`);
395    $("#help2").text(`${jQuery.i18n.prop('help_2')}`);
396    $("#help3").text(`${jQuery.i18n.prop('help_3')}`);
397    $("#help4").text(`${jQuery.i18n.prop('help_4')}`);
398    $("#help5").text(`${jQuery.i18n.prop('help_5')}`);
399}
400
401var loadI18nLocalData = function () {
402    return new Promise((res, rej) => {
403        $.getJSON('./assets/i18n.json', function (data) {
404            if (data == null || typeof data === 'undefined') rej(null);
405            else res(data);
406        }).fail(() => rej(null));
407    });
408}
409
410// =========================================================================
411// EXPORT LOGIC (CSV & REAL EXCEL VIA BASE64)
412// =========================================================================
413
414function handleExport(selector, baseFilename) {
415    const format = document.querySelector('input[name="exportFormat"]:checked').value;
416    if (format === 'excel') {
417        export_to_real_xlsx_base64(selector, baseFilename + ".xlsx");
418    } else {
419        export_to_csv_base64(selector, baseFilename + ".csv");
420    }
421}
422
423function export_to_real_xlsx_base64(selector, filename) {
424    const table = document.querySelector(selector);
425    if (!table) return;
426
427    // Cloniamo la tabella per ripulirla dalle icone visive non utili nell'excel
428    let cloneTable = table.cloneNode(true);
429    let iconCells = cloneTable.querySelectorAll('td i.material-icons');
430    iconCells.forEach(icon => { icon.parentNode.innerText = icon.innerText; });
431
432    const wb = XLSX.utils.table_to_book(cloneTable, { sheet: "Transboundary Summary" });
433    const wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'base64' });
434    const uri = 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,' + wbout;
435    triggerDownload(uri, filename);
436}
437
438function export_to_csv_base64(selector, filename) {
439    let csv = [];
440    let rows = document.querySelectorAll(selector + " tr");
441    for (let i = 0; i < rows.length; i++) {
442        let row = [], cols = rows[i].querySelectorAll("td, th");
443        for (let j = 0; j < cols.length; j++) {
444            // Estrazione del testo base (ignora l'HTML interno come i risk circles)
445            let data = cols[j].innerText.replace(/(\r\n|\n|\r)/gm, " ").replace(/"/g, '""').trim();
446            row.push('"' + data + '"');
447        }
448        csv.push(row.join(","));
449    }
450    const csvContent = "\uFEFF" + csv.join("\n");
451    const encodedUri = "data:text/csv;charset=utf-8," + encodeURIComponent(csvContent);
452    triggerDownload(encodedUri, filename);
453}
454
455function triggerDownload(uri, filename) {
456    const link = document.createElement("a");
457    link.href = uri;
458    link.style.display = 'none';
459    link.setAttribute("download", filename);
460    document.body.appendChild(link);
461    link.click();
462    setTimeout(function () { document.body.removeChild(link); }, 100);
463}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.