Friday, December 19, 2014

Developing photo album using Flickr API in plain JS

In many top companies's machine test interview round they ask to develop a photo album using Flickr API in plain javascript without using any third party libraries like jQuery.

The following solution has below features:

1: Ability to search photos from Flickr
2: Responsive design
3: Showing only top 20 results from the above search

First create Flickr API key following steps mentioned in the below URL:

https://www.flickr.com/services/api/misc.api_keys.html


 The HTML code is below:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <script src="main.js"></script>
    <title></title>
    <link rel="stylesheet" type="text/css" href="main.css">

</head>
<body>
<div class="tools">
    <input type="text" placeholder="searchphotos" id="searchtext">
    <button title="Search Flickr photos" onclick=" exportObj.search()" style="">Search</button>
    <div class="wrap">

        <br/>
    </div>
</div>
</body>
</html>
The main.js javascript code goes below:

var exportObj = (function () {
    var exportObj = {};
    var xmlhttp;
    var jsonResponse;
    /**     * Initialize the AJAX     */    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
    }
    /**     * Response handler for any AJAX request     */    xmlhttp.onreadystatechange = function () {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            console.log(xmlhttp.responseText);
            var actualResponse = JSON.parse(xmlhttp.responseText);
            jsonResponse = actualResponse.photos;

            appendPhotos();
        }
    }
    /**     * It goes through the photos received as response, and append those to the wrapper div     */    function appendPhotos() {
        var src;
        var item;
        var oImg;
        var boxdiv;
        var innerbox;
        var titlebox        var wrapper = document.getElementsByClassName("wrap");
        wrapper[0].innerHTML = '';

        for (var i = 0; i < jsonResponse.photo.length; i++) {

            item = jsonResponse.photo[i];
            src = "http://farm" + item.farm + ".static.flickr.com/" + item.server + "/" + item.id + "_" + item.secret + "_m.jpg";
            oImg = document.createElement("img");
            oImg.setAttribute('src', src);
            oImg.setAttribute('alt', 'na');
            boxdiv = document.createElement("div");
            boxdiv.setAttribute("class", "box");
            innerbox = document.createElement("div");
            innerbox.setAttribute("class", "boxInner");
            titlebox = document.createElement("div");
            titlebox.innerText = item.title;
            innerbox.appendChild(oImg);
            innerbox.appendChild(titlebox);
            boxdiv.appendChild(innerbox);
            wrapper[0].appendChild(boxdiv);

        }
    }

    /**     * This is binded to search button in the view.     * When you click the search button in the UI this function get called.     * It sends a GET request to REST for fetching your serach related data     */    exportObj.search = function () {


        var apiKey = <put your Flickr API key here>;
        var searchtext = document.getElementById("searchtext");
        var searchkeyword = searchtext.value;
        var requestURL = 'https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=' + apiKey + '&text=' + searchkeyword + '&safe_search=1&per_page=20&format=json&nojsoncallback=?';
        xmlhttp.open("GET", requestURL, true);
        xmlhttp.send();
    }
    return exportObj;

}());
The main.css  stylesheet  code goes below:

body {
    margin: 0;
    padding: 0;
    background: #EEE;
    font: 10px/13px 'Lucida Sans',sans-serif;
}

.wrap {
    overflow: hidden;
    margin: 70px;
}


.box {
    float: left;
    position: relative;
    width: 20%;
    padding-bottom: 20%;
}
.boxInner {
    position: absolute;
    left: 10px;
    right: 10px;
    top: 10px;
    bottom: 10px;
    overflow: hidden;
}
.boxInner img {
    width: 100%;
    display:block;
}
.boxInner:hover img {
    -webkit-transform:scale(1.75); /* Safari and Chrome */    -moz-transform:scale(1.25); /* Firefox */    -ms-transform:scale(1.25); /* IE 9 */    -o-transform:scale(1.25); /* Opera */    transform:scale(1.25);
}

@media only screen and (max-width : 480px) {
    /* Smartphone view: 1 tile */    .box {
        width: 100%;
        padding-bottom: 100%;
    }
}
@media only screen and (max-width : 650px) and (min-width : 481px) {
    /* Tablet view: 2 tiles */    .box {
        width: 50%;
        padding-bottom: 50%;
    }
}
@media only screen and (max-width : 1050px) and (min-width : 651px) {
    /* Small desktop / ipad view: 3 tiles */    .box {
        width: 33.3%;
        padding-bottom: 33.3%;
    }
}
@media only screen and (max-width : 1290px) and (min-width : 1051px) {
    /* Medium desktop: 4 tiles */    .box {
        width: 25%;
        padding-bottom: 25%;
    }
}

No comments:
Write comments