最新消息:20210917 已从crifan.com换到crifan.org

【已解决】Mac本地搭建绘本查询推荐系统前台页面

Mac crifan 1729浏览 0评论

折腾了:

【已解决】Mac本地搭建用Flask绘本查询推荐系统后台

后,继续去折腾,mac本地搭建绘本查询系统的前台页面。

暂时先用web页面,后续可以考虑换小程序等其他形式。

先去建git仓库等事情,就不赘述了。

然后就是去开始写代码,画界面了。

根据之前经验,直接用bootstrap的css去画,可以实现基本的不同端的页面适配:

移动端:行内元素紧凑上下显示

PC端:行内元素左右显示

然后去写代码。

先去下载和导入bootstrap

Bootstrap · The most popular HTML, CSS, and JS library in the world.

Download · Bootstrap

再去下载:jQuery

jQuery

然后参考之前代码,先实现基本的从api返回json数据并显示的逻辑:

index.html

<!doctype html>

<html lang="en">

  <head>

    <!– Required meta tags –>

    <meta charset="utf-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!– Bootstrap CSS –>

    <link rel="stylesheet" href="css/bootstrap-4.1.3/bootstrap.css">

    <!– <link rel="stylesheet" href="css/highlight/highlightjs_default.css"> –>

    <link rel="stylesheet" href="css/highlight/highlight_atom-one-dark.css">

    <!– <link rel="stylesheet" href="css/highlight/highlight_monokai-sublime.css"> –>

    <link rel="stylesheet" href="css/main.css">

    <title>xxx查询系统</title>

  </head>

    <div class="logo text-center">

        <img src="img/logo_transparent_183x160.png" alt="NaturLing Logo" width="72" height="72">

    </div>

    <h2>xxx查询系统</h2>

    <div class="row">

      <div class="col-lg-12">

        <div class="input-group">

          <input id="inputQuery" type="text" class="form-control" placeholder="请输入要查询的绘本" value="The Spider and the Fly">

          <span class="input-group-btn">

            <button id="submitQuery" type="submit" class="btn btn-primary" type="button">查询</button>

          </span>

        </div>

      </div>

    </div>

    <div class="panel panel-success">

      <div class="panel-heading">

        <h3 class="panel-title">调试输出</h3>

      </div>

      <div class="panel-body">

        <div id="response_json">

          <code class="json">here will output response</code>

        </div>

      </div>

    </div>

    <!– Optional JavaScript –>

    <!– jQuery first, then Popper.js, then Bootstrap JS –>

    <script src="js/jquery-3.3.1/jquery-3.3.1.js"></script>

    <script src="js/bootstrap-4.1.3/bootstrap.min.js"></script>

    <script src="js/highlight.js"></script>

    <script src="js/main.js"></script>

  </body>

</html>

main.js

// add String.format support

if (!String.format) {

    String.format = function(format) {

      var args = Array.prototype.slice.call(arguments, 1);

      return format.replace(/{(\d+)}/g, function(match, number) {

        return typeof args[number] != ‘undefined’

          ? args[number]

          : match

        ;

      });

    };

}

// 对Date的扩展,返回时间戳(毫秒,13位)

// 例子:

// this=Tue Jun 06 2017 15:00:00 GMT+0800 (CST) -> timesamp=1496732400000

