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

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,微信登陆

搜索

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

[复制链接]
发表于 10-13-2011 02:13 | 显示全部楼层 |阅读模式
Drupal7表单定制和Drupal6大致相同,但是也有一些区别。这次我就来说说Drupal7是如何定制表单的。新建一个“form_theme”模块,然后创建一个表单,显示如下:
' C1 ~0 M. d5 r3 L! x7 w) TMy name is [FORM INPUT] [FORM INPUT] and I am [FORM INPUT] years old.! G  ?+ }1 p8 f  f
这三个表单元素的默认值依次显示“First name”,“Last name”和“Age”,当用户点击某个INPUT时,该表单元素的值为空,然后你就能随意书写了。
7 O. a7 s4 T. T" z这个简易的功能涉及到:
! v8 t0 w, F  `# ~0 _, f
  • 主题化表单
  • 给表单添加JQuery(JavaScript)
  • 给表单添加CSS
    ! q7 V8 B! e* [8 {
这个教程的主要目的是学习如何主题化表单,我不会对一些与主题化不相关的代码做过多地介绍。同样地,如果你想看懂这篇教程,你必须先知道:
, \0 |( f3 U7 [: H
  • 怎样在Drupal7中创建一个模块
  • 怎样在Drupal中使用drupal_get_form()创建一个表单
    % H4 C( t8 s5 z6 X6 |/ U
我也不会对教程中的CSS和JQuery代码做过多的讲解,你可以直接复制并粘贴到本地去试验。呵呵,我的目的是如何将CSS和JQuery添加进Drupal中。5 K1 Y& D1 v/ W; {3 e, D0 }4 w
开始吧!0 L) J- a* c/ ?% X2 p
第一步:使用hook_menu()为表单注册一个路径
. L$ P& L9 V  j) w; p9 \5 s我需要先注册一个页面路径好展现表单,下面是hook_menu()的实现:0 F" V, n- n$ \; Q* R

6 f3 b6 [* u" v3 b- i<?php$ u8 w1 Z$ F2 P4 d* u/ T" I) ^. Y
function form_theme_menu()
$ p7 @3 V' g" N  L% Q{
# h/ Y$ T6 Y8 s  C$ \2 f    $menu['form_theme'] = array
, v- W. B. p9 [- b2 K8 T1 d    (
0 p+ a9 ~, F: T2 N        'title' => 'Theming Forms',
, W4 w: M; \* _6 x- v        'description' => 'Practicing theming forms in Drupal 7',4 R8 ^2 h2 B. ?$ D% T. _
        'page callback' => 'drupal_get_form',  J* T; \* q: Q; v; l6 F2 M
        'page arguments' => array('form_theme_form'),: l8 s9 {5 G  n. H) G
        'access callback' => TRUE,! [5 F( J9 S5 _7 t* f
    );* k% y. s2 C' c& w0 e8 y
    return $menu;6 P1 e  t1 G6 I- u; a
}7 X+ o8 {4 ?6 E8 q6 `3 T
?>

