Thursday, December 29, 2011

Chèn Chabox Gtalk vào BlogSpot.

Nếu site bạn rất nhiều bạn bè có tài khoản Google, tại sao không thử chèn thêm một ChatBox để tăng tình năng trò chuyện kết bạn cho Blog. Việc đơn giản phải làm là bạn chỉ cần nhúng một iframe của Google cho sẵn.





Xem DEMO


Các bạn coppy và cài đặt nhé. Và nhớ chỉnh lại CSS. của mình.


<style>
    #chat{position:fixed; top:0px; left:1px;}
    .bt{background:url('http://cdn1.iconfinder.com/data/icons/androiddevicons/dialog.png') no-repeat; width: 48px; height: 48px;}
    #cbody{border-radius: 3px 10px 0px #444;}
</style>
<div id="chat">
<div class="bt" onclick="toggle()" ></div>
<p id="cbody" style="display:none;">
    <iframe height="350" frameborder="0" width="300" src="http://talkgadget.google.com/talkgadget/client?fid=gtalk0&amp;relay=http%3A%2F%2Fwww.google.com%2Fig%2Fifpc_relay"></iframe>
</p>
</div>
<script>
    var $_ = function(x){return document.getElementById(x);}
   
    function toggle(){
    var ck = $_("cbody").style.display;
        if(ck != "none"){
            $_("cbody").style.display = "none";
        }
        if(ck != "block"){
            $_("cbody").style.display = "block";
        }
    }
</script>


Chúc bạn thành công !

[Thông báo] V/v VNPT chặn BlogSpot.

Chia buồn với cộng đồng Blogger tại Việt Nam. VNPT chính thức đưa BlogSpot vào danh sách đen của mình.... Được biết thì họ không chặn luôn trang blogspot.com mà chặn các subdomain là *.blogspot.com.

Do vậy khi vào fandung load lâu không có gì là lạ. Trên site chưa rất nhiều backlink domain *.blogspot.com


Bá đạo !


Ảnh hưởng tới các domain sau:


*.googleusercontent.com - Nghĩa là khỏi dịch, khỏi xem cache Google luôn.
  (P/s : Hiện tại VNPT đã thả Google Translate).

Picasa cũng dạng *.googleusercontent.com nên chịu chung số phận.
  (P/s : Có lẽ cũng sẽ được thả sớm).

Thêm thông tin là IP của *.blogspot.com và *.googleusercontent.com đều là 74.125.71.132. Vậy là các bạn đã hiểu tại sao cả Blogspot và Google Dịch, Google Cache đều không vào được rồi đấy.






Chung số phận với facebook, blogger.com chính thực lĩnh án chung thân.

Mình theo dõi và phỏng đoán, nguyên nhân về việc chặn subdomain blogspot.com do hiện tại rất nhiều web đen chưa nội dung xấu (xxx, phản động...). Đã được đưa vào tầm ngắm của bộ thông tin. Không lâu nữa, rất có thể em Google + của chúng ta sẽ tiếp tục lên đường vào thăm anh Luyện.


Cộng đồng nghĩ gì, bạn hãy đọc:



http://www.phamen.com/bloggerr-wordpress-tai-sao-vnpt/

Các site có domain riêng không bị chặn là bới dùng faceIP. Do vậy hiện tại để vào được BlogSpot sẽ có 2 cách khắc phục sau.

1. Sử dụng domain riêng...

2. Hướng dẫn bạn bè dùng faceIp ngay trên máy. (cách này sẽ giúp các admin đi ngủ sớm hơn, vì blogger cũng không mặn mà cho lắm với nhiều người xem :| )



Cách này có vẻ không hiệu quả.

==> Dùng UltraSuft

==> BlOg... " Bỗng dưng bị ấy...!!! " - Blogspot bị chăn, khắc phục sao???    (Anh Dũng viết =)) )

Khung giờ bị chặn bắt đầu từ 0h = > 6h sáng. Mình không rõ có phải là 6h sáng không. Bây giờ thì vui rồi. Facebook thì chặn cả ngày, tối mở. Blogger chặn cả đêm ngày mở. :(( Hết cả các sân chơi thật rồi..




Chưa có danh sách chình thức, nhưng thế này cũng đủ hiểu.

Kết luận lại vụ việc này sẽ làm nhiều người buồn hơn bao giờ hết. Nhưng nếu để cái văn hoá phản động ngấm vào thân còn buồn hơn...Mình bắt đầu ghét chúng rồi đấy.


P/s: Anh em sử dụng VNPT để lại comments  cho biết thêm khu vực nhé. Để mọi người biết được khu vực nào không bị dính vào thảm sát.

Jquery Slider Tin Tức - News Slider


Hẳn nhiều bạn cần slide này... mình đã phát triển phiên bản thumbail cho site phim. Nhưng gà CSS quá nên đắp chiếu, lấy silder của trang tin tức này cho các bạn dùng.



Nói về jquery thì mình cũng chả rành lắm, đến từ jquery viết còn hay nhầm thì các bạn chắc cũng đoán được. Phần slider rip của gostep.info, các bạn có thể vào đó xem.

Xem DEMO

Mình cũng hơi buồn ngủ, các bạn setup luôn nhé.


CSS (Cái này cũng gà lắm, mọi người tự căn chỉnh nhé !)

<style>
ul#ticker {
    font: "Helvetica,Arial";
    height: 26px;
    overflow: hidden;
    text-align: right;
    color: red;
    font-size: 12px;
    line-height: 28px;
    background: #444;
}
ul#ticker strong,ul#ticker strong a {
    color: green;
    font-size: 10px;
    padding-right: 5px;
    text-transform: uppercase;
}
#ticker a {
    text-decoration: none;
}
ul#ticker a {
    color: white;
    text-decoration: none;
}
ul, li {
    list-style: none outside none;
}
ul#ticker .meta-comments a,.meta-sep,.meta-date{
    color: #777777;
}
</style>


Javascript

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="http://anhnc.googlecode.com/svn/trunk/p/news.js"></script>
<script src="/feeds/posts/default?max-results=12&amp;orderby=published&amp;alt=json-in-script&amp;callback=news"></script>


Phần numberposts (12) có thể unlimit nhé ;))

Chúc các bạn thành công !

THAO TÁC DỮ LIỆU TRONG ASP.NET BẰNG WEB SERVICE

1. Tạo một dự án ASP.NET EMPTY WEB APPLICATION
2. Bổ sung một Item là WebForm, đặt tên là Default.aspx
3. Bổ sung một Item là Web service