Date.prototype.timestamp = function () {

    // console.log(`Date timesamp: this=${this}`);

    let timesamp = this.getTime();

    // console.log(`this=${this} -> timesamp=${timesamp}`);

    return timesamp;

  };

  

  // 对Date的扩展,将 Date 转化为指定格式的String

  // 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,

  // 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)

  // 例子:

  // (new Date()).Format("yyyy-MM-dd HH:mm:ss.S") ==> 2006-07-02 08:09:04.423

  // (new Date()).Format("yyyy-M-d h:H:s.S")      ==> 2006-7-2 8:9:4.18

  Date.prototype.Format = function (fmt) {

    const o = {

      "M+": this.getMonth() + 1, //月份

      "d+": this.getDate(), //日

      "H+": this.getHours(), //小时

      "m+": this.getMinutes(), //分

      "s+": this.getSeconds(), //秒

      "q+": Math.floor((this.getMonth() + 3) / 3), //季度

      "S": this.getMilliseconds() //毫秒

    };

  

    if (/(y+)/.test(fmt)){

      fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 – RegExp.$1.length));

    }

  

    for (const k in o){

      if (new RegExp("(" + k + ")").test(fmt)){

        fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));

      }

    }

    return fmt;

  };

  

  // var time1 = new Date().Format("yyyy-MM-dd");

  // var time2 = new Date().Format("yyyy-MM-dd HH:mm:ss");

  // console.log(time1);  //2017-06-09

  // console.log(time2);  //2017-06-09 09:54:35

  

  /** * 对Date的扩展,将 Date 转化为指定格式的String * 月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(q)

      可以用 1-2 个占位符 * 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)

   * eg:

   * (new Date()).pattern("yyyy-MM-dd HH:mm:ss.S")==> 2006-07-02 08:09:04.423

   * (new Date()).pattern("yyyy-MM-dd E HH:mm:ss") ==> 2009-03-10 二 20:09:04

   * (new Date()).pattern("yyyy-MM-dd EE HH:mm:ss") ==> 2009-03-10 周二 08:09:04

   * (new Date()).pattern("yyyy-MM-dd EEE HH:mm:ss") ==> 2009-03-10 星期二 08:09:04

   * (new Date()).pattern("yyyy-M-d H:m:s.S") ==> 2006-7-2 8:9:4.18

   */

  Date.prototype.pattern=function(fmt) {

    const o = {

      "M+" : this.getMonth()+1, //月份

      "d+" : this.getDate(), //日

      "h+" : this.getHours()%12 == 0 ? 12 : this.getHours()%12, //小时

      "H+" : this.getHours(), //小时

      "m+" : this.getMinutes(), //分

      "s+" : this.getSeconds(), //秒

      "q+" : Math.floor((this.getMonth()+3)/3), //季度

      "S" : this.getMilliseconds() //毫秒

    };

  

    if (/(y+)/.test(fmt)){

      fmt = fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 – RegExp.$1.length));

    }

  

    if (/(E+)/.test(fmt)){

      fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length>1) ? (RegExp.$1.length>2 ? "星期" : "周") : "") + "日一二三四五六".charAt(this.getDay()));

    }

  

    for (const k in o){

      if (new RegExp("("+ k +")").test(fmt)){

        fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));

      }

    }

  

    return fmt;

  };

  

  // var date = new Date();

  // console.log(date.pattern("yyyy-MM-dd EEE HH:mm:ss"));  //2017-06-09 星期五 10:16:12

  // console.log(date.pattern("yyyy-MM-dd EE HH:mm:ss"));   //2017-06-09 周五 10:16:12

  // console.log(date.pattern("yyyy-MM-dd E HH:mm:ss"));    //2017-06-09 五 10:16:12

  

