Form tìm kiếm nâng cao cực pro từ codyhouse

22/05/2017

Trước đây mình có làm một project sử dụng một form tìm kiếm rất hay mà mình học được từ trang web codyhouse. Với form tìm kiếm này, các bạn có thể vừa hiển thị nội dung , vừa chèn được các link đến những trang cần thiết, đặc biệt là cho phép tìm kiếm từ khóa dựa theo danh mục. Để hiểu rõ hơn về form tìm kiếm này, các bạn chỉ việc xem demo bên dưới là hiểu những gì mà mình giới thiệu nãy giờ.

Form tìm kiếm nâng cao cực pro từ codyhouse

Xem Demo | Download

HTML

Cấu trúc html cho form tìm kiếm này gồm có 3 phần chính : <header>  sẽ là nơi tập trung menu, div.cd-main-search là mẫu form tìm kiếm và main.cd-main-content sẽ là nơi chứa nội dung trang web.

<header class="cd-main-header animate-search">
	<div class="cd-logo"><a href="#0"><img src="img/cd-logo.svg" alt="Logo"></a></div>
 
	<nav class="cd-main-nav-wrapper">
		<a href="#search" class="cd-search-trigger cd-text-replace">Search</a>
		
		<ul class="cd-main-nav">
			<li><a href="#0">Products</a></li>
			<!-- additional navigation items -->
		</ul>
	</nav>
 
	<a href="#0" class="cd-nav-trigger cd-text-replace">Menu<span></span></a>
</header>
 
<main class="cd-main-content">
	<!-- your content here -->
</main>
 
<div id="search" class="cd-main-search">
	<form>
		<input type="search" placeholder="Search...">
 
		<div class="cd-select">
			<span>in</span>
			<select name="select-category">
				<option value="all-categories">all Categories</option>
				<!-- additional options here -->
			</select>
			<span class="selected-value">all Categories</span>
		</div>
	</form>
 
	<div class="cd-search-suggestions">
		<div class="news">
			<h3>News</h3>
			<ul>
				<li>
					<a class="image-wrapper" href="#0"><img src="img/placeholder.png" alt="News image"></a>
					<h4><a class="cd-nowrap" href="#0">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</a></h4>
					<time datetime="2016-01-12">Feb 03, 2016</time>
				</li>
 
				<!-- additional news here -->
			</ul>
		</div> <!-- .news -->
 
		<div class="quick-links">
			<h3>Quick Links</h3>
			<ul>
				<li><a href="#0">Find a store</a></li>
				<!-- additional quick links here -->
			</ul>
		</div>
	</div> <!-- .cd-search-suggestions -->
 
	<a href="#0" class="close cd-text-replace">Close Form</a>
</div> <!-- .cd-main-search -->

CSS

Trong bài viết này, chúng ta sẽ không chỉ đơn thuần áp dụng css cho form tìm kiếm mà còn thêm một chức năng responsive cho menu, khi mà người dùng dùng các thiết bị di động (với kích thước nhỏ hơn 1024px) thì nó sẽ tự động thu nhỏ menu.

.cd-main-header, .cd-main-content {
  position: relative;
  transition: transform 0.3s;
}
.cd-main-header.nav-is-visible, .cd-main-content.nav-is-visible {
  transform: translateX(-260px);
}

Mặc định thì thanh tìm kiếm sẽ được ẩn đi và chỉ được đại diện với icon , khi người dùng click vào icon này, thì lớp .is-visible sẽ được dùng để triệu hồi form.

@media only screen and (min-width: 1024px) {
  .cd-main-search {
    position: absolute;
    z-index: 2;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s, visibility 0.3s;
  }
  .cd-main-search.is-visible {
    /* search form open */
    opacity: 1;
    visibility: visible;
  }
}

Để tạo hiệu ứng động cho form, chúng ta sẽ sử dụng class .animate-search và chèn vào phần tử <header> .

@media only screen and (min-width: 1024px) {
  .animate-search .cd-main-search.is-visible {
    /* trigger search form animation if <header> has the .animate-search class */
    animation: cd-slide-in 0.3s;
  }
  .animate-search .is-visible .cd-search-suggestions {
    /* trigger the dropdown animation if <header> has the .animate-search class */
    transform-origin: center top;
    animation: cd-3d-rotation 0.5s 0.3s;
    animation-fill-mode: backwards;
  }
}
@keyframes cd-slide-in {
  0% {
    transform: translateY(-100%);
  }
  100% {
    transform: translateY(0);
  }
}
 
@keyframes cd-3d-rotation {
  0% {
    transform: perspective(1000px) rotateX(-90deg);
  }
  100% {
    transform: perspective(1000px) translateY(0);
  }
}