Giả sử, ta đặt tên cho nó là MyWebService.asmx.
4. Mặt định, file MyWebService.asmx.cs có dạng như sau:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace MyWebServices
{
///
/// Summary description for MyWebService
///

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class MyWebService : System.Web.Services.WebService
{

[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
}
}
5. Tạo mới một lớp MyConnection
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;

namespace MyWebServices
{
public class MyConnection
{
private SqlConnection con;
private SqlCommand command;

public MyConnection()
{
con = new SqlConnection();
con.ConnectionString = "Data Source=localhost;Initial Catalog=DoAnVB;Persist Security Info=True;User ID=sa;Password=123";
command = new SqlCommand();
command.Connection = con;
con.Open();
}

public SqlDataReader ExecMyQuery(string s)
{
command.CommandType = System.Data.CommandType.Text;
command.CommandText = s;
return command.ExecuteReader();
}
}
}
Cần lưu ý chỉnh lại connectionstring cho phù hợp. Database có tên là DoAnVB, trong đó có một bảng tbl_Khoa(idKhoa int, tenkhoa nvarchar(50)).
6. Xóa phương thức Hello World trong MyWebService.asmx.cs và bổ sung thêm hai phương thức mới:
[WebMethod]
public SqlDataReader GetAllKhoa()
{
return (new MyConnection()).ExecMyQuery("select * from tbl_khoa;");
}

[WebMethod]
public void InsertToKhoa(string tenkhoa)
{
(new MyConnection()).ExecMyQuery("insert into tbl_khoa(tenkhoa) values(N'" + tenkhoa + "')");
}
7. Thiết kế trang Default.aspx như sau:
Lưu ý: Tất cả nội dung này được đặt trong một UpdatePanel và có sử dụng ScriptManager. Trong trang asp.net này, ngoài hai thành phần nói trên, còn có: textbox (tên là txtKhoa); button (tên btKhoa) và một Gridview (tên là dgvData).
8. Bổ sung phương thức sau vào trong Default.aspx.cs
private void UpdatePage()
{
MyWebService ws = new MyWebService();
SqlDataReader reader = ws.GetAllKhoa();
dgvData.DataSource = reader;
dgvData.DataBind();
}
9. Bổ sung đoạn mã sau cho sự kiện Page_Load
protected void Page_Load(object sender, EventArgs e)
{
UpdatePage();
}
10. Bổ sung đoạn mã sau cho sự kiện Click của button
protected void btKhoa_Click(object sender, EventArgs e)
{
MyWebService ws = new MyWebService();
ws.InsertToKhoa(txtKhoa.Text);
UpdatePage();
}

Cuối cùng, test thử chương trình làm việc với Database thông qua web service.

Wednesday, December 28, 2011

From collaborator hell to dependency-free bliss

Let's say you're a developer on a C# app and just got a batch of new requirements. Let's also say that it has a fairly simple requirement: when a user closes his or her account, the account status should be set to closed. You, as a good Test Driven Developer, write your unit test, watch it fail, then add the following code to the Account class and watch your test pass:

public void Close() {
this.Status = AccountStatus.Closed;
}

Easy-peasy.

Many weeks later you come across a requirement that says when a user closes his or her account, the account owner's IsSpecial flag should be set. To make your latest unit test pass, you do the simplest thing that could possibly work.

public void Close() {
this.Status = Status.Closed;
this.Owner.IsSpecial = true;
}

Your test went from Red to Green and now it's time to Refactor. Having your Account mutate some value on another object breaks encapsulation so you Control+R & E to Extract Method then Control+R & M to Move your method to the Owner class and give it a clear name.

public void Close() {
this.Status = Status.Closed;
this.Owner.ClosedAccount(this);
}

That's a little better. In stead of just setting some property you're now telling the other object that something happened. It's free to handle that how it wants and the Account needn't know about it - a textbook case of encapsulation and The Hollywood Principle.

You've worked in this domain long enough to know that all kinds of things are going to happen when an account is closed. Maybe the other things should be moved to a different method? Not entirely YAGNI, but modifying the account and telling others about it are two different things so you could make the argument that they should be two separate methods.

public void Close() {
this.Status = Status.Closed;
this.OnClosed();
}

private void OnClosed(){
this.Owner.ClosedAccount(this);
}

It's a judgment call but this does clearly separate things. There's one method where the account modifies itself and another where all the other objects get to react to the account being updated. You know that if you have requirements that start with when an account is closed, then the code that deals with the account should go in the Close method and code that deals with other classes goes in the OnClosed method. But wait a second - doesn't this sound familiar? There's even something built into the C# language for just this scenario: events and delegates.

public delegate void ClosedEventHandler(object sender, AccountClosedEventArgs e);

public class Account {
public event ClosedEventHandler Closed;

public void Close() {
this.Status = Status.Closed;

if (this.Closed != null)
this.Closed(this, new AccountClosedEventArgs(this));
}
}

Now the owner can register a callback with the account's Closed event and the account can just tell whoever's listening when it has closed. The Account class no longer needs to reference the Owner class and we can rejoice.

But something about this still doesn't quite seem right. Now instead of the Account telling the Owner, the Owner has to listen to the Account. You still have one class directly referencing and depending on another - you just switched the dependency direction. A day or two later you remember you once read something about Messaging and Domain Events so you look it up and get that started.

public void Close() {
this.Status = Status.Closed;
EventBus.Publish(new AccountClosed(this));
}


/* ... elsewhere ... */
public class AccountClosed{
public Account Account { get; set; }

public AccountClosed(Account account){
this.account = account;
}
}


/* ... elsewhere ... */
class AccountEventsHandler {

private IRepository repository;

public AccountEventsHandler(IRepository repository){
this.repository = repository;
}

public void Handle(AccountClosed e){
this.repository.GetOwner(e.Account).IsSpecial = true;
}
}


/* ... elsewhere ... */
public void WireEverythingTogether(IRepository repository){
var accountHandler = new AccountEventsHandler(repository);
EventBus.Subscribe<AccountClosed>(accountHandler.Handle);
}

Much nicer. Not only is the dependency completely removed from the Account and Owner classes, but each class no longer exposes methods that are just used for reacting to each other. The Account only modifies itself and creates events and the Owner only modifies itself and creates events. Now you have the Account depend on the EventBus and somewhere else you subscribe other classes to the appropriate events. You have a simple AccountEventsHandler that deals with coordinating other objects when the account changes so the domain objects themselves don't need to. It can be little bit more work, but it does reduce coupling and allow much cleaner domain objects. But the Account is still referencing the EventBus directly. You could use a service locator:

public void Close() {
this.Status = Status.Closed;
Services.Get<IEventBus>().Publish(new AccountClosed(this));
}

But the service locator can cause problems - like if an IEventBus wasn't registered - and is considered an anti-pattern by some people. You could use constructor injection to pass in the dependency instead.

public Account(IEventBus bus){
this.eventBus = bus;
}

public void Close() {
this.Status = Status.Closed;
this.eventBus.Publish(new AccountClosed(this));
}

That's clean and a good use of the Dependency Inversion Principle, but maybe overkill since the EventBus is so simple and ubiquitous. Maybe hard coding a such a simple dependency is ok. In my limited experience this is an acceptable time for bending the rules and relying on a statefull static class. You will probably never hear me say that again since I hate working with static classes and singletons that have state or complex behavior. On the other hand, constructor injection is a great first step to using a Dependency Injection Container to wire up the EventBus and other dependencies.

Maybe months from now you can switch to actual full-scale event sourcing and CQRS. With command handlers, the Domain Objects create events and store them locally. Then the command handler would fetch all the events from the domain objects and pass them to the event bus; your domain objects don't even need to know about the event bus anymore since the command handler deals with that.



This series of slightly different ways of dealing with different objects involved in the same action is something that I've had a lot of problems with. It's all the same basic result but the important difference is in how to deal with coordinating different objects when something happens. These different designs have very different benefits and costs. The earlier examples are easy for anyone to do, easy to see exactly what happens when debugging or looking at the code, and you know exactly where to make the change: right in the method itself. The downside is that it becomes collaborator hell and all your classes quickly become so bloated that most of the class's code is actually about other classes. The classes become so interdependent that you can't change one thing without having to change everything else. Having lots of dependencies like this can also make build times suffer too. The latter examples only rely on the Event Bus, Service Locator, or Inversion Of Control Container so they are as non-dependent as possible but I can't really tell what's going to happen when the program runs. If everything is wired together with configuration in xml files or sql tables then it can also become exceedingly tedious and error prone to change. This kind of configuration becomes especially difficult if the developer's environment, qa environments, and production environments can all be configured differently. Not everyone will be familiar with or even like the event-based designs either. The whole thing is made even more confusing if different sections of the project have different ways of doing things and people mostly just do whatever they copied and pasted from - not that I've ever done that of course....

Sunday, December 25, 2011

Quà tặng âm nhạc cho BlogSpot

Hehe, gần tết rồi.. thêm không khí cho cho Blog của bạn chút nhỉ. Hôm nay giới thiệu với các bạn một Plugin mới. Quà tặng âm nhạc, điều không tưởng phải không, chỉ có ở các 4rum. Nhờ có load feed comment của anh Dũng, mình mới dám nghĩ đến tạo ra cái gì đó mới lại từ tiện ịch này.


Lâu nay ẩn danh cũng vì đang làm đồ án, rảnh tay mới code được.



Mình cũng không rành lắm CSS, vậy nên mình chỉ viết js thôi. Các bạn code theo phong cách riêng của mình nhé, mới làm hiện bài hát đầu tiên. Có thêm thời gian mới tạo được thêm 2 cái nút tiến lùi, chắc cũng trước tết thôi. ^^! Chờ nhé.

Nhaccuatui.com

Mp3.zing.vn

Nhacso.net

Music.soha.vn

Nhac.vui.vn

Zippshare và *.mp3
Tha hồ chọn lựa skin ;))