$(document).ready(function(){

    console.log("document ready !");

    // console.log($);

    $("#submitQuery").click(function(event){

        event.preventDefault();

        ajaxSubmitQuery();

    });

    // when got response json, update to highlight it

    function updateHighlight() {

        console.log("updateHighlight");

        $(‘pre code’).each(function(i, block) {

            hljs.highlightBlock(block);

        });

    }

    function ajaxSubmitQuery() {

        console.log("ajaxSubmitQuery")

        var inputQuery = $("#inputQuery").val()

        console.log("inputQuery=%s", inputQuery)

        var trimedQuery = $.trim(inputQuery)

        console.log("trimedQuery=%s", trimedQuery)

        var encodedInputQuery = encodeURIComponent(trimedQuery)

        console.log("encodedInputQuery=%s", encodedInputQuery)

        // var HostUrl = "http://127.0.0.1:33800"

        var HostUrl = "http://localhost:33800"

        // var HostUrl = "http://xxx:33800"

        console.log("HostUrl=%s", HostUrl)

        var urlPrefix = HostUrl + "/storybook?q="

        console.log("urlPrefix=%s", urlPrefix)

        var queryUrl = urlPrefix + encodedInputQuery

        console.log("queryUrl=%s", queryUrl)

        $.ajax({

            type : "GET",

            url : queryUrl,

            success: function(respJsonObj){

                console.log("respJsonObj=%o", respJsonObj);

                // var respnJsonStr = JSON.stringify(respJsonObj);

                //var beautifiedJespnJsonStr = JSON.stringify(respJsonObj, null, ‘\t’);

                var beautifiedJespnJsonStr = JSON.stringify(respJsonObj, null, 2);

                console.log("beautifiedJespnJsonStr=%s", beautifiedJespnJsonStr);

                var prevOutputValue = $(‘#response_json’).text();

                console.log("prevOutputValue=%o", prevOutputValue);

                var afterOutputValue = $(‘#response_json’).html(‘<pre><code class="json">’ + beautifiedJespnJsonStr + "</code></pre>");

                console.log("afterOutputValue=%o", afterOutputValue);

                updateHighlight();

                var curResponseDict = respJsonObj["data"]["response"];

                console.log("curResponseDict=%s", curResponseDict);

                $(‘#response_text p’).text(curResponseDict);

            },

            error : function(jqXHR, textStatus, errorThrown) {

                console.error("jqXHR=%o, textStatus=%s, errorThrown=%s", jqXHR, textStatus, errorThrown);

                var errDetail = String.format("status={0}\n\tstatusText={1}\n\tresponseText={2}", jqXHR.status, jqXHR.statusText, jqXHR.responseText);

                var errStr = String.format("GET: {0}\nERROR:\t{1}", fullQaUrl,  errDetail);

                // $(‘#response_text p’).text(errStr);

                var responseError = $(‘#response_json’).html(‘<pre><code class="html">’ + errStr + "</code></pre>");

                console.log("responseError=%o", responseError);

                updateHighlight();

            }

        });

    }

});

main.css

.logo{

    padding: 10px 2%;

}

h2{

    text-align: center;

    margin-top: 10px;

    margin-bottom: 10px;

}

h4{

    text-align: center;

    margin-top: 0px;

    margin-bottom: 20px;

}

form {

    text-align: center;

}

效果:

然后继续去添加多行

query result的多行内容

recommend的多行内容

找找bootstrap中,适合:

  • 上下的多个元素的列表

  • 和每行内的内容显示

发现适合的有:

列表:

List group · Bootstrap

Cards · Bootstrap

或:

Media object · Bootstrap

https://getbootstrap.com/docs/4.1/layout/media-object/#media-list

接着就要去:

【已解决】JQuery中如何生成html并替换原先html节点的内容

然后此处发现个问题:

【已解决】bootstrap中panel缺少边框效果

然后继续调试页面布局:

【已解决】bootstrap 4中实现每行左边图片右边基本信息的布局样式

然后继续画页面:

【已解决】html和bootstrap 4中支持点击每行跳转到新页面且传递参数

然后再去优化详情页的显示的布局:

希望在media的下面,显示出description(很多行的描述文字)

参考:

Cards · Bootstrap

https://getbootstrap.com/docs/4.0/components/card/#card-styles

【总结】

最后的最后,经过多次优化,用代码如下:

js/book_detail.js

// var CurBookIdKey = "cur_book_id"

$(document).ready(function(){

    console.log("boot detail document ready !")

    function backToHome(event){

        console.log("backToHome: event=%o", event)

        var restoredInput = restoreInput()

        console.log("restoredInput=", restoredInput)

        redirectToHome({"q": restoredInput})

    }

    $(document).on("click", "#back_home", backToHome)

    $(document).on("click", ".single_storybook_item", function(event){

        console.log("detail page clicked single_storybook_item: event=%o", event)

        var restoredInput = restoreInput()

        console.log("restoredInput=", restoredInput)

        redirectToDetailPage(this, restoredInput)

    })

    $(document).on("click", ".book_single_tag", function(event){

        console.log("detail page book_single_tag clicked: event=%o", event)

        tagClickCallback(event, this)

    })

    function updateRecommandBookList(allRecommendationList, recBookSelectStr){

        console.log(‘updateRecommandBookList: allRecommendationList=’, allRecommendationList)

        // var recBookListHtml =  $(recBookSelectStr).html()

        console.log(‘before: recBookSelectStr=’, recBookSelectStr)

        $(recBookSelectStr).empty()

        // recBookListHtml =  $(recBookSelectStr).html()

        // console.log(‘recBookListHtml=’, recBookListHtml)

        if (!allRecommendationList) {

            console.warn("updateRecommandBookList: input recommendations is empty")

            return

        }

        for(var eachRecBookDict of allRecommendationList){

            console.log(‘eachRecBookDict=’, eachRecBookDict)

            // var eachRecBookHtml = generateRecBookItemHtml(eachRecBookDict)

            var eachRecBookHtml = generateBookItemHtml(eachRecBookDict)

            $(recBookSelectStr).append(eachRecBookHtml)

        }

        // recBookListHtml =  $(recBookSelectStr).html()

        // console.log(‘after: recBookListHtml=’, recBookListHtml)

    }

    function updateBookDetail(curBookDict){

        console.log(‘updateBookDetail: curBookDict=’, curBookDict)

        var bookSelectStr = "#book_detail"

        var bookInfoHtml =  $(bookSelectStr).html()

        console.log(‘before: bookInfoHtml=’, bookInfoHtml)

        // $(bookSelectStr).html("")

        $(bookSelectStr).empty()

        bookInfoHtml =  $(bookSelectStr).html()

        console.log(‘bookInfoHtml=’, bookInfoHtml)

        if (isEmptyObj(curBookDict)){

            console.warn("input book is empty!")

            return

        }

        var coverImgUrl = curBookDict["coverImgUrl"]

        if (!coverImgUrl){

            coverImgUrl = DefaultCoverImgUrl

            console.log("default coverImgUrl=", coverImgUrl)

        }

        console.log("coverImgUrl=", coverImgUrl)

        var title = curBookDict["title"]

        // for debug

        // title = title + "long name test long name test long name test long name test long name test long name test"

        console.log("title=", title)

        var imgAltStr = title

        // var imgAltStr = ""

        // if (coverImgUrl) {

        //     imgAltStr = title

        // } else {

        //     imgAltStr = ""

        // }

        console.log("imgAltStr=", imgAltStr)

        // var authorsIllustrators = []

        // var bookAuthors = curBookDict["author"]["bookAuthors"]

        // console.log("bookAuthors=", bookAuthors)

        // var illustrators = curBookDict["author"]["illustrators"]

        // console.log("illustrators=", illustrators)

        // authorsIllustrators = authorsIllustrators.concat(bookAuthors)

        // authorsIllustrators = authorsIllustrators.concat(illustrators)

        // console.log("authorsIllustrators=", authorsIllustrators)

        // var authorsIllustratorsStr = listToStr(authorsIllustrators)

        // // for debug

        // // authorsIllustratorsStr += "long author and illustrator name long author and illustrator name"

        // console.log("authorsIllustratorsStr=", authorsIllustratorsStr)

        // authorsIllustratorsStr = processEmptyDefault(authorsIllustratorsStr)

        var bookAuthors = curBookDict["author"]["bookAuthors"]

        console.log("bookAuthors=", bookAuthors)

        var authorsStr = listToStr(bookAuthors)

        console.log("authorsStr=", authorsStr)

        authorsStr = processEmptyDefault(authorsStr)

        var illustrators = curBookDict["author"]["illustrators"]

        console.log("illustrators=", illustrators)

        var illustratorsStr = listToStr(illustrators)

        console.log("illustratorsStr=", illustratorsStr)

        illustratorsStr = processEmptyDefault(illustratorsStr)

        // var gradesStr = listToStr(curBookDict["grades"])

        // console.log("gradesStr=", gradesStr)

        // gradesStr = processEmptyDefault(gradesStr)

        var ageStr = curBookDict["grading"]["age"]

        console.log("ageStr=", ageStr)

        if (ageStr){

            ageStr += "岁"

        }

        ageStr = processEmptyDefault(ageStr)

        var difficultyInt = curBookDict["grading"]["difficulty"]

        console.log("difficultyInt=", difficultyInt)

        var tagsHtml = generateTagsHtml(curBookDict["tags"])

        console.log("tagsHtml=", tagsHtml)

        var genreStr = curBookDict["genre"]

        console.log("genreStr=", genreStr)

        genreStr = processEmptyDefault(genreStr)

        var pages = curBookDict["pages"]

        var pagesStr = ""

        if (pages > 0){

            pagesStr = `${pages}`

        }

        console.log("pages=", pages)

        pagesStr = processEmptyDefault(pagesStr)

        var seriesNameAndNumber = ""

        var seriesName = curBookDict["series"]["name"]

        console.log("seriesName=", seriesName)

        if (seriesName) {

            seriesNameAndNumber = seriesName

            var seriesNumber = curBookDict["series"]["number"]

            // var seriesNumberStr = ""

            if (seriesNumber > 0){

                // seriesNumberStr = `${seriesNumber}`

                seriesNameAndNumber = `${seriesNameAndNumber} # ${seriesNumber}`

            }

        }

        // for debug

        // seriesNameAndNumber = seriesNameAndNumber + " long series and number long series and number long series and number long series and number"

        console.log("seriesNameAndNumber=", seriesNameAndNumber)

        seriesNameAndNumber = processEmptyDefault(seriesNameAndNumber)

        var lexileStr = curBookDict["grading"]["lexile"]

        console.log("lexileStr=", lexileStr)

        lexileStr = processEmptyDefault(lexileStr)

        var naturlingStr = ""

        var naturling = curBookDict["grading"]["naturling"]

        if (naturling) {

            naturlingStr = `${naturling}级`

        }

        console.log("naturlingStr=", naturlingStr)

        naturlingStr = processEmptyDefault(naturlingStr)

        var descriptionStr = curBookDict["description"]

        console.log("descriptionStr=", descriptionStr)

        descriptionStr = processEmptyDefault(descriptionStr)

        var curBookHtml = `

            <div class="single_book_detail">

                <button class="back_home_button" id="back_home">

                    <img width="22px" height="22px" src="img/back_to_home.png">

                </button>

                <div class="text-center book_detail_cover_img_parent">

                    <img class="book_detail_cover_img" src="${coverImgUrl}" alt="${imgAltStr}">

                </div>

                <h5 class="text-center book_detail_title">${title}</h5>

                <ul class="list-group list-group-flush">

                    <p class="book_detail_item"><span class="book_detail_keys">作者: </span><span class="book_detail_values">${authorsStr}</span></p>

                    <p class="book_detail_item"><span class="book_detail_keys">插画师: </span><span class="book_detail_values">${illustratorsStr}</span></p>

                    <p class="book_detail_item"><span class="book_detail_keys">系列: </span><span class="book_detail_values">${seriesNameAndNumber}</span></p>

                    <p class="book_detail_item"><span class="book_detail_keys">兰斯指数: </span><span class="book_detail_values">${lexileStr}</span></p>

                    <p class="book_detail_item"><span class="book_detail_keys">Naturling等级: </span><span class="book_detail_values">${naturlingStr}</span></p>

                    <p class="book_detail_item"><span class="book_detail_keys">参考年龄: </span><span class="book_detail_values">${ageStr}</span></p>

                    <p class="book_detail_item"><span class="book_detail_keys">题材: </span><span class="book_detail_values">${genreStr}</span></p>

                    <p class="book_detail_item"><span class="book_detail_keys">页数: </span><span class="book_detail_values">${pagesStr}</span></p>

                    <p class="book_detail_tags" data-difficulty="${difficultyInt}">${tagsHtml}</p>

                    <div class="book_detail_desc">

                        <span class="book_detail_keys book_detail_summary_title">简介: </span>

                        <div id="summary">

                            <p class="collapse book_detail_values" id="collapseSummary">

                                ${descriptionStr}

                            </p>

                            <button class="more_less_button float-right collapsed" data-toggle="collapse" href="#collapseSummary" aria-expanded="false" aria-controls="collapseSummary">

                            </button>

                        </div>

                    </div>

                </ul>

            </div>`

        console.log(‘curBookHtml=’, curBookHtml)

        $(bookSelectStr).append(curBookHtml)

        bookInfoHtml =  $(bookSelectStr).html()

        console.log(‘after: bookInfoHtml=’, bookInfoHtml)

    }

    // var curBookId = localStorage.getItem(CurBookIdKey)

    var getOk, curBookId

    [getOk, curBookId] = getQueryValueFromCurSearch("book_id")

    console.log("getOk=%s, curBookId=", getOk, curBookId)

    if(getOk && curBookId) {

        var urlPrefix = HostUrl + "/storybook/"

        console.log("urlPrefix=%s", urlPrefix)

        var queryUrl = urlPrefix + curBookId

        console.log("queryUrl=%s", queryUrl)

        $.ajax({

            type : "GET",

            url : queryUrl,

            success: function(respJsonObj){

                console.log("respJsonObj=", respJsonObj)

                var curResponseDict = respJsonObj["data"]

                console.log("curResponseDict=%s", curResponseDict)

                var bookInfoDict = curResponseDict

                console.log(‘bookInfoDict=’, bookInfoDict)

                updateBookDetail(bookInfoDict)

                // console.log(‘after updateBookDetail: bookInfoDict=’, bookInfoDict)

                updateRecommandBookList(bookInfoDict["recommendations"], "#recommend_book_list")

            },

            error: function(jqXHR, textStatus, errorThrown){

                console.error("GET %s -> jqXHR=%o, textStatus=%s, errorThrown=%s", queryUrl, textStatus, errorThrown)

                if (errCallback){

                    errCallback(jqXHR, textStatus, errorThrown)

                } else {

                    debugDisplayErrorInfo(jqXHR, textStatus, errorThrown)

                }

            }

        });

    }

})

js/book_common.js

function generateTagsHtml(tags, highlightTag=""){

    console.log("generateTagsHtml: tags=%o, highlightTag=%s", tags, highlightTag)

    const BadgeType = "badge-secondary"

    const BadgePillType = "badge-pill " + BadgeType + " book_single_tag"

    var highlightTagHtml = ""

    if (highlightTag) {

        highlightTagHtml = `<span class="badge ${BadgePillType} book_single_tag_highlighted">${highlightTag}</span>`

    }

    console.log("highlightTagHtml=", highlightTagHtml)

    var tagsHtml = highlightTagHtml

    for(var eachTag of tags){

        if (eachTag) {

            if (eachTag != highlightTag){

                eachTagHtml = `<span class="badge ${BadgePillType}">${eachTag}</span>`

                tagsHtml += eachTagHtml

            }

        }

    }

    console.log("tagsHtml=", tagsHtml)

    return tagsHtml

}

function generateBookItemHtml(curBookDict, highlightTag=""){

    console.log("generateBookItemHtml: curBookDict=%o, highlightTag=%s", curBookDict, highlightTag)

    var coverImgUrl = curBookDict["coverImgUrl"]

    console.log("coverImgUrl=", coverImgUrl)

    if (!coverImgUrl){

        coverImgUrl = DefaultCoverImgUrl

        console.log("default coverImgUrl=", coverImgUrl)

    }

    var title = curBookDict["title"]

    console.log("title=", title)

    var imgAltStr = ""

    if (coverImgUrl) {

        imgAltStr = title

    } else {

        imgAltStr = ""

    }

    console.log("imgAltStr=", imgAltStr)

    // var authorsStr = listToStr(curBookDict["authors"])

    var authorsStr = listToStr(curBookDict["author"]["bookAuthors"])

    console.log("authorsStr=", authorsStr)

    authorsStr = processEmptyDefault(authorsStr)

    // var illustratorsStr = listToStr(curBookDict["illustrators"])

    var illustratorsStr = listToStr(curBookDict["author"]["illustrators"])

    console.log("illustratorsStr=", illustratorsStr)

    // var gradesStr = listToStr(curBookDict["grades"])

    // console.log("gradesStr=", gradesStr)

    // gradesStr = processEmptyDefault(gradesStr)

    var ageStr = curBookDict["grading"]["age"]

    console.log("ageStr=", ageStr)

    if (ageStr){

        ageStr += "岁"

    }

    ageStr = processEmptyDefault(ageStr)

    var lexileStr = curBookDict["grading"]["lexile"]

    console.log("lexileStr=", lexileStr)

    lexileStr = processEmptyDefault(lexileStr)

    var tagsHtml = generateTagsHtml(curBookDict["tags"], highlightTag)

    console.log("tagsHtml=", tagsHtml)

    var difficultyInt = curBookDict["grading"]["difficulty"]

    console.log("difficultyInt=", difficultyInt)

    title = processEmptyDefault(title)

    var curBookItemHtml = `

        <li class="list-group-item single_storybook_item">

            <div class="media">

                <div class="text-center">

                    <img class="book_list_cover_image" width="100" height="140" src="${coverImgUrl}" alt="${imgAltStr}">

                </div>

                <div class="media-body">

                    <h5 class="book_list_title">${title}</h5>

                    <div hidden><strong>ID: </strong><div id="book_id">${curBookDict["id"]}</div></div>

                    <p class="book_list_text_row"><span class="book_list_keys">作者:</span>${authorsStr}</p>

                    <p class="book_list_text_row"><span class="book_list_keys">兰斯指数:</span>${lexileStr}</p>

                    <p class="book_list_text_row line_before_tags"><span class="book_list_keys">参考年龄:</span>${ageStr}</p>

                    <p class="book_list_tags" data-difficulty="${difficultyInt}">${tagsHtml}</p>

                </div>

            </div>

        </li>`

    console.log(‘curBookItemHtml=’, curBookItemHtml)

    return curBookItemHtml

}

function redirectToDetailPage(curElement, curInput){

    console.log("redirectToDetailPage: curElement=%o, curInput=%s", curElement, curInput)

    var bookId = $(curElement).find("#book_id").text()

    console.log("bookId=", bookId)

    var queryParaDict = {

        "book_id": bookId

    }

    if (curInput) {

        queryParaDict[CurrentInputQsKey] = curInput

    }

    console.log("queryParaDict=", queryParaDict)

    redirectToUrl(DetailPageUrl, queryParaDict)

}

function redirectToHome(queryParaDict){

    console.log("redirectToHome: queryParaDict=%o", queryParaDict)

    redirectToUrl(HomePageUrl, queryParaDict)

}

function tagClickCallback(event, curElement){

    console.log("tagClickCallback: curElement=%o", curElement)

    event.stopPropagation()

    var clickedTagStr = $(curElement).text()

    console.log("clickedTagStr=%s", clickedTagStr)

    // var tagParent = $(curElement).parent(".book_list_tags")

    // var tagParent = $(curElement).parent(".book_detail_tags")

    var tagParent = $(curElement).parent()

    console.log("tagParent=%s", tagParent)

    var dataDifficulty = tagParent.data("difficulty")

    console.log("dataDifficulty=%s", dataDifficulty)

    var queryParaDict = {

        "q": "",

        "tag": clickedTagStr,

        "difficulty": dataDifficulty,

    }

    console.log("queryParaDict=%s", queryParaDict)

    redirectToHome(queryParaDict)

}

// restore previous search input from url

function restoreInput(){

    console.log("restoreInput")

    var restoredCurInput = ""

    var getOk, prevInput

    [getOk, prevInput] = getQueryValueFromCurSearch(CurrentInputQsKey)

    console.log("getOk=%s, prevInput=%s", getOk, prevInput)

    if (getOk) {

        restoredCurInput = prevInput

    }

    console.log("restoredCurInput=", restoredCurInput)

    return restoredCurInput

}

// when got response json, update to highlight it

function updateHighlight() {

    console.log("updateHighlight")

    $(‘pre code’).each(function(i, block) {

        hljs.highlightBlock(block)

    });

}

function debugDisplayErrorInfo(jqXHR, textStatus, errorThrown) {

    console.error("jqXHR=%o, textStatus=%s, errorThrown=%s", jqXHR, textStatus, errorThrown)

    var errDetail = String.format("status={0}\n\tstatusText={1}\n\tresponseText={2}", jqXHR.status, jqXHR.statusText, jqXHR.responseText)

    var responseError = $(‘#response_json’).html(‘<pre><code class="html">’ + errDetail + "</code></pre>")

    console.log("responseError=%o", responseError)

    // updateHighlight()

}

效果是:

转载请注明:在路上 » 【已解决】Mac本地搭建绘本查询推荐系统前台页面

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
92 queries in 0.185 seconds, using 23.51MB memory