4 K* ^, ^* ~$ R& l. W5 U: G9 y2 S9 k. J
第二步:定义表单* S( u& b) I  n: {$ U
在我的表单里,我需要三个textfield,表单定义如下:
) L1 p6 G+ ]  D  @" Q5 _3 m  ~  c5 {, ]
<?php
5 T* Q0 i, E. G7 J( {; @" Q2 j; N" L$form['first_name'] = array
& V; y6 M% h' [0 l(7 M0 E  R0 d# _6 ]8 j' w7 }, e
    '#type' => 'textfield',
( e$ W" n6 J, f8 U/ \);
# E( b: a* G/ p: g. w$form['last_name'] = array( V  i. w: N: }  F
(" Y+ b4 m1 R1 z- N. b
    '#type' => 'textfield',! g$ Y3 z. y" T/ f' a2 R, [. m5 i
);& i" Q: e) K+ v+ ]7 h8 h: a/ K/ K1 o
$form['age'] = array
9 X/ B& N6 l* ~( w(, V6 v, D8 m; d8 F7 I
    '#type' => 'textfield',4 Q: s/ g; y( g( J3 B0 i* s
    '#maxlength' => 3,8 H8 ^- I4 G. k) _
);3 `9 J. N2 q+ ^0 M- h! O5 U
?>

; ^/ V, y8 k1 O! T
# C8 ?" P  k. \+ C嘿嘿,代码十分简洁吧。我已经创建了这些表单元素,它们没什么修饰或其它配置。
2 k+ A' b6 g0 ~% t& Y  @然后,我需要添加CSS和Javascript到该表单。Drupal7有个新属性,#attached,我能通过它添加,代码如下:
; U7 b' f4 J$ C3 O5 m$ l# Z% K8 a+ p0 [" i& X
<?php# ?8 N- _7 j* N% K* Q6 h- `
// Get the path to the module% ^9 A5 Y  b+ M/ w; l! b* R
$path = drupal_get_path('module', 'form_theme');
( w4 ?; q: T2 H% \( J9 u// Attach the CSS and JS to the form) e( G% J' U/ W( W  e2 I
$form['#attached'] = array
* Z% r" b. A$ c! t9 R(
+ v, E6 J0 D5 j- f) O# ~6 l    'css' => array
/ D& ~, w* V: A. h& c# U+ s    (
* `) t" {' Y% S- Q* _% ]- `; }        'type' => 'file',/ Z, [- B8 }, Z- o: u/ l
        'data' => $path . '/form_theme.css',
& B% n# p4 B' |$ [3 I* x# J    ),6 n0 v8 N0 \* ]$ v( d. w
    'js' => array
5 d) J/ o' H  ]8 C  J    (" l( [: {# t( Y0 D% K
        'type' => 'file',
9 l6 ^, K. G7 i8 X        'data' => $path . '/form_theme.js',
; {- y& v4 Z4 b9 W    ),
$ n0 J! G  z+ V! M, _);$ n3 i' A9 w4 _, z% z% Q) L
?>
$ I8 x% x% m3 F( t- f0 K3 \
8 [( I4 I6 _6 R5 m! [* e( W5 V
这种方法相比drupal_add_js()和drupal_add_css()有个很大的好处,就是其它模块可以在该模块的样式和脚本的基础上做修改。* @& j: F' q1 ]7 Q
最后,返回我的$form表单,代码如下:
! u; b, f8 D1 q6 V! I: q, Y% r$ M" {: Q3 z2 W  ?9 t+ a. S$ f
<?php1 u' j5 }! Y7 X" J- t6 r2 T
function form_theme_form($form, &$form_state); ^$ s! L- ]6 C5 I
{
' O. s: v$ C% b: ?* |    $form['first_name'] = array" M  e4 o3 A# V
    (
( y8 n& w) X3 O  T! X. Z        '#type' => 'textfield',
9 s) ]; a2 ~) S/ C) V$ H+ d    );" x$ `, l: E! l, e. c% [- S; C
    $form['last_name'] = array
  A9 ^: z" K/ o# P$ T    (
$ O$ N0 ]# o' a- ]        '#type' => 'textfield',
# l) L+ J* k6 T7 c9 H    );% S' g; G$ Q' j+ y3 ~% l4 C3 L
    $form['age'] = array& A7 }. Q- S0 A
    (! `" Z1 n9 W9 K5 v+ x0 m) d
        '#type' => 'textfield',
3 k( s& X+ k; Y" F        '#maxlength' => 3,( F* Y8 V* z0 H" ]  J( u2 {
    );# R% C0 q. J: P4 U7 Y1 a
    // Get the path to the module
1 Y: c; ?' Q! K6 Q$ I    $path = drupal_get_path('module', 'form_theme');# i- T1 N2 l/ n0 ^
    // Attach the CSS and JS to the form% [( x2 s) I. I7 j) `
    $form['#attached'] = array" ^8 l1 e& d8 s, g' j
    (( K- o1 C% ?$ i
        'css' => array: w  p6 F' H' w& N5 y3 e! u
        (
0 `9 p8 R* F: _# D' O            'type' => 'file',
$ }3 R& K( v$ b" l            'data' => $path . '/form_theme.css',* F3 Z& S9 u2 b! \, {' ~/ Y8 A
        ),2 Q' {" Z* i' n7 L, V0 T; Y- d
        'js' => array
( R! t! `8 B/ ?  y- P: [& L        (
; |- H' T# U/ g( \; r            'type' => 'file',% ]" @$ o9 b" u5 F
            'data' => $path . '/form_theme.js',
% H2 i; e& U# ?- N; j. B- |' U        ),+ H8 q! e# }5 E- T7 R' b+ s
    );
% F% M4 I! ^  l( d6 ^( C; L    return $form;
9 n  Q6 i& F9 n2 ?& _6 i9 C}
7 `& `; Z$ U- S$ q0 ?0 s: k?>
2 k9 U2 }7 K/ d7 y" S, c% N. k9 a. H% W
8 H/ T6 l. S/ |! m1 j
第三步:用hook_theme()注册一个主题函数9 V2 s+ g' @! [' ?" F% w
从Drupal6开始,主题函数就需要通过hook_theme()注册,但是在Drupal6和Drupal7中还是有些细微的区别。在Drupal7中,表单的主题函数不是使用“arguments”,而是使用仅仅只有“form”一个值的“render element”。在注册主题函数时,你必须让索引和你已经定义的表单函数保持一致。代码如下:
, Z. i; E7 i2 l* T: E! r
% Z& ]% M- i& `6 n( p<?php
2 |# P! V8 d/ [* r) A% V7 e2 f9 ]function form_theme_theme()
- y, }! K$ a* l{* o) Q% t4 j+ P6 ]/ H+ R
    return array
/ O) c4 X; @+ Y1 q1 ~    (
9 z& v  A, J1 \& E2 ?        'form_theme_form' => array
! q; y3 m' u$ ]4 O$ l; f8 _4 `1 T" u        (
- S, j+ x) t9 b  f* `+ }6 i            'render element' => 'form'
2 L- ]% U- L$ a4 v2 z5 d        ),
$ N( I( n! D5 D    );& E2 N0 s# n  J; W
}4 v3 Q0 b/ N) l; y1 i! i  ~6 j
?>
$ D/ F2 W) v& M: M

2 O/ Q( F/ T% C" M4 }5 L. g, M* I正如你所见,我已经注册了一个主题函数。主题函数的命名十分重要,因为这个主题函数跟表单有相同的名称,Drupal在实现这个表单时会自动调用该主题函数。我也不需要添加#theme到我定义的表单$form中,这是多余的。* P3 `+ O; Z; x. m, j
第四步:写主题函数4 n5 E' g; e5 ^3 M2 q- B$ I. k2 A
在Drupal7中,写主题函数,有几个注意点。它们是:
9 I3 e* k- E! M4 E3 h! k( P2 W- Z
  • 函数只有一个参数,命名为$variables的数组。$variables有一个form索引,该索引的值就包括所有你已定义的表单元素。
  • 所有的表单元素必须要作为参数传给drupal_render()函数。这个函数能将一个PHP数组转换成HTML,并且将Javascript和css添加进去。这些Drupal会自动帮你完成,你仅仅需要传递这些参数就行了。
  • 在写主题函数的最后,你必须将剩余的表单元素传给drupal_render_children()函数,这样才能将剩下的或隐藏的表单元素转换成HTML。这是跟Drupal6一个很大的不同。在Drupal6中,我们直接传递$form给drupal_render(),但是在Drupal7中,这样做就会导致死循环,而且不会出现任何错误提示。$ y* Z: d. y& m5 [& Z
主题函数是以“theme_”加上我们上面注册过“form_theme_form”命名的。代码如下:) R& q" o1 H, N% s* T

" c; y$ X8 }8 Q1 P) c<?php# P1 g% c4 `& j
function theme_form_theme_form($variables)
, O; T( V+ z3 L/ z9 X{3 ~! _7 G6 |6 L7 @* @  B$ G
    // Isolate the form definition form the $variables array9 q3 [# L9 E; y9 {; j
    $form = $variables['form'];
1 H  B& y2 m# c    $output = '<h2>' . t('Please enter your information below') . '</h2>';
1 A- n* P/ g6 k$ S& k( C1 B- s0 y    // Put the entire structure into a div that can be used for
  o$ ?- ?" |4 y4 {5 x" {    // CSS purposes, ]- f  ~, u, i+ x& p
    $output .= '<div id="personal_details">';
1 z2 ~, G1 f. Y# t$ [8 ^+ ]    // Each of the pieces of text is wrapped in a <span>, _2 W' F9 q; {7 ?. w8 [( {
    // tag to allow it to be floated left3 C, ]$ S- f0 L  \3 b2 f/ F! ?
    $output .= '<span>' . t('My name is') . '</span>';/ Z7 U9 [7 S% w$ V
    // Form elements are rendered with drupal_render()
1 F% w$ ^- E; T5 J; w- i    $output .= drupal_render($form['first_name']);
: B" ^/ P5 K$ f4 |    $output .= drupal_render($form['last_name']);
' Z9 l1 H7 t3 I- n. @    $output .= '<span>' . t('and I am') . '</span>';
# g& r, P6 c9 f+ i    $output .= drupal_render($form['age']);
/ e9 q8 L" |0 Y    $output .= '<span>' . t('years old.') . '</span>';
6 C' S5 A5 f3 x& a8 a& u6 ^' V    $output .= '</div>';- ^( b' g0 @, ^$ q9 u: r
    // Pass the remaining form elements through drupal_render_children()
; m/ v9 y% {8 `( `5 Q0 t    $output .= drupal_render_children($form);3 c, n4 z& a/ M% R
    // return the output
5 X7 J7 t1 P3 ^( V, |" |9 d    return $output;
9 E9 t9 ^: ^+ S9 M* `% x}
& ]2 ~8 f7 V2 e?>

& K! o" b) N, g7 S" C
  t0 t% B; q+ b! _8 I  y/ B6 H到这里,我已经完成大部分的内容,定义表单,注册主题函数,实现主题函数。但是我还没添加CSS和Javascript。
2 c4 I$ G* j/ V2 p1 R3 [" ~# i/ H第五步:创建CSS和Javascript文件3 f* K; Z) z  S* S7 @- b
在第二步中我添加了CSS和JS路径,这两个文件都在form_theme模块的根目录。CSS代码如下:4 G; p- a( R1 ~" F0 w: i, ]
( w5 o* k2 q: j- n+ m4 W3 ^1 w3 K
#personal_details span, #personal_details div) r% o/ k9 }: {* O0 F0 H; G! |. R
{
* p) m9 Q9 D) H) x1 L- l6 b* y3 Qfloat:left;$ d" [2 J! s- e% r/ ?; x4 A& ^  Z: ~
}( `4 o" }4 a6 W& T# \- V7 {$ }
  u6 `$ z6 I7 x4 `: k% \- g. d
#personal_details .form-item-first-name, #personal_details .form-item-last-name8 k3 @( S4 d1 M4 H! e
{
5 G  g; L* ]3 g/ L* v2 x1 [width:115px;: n, w6 z: r, h' }! r
}1 G& t: A& p& t+ _* r+ x* [( t

8 T2 I8 z9 O( V% i#edit-first-name, #edit-last-name
4 _1 l8 z4 X4 Z! F$ G1 c6 @{
; e- u, \& R$ A6 {8 e9 |) {width:100px;2 x& b; b& X  i8 c1 _4 m
}
& S9 w" U% j$ s: h
  U. G" {) Q2 f7 I/ ~! }' M) f0 G* e$ |#personal_details .form-item-age# w) a6 F3 ~8 y2 g! W, O
{
* D# m) x: s( w5 A8 twidth:50px;
  k/ G0 C4 t# t' w% s}
8 L3 Y& R/ m. Z" i
9 Q9 @* p1 T- L% A  A1 N#edit-age8 y- m3 y" t" Y9 A, L- ?8 H
{& K: e& y- W2 @9 ^! ?+ e  _
width:35px;, w* w7 b2 j9 h  F
}
" H) H4 X6 N% `
) g  M' i) @+ E9 P! h) d- i, a; x#personal_details span
5 T! C! E7 V6 T; y" Y+ F; W{
) j0 T9 U' h5 S1 r; Vmargin-right:5px;
. M$ h* x) }' n( \& A& opadding-top:5px;
1 B3 y8 T% [% O/ w$ i}- Y& p  `6 @2 P0 W9 a; R+ Z
3 \0 Z0 x  S2 d7 A9 \
Javascript代码如下:1 c; S  X- }  c- p' u) G* t/ I  F3 O
5 M6 ]( a' S5 o! H) \3 e) K1 h( e
// We wrap the entire code in an anonymous function+ v* I" Z. N9 n% b
// in order to prevent namespace collisions, and to8 A0 n! c. d( I; D1 j
// allow for jQuery to be set in a safe mode where" i7 e) o: b& n# `- |. M
// it will not collide with other javascript libraries.
3 D* ~5 u$ |7 V/ A& ~' L! w// While this is the proper way to do it in Drupal 7,
# k7 T  \" F0 N- H// this method is actually good to use in Drupal 6 as
; o& n: b6 N5 Y// well, for the same reasons.; e4 X! P  U  {# y  j4 K
(function($)2 E( P& g& ?. n) \: u
{
7 _* j3 d! a2 t) }$ O) z// In Drupal 6, each element of Drupal.behaviors# M$ y1 x8 {& P* Z# J" v$ P
// was a function that was executed when the
4 F5 W! i) V+ s. \$ Q' F4 j// document was ready. In Drupal 7, each element
4 P3 D9 A! r/ H// of Drupal.behaviors is an object with an
1 y# m1 w6 v0 K' v// element 'attach' (and optionally an element) y7 K* b' _4 s1 v. I
// 'detach'), which is executed when the document  G# c3 P0 k2 G7 a+ {, ~. O( W
// is ready$ T* n8 T4 \) M. j4 ~
Drupal.behaviors.formTheme = {7 o+ g$ ~+ g5 T$ u
attach:function() {
5 w: a% }2 Q4 s" V// First, define an empty array6 h- p: h* b% M3 E0 |4 @; H
var defaults = [];
# Z! t3 w0 \0 m  R: f( [$ @// Next, add three elements to the array,
0 G) ~- B8 |# i5 [8 S// one for each of the form elements. The value
' }( L$ s- y) y( C5 Q// is of the array element is set as the default3 N1 _% m( Y# X9 J5 |# j* |
// text. This text is run through Drupal.t(),$ ^) x3 o, ~5 a" L) i
// which is the Drupal JavaScript equivalent
% u" H/ Q4 z( d9 F) L// of the Drupal PHP t() function, and allows
2 d" p+ k. {9 O% c- V3 a// for translating of text in a JavaScript document1 d8 e- ^- c& _3 [, v
defaults["#edit-first-name"] = Drupal.t("First Name");
% ]  q/ m' f7 W, R) }; p1 |defaults["#edit-last-name"] = Drupal.t("Last Name");
' {+ H7 \2 r+ z+ N, n0 ~! G3 M9 kdefaults["#edit-age"] = Drupal.t("Age");3 j* i! Z) I! @9 g7 p' L" P! N
// Next we loop through each of the elements of the array" W! y1 S6 M- F6 o
var element;0 L; I$ T+ d4 |& D
for(element in defaults)$ ^- L3 @( x0 y" j  h" Q
{
5 B9 ?# ]3 `( Y' r- J7 S; b! t1 t// We wrap the body in the following if() statement# L: _3 z+ [- t, }9 ^5 o
// as each element in an array will also have a/ P) B' Q$ h, q8 [+ A9 \
// prototype element. If you don't understand this,3 v% r+ ~) U1 }3 @
// don't worry. Just copy it. It will make your  I$ C& ~. v) \3 S& l) }0 Y
// for(A in B) loops run better.
/ [0 O5 s0 h' l! i6 o" q0 Pif(defaults.hasOwnProperty(element)) {
! d- P- C; U# l, D5 L// 1) Set a placeholder in the form element' n0 _; S+ c: k; I! u4 t# o+ Q3 _
// 2) Set the CSS text color to grey for the placeholder
# Y, x9 {+ E( k8 a; D4 Q; T& Y( c// 3) Attach an onfocus and onblur listener to each element
+ k- V2 @1 m- t" @4 e( G( x$(element).val(defaults[element]).css("color", "grey").focus(function()
# D& i9 |# n1 e{
$ [9 ?: a" ]& y' C/ z# y7 m// This is entered on focus. It checks
; G: Z  Q2 O, b# c5 @// if the value of the form element is
! z  \7 s1 H. S/ d7 {// the default value of the placeholder,5 s2 E1 p, p8 K- s, g
// and if it is, it clears the value and
" ~! e# T6 _/ r) K9 Q2 t7 M// sets the text color to black,as the
8 c7 r, H; K3 }// entered text will be the actual text
' A& W$ }) O+ I* x! V% S* ~: a6 y// and not the greyed out placeholder text.
5 ~+ D3 Y1 \! Avar key = "#" + $(this).attr("id");& U* b" X; O7 |) H! n$ k
if($(this).val() === defaults[key]) {
4 }" G' G' X* ?$ M$(this).css("color", "black").val("");$ L: K) t: Q6 X- S
}2 D9 o' I: ~! X& A9 J, J
}).blur(function(); r4 n: H* r9 ]+ u& p' z! e
{
0 f# L6 E& v* u/ \// This is entered on blur, when the element
7 X, {. }' k2 k& Z, U// is exited out of. It checks if the element
/ E+ X) R6 R- y# w# A/ O9 J2 o// is empty, and if it is, it sets the default
5 b* W6 H$ Y* c7 o& L. d// placeholder text back into the element, and
- U, Z! m2 j3 Z( ]3 v// changes the text color to the grey placeholder1 U  U% f0 V( `
// text color.
3 I' M! d+ [8 O. W3 Uif($(this).val() == "") {3 [' ]* f+ h# I! V, a
var key = "#" + $(this).attr("id");
4 ]. Z/ r5 j4 g2 y1 Y$(this).css("color", "grey").val(defaults[key]);) e* q9 o7 W/ ~& e3 n$ ]/ G
}! u: j* q! t; ^+ c  v
});% h# K: f: ?- D* j% c7 H
}
, ?5 X1 \! e: h+ ~: r4 `* w}# T/ e2 y: `. s) U) S$ r
}
4 D  M" v( `8 P, A/ i};
/ F  c* d% @; V' ?* _8 @}(jQuery));
6 R2 I" C: U2 X& H9 r( R) E( @, k. k$ d  w. Q
好了,你可以试试看。
: R5 m- N' i' n8 `原文出自:http://junepeng.info/zh/node/28
6 L; c- n; n+ v4 t7 _
1 v8 Z* n' a' R) I% \7 Y
! K& P% b& a3 |, `* z& O) l, z1 y; R1 @
& V3 n8 C2 m) c* l9 l' w

6 C5 u' [# b, I5 M" t' x+ f5 s' S' U0 [- K( F; X9 l8 b

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

GMT+8, 2-19-2025 14:20 , Processed in 0.460890 second(s), 159 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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