国外设计欣赏网站 - DOOOOR.com

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,微信登陆

搜索

[Drupal教程] 如何添加CSS和Javascript定制Drupal7表单

[复制链接]
发表于 10-13-2011 02:13 | 显示全部楼层 |阅读模式
Drupal7表单定制和Drupal6大致相同,但是也有一些区别。这次我就来说说Drupal7是如何定制表单的。新建一个“form_theme”模块,然后创建一个表单,显示如下:
! P3 ?7 }9 w& F% d/ \2 }My name is [FORM INPUT] [FORM INPUT] and I am [FORM INPUT] years old.6 g$ H# F- ?% s( E& y8 h
这三个表单元素的默认值依次显示“First name”,“Last name”和“Age”,当用户点击某个INPUT时,该表单元素的值为空,然后你就能随意书写了。
- x% [" s/ W0 m  Q! b这个简易的功能涉及到:
# l: c, q6 {6 p: @
  • 主题化表单
  • 给表单添加JQuery(JavaScript)
  • 给表单添加CSS, I" q7 h+ c1 Q3 S7 l0 U9 I. d
这个教程的主要目的是学习如何主题化表单,我不会对一些与主题化不相关的代码做过多地介绍。同样地,如果你想看懂这篇教程,你必须先知道:5 b  N0 a) m  T5 r( R' o
  • 怎样在Drupal7中创建一个模块
  • 怎样在Drupal中使用drupal_get_form()创建一个表单! U! D; M& W8 ~3 u8 Z$ L- s
我也不会对教程中的CSS和JQuery代码做过多的讲解,你可以直接复制并粘贴到本地去试验。呵呵,我的目的是如何将CSS和JQuery添加进Drupal中。& y0 z/ s$ u1 k; E( X9 P1 l% G: W9 L
开始吧!
6 X' Q0 s' n: R' B, E6 H1 A9 K$ S第一步:使用hook_menu()为表单注册一个路径
: |4 c7 v0 `7 L# f0 v我需要先注册一个页面路径好展现表单,下面是hook_menu()的实现:: J' Q8 G6 b/ s5 n8 g

2 Z; \8 F, G$ s, Q( O* ?<?php
8 N5 \+ h6 F; ]function form_theme_menu()
$ v. ~  U( h  O* q! K/ U# O{
7 e: o+ V  W7 k+ W# l3 Q) v9 X    $menu['form_theme'] = array
8 h; d+ M/ H: r6 q/ h    (' R! [! V  M. t- w  T
        'title' => 'Theming Forms',; N: i4 q9 T" J5 i( l# t
        'description' => 'Practicing theming forms in Drupal 7',
+ W; Z9 t9 Q  O        'page callback' => 'drupal_get_form',
- l* o3 b  u+ D; v4 L: ^        'page arguments' => array('form_theme_form'),' ?4 p9 E/ r3 k6 d3 \! \& P* G% _
        'access callback' => TRUE,
: \' H" h6 ?$ I% O    );
! @7 i0 N8 k. `" G# s, s    return $menu;
- r- p& P/ `/ y0 C$ l# Q  b}3 S# f! w5 \  `5 K6 g# N
?>

8 R/ I4 W& k+ s; n" i/ v! h& }; v1 w. E6 I8 B: c4 c
第二步:定义表单9 Q' S8 \5 W; i( O5 s" o4 ~
在我的表单里,我需要三个textfield,表单定义如下:; \' ?0 C$ M. @6 W: R

6 }) A- Q/ |6 @, F* ]" |<?php5 w4 e5 K) g; I1 {
$form['first_name'] = array
: n8 g7 K9 J( r1 B, L(
; V# O3 V0 Z# g) E( ?    '#type' => 'textfield',
! {: f& k' P- }  E* {);
: I& N- j% e$ [: f1 n1 p$form['last_name'] = array% b& I$ x1 |3 B; E% h0 A# @
(* `) D8 T: S1 B
    '#type' => 'textfield',
0 n9 ^" t+ k. w, X# S. y7 G);& O: S4 s% B& v  G1 Z
$form['age'] = array' H# J3 d. s; r  p, ]
(/ ?# K; o, H8 B5 V3 B, ~
    '#type' => 'textfield',
/ d0 \0 }! x' Q    '#maxlength' => 3,
: W8 a! ^3 |3 L7 A' U);
6 r9 ?8 k! @2 z( Y7 m?>
0 B6 i( ]6 B" Z: |: a6 b
* Q' p& @) G; y+ a7 k
嘿嘿,代码十分简洁吧。我已经创建了这些表单元素,它们没什么修饰或其它配置。1 M  `. z) E) C! e
然后,我需要添加CSS和Javascript到该表单。Drupal7有个新属性,#attached,我能通过它添加,代码如下:% ?  t# l  g. ]4 `) E  m
3 G4 ], h3 M. Q4 U
<?php: S7 ^$ S7 S( |! L( \/ E
// Get the path to the module# W" V! Z  F: C- }
$path = drupal_get_path('module', 'form_theme');7 }" E$ K- ]! p' y+ T. F& Y; F
// Attach the CSS and JS to the form# ~8 ]) e* k5 f& `
$form['#attached'] = array: ~. R$ y- c) P' a
(
7 l; U, ~; w- w+ ^# u& ?0 D* w. S2 M/ h0 ~    'css' => array- v7 k* K2 Y! b1 v% d- _
    (8 m% H& L# D9 k0 z& N! m' u2 m
        'type' => 'file',: T1 B5 Q! Q6 c8 Z7 Q
        'data' => $path . '/form_theme.css',) r4 x- |  J. Y4 G& f6 {, O8 O5 M
    ),8 p: k. N' Z2 Q7 D  T/ z
    'js' => array& V3 x9 t* y- ]* o3 V+ S; ^) ]# I
    (
6 `( F- t  b- A4 \! r        'type' => 'file',- b9 I0 @& X3 w3 F# ^" ]
        'data' => $path . '/form_theme.js'," }. H* A- A4 H. z
    ),+ b  o, ~: T2 U. M# n
);
  U& e8 d( C1 q7 U2 Q5 J* T* n?>
: x' T% n4 ]  C% P
* O. e( s  z% B" m
这种方法相比drupal_add_js()和drupal_add_css()有个很大的好处,就是其它模块可以在该模块的样式和脚本的基础上做修改。
) [0 }& A) b) x4 b最后,返回我的$form表单,代码如下:1 q. u0 N$ n7 r
$ s$ c& Y- i6 `
<?php
9 U# `9 b& b( y, @7 }function form_theme_form($form, &$form_state)
* y9 m! o! `# }2 K/ L1 U{/ V, N4 z3 u! y  p; x7 m
    $form['first_name'] = array+ q' p; G8 ^7 g3 ~1 ^
    (/ ^! Y2 ~* l) S7 Y& P
        '#type' => 'textfield',
) K( J/ s5 j) Y    );
( o1 U  p0 E5 P5 ]. H9 ~6 t    $form['last_name'] = array6 o4 M, Q* y* ~+ H
    (2 K: d) M9 Z3 [% w+ d7 {6 d# q4 g
        '#type' => 'textfield',
. R! F9 g: I9 \* Z: U' V    );
) S6 ~* k9 b, \    $form['age'] = array( r- q3 [0 c+ |5 D& F
    (  \- ^" ]7 y" F5 q+ {9 g8 w
        '#type' => 'textfield',
3 V0 q+ w0 H( F* `9 {        '#maxlength' => 3,
* F4 C4 i1 W0 s" S    );
. R" w) Q: g8 t! V, p    // Get the path to the module
8 v% k7 q% s4 }# W* v7 l  c" F/ q/ N    $path = drupal_get_path('module', 'form_theme');; H( B* D$ n9 ]8 m* j4 s$ k
    // Attach the CSS and JS to the form
0 I# D/ w  ]" t2 [3 z$ X    $form['#attached'] = array( t5 j' O4 `" H
    (
; U: P8 r5 X  p- s$ q* L8 e        'css' => array
# S  M" D# }  C* L0 r        (
- T' x* J: g: M# g' p            'type' => 'file',; P8 @5 p/ M- }1 ]$ D$ W
            'data' => $path . '/form_theme.css',7 H  s4 Q, ], s" v7 G7 B% N" w
        ),. G( Y" J" Z; r% t" R
        'js' => array
; J3 f; }) Z# a$ G8 ]% T! I        (
  X4 C: N, T: }1 @8 \& Z+ f" S            'type' => 'file',
