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

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,微信登陆

搜索

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

[复制链接]
发表于 10-13-2011 02:13 | 显示全部楼层 |阅读模式
Drupal7表单定制和Drupal6大致相同,但是也有一些区别。这次我就来说说Drupal7是如何定制表单的。新建一个“form_theme”模块,然后创建一个表单,显示如下:
/ p) e; J, j2 ^7 H' IMy name is [FORM INPUT] [FORM INPUT] and I am [FORM INPUT] years old.
2 n& O3 C2 q! J' x. Y这三个表单元素的默认值依次显示“First name”,“Last name”和“Age”,当用户点击某个INPUT时,该表单元素的值为空,然后你就能随意书写了。- j: w& \1 {* c/ O
这个简易的功能涉及到:
8 N$ _% y2 e3 J1 I0 B- c- ?. u
  • 主题化表单
  • 给表单添加JQuery(JavaScript)
  • 给表单添加CSS9 p% _  j, `- |% a  d+ f
这个教程的主要目的是学习如何主题化表单,我不会对一些与主题化不相关的代码做过多地介绍。同样地,如果你想看懂这篇教程,你必须先知道:
" u: t6 N" L, n$ Z5 ^
  • 怎样在Drupal7中创建一个模块
  • 怎样在Drupal中使用drupal_get_form()创建一个表单
    * I4 d$ \. Q4 d1 d. |: l
我也不会对教程中的CSS和JQuery代码做过多的讲解,你可以直接复制并粘贴到本地去试验。呵呵,我的目的是如何将CSS和JQuery添加进Drupal中。
1 R) t2 [, _$ |1 c) |3 e" D$ c, _开始吧!
& ]$ S7 i2 f8 v: d3 a第一步:使用hook_menu()为表单注册一个路径
! h: q- d2 P' z/ [- L6 ~% ~6 M- V我需要先注册一个页面路径好展现表单,下面是hook_menu()的实现:
! y; t( w/ `- H; ~2 V, ?5 u% z: G5 A3 v9 i2 k
<?php
* _- @1 F( a, r- h# }function form_theme_menu(), t* b5 q+ i5 h4 W" V* N
{( V, U% f. k, Q1 v/ J; }2 O) l
    $menu['form_theme'] = array
9 d0 L$ R7 j7 c# t/ f% ?$ `    (3 ?0 f' z% H" U  t* j
        'title' => 'Theming Forms',
: K6 n' X. ^4 C& t3 ?4 M6 ?) G        'description' => 'Practicing theming forms in Drupal 7',- q$ P) ~: o( T0 P4 }7 B( G
        'page callback' => 'drupal_get_form',1 \* p, j1 _* U' ^/ j: u
        'page arguments' => array('form_theme_form'),0 C) y8 [. H, ^" v& o4 X
        'access callback' => TRUE,) [: T; ^# x2 x2 p( F  O! |6 x5 L
    );
