wanjingy.github.io / hw6 / static / functions.js
functions.js
Raw
var keywordInput;
var distanceInput;
var categorySelect;
var locationInput;
var autoloc;
var eventsTable;
var searchForm;
var noRecords;
var request;
var eventDetail;
var showVenue;
var venueDetail;
var arrow;
window.onload = function(){
    keywordInput = document.getElementById("keyword");
    distanceInput = document.getElementById("distance");
    categorySelect = document.getElementById("category");
    locationInput = document.getElementById("location");
    autoloc = document.getElementById("autoloc");
    eventsTable = document.getElementById("events_table");
    searchForm = document.getElementById("search_form");
    noRecords = document.getElementById("no_records");
    eventDetail = document.getElementById("event_detail");
    showVenue = document.getElementById("show_venue");
    arrow = document.getElementById("arrow");
    venueDetail = document.getElementById("venue_detail");
    request = new XMLHttpRequest();
};
function clearSearch(){
    keywordInput.value = "";
    distanceInput.value = "";
    categorySelect.value = "default";
    locationInput.value = "";
    searchForm.insertBefore(locationInput, document.getElementById("searchbt"));
    autoloc.checked = false;
    clearTable();
    noRecords.style.display = "none";
    eventDetail.style.display = "none";
    venueDetail.style.display = "none";
    showVenue.style.display = "none";
}

function isAutoLoc(){
    if(autoloc.checked){
        locationInput.remove();
    }else{
        searchForm.insertBefore(locationInput, document.getElementById("searchbt"));
    }
}

function clearTable(){
    var events_num = eventsTable.rows.length;
    for(var i=1; i<events_num; i++){
        eventsTable.deleteRow(1);
    }
    eventsTable.style.display = "none";
}

function search(){
    clearTable();
    noRecords.style.display = "none";
    eventDetail.style.display = "none";
    venueDetail.style.display = "none";
    showVenue.style.display = "none";
    var searchJSON = {};
    searchJSON[keywordInput.name] = keywordInput.value;
    if(distanceInput.value == ""){
        searchJSON[distanceInput.name] = parseInt(distanceInput.placeholder);
    }else{
        searchJSON[distanceInput.name] = parseInt(distanceInput.value);
    }
    searchJSON[categorySelect.name] = categorySelect.value;
    // Get the latitude and longitude of the location
    if(autoloc.checked){
        request.open("GET", "https://ipinfo.io/?token=4fd050f2c74c76", false);
        request.send();
        if(request.status == 200){
            const responseJSON = JSON.parse(request.response);
            const locs = responseJSON["loc"].split(",");
            searchJSON["lat"] = parseFloat(locs[0]);
            searchJSON["lng"] = parseFloat(locs[1]);
        }
        else{
            console.log("API Ipinfo Error "+request.status+ " " +request.statusText);
        }
    }else{
        const locationString = encodeURIComponent(locationInput.value)
        request.open("GET", " https://maps.googleapis.com/maps/api/geocode/json?address="+ locationString +"&key=AIzaSyCBh6oeZbwNvjndCsfOmHzJnxarRocGXTY", false);
        request.send();
        if(request.status == 200){
            const responseJSON = JSON.parse(request.response);
            console.log(responseJSON);
            const locationResults = responseJSON.results;
            if(locationResults.length >= 1){
                searchJSON["lat"] = locationResults[0].geometry.location["lat"];
                searchJSON["lng"] = locationResults[0].geometry.location["lng"];
            }
            else{
                noRecords.style.display = "block";
                eventsTable.style.display = "none";
                return false;
            }
        }
        else{
            console.log("API Geocoding Error "+request.status+ " " +request.statusText);
        }
    }
    console.log(searchJSON);
    request.open("GET", getUrl("/search", searchJSON))
    request.send();
    request.onload= function(){
        if(request.status == 200){
            showEventResults(JSON.parse(request.response));
        }
        else{
            console.log("Call Flask Search Error "+request.status+ " " +request.statusText);
        }
    }
    return false;
}
function getUrl(base, params) {
    var url = base + '?';
    var first = true;
    for (var key in params) {
      if (params.hasOwnProperty(key)) {
        if(first){
            url += (key + "=" + encodeURIComponent(params[key]));
        }else{
            url += ("&" + key + "=" + encodeURIComponent(params[key]));
        }
      }
      first = false;
    }
    return url;
  }
