Một ứng dụng nữa của Blogger JSON Feed API đó là phục vụ cho tính năng search trên blog. Trong bài viết này tôi sẽ hướng dẫn bạn cách kết hợp widget label cùng json feed api để load bài viết mà không cần tải lại trang
Xem demo
Để làm được điều này, ngoài kiến thức cơ bản về HTML, JS, CSS bạn cũng cần biết thêm về thẻ b:section và b:widget của blog để có thể can thiệp vào bố cục của blog.
Cách thức hoạt động của tiện ích này rất đơn giản, đó là bạn sử dụng widget label của blog để thống kê toàn bộ các nhãn hiện có, với mỗi lựa chọn label từ phía người dùng, ta sẽ get dữ liệu theo label đó để hiển thị ra thanh tìm kiếm.
Việc sử dụng method ajax get sẽ giúp bạn không cần phải chuyển trang để tìm kiếm bài đăng (/search/label/label-name) đồng thời cũng giúp người dùng có nhiều lựa chọn hơn khi vào trang của bạn mà không biết tìm gì và xem gì
Trong bài này tôi dùng font awesome 4.7, bạn tự tích hợp jQuery nhé
Tạo mới 1 section để chứa 1 widget label và 1 widget HTML (thường ta sẽ đặt nó nằm trong vùng header)
<b:section class='search-wrap' id='search-wrap' showaddelement='no'>
<b:widget id='Label69' locked='false' title='Category' type='Label' version='1'>
<b:widget-settings>
<b:widget-setting name='sorting'>ALPHA</b:widget-setting>
<b:widget-setting name='display'>LIST</b:widget-setting>
<b:widget-setting name='selectedLabelsList' />
<b:widget-setting name='showType'>ALL</b:widget-setting>
<b:widget-setting name='showFreqNumbers'>false</b:widget-setting>
</b:widget-settings>
<b:includable id='main'>
<div expr:class='"widget-content " + data:display + "-label-widget-content"'>
<b:if cond='data:display == "list"'>
<div class='droplabel'>
<select class='dropdown-select'>
<option class="labdrop" title="Select category" value="0">
Select category
</option>
<b:loop values='data:labels' var='label'>
<option class='labdrop' expr:title='data:label.name' expr:value='data:label.name'>
<data:label.name/> (<data:label.count/>)
</option>
</b:loop>
</select>
</div>
</b:if>
</div>
</b:includable>
</b:widget>
<b:widget id='HTML777' locked='true' title='Search' type='HTML' version='1'>
<b:widget-settings>
<b:widget-setting name='content'>
<![CDATA[
<form autocomplete="off" id="hh-search-form" method="get" action="/search">
<div class="hh-search-wrap">
<input id="hh-search" name="q" type="text" required="" placeholder="Search ...">
<button id="hh-submit" type="submit"><i class="fa fa-search"></i></button>
<input name="max-results" type="hidden" value="20">
<div class="filter-label"></div>
</div>
</form>
]]>
</b:widget-setting>
</b:widget-settings>
<b:includable id='main'>
<div class='widget-content'>
<data:content/>
</div>
</b:includable>
</b:widget>
</b:section>
Nếu trùng id của widget label hoặc widget HTML bạn thay thành con số khác nhé
Viết css cơ bản giống demo (code chưa responsive và chỉ giống demo, khi bạn áp vào template chắc chắn sẽ bị ảnh hưởng css, bạn tự căn chỉnh sao cho hợp lý)
.search-wrap .widget{float:left}
.search-wrap .Label .list-label-widget-content .droplabel>select{border:1px solid #ddd;padding:5px 10px 4px;font-size:15px;max-width:170px;overflow:hidden;outline:none}
.search-wrap .HTML .hh-search-wrap{position:relative}
.search-wrap .HTML .hh-search-wrap #hh-search{outline:none;border-bottom:1px solid #ddd;border-top:1px solid #ddd;border-left:0;border-right:0;padding:6px 10px 5px;float:left;min-width:250px;font-size:15px;color:#000}
.search-wrap .HTML .hh-search-wrap #hh-search::-webkit-input-placeholder{color:#000}
.search-wrap .HTML .hh-search-wrap #hh-search:-moz-placeholder{color:#000;opacity:1}
.search-wrap .HTML .hh-search-wrap #hh-search::-moz-placeholder{color:#000;opacity:1}
.search-wrap .HTML .hh-search-wrap #hh-search:-ms-input-placeholder{color:#000}
.search-wrap .HTML .hh-search-wrap #hh-search::-ms-input-placeholder{color:#000}
.search-wrap .HTML .hh-search-wrap #hh-search::placeholder{color:#000}
.search-wrap .HTML .hh-search-wrap #hh-submit{outline:none;background:#f1f1f1;border:1px solid #ddd;padding:6px 20px 7px;cursor:pointer}
.search-wrap .HTML .hh-search-wrap #hh-submit:hover{background:#e6e6e6;-webkit-transition:all .3s ease;-moz-transition:all .3s ease;-ms-transition:all .3s ease;-o-transition:all .3s ease;transition:all .3s ease}
.filter-label{display:none;position:absolute;top:100%;padding:15px 15px 0 10px;border-top:0;border:1px solid #eee;left:-1px;width:92%;max-height:350px;overflow:auto}
.filter-label .filter-inner .filter-thumb{clear:both}
.filter-label .filter-inner .filter-thumb img{float:left;width:80px;height:55px;margin:0 12px 15px 0;border-radius:4px}
.filter-label .filter-inner .filter-title a{text-decoration:none;color:#000}
.filter-label .filter-inner .filter-title a:hover{color:#2187e7;-webkit-transition:all .3s ease;-moz-transition:all .3s ease;-ms-transition:all .3s ease;-o-transition:all .3s ease;transition:all .3s ease}
Code js trước thẻ đóng </body>
<script type='text/javascript'>//<![CDATA[
// Dropdown Suggest Search by Hung1001
$('.dropdown-select').on('change', function() {
if (this.value != 0) {
$('.filter-label').show().empty();
$.ajax({
url: '/feeds/posts/default/-/' + this.value,
type: 'GET',
dataType: 'jsonp',
data: {
alt: 'json',
'max-results': 150,
},
}).done(function(e) {
var r = '';
for (var n = 0; n < e.feed.entry.length; n++) {
for (var s = 0; s < e.feed.entry[n].link.length; s++) {
if (e.feed.entry[n].link[s].rel === "alternate") {
t = e.feed.entry[n].link[s].href;
break
}
}
f = e.feed.entry[n].title.$t;
if ("media$thumbnail" in e.feed.entry[n]) {
d = e.feed.entry[n].media$thumbnail.url.replace("s72-c", "s640");
} else {
d = "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXvoeWlnXfuDDxD0LIWf1tODuI3Wti5c3N2v73T19xj9fNAM45q8OWvY4cL-rRcVe0NisWEk9lZ0v4uuDUX4b54sx0uFOgNBRC6Gfoj7nUJaCh-JsZLVa-G-Nt0j5OrQ5vOfcCLsG-HqI/s1600-r/nth.png"
}
r += "<div class='filter-inner'><div class='filter-thumb'><a href='" + t + "'><img src='" + d + "'/></a></div><div class='filter-title'><a title='" + f + "' href='" + t + "'>" + f + "</a></div></div>";
}
$('.filter-label').append(r);
r = "";
})
} else {
$('.filter-label').hide().empty();
}
});
//]]></script>
Về mã xml và js bạn không cần chỉnh sửa, chủ yếu là css sao cho hợp lý với bố cục template của bạn
Về phần tải feed tôi chỉ lấy tối đa 150 bài đầu, như vậy các label có trên 150 bài viết các bài từ 151 trở đi sẽ không được liệt kê vào list suggest. Điều này nếu bạn đọc hết chuyên mục json feed api của tôi chắc sẽ biết xử lý như nào rồi
Cuối cùng bạn lưu mẫu lại và xem kết quả thu được
Như vậy bạn có thể thấy được những ứng dụng rất thực tế và đầy quý tộc mà blogger json feed mang lại, cái chính là ý tưởng ta nghĩ ra để có thể build những tiện ích đẹp độc lạ, mà các blog khác không có
Để lại bình luận nếu bạn gặp khó khăn và chúc thành công !
1. Không vi phạm luật pháp nước CHXHCN Việt Nam
2. Không vi phạm thuần phong mỹ tục Việt Nam
3. Không bàn luận vấn đề liên quan đến tôn giáo, chính trị
4. Không đả kích, chửi bới hay đưa ra những lời nói không phù hợp với mục tiêu của website
5. Không bình luận với mục đích quảng cáo, trao đổi, mua bán
6. Khuyến khích sử dụng Tiếng Việt có dấu, hạn chế sử dụng tiếng lóng, viết tắt
7. Khi cần sự trợ giúp, vui lòng miêu tả chi tiết lỗi và để lại link đính kèm, tránh nói chung chung gây mất thời gian cho đôi bên