$ d! n% l, L/ |            'data' => $path . '/form_theme.js',$ i6 ]  J1 G( Z) y
        ),
/ l) e5 b; V5 ^% D% L    );1 o4 ^( e$ f' e8 U
    return $form;7 t! }* B9 p6 q8 A* B
}
& O5 P) q4 s- L9 `?>

5 _; `1 T" ~1 h: M) _$ ~2 R% a
7 x  w1 F3 ]4 T& D' b3 s' f6 t$ X第三步:用hook_theme()注册一个主题函数1 N$ @& y% x1 {
从Drupal6开始,主题函数就需要通过hook_theme()注册,但是在Drupal6和Drupal7中还是有些细微的区别。在Drupal7中,表单的主题函数不是使用“arguments”,而是使用仅仅只有“form”一个值的“render element”。在注册主题函数时,你必须让索引和你已经定义的表单函数保持一致。代码如下:( K3 y4 b  _6 ~/ T) A/ C% R. M% M
6 ~/ t+ R# n8 Z/ n
<?php
: {, N/ u* Y- W) M. g% F6 ufunction form_theme_theme()' H# v" f  v+ |, e5 u
{- s7 l! b& I" y' ?  ^3 d
    return array
3 T  ]% ]3 ]* D  g0 ?* C$ G) U    (
  r4 p- [; d+ ]4 O* B" w        'form_theme_form' => array
& S2 X3 M5 m: P1 F* l& R, w' q! p) `        (/ h: D, `# `6 k$ \/ u4 E8 A
            'render element' => 'form'
, [% j9 g) M( b" j        ),' Y) s8 [- \& C& i5 \
    );
$ G6 T+ `- j- F; M0 g3 }2 ^}3 u( l, R& }  G6 |! p& H" M
?>

+ ?; S/ |8 W. z, @; u- t( x
* Q6 Q% o% v4 B  A. Y4 w  d正如你所见,我已经注册了一个主题函数。主题函数的命名十分重要,因为这个主题函数跟表单有相同的名称,Drupal在实现这个表单时会自动调用该主题函数。我也不需要添加#theme到我定义的表单$form中,这是多余的。# y" d; M- c# q% f2 Q
第四步:写主题函数8 L! v; e! w1 I8 g0 Z
在Drupal7中,写主题函数,有几个注意点。它们是:
3 Y9 u( S) F9 [8 ^# E6 M
  • 函数只有一个参数,命名为$variables的数组。$variables有一个form索引,该索引的值就包括所有你已定义的表单元素。
  • 所有的表单元素必须要作为参数传给drupal_render()函数。这个函数能将一个PHP数组转换成HTML,并且将Javascript和css添加进去。这些Drupal会自动帮你完成,你仅仅需要传递这些参数就行了。
  • 在写主题函数的最后,你必须将剩余的表单元素传给drupal_render_children()函数,这样才能将剩下的或隐藏的表单元素转换成HTML。这是跟Drupal6一个很大的不同。在Drupal6中,我们直接传递$form给drupal_render(),但是在Drupal7中,这样做就会导致死循环,而且不会出现任何错误提示。, q1 r' H$ ~, O6 T
主题函数是以“theme_”加上我们上面注册过“form_theme_form”命名的。代码如下:/ d" v5 r  ?$ d2 l

) Y9 `/ M3 K6 O<?php! J# m$ D3 r  M# s3 x( G* M& _1 N
function theme_form_theme_form($variables)
! U; E! F; q! |. B{& e& f9 U2 L! ]8 e6 d8 K
    // Isolate the form definition form the $variables array- F& D$ z- o2 B7 ~- k7 q
    $form = $variables['form'];
) O* E3 b  n4 [2 T4 V$ M4 ~, r* o    $output = '<h2>' . t('Please enter your information below') . '</h2>';9 ^3 _+ L6 F$ ~8 o* \! N
    // Put the entire structure into a div that can be used for1 N6 ~5 N8 Q7 r. B
    // CSS purposes. e& U) P; U# J! r6 Z6 s( k
    $output .= '<div id="personal_details">';  r+ s  p5 v/ t; R$ Q) ~; S
    // Each of the pieces of text is wrapped in a <span>" g* `9 U8 C5 B
    // tag to allow it to be floated left
, Q4 P, v/ i6 Z$ X% {    $output .= '<span>' . t('My name is') . '</span>';
% M( i# K7 J! {/ p0 e. o8 \    // Form elements are rendered with drupal_render()
  ~" O: ?: P4 q    $output .= drupal_render($form['first_name']);; C% k  D% k. i8 V5 u$ }
    $output .= drupal_render($form['last_name']);* B* U3 G( ^' _$ m& F
    $output .= '<span>' . t('and I am') . '</span>';
3 |5 c0 Z8 R$ \3 Z9 _    $output .= drupal_render($form['age']);9 O( H# Y/ K1 h+ l
    $output .= '<span>' . t('years old.') . '</span>';7 B. J! u. d0 W2 ~, m
    $output .= '</div>';7 ]! _% ]: X) V, a7 a
    // Pass the remaining form elements through drupal_render_children()
" F6 i" C7 S& S' X! t    $output .= drupal_render_children($form);, R( ~( s( J- v* i6 f1 M+ G$ v
    // return the output
1 W/ i. v  W3 }, q; Z# P    return $output;7 u* |5 c2 x8 Q
}
; P+ \3 t3 r+ R- x6 i0 h# k& l" U) r?>
* c% `6 c/ k% B: U3 r* i5 L
$ [* W5 W6 k" B) P4 y+ ^( e/ L9 t
到这里,我已经完成大部分的内容,定义表单,注册主题函数,实现主题函数。但是我还没添加CSS和Javascript。3 {! D- A- s9 U' r' H. o
第五步:创建CSS和Javascript文件' k6 R+ _) P: T1 }
在第二步中我添加了CSS和JS路径,这两个文件都在form_theme模块的根目录。CSS代码如下:
4 r. K$ R4 K$ }
  w8 K3 R8 r; @6 N#personal_details span, #personal_details div
% x1 @+ o* n/ T{
% Q) d0 Z+ a5 ]. P$ \& ufloat:left;+ p) y) K6 H4 [
}
. ]. }) s) x4 O; ~
2 z7 K" x- P6 S#personal_details .form-item-first-name, #personal_details .form-item-last-name
8 e/ W* ]: m: v- |2 }8 M' G{
3 ]0 q: G; Q" j. p: A) e8 Zwidth:115px;$ G2 w4 ~$ t' a7 i
}7 y: y; L8 x( ]7 s6 s4 O& M8 [  o# j" @

+ @8 {  _9 T9 Z( J" Y4 I#edit-first-name, #edit-last-name% h; }" w: K4 J8 b
{
& }5 |* X7 K, ?) awidth:100px;
/ d) n2 K# b& F}
6 W7 O" y$ D7 }/ l; j2 Y, p. R; R, u1 r$ e( k
#personal_details .form-item-age
2 w0 }* G/ F) B, W1 _. I4 U{( [! _0 n1 g% D! ]
width:50px;3 J! M. H7 f! Y/ c. [, {
}
& M: H& u# ]9 [* j0 a2 w
8 w5 M4 i8 `" X5 [#edit-age$ Q" M5 a3 h+ ^
{
' n6 B; p% u4 owidth:35px;
$ h+ F/ r. S% y}
5 h' g+ U8 ^# j1 v- E2 e3 m) I- ~" J0 T' |. \
#personal_details span$ z$ a! l9 p. O( R  f
{
8 z! }1 ?' @1 K1 wmargin-right:5px;
. t9 B8 k, k# k+ l6 o% f* upadding-top:5px;
. j& z1 o. m1 Z3 m}* I1 m/ O# k8 n, a) O