Để sử dụng tiện ích, các bạn tạo một trang mới hoặc một bài mới. Tạo một widget HTML mới, dán code sau vào.

CSS

<style type="text/css">
#tomusic{border:1px dashed #444; padding: 5px; width: 680px;}
#avmusic img{padding: 1px; width: 120px;}
#avmusic a{position: relative; left:0px; bottom:-px;}
#anc_chuc{width:90%; height: 95px; float: right;}
.process{
    background: url("http://dl.dropbox.com/u/52283085/47/sr.gif") no-repeat scroll right top transparent;
    color: #EDE7C2;
    display: block;
    float: left;
    font-size: 13px;
    height: 33px;
    margin-left: -13px !important;
    margin-top: 80px;
    padding-right: 9px;
    position: absolute;
    text-shadow: 1px 1px 1px #131212;
    z-index: 100;
}
.process a{text-decoration:none; color: #888888;}
.process span {
    background: url("http://dl.dropbox.com/u/52283085/47/gc.png") no-repeat scroll 0 0 transparent !important;
    float: left;
    height: 33px;
    padding: 5px 0 0 8px;
}
</style>


JavaScript

<script type="text/javascript">
var cm_desc = 50; // Để 50 chắc là đủ (sô ký tự hiển thị)
var homepage = "domain";
postID = "id_bai_qua_tang_am_nhac";

var cm_ava = new Array();
cm_ava['openid'] = "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglwfS56bSi4PxbWlXa4R1NMMMAbK8EXrVcme6_SJExD1p7pMJUba8cssnVyGd-H64UBaMDunjr4fCP58DbewBgvZpxDMkzAFk_ceqqf18nokXRqxno434P_c6oRVEVPd8WF6zitMSe4nlp/";
cm_ava['livej'] = "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZ6Q1z3gZweBBXc754BfXH3qeFZBl7vGdzgkbQxmnnZrKiugOpP-Tyt2lkzjsbo0dk_OZlK4XCePR57pRY45wKtAxPV_Ksb1eWqLPxjqJfKDIsTVr5dL46cfPuGQdtnOOi-IujLHfTXd06/";
cm_ava['wp'] = "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjgpvh7T336UmVU-TVEjUeUW-s9wAUPL16hnthYPXrT-RcGYNNSGyO9qS_I1ZeqYBYW4vde-NXuNaSHypzuIHq7C1vpyr4qFF9YfYj3AOOMp1L_fkieLevazCFACDFdWMUFBosKrvSQvF8/";
cm_ava['typepad'] = "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZab1IZ49XM4z5aTvxmO8S1zTBXiGZDMNIfGyauh_2RaA7-z91s1EEwiGYAgubbzwaM5RACiszQ1IMCqBmQ_Y7A52wW4LH_MIXJtnDY0k0kpU7ovtRg-ukqiuOkOEOvxb7ELU2K0Zda1D2/";
cm_ava['aim'] = "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOo2yfP5TFivG4aGBmaLBmYPsfh46Q_Fca5Z7WbzHeFeWXBUIUKR3qRwr2QJDrNwxQG_j3B8zAVoMhg1Bl9OmGmJpZtK2o-kYc_fE126N-CjwlX3NitZmqnA7x_rOMptupIswdqHivL8cR/";
cm_ava['url'] = "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiARO8SAGksEbrrX0HeyCGECwHsbRBDqcIy-L-gYE-2xFgMQMnS3Guxk_b6ZYZ-pi-KHGwpQfCKrc03OPe1mwmRk6cz1vdj_69Yv6fMIqQUZPRFiKP_-WNvjbuKcfQZSVMtmMwhztB-Z_dk/";
cm_ava['anon'] = "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaBZdFVx1wGSeIkCHZrH95dIqRwjGd4Bl045cfUM_q_1BBp57Z1cDReSvlBWfNXNrSIue4oY-LUcMGZEGqX_OGjO4MHASqDEWXVtyu9OgDUqn79t2QVX3i5WZ8E2tHeCEeNSBvQuAyL5Zx/";

</script>
<script src="http://anhnc.googlecode.com/svn/trunk/p/qtan.js" type="text/javascript"></script>
<script>
M.p(M.r());
</script>

File js này các bạn hãy edit lại nhé. Mình làm cho nó giống cấu trúc site mình thôi.

http://anhnc.googlecode.com/svn/trunk/p/qtan.js

Cấu trúc gửi bài hát như sau:

[m]link bài hát|nguoi_nhan|Lời muốn nói[/m]

Chúc mọi người thành công !

Làm việc với ADO.NET Entity


Bước 1. Tạo một dự án trong Visual Studio: có thể là dự án ASP.NET hoặc WinForm.
Bước 2. Kích chuột phải vào dự án và chọn Add > New Items > ADO.NET Entity Data Model

Bước 3. Đặt tên và Nhấp Next



Bước 4. Chọn Generate from Database > Next.

Bước 5. Tạo một kết nối bằng cách nhấp vào New Connection và cấu hình:

Server name: server lưu trữ dữ liệu. Ví dụ: chọn localhost
Use SQL Server Authentication: login vào dữ liệu bằng tài khoản được cấp. Ví dụ: username=sa; password=123.
Select or Enter a Database name: nhập tên database cần làm việc.
Sau đó, nhấp Test Connection để kiểm tra. Nếu thông báo:

Thì đã thành công. Chuyển sang bước tiếp theo.
Bước 6. Chọn các bảng dữ liệu trong Database

Bước 7. Nhấp Finish. Khi đó, các thực thể sẽ được khởi tạo. Ví dụ, trong trường hợp này, tôi có các thực thể: DoAnVBEntities. Mã sau đây do VS sinh tự động:

//------------------------------------------------------------------------------ 
  //  <auto-generated>
  //    This code was generated from a template.
  //
  //    Manual changes to this file may cause  unexpected behavior in your application.
  //    Manual changes to this file will be  overwritten if the code is regenerated.
  //  </auto-generated>
  //------------------------------------------------------------------------------ using System;
  using System.Data.Objects;
  using System.Data.Objects.DataClasses;
  using System.Data.EntityClient;
  using System.ComponentModel;
  using System.Xml.Serialization;
  using System.Runtime.Serialization;

[assembly: EdmSchemaAttribute()]

namespace EntityModel
  {
  #region Contexts
 
  /// <summary>
  /// No Metadata Documentation available.
  /// </summary>
  public partial class DoAnVBEntities : ObjectContext
  {
  #region Constructors
 
  /// <summary>
  /// Initializes a new DoAnVBEntities object using the  connection string found in the 'DoAnVBEntities' section of the application  configuration file.
  /// </summary>
  public  DoAnVBEntities() : base("name=DoAnVBEntities", "DoAnVBEntities")
  {
  this.ContextOptions.LazyLoadingEnabled  = true;
  OnContextCreated();
  }
 
  /// <summary>
  /// Initialize a new DoAnVBEntities object.
  /// </summary>
  public  DoAnVBEntities(string connectionString) : base(connectionString, "DoAnVBEntities")
  {
  this.ContextOptions.LazyLoadingEnabled  = true;
  OnContextCreated();
  }
 
  /// <summary>
  /// Initialize a new DoAnVBEntities object.
  /// </summary>
  public  DoAnVBEntities(EntityConnection connection)  : base(connection, "DoAnVBEntities")
  {
  this.ContextOptions.LazyLoadingEnabled  = true;
  OnContextCreated();
  }
 
  #endregion
 
  #region Partial Methods
 
  partial  void OnContextCreated();
 
  #endregion
 
  #region ObjectSet Properties
 
  /// <summary>
  /// No Metadata Documentation available.
  /// </summary>
  public ObjectSet<tbl_Khoa>  tbl_Khoa
  {
  get
  {
  if  ((_tbl_Khoa == null))
  {
  _tbl_Khoa = base.CreateObjectSet<tbl_Khoa>("tbl_Khoa");
  }
  return  _tbl_Khoa;
  }
  }
  private  ObjectSet<tbl_Khoa>  _tbl_Khoa;
 
  /// <summary>
  /// No Metadata Documentation available.
  /// </summary>
  public ObjectSet<tbl_lop>  tbl_lop
  {
  get
  {
  if  ((_tbl_lop == null))
  {
  _tbl_lop = base.CreateObjectSet<tbl_lop>("tbl_lop");
  }
  return  _tbl_lop;
  }
  }
  private  ObjectSet<tbl_lop>  _tbl_lop;

       #endregion
  #region AddTo  Methods
 
  /// <summary>
  /// Deprecated Method for adding a new object to the tbl_Khoa  EntitySet. Consider using the .Add method of the associated  ObjectSet&lt;T&gt; property instead.
  /// </summary>
  public void AddTotbl_Khoa(tbl_Khoa  tbl_Khoa)
  {
  base.AddObject("tbl_Khoa", tbl_Khoa);
  }
 
  /// <summary>
  /// Deprecated Method for adding a new object to the tbl_lop  EntitySet. Consider using the .Add method of the associated  ObjectSet&lt;T&gt; property instead.
  /// </summary>
  public void AddTotbl_lop(tbl_lop  tbl_lop)
  {
  base.AddObject("tbl_lop", tbl_lop);
  }

       #endregion
  }

   #endregion
 
  #region Entities
 
  /// <summary>
  /// No Metadata Documentation available.
  /// </summary>
  [EdmEntityTypeAttribute(NamespaceName="DoAnVBModel", Name="tbl_Khoa")]
  [Serializable()]
  [DataContractAttribute(IsReference=true)]
  public partial class tbl_Khoa : EntityObject
  {
  #region Factory Method
 
  /// <summary>
  /// Create a new tbl_Khoa object.
  /// </summary>
  /// <param  name="idKhoa">Initial value of  the idKhoa property.</param>
  /// <param  name="tenKhoa">Initial value of  the TenKhoa property.</param>
  public static tbl_Khoa  Createtbl_Khoa(global::System.Int32 idKhoa, global::System.String tenKhoa)
  {
  tbl_Khoa  tbl_Khoa = new tbl_Khoa();
  tbl_Khoa.idKhoa = idKhoa;
  tbl_Khoa.TenKhoa = tenKhoa;
  return  tbl_Khoa;
  }

       #endregion
  #region Primitive Properties
 
  /// <summary>
  /// No Metadata Documentation available.
  /// </summary>
  [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
  [DataMemberAttribute()]
  public global::System.Int32  idKhoa
  {
  get
  {
  return  _idKhoa;
  }
  set
  {
  if  (_idKhoa != value)
  {
  OnidKhoaChanging(value);
  ReportPropertyChanging("idKhoa");
  _idKhoa = StructuralObject.SetValidValue(value);
  ReportPropertyChanged("idKhoa");
  OnidKhoaChanged();
  }
  }
  }
  private  global::System.Int32  _idKhoa;
  partial  void OnidKhoaChanging(global::System.Int32 value);
  partial  void OnidKhoaChanged();
 
  /// <summary>
  /// No Metadata Documentation available.
  /// </summary>
  [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
  [DataMemberAttribute()]
  public global::System.String  TenKhoa
  {
  get
  {
  return  _TenKhoa;
  }
  set
  {
  OnTenKhoaChanging(value);
  ReportPropertyChanging("TenKhoa");
  _TenKhoa = StructuralObject.SetValidValue(value, false);
  ReportPropertyChanged("TenKhoa");
  OnTenKhoaChanged();
  }
  }
  private  global::System.String  _TenKhoa;
  partial  void OnTenKhoaChanging(global::System.String value);
  partial  void OnTenKhoaChanged();

       #endregion
 
  }
 
  /// <summary>
  /// No Metadata Documentation available.
  /// </summary>
  [EdmEntityTypeAttribute(NamespaceName="DoAnVBModel", Name="tbl_lop")]
  [Serializable()]
  [DataContractAttribute(IsReference=true)]
  public partial class tbl_lop : EntityObject
  {
  #region Factory Method
 
  /// <summary>
  /// Create a new tbl_lop object.
  /// </summary>
  /// <param  name="malop">Initial value of the  malop property.</param>
  /// <param  name="makhoa">Initial value of  the makhoa property.</param>
  public static tbl_lop  Createtbl_lop(global::System.Int32 malop, global::System.Int32 makhoa)
  {
  tbl_lop  tbl_lop = new tbl_lop();
  tbl_lop.malop = malop;
  tbl_lop.makhoa = makhoa;
  return  tbl_lop;
  }

       #endregion
  #region Primitive Properties
 
  /// <summary>
  /// No Metadata Documentation available.
  /// </summary>
  [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
  [DataMemberAttribute()]
  public global::System.Int32  malop
  {
  get
  {
  return  _malop;
  }
  set
  {
  if  (_malop != value)
  {
  OnmalopChanging(value);
  ReportPropertyChanging("malop");
  _malop = StructuralObject.SetValidValue(value);
  ReportPropertyChanged("malop");
  OnmalopChanged();
  }
  }
  }
  private  global::System.Int32  _malop;
  partial  void OnmalopChanging(global::System.Int32 value);
  partial  void OnmalopChanged();
 
  /// <summary>
  /// No Metadata Documentation available.
  /// </summary>
  [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
  [DataMemberAttribute()]
  public global::System.Int32  makhoa
  {
  get
  {
  return  _makhoa;
  }
  set
  {
  if  (_makhoa != value)
  {
  OnmakhoaChanging(value);
  ReportPropertyChanging("makhoa");
  _makhoa = StructuralObject.SetValidValue(value);
  ReportPropertyChanged("makhoa");
  OnmakhoaChanged();
  }
  }
  }
  private  global::System.Int32  _makhoa;
  partial  void OnmakhoaChanging(global::System.Int32 value);
  partial  void OnmakhoaChanged();
 
  /// <summary>
  /// No Metadata Documentation available.
  /// </summary>
  [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
  [DataMemberAttribute()]
  public global::System.String  tenlop
  {
  get
  {
  return  _tenlop;
  }
  set
  {
  OntenlopChanging(value);
  ReportPropertyChanging("tenlop");
  _tenlop = StructuralObject.SetValidValue(value, true);
  ReportPropertyChanged("tenlop");
  OntenlopChanged();
  }
  }
  private  global::System.String  _tenlop;
  partial  void OntenlopChanging(global::System.String value);
  partial  void OntenlopChanged();

       #endregion
 
  }

   #endregion
 
  }
Bước 8. Thiết kế một Form như sau:
Trong đó:
                ListBox có tên là lbKhoa;
                ComboBox có tên là cbKhoa;
                Hai TextBox có tên là: txtTenKhoaMoi và txtKhoa;
                Các nút “Xem Khoa”, “Đổi Tên”, “Xóa” và “Thêm Khoa” lần lượt có tên là btXemKhoa, btUpdate, btXoa, btThem.
Bước 9. Ta thực thi các truy vấn tương ứng với Select, Update, Insert và Delete.
Phương thức
Giải thích
Select
Tạo một đối tượng DoAnVBEntities, sau đó sử dụng thuộc tính tbl_Khoa
Insert
Tạo một đối tượng DoAnVBEntities, sau đó sử dụng phương thức AddTotbl_Khoa.
Tham số trong trường hợp này là một thực thể Khoa, do đó, ta sử dụng phương thưc tĩnh Createtbl_Khoa của đối tượng tbl_Khoa.
Kết thúc việc thêm dữ liệu, ta triệu gọi phương thức SaveChanges.
Update và Delete
Ta làm hoàn toàn tương tự, nhưng lưu ý để chọn được đối tượng cần update hay delete, ta cần sử dụng LINQ để xử lý.
Đây là mã nguôn của chương trình minh họa:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace EntityModel
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//Liệt kê đối tượng select
private void btShow_Click(object sender, EventArgs e)
{
DoAnVBEntities vb = new DoAnVBEntities();
lbKhoa.DataSource = vb.tbl_Khoa;
lbKhoa.DisplayMember = "TenKhoa";
}
//Thêm đối tượng Insert
private void btThem_Click(object sender, EventArgs e)
{
DoAnVBEntities vb = new DoAnVBEntities();
vb.AddTotbl_Khoa(tbl_Khoa.Createtbl_Khoa(0, txtKhoa.Text));
vb.SaveChanges();
Form1_Load(null, null);
btShow_Click(null, null);
}

private void Form1_Load(object sender, EventArgs e)
{
DoAnVBEntities vb = new DoAnVBEntities();
cbKhoa.DataSource = vb.tbl_Khoa;
cbKhoa.DisplayMember = "tenkhoa";
btShow_Click(null, null);
}

//Update thông tin đối tượng
private void btUpdate_Click(object sender, EventArgs e)
{
DoAnVBEntities vb = new DoAnVBEntities();
var khoa = (from d in vb.tbl_Khoa
where d.TenKhoa == cbKhoa.Text
select d).First();
khoa.TenKhoa = txtTenKhoaMoi.Text;
vb.SaveChanges();
Form1_Load(null, null);
}

//Xóa đối tượng
private void btXoa_Click(object sender, EventArgs e)
{
DoAnVBEntities vb = new DoAnVBEntities();
var khoa = (from d in vb.tbl_Khoa
where d.TenKhoa == cbKhoa.Text
select d).First();
vb.DeleteObject(khoa);
vb.SaveChanges();
Form1_Load(null, null);
}
}
}
Chương trình khi thực thi:

Friday, December 23, 2011

Tiện ích Top Commentators cho blogspot

Tiện ích Top Commentators cho phép hiển thị những đọc giả có lượng comment nhiều nhất. Hiện tại có 1 số blog đã có tiện ích này nhưng họ đã mã hóa code và không chia sẻ, đối với 1 số bạn không rành về javacript sẽ không đọc được các đoạn mã này. Hôm nay nhân tiện có người hỏi về thủ thuật này nên mình cũng xin chia sẻ để mọi người dùng.


Một vài thông tin của tiện ích :
- Không đếm comment của khách nặc danh.
- Chỉ thống kê được tối đa trong 200 comment mới nhất.
- Hiện thị ảnh đại diện (tất cả các author ngoại trừ nặc danh).
- Hiện thị số comment của từng người.

Xem DEMO

Hình ảnh minh họa

Để thực hiện các bạn chỉ việc tạo 1 widget HTML/javascript ở nơi muốn hiển thị rồi dán đoạn code bên dưới vào là được:
<style type="text/css">
.top-author ul li {
list-style:none;
width:250px;
height:45px!important;
border-bottom:1px solid #ccc;
margin-top:5px;
display:block!important;
}
.tau-cont {margin-left:38px;}
.tau-cont h4 {margin:0;padding:0;}
.tau-cont span {color:#555;}
img.tau-thumb {
float: left;
margin-right: 10px;
border: 1px solid #CCC;
padding: 0;
width: 36px;
height: 36px;
}
</style>

<script type="text/javascript">
var no_photo='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwwsYQOhDTEr_TzV1r3Q3DIzk4Eyy-HfgKkV2xSKhkc2bKZDj63kxGBWzfzF_0QozUykF-lvLKMC5QIEq4Vb_y2mJoSFCH0bTM1R0DB3XH2tSn8oAFRac3ugU5DzS1WJhKZ3D9MlqcVGYj/s50/blogger-nophoto.png';
var another_au='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhszOkPkfCw-eemC87jC2HgR0qB98_sEFQVAEHnd4NJFHjjQi9nKZnffETulit55E0Tbbm0JyySagHTuPrKFCNh9iRGLlENhyphenhyphenIlCQCpYsTor7MjZKOzBq6k4wr5_2SIzOj8wUUy3xL_eTwj/s23/another-ico.png';
var au_nums=5;
var rcm_nums=100;
var homepage="http://www.fandung.com";
</script>
<div class="top-author">
<script type="text/javascript" src="http://fandung.googlecode.com/svn/trunk/js/top-author.js"></script>
</div>
Một vài lưu ý :
- var no_photo : avatar của tài khoản blogger chưa có ảnh đại diện.
- var another_au : avatar của tài khoản khác blogger.
- var au_nums=5; số tác giả được hiển thị
- var rcm_nums=100; số comment sẽ được khoanh vùng để thống kê (phải nhỏ hơn hoặc bẳng 200)
- var homepage="http://www.fandung.com"; thay http://www.fandung.com bằng tên miền của blog bạn.

Chúc các bạn thành công.

Thực hiện theo yêu cầu của Trần Việt Đức

Thursday, December 22, 2011

Chèn link Google Search vào footer của bài viết

Ở thủ thuật này, theo như yêu cầu, mình sẽ tạo 1 link text nhỏ ở dưới mỗi bài viết. Khi click vào link này thì lập tức sẽ mở ra 1 cửa sổ mới của trang Google với nội dung tìm kiếm chính là tiêu đề bài viết mà bạn đang xem. Như yêu cầu thì tiện ích sẽ thay thế cho việc copy tiêu đề bài viết và dán vào google để tìm kiếm. Thủ thuật này cũng là 1 cách để cho các bạn có thể kiểm tra xem bài biết của bạn đứng thứ bao nhiêu trong kết quả tìm kiếm của google (với từ khóa chính là tiêu đề bài viết).


Xem DEMO

Sau đây là các bước thực hiện :
1. Vào thiết kế
2. Vào chỉnh sửa code HTML
3. Nhấp chọn mở rộng mẫu tiện ích
4. Tìm đoạn code như bên dưới :
<div class='post-footer-line post-footer-line-3'>
- nếu không tìm thấy đoạn mã này, bạn có thể tìm các đoạn mã bên dưới :
<div class='post-footer'>
hoặc :
<data:post.body/>

5. Sau khi tìm được 1 trong các đoạn code trên, các bạn dán đoạn code bên dưới vào ngay sau nó :
<div class='google-search-link' style='text-align:center;'>
<form action='http://www.google.com.vn/search' method='get' name='search-pt' target='_blank'>
<input autocomplete='off' expr:value='data:post.title' id='search-text' name='q' style='display:none;' tabindex='7' type='text'/>
<a href='#' onclick='document[&quot;search-pt&quot;].submit()'>=== click search google ===</a>
</form>
</div>
- các bạn có thể thay dòng === click search google === thành đoạn text khác mà các bạn thích.

6. Save template.

Chúc các bạn thành công.

Theo yêu cầu của ChoiBlogs.blogspot.com

SlideTab Recent posts (jQuery)

Phải nói là ở blog của mình tiện ích recent posts rất nhiều, nhiều là do mỗi cái có giao diện khác nhau, chứ về cơ bản thì nó đều như nhau, và đa phần là do các bạn yêu cầu. Và bài này cũng không ngoại lệ. Bài này mình rip lại giao diện theo yêu cầu, chỉ có khác là thay nội dung của nó bằng tiện ích Recent Posts mà thôi.

Xem DEMO

Hình minh họa :

Sau đây là các bước thực hiện :
- Vào code template (thiết kế -> chỉnh sửa code HTML), và chèn đoạn mã code bên dưới vào trước thẻ đóng </head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
- lưu ý là nếu trong code template của bạn đã có file jquery.min.js thì không cần chèn vào nữa, hiện tại jquery đã ra bản 1.7.1

- tiếp theo, tạo 1 widget HTML/javascript và chèn đoạn code bên dưới :
<style type="text/css">
#slidearea {
height: 242px;
overflow: hidden;
margin: 0px 20px 0 20px;
position: relative;
width: 960px;
background: url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRwuYYdpcQ9NILZFLBg2Ef7W9w3a9krCJo6vrzZHZ-LM7fgdTc431z11aCLqXgGuhU-tvgQmi1CoYPgwXItXLpH2UR2mANtfZ6TPxvvGFrvK-GfcPmoTRrBBXmBNygbGj_FggfnOwmA7qc/s0/slider.png) no-repeat;
}
#gallerycover {
overflow: hidden;
margin: 15px 30px 0 30px;
width: 900px;
}
.mygallery {
overflow: hidden;
visibility: visible;
position: relative; z-index: 2;
left: 0px;
width: 900px;
}
.mygallery ul {
margin:0;
padding:0;
position: relative;
list-style-type: none;
z-index: 1;
width: 2700px;
left: -1620px;
}
.mygallery ul li {
overflow: hidden;
float: left;
width: 180px;
height: 210px;
}
.mytext {
position: relative;
margin: 0 5px 0 5px;
width: 170px;
height: 210px;
display: inline;
float: left;
color: #C4C4C4;
}
.mytext p {
padding: 0 0;
color: #555;
font-size: 12px;
line-height: 20px;
width: 170px;
text-shadow: 1px 1px 0 #F6F6F6;
}
.mytext h2 {
padding: 5px 0;
color: black;
width: 170px;
font-size: 14px;
font-weight: bold;
}
.mytext h2 a:link, .mytext h2 a:visited {
color: black;
text-decoration: none;
outline: none;
}
.mytext h2 a:hover {color:#888;}
img.sidim {
width: 170px;
height: 100px;
}
.prevb {
float: left;
width: 20px;
height: 35px;
z-index: 200;
background: url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJw7g7vWW2tz4XQM65G09ikKQmwRBgE0MAzZbSEHF1UURCRt8CT0sU9qR17wesRR1ldxEsY3YrVVJ3o7X64mRO0y7mp__vNYOVuoMsEBJoZByQpPL0SAAx8MjxSo-qZpq6mYTsi8OQRmVE/s0/prev.png)!important;
position: absolute;
left: 5px;
bottom: 110px;
}
.nextb {
float: right;
width: 20px;
height: 35px;
z-index: 200;
background: url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaXYlITrQnaJwGBkhvXFsLgZSsJX8DA1c2qiLucDd8RV8s3tWAVpeCaKYo3ZnCn6wCXPzVUIu_71XpytoFv5r-HQD0jNYc1mEgwWMtW1_9OszfKqtMiSOHtJ8vjc3xpU6W9_v-lsQin3qJ/s0/next.png)!important;
position: absolute;
right: 5px;
bottom: 110px;
display: block;
}
</style>

<script src="http://fandung.googlecode.com/svn/trunk/js/slide-mygallery.js" type="text/javascript"></script>

<script stype="text/javascript">
var $jx = jQuery.noConflict();
$jx(function() {
$jx(".mygallery").jCarouselLite({
btnNext: ".nextb",
btnPrev: ".prevb",
visible: 5,
auto: 3000,
speed: 1000,
easing: "backout"
});
});
</script>

<div id="slidearea">
<div id="gallerycover">
<div class="mygallery">
<ul>
<script type="text/javascript">
var mode = "all";
var g_numposts = 10;
var g_numcontents = 15;
var g_label="B-advance";
var homepage="http://www.fandung.com";
</script>

<script src="http://fandung.googlecode.com/svn/trunk/js/feed-mygallery.js" type="text/javascript"></script>
</ul>

<div class="clear"></div>
</div>
</div>
<a class="prevb" href="#"></a>
<a class="nextb" href="#"></a>
</div>

Hướng dẫn tùy chỉnh :
- visible: 5 đây là số bài viết sẽ được hiển thị ra ngoài, như trong demo là 3.
- auto: 3000 đây là thời gian chạy auto, 3000 tương ứng với 3 giây, tức là sau 3 giây tự động chuyển bài.
- speed: 1000 là tốc độ chuyển bài viết khi click vào button left hoặc right (mũi tên màu cam)
- Lưu ý : nếu không muốn chạy auto, thì bạn bỏ dòng auto: 3000, trong đoạn code javascript, tức là đoạn script ở trên chỉ còn như bên dưới :
<script stype="text/javascript">
var $jx = jQuery.noConflict();
$jx(function() {
$jx(".mygallery").jCarouselLite({
btnNext: ".nextb",
btnPrev: ".prevb",
visible: 5,
speed: 1000,
easing: "backout"
});
});
</script>
- var mode = "all"; là chế độ hiển thị theo cả blog hoặc theo 1 nhãn nào đó, nếu giá trị là all thì hiển thị các bài viết mới của blog, nếu giá giá trị là single thì sẽ hiển thị bài viết theo nhãn được chọn (là biến g_label bên dưới)
- var g_numposts = 10; là số bài viết sẽ load (lưu ý là số bài viết sẽ load (g_numposts) khác với số bài viết sẽ được hiển thị (visible: {giá trị thiết lập}) )
- var g_numcontents = 15; số chữ (là các chuỗi ngăn cách bằng dấu khoảng trắng) sẽ được hiển thị ở đoạn mô tả bài viết.
- var g_label="B-advance"; tên nhãn sẽ được chọn nếu hiển thị ở chế độ mode = "single";
- var homepage="http://www.fandung.com"; thay http://www.fandung.com thành tên domain của blog bạn, ví dụ http://YOUR-BLOG-NAME.blogspot.com

- Ngoài ra nếu tiện ích rộng quá thì các bạn tùy chỉnh lại các thông số về chiều dài và rộng trong code CSS.

- Thủ thuật này xin lưu ý là hơi nặng, nên bạn nào thật sự thích thì hãy sử dụng, còn không thì có thể tham khảo thôi.

Thực hiện theo yêu cầu của Việt Nam

Saturday, December 17, 2011

[Update] Tạo Menu Thanh menu ngang có sổ dọc xuống

Create Dropdown Menu
[FD BlOg] - Để cho khách viếng thăm có thể dễ dàng truy cập và tìm kiếm thông tin về bài viết trên blog của bạn thì phổ biến nhất là tạo 1 menu truy cập cho blog. Việc tạo menu sẽ giúp cho người truy cập dễ dàng tìm thấy thông tin mà mình muốn tìm.

Ở đây mình sẽ giới thiệu menu nằm ngang và có liên kết với các menu con khác, và hiển thị của các menu con này là sổ dọc xuống theo từng menu chính.

Update 17/12/2011:

- Đây có thể nói là 1 trong các bài viết có lượng view lớn nhất trên BlOg FD, và cũng là bài viết có nhiều comment phàn nàn nhất về việc bài viết khó hiểu, hoặc không làm được. Hôm nay mình sẽ fix lại bài hướng dẫn. Và nhân tiện mình cũng fix lại code của thủ thuật để cho tiện và cho đẹp hơn 1 chút.

- Ở thủ thuật cũ, phần chèn link của các menu phụ (menu con) chỉ góm gọn trong các link của các nhãn, trong bài fix này các link của menu con sẽ cơ động hơn, không còn phải theo khuôn mẫu link như thế này http://YOUR-BLOG-NAME.blogspot.com/search/label/LABEL-NAME, tức là có thể chèn các link khác như link của 1 bài viết nào đó chẳng hạn.


Xem DEMO

Hình ảnh minh họa :




Trước tiên để tạo menu, bạn phải thống kê lại các nhãn, (giống như lập 1 bản đồ trong blog vậy) sau đó ta sẽ gôm các nhãn lại theo từng mục, ví dụ: giải trí , học tập... và các mục giải trí, học tập sẽ là 1 menu chính, còn các trang nhãn hoặc 1 trang bài viết nào đó sẽ là 1 menu phụ.

Thứ 2 là xác định nơi đặt menu, thông dụng nhất sẽ là ở trên phần header.Như vậy các bạn phải tạo 1 widget HTML/Javascript vào header rồi dán code của thủ thuật vào.

☼ Bây giờ ta bắt đầu vô chi tiết:
1. Đăng nhập blog
2. Vào Bố cục (layout)
3. Vào chỉnh sửa code HTML (không cần nhấp chọn mở rộng tiện ích)
4.Chèn đọan code sau vào ngay bên dưới thẻ mở <head>

<script src="http://fandung.googlecode.com/svn/trunk/js/dropdown2.js" type="text/javascript">
</script>

- nếu chèn code ở bước 4 vào template mà submenu không hiển thị, thì các bạn chèn nó vào ngay trong widget HTML/javascript chưa code thủ thuật, tức là chèn chung với code ở bước 6 bên dưới, và chèn ngay trên cùng. (updated 18/12/2011)

5. Save template lại.
6. Quay trở lại bố cục, vào phần tử trang, tạo 1 cái widget HTML/Javascript,sau đó dán đọan code bên dưới vào.

►CODE:

<style type="text/css">
.nav23{
height: 27px;
padding: 2px 0 0;
margin-right:5px;
background-image: url(http://sites.google.com/site/fdblogsite/Home/fd.gif);
width: 100%;
border-top:1px solid #bbb;
border-bottom:1px solid #ffdab6;
}

.nav23 a, .nav23 a:visited {
color:#000;
font-weight:bold;
font-family:Arial, Helvetica, sans-serif;
text-decoration:none;
font-size:12px;
padding: 5px 10px;
display: block;
float:left;
border-right:1px solid #f17813;
}
.nav23 a:hover {
background-image: url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHeTvTCIuK5kaFmD3H8hffVeg0-Fzd9z8kIPSnmEFGNyX9KCuZJyei0raBVOtleZ_w9V-8jIGiE3__TF5oAfyJJcpHbI904CS9HRAwQuIWbqj5ePWz-nDQ5LRWXq25pZziVUqVw3aVXvSD/s26/nav23-bg-hv.png);
color:#FFF;
}
.nav23sub{
background:#F57900;
margin-top:1px;
padding:1px;
color: #fff;;
margin: 1 1px;
padding: 5px 10px;
font-weight:bold;
font-family:Arial, Helvetica, sans-serif;
font-size:12px;
border-top:1px #ffc185 solid;
cursor:pointer;
}
</style>

<script type="text/javascript">

var bg_submenu="#F57900"; // màu nền của submenu
var bg_hv_submenu="#24BDE2"; // màu nền của submenu khi rê chuột

function otab(){
document.write('<table border="0" bordercolor="#999" style="background-color: #FFF" cellspacing="0" cellpadding="0">');
}
function submn(submn_link,submn_text){
document.write('<tr><td onmouseover="this.style.background=\''+bg_hv_submenu+'\'" onmouseout="this.style.background=\''+bg_submenu+'\'" class="nav23sub" onclick="window.location.href=\''+submn_link+'\'">'+submn_text+'</td></tr>');
}
function ctab(){document.write('<\/table>');}

function otab(child_id){document.write('<table id="' + child_id +'" border="0" bordercolor="#999" style="background-color: #FFF" cellspacing="0" cellpadding="0">');
}

// end of define functions!

</script>
<div class="nav23">
<a id="idmenu1" href="#" >Menu 1</a>
<a id="idmenu2" href="#">Menu 2</a>
<a id="idmenu3" href="#">Menu 3</a>
<a id="idmenu4" href="#">Menu 4</a>
<a id="idmenu5" href="#">Menu 5</a>
<a id="idmenu6" href="#">Menu 6</a>
<a id="idmenu7" href="#">Menu 7</a>
</div>

<script type="text/javascript">
otab("idmenu1_child");
submn('link_submenu1.1','Submenu 1.1');
submn('link_submenu1.2','Submenu 2.1');
ctab();
at_attach("idmenu1", "idmenu1_child", "hover", "y", "pointer");

otab("idmenu2_child");
submn('link_submenu2.1','Submenu 2.1');
ctab();
at_attach("idmenu2", "idmenu2_child", "hover", "y", "pointer");

otab("idmenu3_child");
submn('link_submenu3.1','Submenu 3.1');
ctab();
at_attach("idmenu3", "idmenu3_child", "hover", "y", "pointer");

otab("idmenu4_child");
submn('link_submenu4.1','Submenu 4.1');
submn('link_submenu4.2','Submenu 4.2');
submn('link_submenu4.3','Submenu 4.3');
submn('link_submenu4.4','Submenu 4.4');
submn('link_submenu4.5','Submenu 4.5');
submn('link_submenu4.6','Submenu 4.6');
ctab();
at_attach("idmenu4", "idmenu4_child", "hover", "y", "pointer");

otab("idmenu5_child");
submn('link_submenu5.1','Submenu 5.1');
submn('link_submenu5.2','Submenu 5.2');
ctab();
at_attach("idmenu5", "idmenu5_child", "hover", "y", "pointer");

otab("idmenu6_child");
submn('link_submenu6.1','Submenu 6.1');
ctab();
at_attach("idmenu6", "idmenu6_child", "hover", "y", "pointer");

otab("idmenu7_child");
submn('link_submenu7.1','Submenu 7.1');
submn('link_submenu7.2','Submenu 7.2');
submn('link_submenu7.3','Submenu 7.3');
ctab();
at_attach("idmenu7", "idmenu7_child", "hover", "y", "pointer");
</script>

- Chú ý :
+ Menu 1, Menu 2, ... Menu 7 là các menu chính (menu cha)
+ Submenu 1.1, Submenu 2.1, ... Submenu 7.1, ... là tên các menu phụ (menu con)
+ link_submenu1.1, link_submenu1.2, ... link_submenu7.1, ... là link liên kết của các menu phụ ví dụ như : http://www.fandung.com/search/label/B-basic hoặc http://www.fandung.com/p/contact.html
+ Nếu các menu chính có liên kết đến thì các bác bạn thay kí tự # trong code của nó thành link liên kết nào đó. Ví dụ như bên dưới :
<a id="idmenu1" href="http://www.fandung.com" >Menu 1</a>
+ Các code cùng màu (đỏ, xanh dương, xanh, cam, đen, tím, xanh xám)sẽ liên kết với nhau (kiểu : cha - con)
+ Ví dụ 1 đoạn code :
otab("idmenu1_child");
submn('link_submenu1.1','Submenu 1.1');
submn('link_submenu1.2','Submenu 1.2');
ctab();
at_attach("idmenu1", "idmenu1_child", "hover", "y", "pointer");
- Đây là code để hiển thị các menu con của Menu chính (cha) có tên là Menu 1, và code của menu cha là bên dưới :
<a id="idmenu1" href="#" >Menu 1</a>
- Bạn lưu ý dòng id="idmenu1" trong code trên, chữ idmenu1 này bắt buộc phải giống với chữ idmenu1 trong code của menu con, tức là đoạn code này :
otab("idmenu1_child");
submn('link_submenu1.1','Submenu 1.1');
submn('link_submenu1.2','Submenu 1.2');
ctab();
at_attach("idmenu1", "idmenu1_child", "hover", "y", "pointer");
- Nếu muốn tạo thêm nhiều menu con cho menu cha (ví dụ đối với menu cha Học Tập như trong code mẫu), ta sẽ thêm code như bên dưới :
otab("idmenu1_child");
submn('link_submenu1.1','Submenu 1.1');
submn('link_submenu1.2','Submenu 1.2');
submn('link_submenu1.3','Submenu 1.3');
submn('link_submenu1.4','Submenu 1.4');
ctab();
at_attach("idmenu1", "idmenu1_child", "hover", "y", "pointer");
- Còn nếu như các bạn muốn 1 menu chính nào đó không có submenu thì các bạn chỉ việc xóa code của submenu, lấy ví dụ ở Menu 6, thì ta sẽ xóa đoạn code như bên dưới :
...
...
...
otab("idmenu6_child");
submn('link_submenu6.1','Submenu 6.1');
ctab();
at_attach("idmenu6", "idmenu6_child", "hover", "y", "pointer");
...
...
...
- Nếu muốn thêm 1 menu nữa (ví dụ Menu 8) thì ta thêm code tương tự ở 2 phần như bên dưới :
...
...
...
<a id="idmenu6" href="#">Menu 6</a>
<a id="idmenu7" href="#">Menu 7</a>
<a id="idmenu8" href="#">Menu 8</a>
</div>
...
...
...
otab("idmenu7_child");
submn('link_submenu7.1','Submenu 7.1');
submn('link_submenu7.2','Submenu 7.2');
submn('link_submenu7.3','Submenu 7.3');
ctab();
at_attach("idmenu7", "idmenu7_child", "hover", "y", "pointer");

otab("idmenu8_child");
submn('link_submenu8.1','Submenu 8.1');
submn('link_submenu8.2','Submenu 8.2');
ctab();
at_attach("idmenu8", "idmenu8_child", "hover", "y", "pointer");


</script>

Bạn nên đặt menu này ở trên head là đẹp nhất, nếu blog của bạn nào chưa có tạo thủ thuật "Thêm tiện ích" vào phần header thì có thể xem ở đây.

-------------- BONUS --------------

- Trong demo mình có 4 mẫu menu, ở trên là code của mẫu 0, và đây là code của 3 mẫu còn lại, các bạn có thể download về tham khảo :
http://fandung.googlecode.com/svn/trunk/menu_type1.txt
http://fandung.googlecode.com/svn/trunk/menu_type2.txt
http://fandung.googlecode.com/svn/trunk/menu_type3.txt
- để có được 1 menu với màu sắc như ý muốn, các bạn thay đổi các giá trị mã màu như trong code highlight bên dưới là được :
<style type="text/css">
.nav23 {
height: 27px;
padding: 2px 0 0;
margin-right:5px;
width: 100%;
border-top:1px solid #bbb;
border-bottom:1px solid #ffdab6;
background-color:#88bb22;
}

.nav23 a, .nav23 a:visited {
color:#fff;
font-weight:bold;
font-family:Arial, Helvetica, sans-serif;
text-decoration:none;
font-size:12px;
padding: 5px 10px;
display: block;
float:left;
border-right:1px solid #528500;
}

.nav23 a:hover {
background-color:#528500;
}

.nav23sub {
margin-top:1px;
padding:1px;
color: #fff;;
margin: 1 1px;
padding: 5px 10px;
font-weight:bold;
font-family:Arial, Helvetica, sans-serif;
font-size:12px;
cursor:pointer;
background:#97cf26;
border-top:1px #d7ff86 solid;
}
</style>
<script type="text/javascript">
var bg_submenu="#97cf26";
var bg_hv_submenu="#528500";
...
...
...
Chúc các bạn thành công.

Popular Posts