function showEventResults(event_results){
    console.log(event_results);
    if(typeof(event_results._embedded) == 'undefined'){
        noRecords.style.display = "block";
        eventsTable.style.display = "none";
    }else{
        const events = event_results._embedded.events;
        noRecords.style.display = "none";
        eventsTable.style.display = "table";
        for(var i=0; i<events.length; i++){
            addEventToTable(events[i]);
        }
    }
}

function addEventToTable(event){
    var eventTr = document.createElement("tr");
    
    var dateTd = document.createElement("td");
    var eventDate, eventTime;
    if(event.dates.start.dateTBD){
        eventDate = "TBD";
    }else if(event.dates.start.dateTBA){
        eventDate = "TBA";
    }else{
        eventDate = event.dates.start.localDate;
    }
    if(event.dates.start.timeTBA){
        eventTime = "TBA";
    }else if(event.dates.start.noSpecificTime){
        eventTime = "No Specific Time";
    }else{
        eventTime = event.dates.start.localTime;
    }
    dateTd.innerHTML = eventDate + "<br />" + eventTime;
    eventTr.appendChild(dateTd);
   
    var iconTd = document.createElement("td");
    if(typeof(event.images) != 'undefined' && event.images.length >= 1){
        iconTd.innerHTML = "<img src='"+ find169Image(event.images) +"'>"
    }
    eventTr.appendChild(iconTd);
    
    var eventTd = document.createElement("td");
    var eventA = document.createElement("a");
    eventA.href = "javascript:getEventDetail('" + event.id + "')";
    eventA.innerText = event.name;
    eventTd.appendChild(eventA);
    eventTr.appendChild(eventTd);
    
    var genreTd = document.createElement("td");
    if(typeof(event.classifications) != 'undefined' && event.classifications.length >= 1 && event.classifications[0].segment.name != 'Undefined'){
        genreTd.appendChild(document.createTextNode(event.classifications[0].segment.name));
    }
    eventTr.appendChild(genreTd);
    
    var venueTd = document.createElement("td");
    if(typeof(event._embedded) != 'undefined' && typeof(event._embedded.venues) != 'undefined' && event._embedded.venues.length >= 1){
        venueTd.appendChild(document.createTextNode(event._embedded.venues[0].name));
    }
    eventTr.appendChild(venueTd);
    
    eventsTable.appendChild(eventTr);
}
function sortTable(n){
    var isAsc = true;
    var isSorted = false;
    var switchCount = 0;
    while(!isSorted){
        isSorted = true;
        var rows = eventsTable.rows;
        for(i = 1; i < rows.length - 1; i++){
            var needSwitch = false;
            var text1 = rows[i].children[n].innerText;
            var text2 = rows[i+1].children[n].innerText;
            if(isAsc){
                if(text1.toLowerCase() > text2.toLowerCase()){
                    needSwitch = true;
                    break
                }
            }else{
                if(text1.toLowerCase() < text2.toLowerCase()){
                    needSwitch = true;
                    break
                }
            }
        }
        if(needSwitch){
            rows[i].parentNode.insertBefore(rows[i+1], rows[i]);
            isSorted = false;
            switchCount++;
        }else{
            if(switchCount == 0 && isAsc){
                isAsc = false;
                isSorted = false;
            }
        }
    }
}
function getEventDetail(eventId){
    request.open("GET", "/eventdetail/" + eventId);
    request.send();
    request.onload = function(){
        if(request.status == 200){
            console.log(JSON.parse(request.response));
            showEventDetail(JSON.parse(request.response));
        }
        else{
            console.log("Call Flask Event Detail Error "+request.status+ " " +request.statusText);
        }
    }
}
function showEventDetail(eventDetailJSON){
    eventDetail.innerHTML = "";
    venueDetail.style.display = "none";
    var eventName = document.createElement("h1");
    eventName.innerText = eventDetailJSON.name;
    eventDetail.appendChild(eventName);
    
    var eventDetailInfo = document.createElement("div");
    eventDetailInfo.id = "event_detail_info";

    var dateInfo = document.createElement("div");
    dateInfo.className = "info";
    var dateInfoTag = document.createElement("div");
    dateInfoTag.className = "info_tag";
    dateInfoTag.innerText = "Date";
    dateInfo.appendChild(dateInfoTag);
    var dateInfoContent = document.createElement("div");
    dateInfoContent.className = "info_content";
    var eventDate, eventTime;
    if(eventDetailJSON.dates.start.dateTBD){
        eventDate = "TBD";
    }else if(eventDetailJSON.dates.start.dateTBA){
        eventDate = "TBA";
    }else{
        eventDate = eventDetailJSON.dates.start.localDate;
    }
    if(eventDetailJSON.dates.start.timeTBA){
        eventTime = "TBA";
    }else if(eventDetailJSON.dates.start.noSpecificTime){
        eventTime = "No Specific Time";
    }else{
        eventTime = eventDetailJSON.dates.start.localTime;
    }
    dateInfoContent.innerText = eventDate + " " + eventTime;
    dateInfo.appendChild(dateInfoContent);
    eventDetailInfo.appendChild(dateInfo);

    const attractions = eventDetailJSON._embedded.attractions
    if(typeof(attractions) != 'undefined' && attractions.length >= 1){
        var attractionInfo = document.createElement("div");
        attractionInfo.className = "info";
        var attractionInfoTag = document.createElement("div");
        attractionInfoTag.className = "info_tag";
        attractionInfoTag.innerText = "Artist/Team"
        attractionInfo.appendChild(attractionInfoTag);
        var attractionInfoContent = document.createElement("div");
        attractionInfoContent.className = "info_content";
        var attractionText = "";
        if(typeof(attractions[0].url) != 'undefined'){
            attractionText += "<a href='" + attractions[0].url +"' target='_blank'>" + attractions[0].name +"</a>"
        }else{
            attractionText += attractions[0].name;
        }
        for(var i=1; i<attractions.length; i++){
            attractionText += " | ";
            if(typeof(attractions[i].url) != 'undefined'){
                attractionText += "<a href='" + attractions[i].url +"' target='_blank'>" + attractions[i].name +"</a>"
            }else{
                attractionText += attractions[i].name;
            }
        }
        attractionInfoContent.innerHTML = attractionText;
        attractionInfo.appendChild(attractionInfoContent);
        eventDetailInfo.appendChild(attractionInfo);
    }

    const venues = eventDetailJSON._embedded.venues;
    if(typeof(venues) != 'undefined' && venues.length >= 1){
        var venueInfo = document.createElement("div");
        venueInfo.className = "info";
        var venueInfoTag = document.createElement("div");
        venueInfoTag.className = "info_tag";
        venueInfoTag.innerText = "Venue";
        venueInfo.appendChild(venueInfoTag);
        var venueInfoContent = document.createElement("div");
        venueInfoContent.className = "info_content";
        venueInfoContent.innerText = venues[0].name;
        venueInfo.appendChild(venueInfoContent);
        eventDetailInfo.appendChild(venueInfo);
        showVenue.style.display = "block";
        arrow.onclick = function(){
            getVenueDetail(venues[0].name);
        }
    }

    const classifications = eventDetailJSON.classifications;
    if(typeof(classifications) != 'undefined' && classifications.length >=1){
        var genreInfo = document.createElement("div");
        genreInfo.className = "info";
        var genreInfoTag = document.createElement("div");
        genreInfoTag.className = "info_tag";
        genreInfoTag.innerText = "Genres";
        genreInfo.appendChild(genreInfoTag);
        var genreInfoContent = document.createElement("div");
        genreInfoContent.className = "info_content";
        var genreText = "";
        if(typeof(classifications[0].segment) != 'undefined' && classifications[0].segment.name != 'Undefined'){
            genreText += classifications[0].segment.name;
        }
        if(typeof(classifications[0].genre) != 'undefined' && classifications[0].genre.name != 'Undefined'){
            if(genreText.length >= 1){
                genreText += " | ";
            }
            genreText += classifications[0].genre.name;
            if(typeof(classifications[0].subGenre) != 'undefined' && classifications[0].subGenre.name != 'Undefined'){
                genreText += (" | " + classifications[0].subGenre.name);
            }
        }
        if(typeof(classifications[0].type) != 'undefined' && classifications[0].type.name != 'Undefined'){
            if(genreText.length >= 1){
                genreText += " | ";
            }
            genreText += classifications[0].type.name;
            if(typeof(classifications[0].subType) != 'undefined' && classifications[0].subType.name != 'Undefined'){
                genreText += (" | " + classifications[0].subType.name);
            }
        }
        genreInfoContent.innerText = genreText;
        genreInfo.appendChild(genreInfoContent);
        eventDetailInfo.appendChild(genreInfo);
    }
    

    const priceRanges = eventDetailJSON.priceRanges;
    if(typeof(priceRanges) != 'undefined' && priceRanges.length >= 1){
        var priceInfo = document.createElement("div");
        priceInfo.className = "info";
        var priceInfoTag = document.createElement("div");
        priceInfoTag.className = "info_tag";
        priceInfoTag.innerText = "Price Ranges";
        priceInfo.appendChild(priceInfoTag);
        var priceInfoContent = document.createElement("div");
        priceInfoContent.className = "info_content";
        var priceText = "";
        if(typeof(priceRanges[0].min) != 'undefined'){
            priceText += priceRanges[0].min;
        }
        if(typeof(priceRanges[0].max) != 'undefined'){
            if(priceText.length >= 1){
                priceText += " - ";
            }
            priceText += priceRanges[0].max;
        }
        if(typeof(priceRanges[0].currency) != 'undefined'){
            priceText += (" " + priceRanges[0].currency);
        }
        priceInfoContent.innerText = priceText;
        priceInfo.appendChild(priceInfoContent);
        eventDetailInfo.appendChild(priceInfo);
    }

    var statusInfo = document.createElement("div");
    statusInfo.className = "info";
    var statusInfoTag = document.createElement("div");
    statusInfoTag.className = "info_tag";
    statusInfoTag.innerText = "Ticket Status";
    statusInfo.appendChild(statusInfoTag);
    var statusInfoContent = document.createElement("div");
    statusInfoContent.className = "info_status";
    switch(eventDetailJSON.dates.status.code){
        case 'onsale':
            statusInfoContent.style.backgroundColor = "green";
            statusInfoContent.innerText = "On Sale";
            break;
        case 'offsale':
            statusInfoContent.style.backgroundColor = "red";
            statusInfoContent.innerText = "Off Sale";
            break;
        case 'cancelled':
            statusInfoContent.style.backgroundColor = "black";
            statusInfoContent.innerText = "Cancelled";
            break;
        case 'postponed':
            statusInfoContent.style.backgroundColor = "orange";
            statusInfoContent.innerText = "Postponed";
            break;
        case 'rescheduled':
            statusInfoContent.style.backgroundColor = "orange";
            statusInfoContent.innerText = "Rescheduled";
            break;
    }
    statusInfo.appendChild(statusInfoContent);
    eventDetailInfo.appendChild(statusInfo);

    var buyInfo = document.createElement("div");
    buyInfo.className = "info";
    var buyInfoTag = document.createElement("div");
    buyInfoTag.className = "info_tag";
    buyInfoTag.innerText = "Buy Ticket At:";
    buyInfo.appendChild(buyInfoTag);
    var buyInfoContent = document.createElement("div");
    buyInfoContent.className = "info_content";
    buyInfoContent.innerHTML = "<a href='" + eventDetailJSON.url + "' target='_blank'>Ticketmaster</a>";
    buyInfo.appendChild(buyInfoContent);
    eventDetailInfo.appendChild(buyInfo);

    eventDetail.appendChild(eventDetailInfo);

    if(typeof(eventDetailJSON.seatmap) != 'undefined'){
        var eventDetailSeatmap = document.createElement("div");
        eventDetailSeatmap.id = "event_detail_seatmap";
        var seatMapImg = document.createElement("img");
        seatMapImg.src = eventDetailJSON.seatmap.staticUrl;
        seatMapImg.onload = function(){
            if(seatMapImg.naturalHeight < seatMapImg.naturalWidth){
                seatMapImg.style.width = "100%";
            }else{
                seatMapImg.style.height = "100%";
            }
        }
        eventDetailSeatmap.appendChild(seatMapImg);
        eventDetail.appendChild(eventDetailSeatmap);
    }

    eventDetail.style.display = "block";
    eventDetail.scrollIntoView({ behavior: 'smooth', block: 'center'});
}