1 W0 P( w, V' k, V0 t. ]+ ^% VJavascript代码如下:6 U5 K% p# t& G  q1 c' D( @4 @2 t
6 r+ J7 X* u* \8 \; C0 \7 g
// We wrap the entire code in an anonymous function1 d" A5 D) ~4 t
// in order to prevent namespace collisions, and to0 ~! T, Y. \, f4 G
// allow for jQuery to be set in a safe mode where% @: O- e2 ?3 ~( ]6 Y3 V. L; \
// it will not collide with other javascript libraries.& Q# l7 O) u: @3 i
// While this is the proper way to do it in Drupal 7,! T) v# [, c9 E2 S# ]  ]; s
// this method is actually good to use in Drupal 6 as
3 ~6 ?$ \& c0 y0 P! v9 V/ ?3 o4 Q// well, for the same reasons.
+ r6 ~! n) C0 t$ l* W(function($); F9 [* H6 h0 K% w; m
{3 Y% w; E/ f2 s3 w, w8 O! i9 S
// In Drupal 6, each element of Drupal.behaviors" i' F! r) D1 C$ O5 @' ~
// was a function that was executed when the0 O" E, m+ R9 t
// document was ready. In Drupal 7, each element9 {& h4 @1 c5 K9 n2 i/ b
// of Drupal.behaviors is an object with an5 I$ K+ M8 u* `  ]2 `3 M  U
// element 'attach' (and optionally an element8 `7 h" ^8 j. H4 C5 L
// 'detach'), which is executed when the document2 j, j2 \  k) s* M* p1 a0 Z* T0 \: \
// is ready5 t0 [- G7 E8 i& @" |* t, `
Drupal.behaviors.formTheme = {9 h# F  E1 @# j1 X) _3 P
attach:function() {
+ w1 t3 B4 a: ^+ E3 H1 l// First, define an empty array& E  l. X; ?, k' o
var defaults = [];% E$ A, H' S& B$ I
// Next, add three elements to the array,  B. w$ ~/ F. H2 B7 G* \
// one for each of the form elements. The value0 Z6 W- A) W+ c: U& z
// is of the array element is set as the default2 U5 ]7 K5 d1 U
// text. This text is run through Drupal.t(),
( S4 X+ q1 v  q+ s* v0 {" {// which is the Drupal JavaScript equivalent
" M$ ^( U" M: d! D) A) _// of the Drupal PHP t() function, and allows  s/ J: v& j9 S% m; D5 x
// for translating of text in a JavaScript document
  J6 D& R' {/ L* o/ Mdefaults["#edit-first-name"] = Drupal.t("First Name");3 F2 w* a5 O7 g4 ^7 B+ f
defaults["#edit-last-name"] = Drupal.t("Last Name");
& M1 t( v' R* B0 [- y9 xdefaults["#edit-age"] = Drupal.t("Age");7 l' G# t8 H, \6 C
// Next we loop through each of the elements of the array
' x$ A. [% q! j3 v! i8 y2 M! wvar element;
+ G6 v  I; }8 Y# Ufor(element in defaults)
: e. y7 T% _# [- M" i$ z$ `$ r{
2 i3 N; q8 z7 x) r// We wrap the body in the following if() statement! A* c# ~& U) J  |
// as each element in an array will also have a4 a4 _% l& Z6 B0 D. k
// prototype element. If you don't understand this,
3 w( C" E$ c6 P; o/ S3 S: G8 k// don't worry. Just copy it. It will make your: V' h* c" f' T+ o1 O7 u( O
// for(A in B) loops run better.& o& E% p5 k: p4 h
if(defaults.hasOwnProperty(element)) {1 L0 B+ K: O2 w, U
// 1) Set a placeholder in the form element( e- B8 ~+ H3 F1 ~* `3 K8 \
// 2) Set the CSS text color to grey for the placeholder3 _8 H9 D. U0 P6 W8 _8 |) j
// 3) Attach an onfocus and onblur listener to each element
: i3 s1 w* f4 n8 m4 k1 v# J- U; C$(element).val(defaults[element]).css("color", "grey").focus(function()
: X/ M, @. L8 Z7 z5 o5 F{0 E8 C* S7 F* b! e% ]8 t) M6 [) x
// This is entered on focus. It checks6 F1 y' d- r* O" Z5 E8 m8 R0 R
// if the value of the form element is" p  v6 ^' H8 H8 _4 p
// the default value of the placeholder,& [9 G6 Y( ]" F+ p
// and if it is, it clears the value and5 e9 d9 J) e% ]; |& @
// sets the text color to black,as the
# }* ?9 r  P4 w" E, W; S2 |// entered text will be the actual text
- A( {% Y' l; f// and not the greyed out placeholder text.9 M. |2 l4 Q' H4 Z0 Z  n
var key = "#" + $(this).attr("id");
. C# D) I' e: I; ]1 [  y6 m8 kif($(this).val() === defaults[key]) {
0 \& p2 e9 i+ B$(this).css("color", "black").val("");
& F$ R6 n0 P! V5 h  L0 k}% }: x0 a/ A) t+ Q/ q4 N
}).blur(function()
9 K% e6 K& _& Z, w: k8 s% D/ f+ x: ~{1 B1 u/ ]) m' R  O9 N0 R
// This is entered on blur, when the element4 i7 O7 `5 r! J% Y1 i
// is exited out of. It checks if the element
) u& r. ?! ?7 w3 R0 A. W$ \6 l* s// is empty, and if it is, it sets the default6 ?( ]( N; K+ Q% z
// placeholder text back into the element, and' r' C' ~1 Q' F0 V; V$ l
// changes the text color to the grey placeholder
/ s* {3 L8 I3 ~  s// text color.$ q; Y/ @1 ^' l1 @: n7 c
if($(this).val() == "") {
, `( s* h5 }& i2 K: k' j# }var key = "#" + $(this).attr("id");
4 n6 d6 e5 K# L( T8 @; I! ^$(this).css("color", "grey").val(defaults[key]);
) b! `& o$ M. R( }}
3 ~! m# Q2 l5 s});
8 K# G0 L: G  x* |5 T}
% k7 i( R/ A9 c2 p1 \$ z}/ T6 i, y9 A0 n( }0 ~8 g. |& G
}
$ T5 W9 W! e# r' ~0 o  x3 F};
- Y+ H% t6 u" T! M: ]}(jQuery));
! I$ p& j) s# ?8 z. V* I, M' ^/ q. U. M6 ?
好了,你可以试试看。
. B! D& c! N$ P1 L) j1 r原文出自:http://junepeng.info/zh/node/28
. K7 I; w% f. Y4 R* H- t* {$ V: x5 o: K

- s8 ~* U( V2 z5 b
$ V. `2 p5 ?- F7 t+ d7 O2 X: Q9 f+ D4 c+ M

" r$ @# U# R5 s* b- R& h( h" p8 w# s( E% E' F

|2011-2026-版权声明|平台(网站)公约|DOOOOR 设计网 ( 吉ICP备2022003869号 )

GMT+8, 5-2-2025 06:12 , Processed in 0.380570 second(s), 162 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表