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

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,微信登陆

搜索

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

[复制链接]
发表于 10-13-2011 02:13 | 显示全部楼层 |阅读模式
Drupal7表单定制和Drupal6大致相同,但是也有一些区别。这次我就来说说Drupal7是如何定制表单的。新建一个“form_theme”模块,然后创建一个表单,显示如下:
0 g6 t& H. D9 J4 l( `My name is [FORM INPUT] [FORM INPUT] and I am [FORM INPUT] years old.* a6 H, @4 `- v) ?  l  B
这三个表单元素的默认值依次显示“First name”,“Last name”和“Age”,当用户点击某个INPUT时,该表单元素的值为空,然后你就能随意书写了。
: V5 m) i/ J, u; [: K! Q; k这个简易的功能涉及到:  ?/ M5 {* z0 A; W% f7 S  e
  • 主题化表单
  • 给表单添加JQuery(JavaScript)
  • 给表单添加CSS
    : ]4 y6 [. o5 W) ~1 b- w: B, d
这个教程的主要目的是学习如何主题化表单,我不会对一些与主题化不相关的代码做过多地介绍。同样地,如果你想看懂这篇教程,你必须先知道:
9 V" r  k5 L2 a( U$ n# k
  • 怎样在Drupal7中创建一个模块
  • 怎样在Drupal中使用drupal_get_form()创建一个表单& j5 ^) C6 k: B+ C