Nếu các bạn muốn sử dụng hiệu ứng fade-in , thì chỉ cần loại bỏ class .animate-search trong phần tử <header>. Để đảm bảo độ rộng thay đổi khi chọn lựa các danh mục (category) khác nhau, chúng ta sẽ đặt phần tử <select> ở trạng thái positon: absolute .

@media only screen and (min-width: 1024px) {
  .cd-main-search .cd-select {
    position: absolute;
    right: 0;
    overflow: hidden;
  }
  .cd-main-search select {
    /* the <select> element is not visible - it is covered by the .selected-value element */
    position: absolute;
    right: 0;
    opacity: 0;
    color: transparent;
  }
  .cd-main-search .selected-value {
    color: #ffffff;
    pointer-events: none;
  }
  .cd-main-search select, .cd-main-search .selected-value {
    padding: 0.5em 1.7em 0.5em .3em;
    font-size: 1.4rem;
    border-radius: 3px;
  }
}

Javascript

Việc làm cuối cùng của các bạn là chèn đoạn script bên dưới để điều khiển hiệu ứng.

<script src="js/jquery-2.1.4.js"></script>
<script>
jQuery(document).ready(function($){
	var resizing = false,
		navigationWrapper = $('.cd-main-nav-wrapper'),
		navigation = navigationWrapper.children('.cd-main-nav'),
		searchForm = $('.cd-main-search'),
		pageContent = $('.cd-main-content'),
		searchTrigger = $('.cd-search-trigger'),
		coverLayer = $('.cd-cover-layer'),
		navigationTrigger = $('.cd-nav-trigger'),
		mainHeader = $('.cd-main-header');
	
	function checkWindowWidth() {
		var mq = window.getComputedStyle(mainHeader.get(0), '::before').getPropertyValue('content').replace(/"/g, '').replace(/'/g, "");
		return mq;
	}

	function checkResize() {
		if( !resizing ) {
			resizing = true;
			(!window.requestAnimationFrame) ? setTimeout(moveNavigation, 300) : window.requestAnimationFrame(moveNavigation);
		}
	}

	function moveNavigation(){
  		var screenSize = checkWindowWidth();
        if ( screenSize == 'desktop' && (navigationTrigger.siblings('.cd-main-search').length == 0) ) {
        	//desktop screen - insert navigation and search form inside <header>
        	searchForm.detach().insertBefore(navigationTrigger);
			navigationWrapper.detach().insertBefore(searchForm).find('.cd-serch-wrapper').remove();
		} else if( screenSize == 'mobile' && !(mainHeader.children('.cd-main-nav-wrapper').length == 0)) {
			//mobile screen - move navigation and search form after .cd-main-content element
			navigationWrapper.detach().insertAfter('.cd-main-content');
			var newListItem = $('<li class="cd-serch-wrapper"></li>');
			searchForm.detach().appendTo(newListItem);
			newListItem.appendTo(navigation);
		}

		resizing = false;
	}

	function closeSearchForm() {
		searchTrigger.removeClass('search-form-visible');
		searchForm.removeClass('is-visible');
		coverLayer.removeClass('search-form-visible');
	}

	//add the .no-pointerevents class to the <html> if browser doesn't support pointer-events property
	( !Modernizr.testProp('pointerEvents') ) && $('html').addClass('no-pointerevents');

	//move navigation and search form elements according to window width
	moveNavigation();
	$(window).on('resize', checkResize);

	//mobile version - open/close navigation
	navigationTrigger.on('click', function(event){
		event.preventDefault();
		mainHeader.add(navigation).add(pageContent).toggleClass('nav-is-visible');
	});

	searchTrigger.on('click', function(event){
		event.preventDefault();
		if( searchTrigger.hasClass('search-form-visible') ) {
			searchForm.find('form').submit();
		} else {
			searchTrigger.addClass('search-form-visible');
			coverLayer.addClass('search-form-visible');
			searchForm.addClass('is-visible').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
				searchForm.find('input[type="search"]').focus().end().off('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend');
			});
		}
	});

	//close search form
	searchForm.on('click', '.close', function(){
		closeSearchForm();
	});

	coverLayer.on('click', function(){
		closeSearchForm();
	});
	
	$(document).keyup(function(event){
		if( event.which=='27' ) closeSearchForm();
	});

	//upadate span.selected-value text when user selects a new option
	searchForm.on('change', 'select', function(){
		searchForm.find('.selected-value').text($(this).children('option:selected').text());
	});
});
</script>

Các bạn nên download demo về máy để tìm hiểu kỹ hơn, chúc các bạn thực hiện thành công !

Chuyên Mục: ,

Bài viết được đăng bởi webmaster

Nếu các bạn thấy bài viết hữu ích thì giúp mình Like cái nhé !