5 @, f, S9 ]: M0 o4 Y3 m$ Y# B    return $menu;
2 P6 q/ \2 Q/ h5 k4 F}* A- f& |( l: }& V8 t+ b# r
?>

) ]0 _$ Y, o) y( P: T; A8 _# ^7 Q; [/ o5 T: w
第二步:定义表单* e# J0 T& J" F0 `9 m& B
在我的表单里,我需要三个textfield,表单定义如下:
# G5 ~4 c- s) C- ?% G: h  w! @% {
7 ?/ `# r. S$ r3 p+ ?<?php; l- E- X1 h- U8 c( q$ F! `) [# J
$form['first_name'] = array) ]+ K6 K) G7 k( e1 y+ |0 U- U" r
(* }5 c9 O& F% p$ R; [
    '#type' => 'textfield',
) W/ Y# M% j' N6 t5 S) V);
4 L- t% B  O8 C9 v6 D* E$form['last_name'] = array
! l1 Q9 J$ ^( A(, L1 I$ c& B% j* v& u
    '#type' => 'textfield',
" B# a$ t- |# h) ]7 W/ V! y4 D5 W1 L);
6 v, }) U9 A5 ?( a  l( s1 M$form['age'] = array; P/ \3 _6 L. O+ G2 Z+ y
(6 N, X* R* X0 O2 N1 z% a
    '#type' => 'textfield',
( I% n! a% ]2 K' f4 x! b) k    '#maxlength' => 3,3 N7 V  B2 K/ \* h% v' Z9 T
);
; M) Y: r- G6 S?>
: Q9 b3 W8 U# Q. m3 ~

/ G4 y: A& k+ X1 Y嘿嘿,代码十分简洁吧。我已经创建了这些表单元素,它们没什么修饰或其它配置。
& w& g! z. j: x4 \7 f" M然后,我需要添加CSS和Javascript到该表单。Drupal7有个新属性,#attached,我能通过它添加,代码如下:
/ c8 ~( C9 O6 R! R6 A. B
2 {# P" ]) o% B! L) G, B  _; B$ n<?php( i7 v* L" O$ `6 z/ u
// Get the path to the module
. _6 e% T# D4 e7 k# a* S; c$path = drupal_get_path('module', 'form_theme');# I5 d5 V% T! X
// Attach the CSS and JS to the form
6 [/ d" Q# \, K/ K! B7 e: z' v$form['#attached'] = array
( V5 r/ N: ~- J4 f1 r2 b. `(
$ j0 k# ?: V9 Z  E7 N5 ~    'css' => array
* q: K2 I2 }% c    (
% n, L) U& f, v  M% _        'type' => 'file',7 Y1 {4 j4 i0 `1 F
        'data' => $path . '/form_theme.css',
3 {7 W' F: }8 w# Y' s# [* f    ),
  z" Q' p) ?+ O- d, ]# \    'js' => array
: t4 ~6 T5 ~' z$ E2 D' F: Z    (
1 e0 V8 ]9 q' z2 x        'type' => 'file',2 f' v# E, F9 C3 M
        'data' => $path . '/form_theme.js',2 j+ H7 Z3 K9 ]# ]" p* _$ a* t
    ),
2 h9 x' W3 P/ P( Q0 ^);
$ W0 _: ]* o- y: M1 u4 U?>
- M* e9 n7 V2 A2 ~. y8 F
- x. y0 k/ i& v* `
这种方法相比drupal_add_js()和drupal_add_css()有个很大的好处,就是其它模块可以在该模块的样式和脚本的基础上做修改。
8 b# C7 n7 O  R最后,返回我的$form表单,代码如下:% E0 p2 T" X, D4 Y

/ b. \% H/ [5 _% m2 ~9 D/ s<?php
( u, v! S7 ]1 g6 afunction form_theme_form($form, &$form_state)4 U2 I; q  ~* l; a5 ^9 r
{
8 c9 S2 o! R5 [) C1 t" y    $form['first_name'] = array, H2 P8 r/ |8 e: T& M+ }& q0 w  W
    (% R: R0 x! Y: T8 e" [
        '#type' => 'textfield',
/ X6 U6 T- x( z. F, }5 @    );! `1 \) r! i( ~1 S) ?. e7 y- b
    $form['last_name'] = array  X' |$ k, m; K8 U, L% V
    (/ L1 Y- R0 M' x9 ?! k/ N  R; B
        '#type' => 'textfield',
/ |$ u# g( w* ?' u; [$ s# o    );
! w' j- |% [9 i7 K    $form['age'] = array( r5 G9 c8 O% k5 C% `& j, T: A
    ($ Q. n4 J2 Q% z$ B7 ^
        '#type' => 'textfield',
2 g8 t: h  _- U' q! ^2 j. e- J        '#maxlength' => 3,
& P8 S( n' z, A) d  u4 C    );1 U. G' t3 c$ x; [0 j4 ?2 ~
    // Get the path to the module3 l( K. l  b3 c" T
    $path = drupal_get_path('module', 'form_theme');
% V0 r) G, W+ O2 j8 d- m    // Attach the CSS and JS to the form% |7 V/ T5 B2 D- H! N# o
    $form['#attached'] = array
) h. S$ H& X  \0 A/ S    (
5 C6 j, H& C9 u. O% Y: w) \# `* I: {        'css' => array9 N$ p& U4 G/ T- f) k
        (. R# B" z6 v* ?( l
            'type' => 'file',
. `+ }( X% p/ g; w            'data' => $path . '/form_theme.css'," c0 ?3 Y$ g! ^, Q- M
        ),# I/ a1 @/ |) m: V, w7 Z7 d
        'js' => array
% b- W' j' u% y! H& p        (1 E5 p( z% [/ b0 {2 M' Y
            'type' => 'file',  D7 m5 [  \; Z. D. T
            'data' => $path . '/form_theme.js',
' [5 v$ }3 S8 I. g        ),4 }3 X. g1 P4 O
    );
/ Q, S$ E0 |# a    return $form;7 d0 s5 p5 F( P6 K, z
}. h4 X1 [6 i1 w8 T
?>

# s" q1 |: m3 m2 t# U5 c4 C' b4 G. j- \9 J! U+ P
第三步:用hook_theme()注册一个主题函数. i3 `1 I9 G( ?6 B6 V4 ?9 u& q
从Drupal6开始,主题函数就需要通过hook_theme()注册,但是在Drupal6和Drupal7中还是有些细微的区别。在Drupal7中,表单的主题函数不是使用“arguments”,而是使用仅仅只有“form”一个值的“render element”。在注册主题函数时,你必须让索引和你已经定义的表单函数保持一致。代码如下:8 D! d( E/ m, t$ ?
7 ?# n0 Z! @" j6 S* Q. [
<?php
# \" j3 Z- t/ U+ `0 wfunction form_theme_theme()
. k9 H7 ?  [/ @. x{$ s; ]& j6 N3 l
    return array8 J+ p) v9 u6 h6 M5 I3 k0 Y, k
    (7 z  q/ x+ g2 R$ F5 O9 N
        'form_theme_form' => array
  U1 Z2 c* C+ Y' A  W$ s        (9 u& W! e2 N7 k' g
            'render element' => 'form'% l" c8 o9 w) S" ]; ?+ V
        ),  i( E" w) |& }5 H
    );
. P# w3 `1 G, Y$ i& A# R2 i% M}
6 u% D# X( Q, b" b4 y?>

( C  G' J7 F* a$ w9 c( ^6 g, [* {+ W. s& y3 E% Z6 Y/ ]: ]; n
正如你所见,我已经注册了一个主题函数。主题函数的命名十分重要,因为这个主题函数跟表单有相同的名称,Drupal在实现这个表单时会自动调用该主题函数。我也不需要添加#theme到我定义的表单$form中,这是多余的。
4 b8 z; q( W/ L8 E: N% U第四步:写主题函数
0 `3 U* C$ ?2 t% Q/ X# t在Drupal7中,写主题函数,有几个注意点。它们是:
; K3 d" U/ q8 Q$ m5 `
  • 函数只有一个参数,命名为$variables的数组。$variables有一个form索引,该索引的值就包括所有你已定义的表单元素。
  • 所有的表单元素必须要作为参数传给drupal_render()函数。这个函数能将一个PHP数组转换成HTML,并且将Javascript和css添加进去。这些Drupal会自动帮你完成,你仅仅需要传递这些参数就行了。
  • 在写主题函数的最后,你必须将剩余的表单元素传给drupal_render_children()函数,这样才能将剩下的或隐藏的表单元素转换成HTML。这是跟Drupal6一个很大的不同。在Drupal6中,我们直接传递$form给drupal_render(),但是在Drupal7中,这样做就会导致死循环,而且不会出现任何错误提示。* E# O( u) ]  h+ d
主题函数是以“theme_”加上我们上面注册过“form_theme_form”命名的。代码如下:
) v% b, ]3 @% G' W7 Y! h$ M
) L0 K6 m, F7 f- I<?php
8 D# W* n' Q8 H$ j* gfunction theme_form_theme_form($variables)3 j/ i) h& m' x! t' V8 p' r
{
. A* w7 E( Y" V% {    // Isolate the form definition form the $variables array2 d; w5 s/ g# N6 v3 \' r: G
    $form = $variables['form'];
3 ?8 ^+ D( C4 S# R  ^. u3 w4 k    $output = '<h2>' . t('Please enter your information below') . '</h2>';6 W5 }$ M$ r3 X' w" r, j, w
    // Put the entire structure into a div that can be used for
0 T- ^0 n* P. ~" m: X6 g    // CSS purposes
+ I2 S2 J- x0 T  s: W, u, ^" S1 o* T    $output .= '<div id="personal_details">';
8 `) [' k. E# l2 g* v    // Each of the pieces of text is wrapped in a <span>
7 P2 t  M% b; @# ?5 D    // tag to allow it to be floated left
! O, z& y$ ?+ M* r: v- A  |    $output .= '<span>' . t('My name is') . '</span>';
. A1 c2 h) m  A& F( R3 k$ O    // Form elements are rendered with drupal_render()
0 T9 Q, h& Q' H$ i    $output .= drupal_render($form['first_name']);
8 `4 N. B5 ^' h: m  t  c+ q) A    $output .= drupal_render($form['last_name']);% L- O4 Z$ S2 E% ^5 k1 J
    $output .= '<span>' . t('and I am') . '</span>';: Z5 K9 b  v* l$ ]: q+ O- D6 o
    $output .= drupal_render($form['age']);
2 _( c. R$ }5 j, G$ @# ?6 J    $output .= '<span>' . t('years old.') . '</span>';6 ?3 O% G3 i$ r6 o7 O& }- P
    $output .= '</div>';1 \0 e; U# x" n* Q- S2 m9 L0 ^
    // Pass the remaining form elements through drupal_render_children()' u4 p' E, z# K+ g3 }' T
    $output .= drupal_render_children($form);
8 B4 W( }8 f3 A) g8 [    // return the output) q( [; w( l' K. S. W
    return $output;6 B- l3 U6 G9 x
}6 s6 v# F* _" t
?>
/ x0 p, `+ R$ H( [$ Z

) j" X% j% V5 K" ~. U4 c. Z; K到这里,我已经完成大部分的内容,定义表单,注册主题函数,实现主题函数。但是我还没添加CSS和Javascript。
/ o. m, a) y! i% j% ^8 f第五步:创建CSS和Javascript文件
2 d( x3 V" o# d0 w" Y; c) K- h在第二步中我添加了CSS和JS路径,这两个文件都在form_theme模块的根目录。CSS代码如下:
( t3 V6 {3 b0 L  o' l. C5 H3 F% e
/ s' `% B3 c  w* h" ]#personal_details span, #personal_details div- j, y1 \$ e2 }/ }. G+ h" n
{: d1 O; z8 B7 ~  D( ?
float:left;
5 W8 Z0 m- C, ]8 ~8 H6 R: Z}
' X/ f3 X' J5 z1 Q
: p( Q0 k& h4 V; q" O3 P" H- D#personal_details .form-item-first-name, #personal_details .form-item-last-name; _' y6 I' X0 p% j1 Q2 y# k
{
  C) _0 m0 l4 mwidth:115px;/ `4 g' G* d7 Y9 ]8 N$ j
}
7 q& R( b2 a% I/ i" ~. d1 _
2 j) A  a$ v9 q' f3 e#edit-first-name, #edit-last-name1 ^7 I0 ^" d5 z1 D, f" `  |
{
! ~- U- E. k- B6 q- d/ s2 L; l- ]width:100px;
# @" \( |- M+ Y& Z}
/ e) y, Y9 t' t3 R- I% K' M$ a& t, s' _5 H* s) W1 y' q$ G4 d' `
#personal_details .form-item-age; ]! n) ]0 c9 q, x
{8 v; N0 }3 D) ^
width:50px;
( R% S( T$ D3 s9 d$ ?8 v}3 ~( V& l$ y( k6 q, `5 h

  E2 b( h) ~) z8 Y0 C9 @" |1 t#edit-age
2 Y" c3 b. b+ `7 B$ ]+ f& b; J{
0 q5 K6 l5 J- dwidth:35px;
8 }% ]' v  m* d}; n8 j+ n/ H5 B6 N& V2 q4 }

( M) a  w" E0 _9 L5 F  l#personal_details span: F7 R; ]* M+ ]- A6 ]( }
{; {* \9 \+ A- N( V, a- R6 q
margin-right:5px;# L9 p/ t0 N; C+ o2 t
padding-top:5px;
4 d  O# g( A& t}
5 m5 m$ i: K- z- M
* k- a* ?* h2 b# g. ?Javascript代码如下:- _2 o7 J9 @  a0 ~, t, W6 c

) H7 b. `1 ^" _  `2 U% y// We wrap the entire code in an anonymous function
: v3 x/ o3 i' p2 l// in order to prevent namespace collisions, and to
1 C8 ~% {8 x  f. L// allow for jQuery to be set in a safe mode where
" `  C+ ~/ E# U1 L// it will not collide with other javascript libraries.
# K: r% O! D6 \; M// While this is the proper way to do it in Drupal 7,5 L, X4 q5 e. k# n
// this method is actually good to use in Drupal 6 as
/ ~# b" z, |" B/ N' H. a// well, for the same reasons.6 V4 J7 v" V( B7 H2 R
(function($)  B6 s+ l( c$ o+ E# r
{; Q2 t1 [% b1 r& O8 b
// In Drupal 6, each element of Drupal.behaviors( i% l# v: N. Q0 w7 s" a
// was a function that was executed when the: x, g+ J- J, A+ E3 b& `, F" ]0 G. l4 D
// document was ready. In Drupal 7, each element7 p5 S; Q. d: E% O$ N6 R5 |
// of Drupal.behaviors is an object with an
0 T. z4 n' G" K' p6 I2 T: \8 w// element 'attach' (and optionally an element2 Q. }7 u$ t& y4 Q) ~3 n9 H
// 'detach'), which is executed when the document' e7 l0 y, t, I- A4 y# b* c* ?
// is ready
- F0 n+ F; R  J; Q# ]. SDrupal.behaviors.formTheme = {( M% q6 ^& i. m. _* H0 Q
attach:function() {2 U" F% _( O# i  ?. d, H
// First, define an empty array& {' {7 V, D' Q8 e1 i$ p
var defaults = [];
* D: P* @5 [) Z- J0 U// Next, add three elements to the array,/ m3 g# w5 c2 |$ z/ X. z
// one for each of the form elements. The value
( {: X6 e0 D; B( p( `; A// is of the array element is set as the default! ^7 P4 _/ i' l+ U
// text. This text is run through Drupal.t(),
* y: ^* U+ X! o5 i6 I1 b& d' m% d// which is the Drupal JavaScript equivalent0 Z0 G# r7 c& h7 z/ V+ t/ c
// of the Drupal PHP t() function, and allows  @  r8 Q8 X$ ]9 W! i) B8 o
// for translating of text in a JavaScript document
; @' H; ?8 B7 r5 c$ |# Jdefaults["#edit-first-name"] = Drupal.t("First Name");
4 w  u! B3 Z+ Y# ^) p2 udefaults["#edit-last-name"] = Drupal.t("Last Name");, V! U+ p: q1 T* ~( C5 m& l
defaults["#edit-age"] = Drupal.t("Age");! Q  ?  {8 J. H/ K4 j
// Next we loop through each of the elements of the array# c. I- t9 `' X, u) _' X
var element;. D% t7 M+ r  C1 X& a
for(element in defaults)
1 @0 K7 |) J* H0 h* C. v* x* O# T( L{/ b. m. Y  c1 e; U  p! M
// We wrap the body in the following if() statement$ q5 K3 P6 h* p, M9 R7 Z7 w; Q6 Y
// as each element in an array will also have a
* K) R# q4 O& l5 S// prototype element. If you don't understand this,! c& w6 p& w/ l
// don't worry. Just copy it. It will make your
7 a# M2 |" {( B+ @1 F* j// for(A in B) loops run better.* f# w. s1 x8 i7 z0 I% H" d/ n5 y
if(defaults.hasOwnProperty(element)) {1 W( k4 A' z2 j1 ^' K7 w- j
// 1) Set a placeholder in the form element
6 Q" P4 Y8 O7 J// 2) Set the CSS text color to grey for the placeholder
5 X) P* q; V; j6 T4 Y// 3) Attach an onfocus and onblur listener to each element
5 C3 u3 v* c4 l+ H  g$(element).val(defaults[element]).css("color", "grey").focus(function()
  T3 \0 j* U3 D8 G, ]{
9 F! R& ~+ i# @) P// This is entered on focus. It checks
0 C' h4 L3 i8 x% v/ _3 Y7 J// if the value of the form element is
1 Q6 O1 V- k; i5 u+ f6 E' z& X// the default value of the placeholder,% B* r" U; d5 M" m$ S* K- j
// and if it is, it clears the value and
+ ^3 }6 d. G5 c+ [/ {// sets the text color to black,as the
! i: _# V% l9 v& I. C  P* j+ D// entered text will be the actual text
* A3 i  n9 `" X. h# A3 a" p// and not the greyed out placeholder text.. X- m7 f/ R2 t' `
var key = "#" + $(this).attr("id");
6 ^( M" m) n/ n) d& Y% Z) Cif($(this).val() === defaults[key]) {& v6 p/ }; @+ i7 Y3 [
$(this).css("color", "black").val("");
! \9 n( [% f6 i* z& k}
6 \4 k0 y0 M! e( F) N8 i8 |& Z}).blur(function()  H3 z8 I$ q0 G6 r2 k
{
, l$ \% t$ o7 Z// This is entered on blur, when the element5 Y& v7 b" B' ~, |& J5 g/ ~& h! ]
// is exited out of. It checks if the element
' x, C; w. s# A6 S1 X// is empty, and if it is, it sets the default
& e+ l/ ^: N$ u9 G$ \8 v; R// placeholder text back into the element, and
( k- o# t3 b) E// changes the text color to the grey placeholder
, U5 X% K! A: x1 H, W// text color.
) R, O2 e( a1 a* R, B4 s7 rif($(this).val() == "") {
+ n' B& K8 i- Z+ Kvar key = "#" + $(this).attr("id");
4 L8 d$ v6 a1 I$ ~8 ~$(this).css("color", "grey").val(defaults[key]);) y& q* [2 p5 b, L* A: ~
}
' G2 ~. U  k! n' K});
7 l6 B* z) p% A7 ~+ j9 {}
. B! n* r2 C8 s. ?}
* \$ C6 A6 O+ ~' H" I: x}
7 H3 O/ X, D- U/ O2 w};
$ [) A9 q; J) A- P0 `% n1 [  ^) n}(jQuery));0 F  u8 r! O/ |7 u4 s1 `

- Z2 [  a. H- v3 v( k好了,你可以试试看。7 z8 B2 z& U6 z
原文出自:http://junepeng.info/zh/node/28
8 Z2 n/ a$ ~7 D& O: y8 {( d& g; T
' W9 p# J6 ]9 V2 L
7 ~2 R/ f! b$ Z4 @1 `$ s1 U0 L# r3 g4 \% L* O* q1 Z

! C, g7 \# A! X- P1 ^7 L# y0 E
$ e" E) j5 u$ b2 @/ `4 h
# m8 ?8 @7 E: l$ c9 w4 N1 G7 `3 B/ g4 X

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

GMT+8, 6-22-2025 20:20 , Processed in 0.637239 second(s), 158 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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