我也不会对教程中的CSS和JQuery代码做过多的讲解,你可以直接复制并粘贴到本地去试验。呵呵,我的目的是如何将CSS和JQuery添加进Drupal中。
+ K* h( g0 g% `: n开始吧!
4 R( `0 m3 F6 ?5 k* M  e9 A第一步:使用hook_menu()为表单注册一个路径. k+ x& I3 i9 P: ^
我需要先注册一个页面路径好展现表单,下面是hook_menu()的实现:
' m: ?  `5 z5 o' S+ f8 w! R* O6 t! D! k) J: X+ k* `% q
<?php
! P! f* o& D8 o, I4 |function form_theme_menu()7 @! e. o& \. \5 g, S" p
{
$ A; ^, P8 L5 x' n    $menu['form_theme'] = array
# G  z* W* W) y: L4 h) k7 L    () f9 F9 c3 ]5 ~9 |5 h8 S: b( r7 t
        'title' => 'Theming Forms',: _8 H$ `3 `% ?8 C. N
        'description' => 'Practicing theming forms in Drupal 7',% e. H3 C3 s  k
        'page callback' => 'drupal_get_form',% B, O& j5 S0 p. D- r2 ^- P' [! ~
        'page arguments' => array('form_theme_form'),% q9 _" {$ s; x+ P
        'access callback' => TRUE,
8 P& ~( y2 R( @0 `    );
. N3 N# l3 G+ p# N3 j& o! }( v    return $menu;7 R+ q. ?4 X; p, r% m! Y. D
}
' Q! L1 s2 a9 e; P$ U$ B4 A; F# G?>
: h8 R3 c8 h; V3 w* i) H. L
! C; Z' K2 q; \6 H0 u
第二步:定义表单% {  p2 A' ?. F
在我的表单里,我需要三个textfield,表单定义如下:
1 a9 w  B+ b4 d' y9 x
# f8 p' M4 [0 I# c3 M2 t1 U<?php
1 I1 D/ @3 z  U  f$form['first_name'] = array
3 N' \- a6 t5 E9 a  C4 V1 W(1 ^( Z( O0 E* I0 W9 X% A- [' g: E' Q
    '#type' => 'textfield',
8 c- T5 J1 s& ?- l0 I7 ^  \);
3 m& v5 q& {5 x1 B$form['last_name'] = array
; b9 [+ h9 @- l9 H(* \: g$ J, @5 _! S! i1 w
    '#type' => 'textfield',# H, Q) P! M' ~: p/ o! F
);
+ L; }( v+ z2 }5 m- p9 e8 O$form['age'] = array5 d4 V  V. I2 w
(# Y) Y- M& ?+ ]5 u
    '#type' => 'textfield',
. N* {% C( X  B$ x' k. G    '#maxlength' => 3,: P9 I$ @0 n2 {$ ^' H% k" {
);
6 K( ^# e* V$ G& h; i( {! s8 M?>

% @/ s5 ~( T& J9 e. ^& g
! N' ?$ T$ _2 A0 g. W- b5 c( m- j嘿嘿,代码十分简洁吧。我已经创建了这些表单元素,它们没什么修饰或其它配置。
9 m) {8 y/ r' o- n4 G& U然后,我需要添加CSS和Javascript到该表单。Drupal7有个新属性,#attached,我能通过它添加,代码如下:
6 G+ x, y* Z/ w" D( }0 B. z& Y7 b( O. q- ^8 c4 ?- O
<?php2 @* [) ?; P1 t  k
// Get the path to the module
, V) e$ a/ [- Q0 h$ J: {2 H- S2 n$path = drupal_get_path('module', 'form_theme');
1 ^  S2 D5 i  a! _- C! D  G, a) [; ^// Attach the CSS and JS to the form
2 E5 W; [) t- B( _- r0 l$form['#attached'] = array0 O" o  v; i6 e  N; K
(
" ~9 b+ t0 W; s3 X! c0 n/ a! u    'css' => array5 |0 c) g& n% J
    (
2 p0 b: P! G4 m" G% I& g8 k9 b! X1 x        'type' => 'file',
+ K% R- c) K) w+ g3 N. n1 J        'data' => $path . '/form_theme.css',, s. t9 }+ q) E, f, e" h/ K+ F/ A
    ),
& X: @- ]# K- U% _8 l# c    'js' => array) Z9 E% _2 G6 i4 u7 I8 i  w3 r+ L
    (0 J* ?! X# Z3 p1 c+ `% N
        'type' => 'file',
9 q/ B" [1 B; p2 N1 ~        'data' => $path . '/form_theme.js',/ Q1 b3 @- ]6 H9 {$ `
    ),
7 o2 H9 x) `; F, I  [);
3 u1 U) G6 v, @$ ^?>
1 P* c$ ^  a; q' f' c8 P; r' M* D

- k6 |! o$ h0 C% W这种方法相比drupal_add_js()和drupal_add_css()有个很大的好处,就是其它模块可以在该模块的样式和脚本的基础上做修改。2 z5 x0 d1 E+ T9 K4 |1 j! r
最后,返回我的$form表单,代码如下:
: n9 K- K" S  t$ P; c7 C" Q4 f
* v; o9 C, T8 |- U  {<?php9 ]. U7 C. ?7 G( \
function form_theme_form($form, &$form_state)
' Z& W* V0 s8 c% u* _{3 V% d, V1 Y2 A1 v1 L6 @" Y) A3 p
    $form['first_name'] = array
# }3 ^( }) Y$ B' w- H- A) `# U    (& W% J7 ^; W" n6 f* g% i$ C
        '#type' => 'textfield'," i7 [" `9 s$ h4 W' w- E/ {( S
    );
+ ]( o7 G3 W! T; w    $form['last_name'] = array- S$ S; S7 z* _, Z( ]
    (  Y, D. ?* j$ j/ M) ?) d
        '#type' => 'textfield',! e$ f3 \4 R0 }# h$ P8 c
    );
7 o3 E, _. Y" P* c; N5 l    $form['age'] = array
4 X4 w) [9 p' |! S4 {) q! ]) e    (5 y1 ^# |# m% a0 Q
        '#type' => 'textfield',/ S0 Z) B6 x! E+ d9 c
        '#maxlength' => 3,
& i% h* s) i1 l# e0 I# H    );) H# t& R, J5 `" ~; J0 w% x1 ?& K
    // Get the path to the module: K8 X* H' g+ _) x" k
    $path = drupal_get_path('module', 'form_theme');# A9 E( X0 k/ t: u. p) ^- x/ h
    // Attach the CSS and JS to the form
6 }" M7 l: |" n* m. |    $form['#attached'] = array, V+ F6 W0 o4 |
    (
3 |/ {. d! S& h4 t; {        'css' => array
- B' B! D$ ]" e& p        (
$ H7 U0 r9 Q! K  P& Z' L            'type' => 'file',. c+ @0 g# d( O& \6 `8 o  C2 ~& S
            'data' => $path . '/form_theme.css',, z$ _* e% k+ c4 N
        ),
2 p) J* `# s& M7 W- W1 g9 r        'js' => array
' P+ Z8 w2 }, A1 _% _' e" x4 H        (% ^" u2 x# p8 d; g# {- o8 e3 @
            'type' => 'file',( A3 K6 i5 I; l. @4 M
            'data' => $path . '/form_theme.js',
/ p, ]2 q- N( v        ),
6 H: T: K! [% F& _3 p$ c    );$ }8 j& `" D* h/ q. H
    return $form;
) [& a. b; `+ x/ w1 B! l}
2 F: L: _+ B1 F4 p* ??>
7 B3 J0 M  F. {+ }' N. ]+ e
% Z# h3 z% b4 w, z% e  p
第三步:用hook_theme()注册一个主题函数
' V& U# _" e6 S. K! {7 S从Drupal6开始,主题函数就需要通过hook_theme()注册,但是在Drupal6和Drupal7中还是有些细微的区别。在Drupal7中,表单的主题函数不是使用“arguments”,而是使用仅仅只有“form”一个值的“render element”。在注册主题函数时,你必须让索引和你已经定义的表单函数保持一致。代码如下:& z* ^5 T! A% P3 O* b; z

4 T* I+ w: U* I, v<?php
, r) a$ Z! w# v/ E/ Q3 Q  ~function form_theme_theme()7 c3 F7 R: ?# j+ T" V8 F5 Z
{( c7 F! f+ Y; X9 M7 V9 |1 p$ l
    return array
! P( U- m+ b4 Z4 u/ n    (
' q6 X6 [7 L  {# w! A3 X3 p- e        'form_theme_form' => array
3 y. }/ v( G& ]7 ~        (5 v7 f# u# Y; B+ q* u
            'render element' => 'form'7 V! Y. n! R: T) D& ?
        ),
5 J+ C, i+ _2 j+ B    );, Y. U$ u8 c% Y
}, q( L7 ~  a( E. g( b/ }. [' T  H1 X
?>

0 P) n! D1 v, C- A, [8 s9 m9 ]$ b) o: Z6 w+ @* v
正如你所见,我已经注册了一个主题函数。主题函数的命名十分重要,因为这个主题函数跟表单有相同的名称,Drupal在实现这个表单时会自动调用该主题函数。我也不需要添加#theme到我定义的表单$form中,这是多余的。
- H# N& I/ e; E  f6 H第四步:写主题函数( w$ i7 Y7 ]. \- o' K% S$ K
在Drupal7中,写主题函数,有几个注意点。它们是:
3 I* ?4 j4 k- }0 n9 P
  • 函数只有一个参数,命名为$variables的数组。$variables有一个form索引,该索引的值就包括所有你已定义的表单元素。
  • 所有的表单元素必须要作为参数传给drupal_render()函数。这个函数能将一个PHP数组转换成HTML,并且将Javascript和css添加进去。这些Drupal会自动帮你完成,你仅仅需要传递这些参数就行了。
  • 在写主题函数的最后,你必须将剩余的表单元素传给drupal_render_children()函数,这样才能将剩下的或隐藏的表单元素转换成HTML。这是跟Drupal6一个很大的不同。在Drupal6中,我们直接传递$form给drupal_render(),但是在Drupal7中,这样做就会导致死循环,而且不会出现任何错误提示。
    : k. W$ m- J- @. U2 F3 L" Q: J/ C
主题函数是以“theme_”加上我们上面注册过“form_theme_form”命名的。代码如下:
1 L4 M4 K& ]9 V$ L1 x" m& H/ H- o7 n
<?php% d+ N2 U) ~) P
function theme_form_theme_form($variables)& _* P% \9 `/ X) a- W' p* {
{
& W8 H, N. K0 F; R    // Isolate the form definition form the $variables array
: R) {: X0 H3 S: C$ S1 t8 j3 ?    $form = $variables['form'];
& R1 l0 g2 R/ {9 [4 |/ F    $output = '<h2>' . t('Please enter your information below') . '</h2>';: l* M; ^$ f( W; v1 u
    // Put the entire structure into a div that can be used for$ p1 e5 C! j+ s( G3 m
    // CSS purposes+ I- T9 Y  }" j8 r5 e0 s
    $output .= '<div id="personal_details">';! |: @" a  J3 j0 C4 o# u) ]( `
    // Each of the pieces of text is wrapped in a <span>
  f! ]% v& s8 W" ]% g5 g8 O    // tag to allow it to be floated left
6 ?4 R( x* v0 m- e7 w4 `. D! E    $output .= '<span>' . t('My name is') . '</span>';, o* ?, X+ u% r8 ^9 }; w
    // Form elements are rendered with drupal_render()2 x% |. F, Y. x
    $output .= drupal_render($form['first_name']);
8 X( \0 a4 e* E    $output .= drupal_render($form['last_name']);9 z% V9 M4 ]4 F& g8 ~
    $output .= '<span>' . t('and I am') . '</span>';( P: r6 I( T: Y$ M: Y8 Q0 N4 R
    $output .= drupal_render($form['age']);
) y0 f  M" o/ h: p8 U    $output .= '<span>' . t('years old.') . '</span>';
. X* c9 f3 ?- H6 `: ?4 s    $output .= '</div>';
+ x( D3 p6 _# U    // Pass the remaining form elements through drupal_render_children(). o9 c, {; M: k
    $output .= drupal_render_children($form);% Y6 i* ]/ }7 S7 @' ~8 M# _/ a" i
    // return the output# }5 V2 ]! {8 X1 m
    return $output;
+ H+ w: [1 O6 L$ z+ b}4 H9 |! C2 y9 W9 k
?>

4 K6 ~/ {9 z" o8 {4 |' n2 Y& Z- T9 u$ Z' T  ?0 ?! C( D3 }
到这里,我已经完成大部分的内容,定义表单,注册主题函数,实现主题函数。但是我还没添加CSS和Javascript。
0 {7 u" w  \  }0 h! l8 f! o第五步:创建CSS和Javascript文件1 }! F( k8 e! A3 z
在第二步中我添加了CSS和JS路径,这两个文件都在form_theme模块的根目录。CSS代码如下:0 N( i8 d7 m# K) t- E

- J3 y( a: ~. e$ N#personal_details span, #personal_details div( T' s) h" \$ P/ w/ v& D; m
{
' [6 H! E2 |! F( b9 Dfloat:left;
1 n  ]  P( g! C2 m8 X" ^}) u+ K. }. U4 |- W0 j% _) ]
* R% u9 p4 o. x8 U) ]  N5 G# w
#personal_details .form-item-first-name, #personal_details .form-item-last-name- P+ q2 K6 w5 o: k
{  G: s" F8 f, @/ t$ f! t5 ]
width:115px;
+ Y* S% ^. N6 I" Z}/ o& i  o% w4 e. v
5 P8 i7 j4 j( \$ a
#edit-first-name, #edit-last-name& F4 n0 U% e3 g7 K/ B/ s; V5 N
{
. ^: h) G3 m) \4 jwidth:100px;& ~# m' d/ t+ i- N: x+ J& |# K
}& W, ^( _! @8 }7 z
. l. b. T8 z# `2 F
#personal_details .form-item-age
& ]+ D% w3 c. R4 v( z) K/ W{5 `0 `3 w- r: X2 _3 |
width:50px;
! \+ `$ w) `9 R& [. J; I% v}
" G  B3 y0 ?! d0 I- K' S: n6 \: g$ M6 j, `
#edit-age
* ?2 m0 b5 U3 r( `# }* z' |{
" l; D, b- h. E: H, gwidth:35px;0 |9 x% k5 c/ r. v1 R- t
}/ i  E) [6 F" j

2 Q0 n, `8 Q  d1 ]% P#personal_details span! c" X' w& [2 }2 I; O6 z( _
{
) S6 R: U: p0 p4 |7 ^1 l/ t% @margin-right:5px;* I# o: t, F4 F% N2 `5 y2 ?
padding-top:5px;
8 d1 e: _3 H5 P9 T6 o* B: t) `% O}
- Q, Z! t- q9 Z( h4 |: N3 X' a. C) \! s0 \$ J8 P
Javascript代码如下:
5 b2 j" I! r5 e0 j. y- e/ f, X; `& @0 k
// We wrap the entire code in an anonymous function
% ?- ~* ^" e# W+ i; ~& o// in order to prevent namespace collisions, and to
3 |6 B) l) Y" ^4 f& f0 c" B// allow for jQuery to be set in a safe mode where
0 f6 N) V& Q0 e// it will not collide with other javascript libraries.: a$ [  u( c9 [6 a" l
// While this is the proper way to do it in Drupal 7,
' v& f" r4 W" _9 a9 K// this method is actually good to use in Drupal 6 as0 N6 d2 [, f. D- Z& s
// well, for the same reasons.: K2 h, s3 i' S, C$ J
(function($)
* s, p; R7 ^: M- O( q- H/ \{' H1 w9 u; Z% \
// In Drupal 6, each element of Drupal.behaviors; @6 t8 F3 m1 W$ D( |  ~
// was a function that was executed when the
, }7 M. d' s4 {// document was ready. In Drupal 7, each element1 Q9 |; Z% ~2 G( Z6 f
// of Drupal.behaviors is an object with an
2 x6 b" i8 s! b+ Y+ ~1 b// element 'attach' (and optionally an element9 X6 W% B( _& m; M+ ?7 l5 I! C
// 'detach'), which is executed when the document5 v( W7 g8 ?9 P% u+ j! A' k
// is ready6 o9 Z4 @2 V9 e5 z2 F; E
Drupal.behaviors.formTheme = {% ~# p  G% G( F; H" v: B& {( b
attach:function() {0 z- D6 |' x! b
// First, define an empty array
1 \- t( m9 c- j% z( @$ Q# u$ vvar defaults = [];
6 X' U1 p7 z: D- \# U- T0 \. c& i// Next, add three elements to the array,1 z7 @6 h6 I% N. f/ S
// one for each of the form elements. The value0 n7 \5 |1 ~8 o
// is of the array element is set as the default( m. t1 D: V0 `  }7 Z% V5 z
// text. This text is run through Drupal.t(),) V0 ^( m! s) D& R4 H
// which is the Drupal JavaScript equivalent
) i" F" v. `( S! U3 ?! j+ [# X1 V6 c, x// of the Drupal PHP t() function, and allows
2 e5 u3 `2 E* W) I8 R1 C  l3 G& T// for translating of text in a JavaScript document
; V( A- p! U; j0 |defaults["#edit-first-name"] = Drupal.t("First Name");/ ]9 R* n$ V2 ?! P( x: C0 H5 d# \) B- ?
defaults["#edit-last-name"] = Drupal.t("Last Name");3 R2 I5 D  T# W. I/ I
defaults["#edit-age"] = Drupal.t("Age");9 B/ Q" M1 @% b# \5 c, e
// Next we loop through each of the elements of the array
. P8 A* O2 Z  U& q( o. ivar element;
% v1 E  w* ]+ s9 Jfor(element in defaults)( [) t1 I! H9 `: m1 C' F) f* D% t
{9 N" K7 I  _" T" p, }* @' [7 E
// We wrap the body in the following if() statement
9 z& ]) z* M9 ]// as each element in an array will also have a! e: G( x: G! `7 d0 V" e. }0 [
// prototype element. If you don't understand this,
) ?& O, y( ^7 c* y/ C9 Q+ j// don't worry. Just copy it. It will make your
0 u& ^* n* V' f/ Y2 S1 F// for(A in B) loops run better.
3 s  u* q& q2 ]( j/ Gif(defaults.hasOwnProperty(element)) {
- `/ g+ z1 [! H$ A- K9 K// 1) Set a placeholder in the form element
# ?. m2 q2 q1 E; k3 @// 2) Set the CSS text color to grey for the placeholder& C6 K. z: N, X/ ~
// 3) Attach an onfocus and onblur listener to each element/ p, c- _, m/ g' c
$(element).val(defaults[element]).css("color", "grey").focus(function()
2 S3 k; j- W. {, {+ D8 P4 d, j{4 H3 b; C9 y  P* I, e. N
// This is entered on focus. It checks0 G* b. @( R% K
// if the value of the form element is/ O" H! ~- X/ A
// the default value of the placeholder,
. n4 t1 Y8 d# \) o// and if it is, it clears the value and. j4 Y" j! t& g9 ?2 }; u
// sets the text color to black,as the
8 R  f( A# m' Q8 |/ F$ X0 T. J// entered text will be the actual text
& \) Y5 B( Z0 y& m# X// and not the greyed out placeholder text.
% f. f: }. h5 A9 w6 Cvar key = "#" + $(this).attr("id");
$ V$ ~( w% W! w, y% o6 n) G& @9 oif($(this).val() === defaults[key]) {
% T  l! d  {  g9 C7 W- Q- O- M9 @: l$(this).css("color", "black").val("");4 _2 ^& ^! w3 y+ W* x) \% B! Q% D
}+ T: h7 N  G' f/ }9 S, v
}).blur(function()) K1 j' W7 W% w) J: G6 V
{: W2 J" a2 T6 ~
// This is entered on blur, when the element
1 Y1 a+ t4 y5 `; K" M! Z" p: F// is exited out of. It checks if the element; A2 ~, T' _$ @* t  \5 A$ y( A
// is empty, and if it is, it sets the default
& X! Y) f) O4 k% l& M// placeholder text back into the element, and
' I" A- x4 P+ Y// changes the text color to the grey placeholder! z1 |% f. D- s# }: P. a! l, T
// text color.
$ p4 @2 @" t5 H' e$ r3 U- ?; zif($(this).val() == "") {7 w7 i+ o" Y% B9 I( G% _
var key = "#" + $(this).attr("id");
- h. v" o( {$ Y! T) j( q$(this).css("color", "grey").val(defaults[key]);, G+ p. J+ j; L/ `' M; J$ {( b
}9 E, m8 q0 B% c" e7 d# |
});
4 h9 h6 ]5 j& J}- X- r' T; q( Q9 @# f7 j  g* F
}. J* b3 y7 ^9 h) }
}) F9 _1 N5 u2 _
};! ^, a  G5 b% C  s
}(jQuery));
1 q: ]# H! ?+ k9 n" @( ]# ~* J+ }6 e8 E5 `3 `3 \
好了,你可以试试看。% O; L& z( I2 d2 j
原文出自:http://junepeng.info/zh/node/286 q/ l/ X& A$ c
: q7 K9 ]+ P/ [, [% Z: s4 G
) H/ s8 o4 e# f0 i$ M& I3 p! e
' |4 Z/ d5 H* d) J' d

# U3 ?  \' ~6 i$ a  A7 R/ t, L' K# I9 O4 R& c  [

1 W1 y9 D+ K- {' J$ k0 ?  C

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

GMT+8, 7-4-2025 09:39 , Processed in 1.980925 second(s), 159 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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