function getVenueDetail(venueName){
    request.open("GET", "/venuedetail/" + venueName);
    request.send();
    request.onload = function(){
        if(request.status == 200){
            console.log(JSON.parse(request.response));
            showVenueDetail(JSON.parse(request.response));
        }
        else{
            console.log("Call Flask Venue Detail Error "+request.status+ " " +request.statusText);
        }
    }
}

function showVenueDetail(venueDetailJSON){
    console.log(venueDetailJSON);
    
    if(typeof(venueDetailJSON._embedded) != 'undefined' && typeof(venueDetailJSON._embedded.venues) != 'undefined' && venueDetailJSON._embedded.venues.length >= 1){
        var venue = venueDetailJSON._embedded.venues[0];
        var venueName = document.getElementById("venue_detail_name");
        venueName.innerText = venue.name;
        var venueImg = document.getElementById("venue_detail_img");
        if(typeof(venue.images) != 'undefined' && venue.images.length >= 1){
            venueImg.src = find169Image(venue.images);
            venueImg.style.display = "block";
        }else{
            venueImg.style.display = "none";
        }
        var addressDetail = document.getElementById("address_detail");
        var addressText = "";
        if(typeof(venue.address.line1) != 'undefined'){
            addressText += (venue.address.line1 + "<br>");
        }
        if(typeof(venue.address.line2) != 'undefined'){
            addressText += (venue.address.line2 + "<br>");
        }
        if(typeof(venue.address.line3) != 'undefined'){
            addressText += (venue.address.line3 + "<br>");
        }
        if(typeof(venue.city) != 'undefined' && typeof(venue.city.name) != 'undefined'){
            addressText += (venue.city.name + ", " + venue.state.stateCode + "<br>");
        }
        if(typeof(venue.postalCode) != 'undefined'){
            addressText += (venue.postalCode + "<br>");
        }
        addressDetail.innerHTML = addressText;
        var searchText = venue.name + ", " + addressText.replaceAll("<br>", ", ");
        searchText = searchText.substring(0, searchText.length - 2);
        var mapLink = document.getElementById("map_link");
        mapLink.href = "https://www.google.com/maps/search/?api=1&query="+ encodeURIComponent(searchText);
        var moreLink = document.getElementById("more_link");
        if(typeof(venue.url) != 'undefined'){
            moreLink.style.display = "block";
            moreLink.href = venue.url;
        }else{
            moreLink.style.display = "none";
        }
        venueDetail.style.display = "block";
        venueDetail.scrollIntoView({ behavior: 'smooth', block: 'center'});
    }
    showVenue.style.display = "none";
}

function find169Image(images){
    for(var i=0; i<images.length; i++){
        if(images[i].ratio == "16_9"){
            return images[i].url
        }
    }
    return images[0].url;
}