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

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,微信登陆

搜索

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

[复制链接]
发表于 10-13-2011 02:13 | 显示全部楼层 |阅读模式
Drupal7表单定制和Drupal6大致相同,但是也有一些区别。这次我就来说说Drupal7是如何定制表单的。新建一个“form_theme”模块,然后创建一个表单,显示如下:8 D  R2 T, I' X5 D) ?$ P  F
My name is [FORM INPUT] [FORM INPUT] and I am [FORM INPUT] years old.  W* H% d9 K: I' b# ]
这三个表单元素的默认值依次显示“First name”,“Last name”和“Age”,当用户点击某个INPUT时,该表单元素的值为空,然后你就能随意书写了。
, }3 F5 ]- P- Z+ ^: t- ?这个简易的功能涉及到:1 }/ P+ }# ^: E- p' O' o+ e
  • 主题化表单
  • 给表单添加JQuery(JavaScript)
  • 给表单添加CSS* Y5 Y5 `. ?* X: U  `. P
这个教程的主要目的是学习如何主题化表单,我不会对一些与主题化不相关的代码做过多地介绍。同样地,如果你想看懂这篇教程,你必须先知道:
' ^, N1 a: G9 k5 L) u3 R' p
  • 怎样在Drupal7中创建一个模块
  • 怎样在Drupal中使用drupal_get_form()创建一个表单1 Z2 f( s/ ~% ~% V" k# u9 }5 {. J
我也不会对教程中的CSS和JQuery代码做过多的讲解,你可以直接复制并粘贴到本地去试验。呵呵,我的目的是如何将CSS和JQuery添加进Drupal中。
- y% ]+ [7 N1 w# F# d开始吧!5 p& b; x/ @4 Q% ~# p, A
第一步:使用hook_menu()为表单注册一个路径# N6 R' M/ i* H( u$ k' G" b4 \
我需要先注册一个页面路径好展现表单,下面是hook_menu()的实现:- [! d! U% ?- H: L' L0 |
7 `( d$ |6 s3 R) P8 X
<?php
1 v4 L; L6 |' mfunction form_theme_menu()4 `5 V- _1 {; |  Y& w
{1 ?4 `* Z' \5 d( ~8 ]
    $menu['form_theme'] = array5 @( E# v% A* ^  X$ A  C! J
    (
& |$ p' n3 W: \" p- H- q3 M        'title' => 'Theming Forms',; q. C, _7 X) E+ @
        'description' => 'Practicing theming forms in Drupal 7',
) N+ @& o4 r( R: J9 w        'page callback' => 'drupal_get_form',
- ]( Q' S* K. S: C( x. P; A        'page arguments' => array('form_theme_form'),
% e# J& T% `9 L( ^$ X; I7 Q        'access callback' => TRUE,
  J! M$ D( h* K6 j6 Q    );" Q* G) ?  z8 d" r) L$ K4 Y% h5 h! f9 f
    return $menu;
3 t" |1 ~5 ?0 K2 `$ B2 l5 Q}
2 l) D8 t, {! V' b- `?>
, x/ G( |0 J. i' Q6 q' H. ]: I/ }) Q
& d" ^  ~+ c) w/ f% \
第二步:定义表单& K+ ]3 O5 F+ [6 O* }
在我的表单里,我需要三个textfield,表单定义如下:* e' v, _1 F  O3 g  C. p/ T

0 [& J# e! A; J3 I/ f5 @  h, M<?php
- h4 I) q9 f( Z$form['first_name'] = array: O" v9 H6 _4 D# Z
(8 a! l" M) v7 J. X, H3 s* a& W4 Y- ~6 q
    '#type' => 'textfield',
' z% O$ F2 s0 D- @" G);- u& g2 K2 @  c0 X6 R9 M- U6 u1 u
$form['last_name'] = array
  V/ _$ Q9 y) C$ y$ w(
0 E& \5 i( V6 X. e: O3 w    '#type' => 'textfield',# X0 |3 r/ \& E9 y9 Z$ {2 _7 Z
);
8 w! M7 r- g; f$form['age'] = array
4 c$ q$ t% |9 F+ c! r& U$ f6 |(
' P/ ^( O7 d1 S$ }  x    '#type' => 'textfield',
) l3 R1 @& r& k/ F7 S% E; L" ^    '#maxlength' => 3,
5 V8 \( g1 v7 Y7 P7 K);
! A1 w& c/ ]1 r# I3 \5 K3 _! {?>
7 p! }8 d  f+ a. }
; T" w' j5 b& W& I, |5 k
嘿嘿,代码十分简洁吧。我已经创建了这些表单元素,它们没什么修饰或其它配置。; R7 k9 Q1 z$ O
然后,我需要添加CSS和Javascript到该表单。Drupal7有个新属性,#attached,我能通过它添加,代码如下:# t- x3 l2 R& S& T  T

  M. ~" a+ r* t; @<?php
. K5 U3 ~$ w% J9 y3 ?// Get the path to the module5 R& S/ m$ |3 J8 P/ i0 P
$path = drupal_get_path('module', 'form_theme');& j1 K5 R4 l3 v8 J
// Attach the CSS and JS to the form' ~2 n% y' ^  n2 A: n$ [
$form['#attached'] = array: ?- d8 t+ j2 j' [
(& f5 v8 q( l/ c
    'css' => array2 H( S3 ~2 E% s% ]8 n) `) Z3 A& \* h
    (: t& ]; O2 Z+ h
        'type' => 'file',/ X! _0 J% R5 k  t$ U
        'data' => $path . '/form_theme.css'," o8 s: a/ D/ y: `
    ),
* J: `4 w+ n% q/ s0 ?" t( ~5 H    'js' => array
, N: G( p% [" m' t5 o+ {% L/ H0 s    (8 g* V& y1 D$ D. m# E7 }5 I1 T
        'type' => 'file',
. d3 J( o3 S( l0 N        'data' => $path . '/form_theme.js',
  }$ f. S3 J" \3 O    ),1 z7 I9 u7 |, S9 M2 B
);
4 n$ A# p# v  M8 e?>
1 P# [: U, `9 n' s$ F

7 e& W- }" {$ Z: w  A这种方法相比drupal_add_js()和drupal_add_css()有个很大的好处,就是其它模块可以在该模块的样式和脚本的基础上做修改。
( a5 E) P: ^5 y+ C' n5 \最后,返回我的$form表单,代码如下:" C% |2 X" Y7 C/ B3 \7 }- H

3 v! z3 c& i& h+ h<?php& H+ J. W6 o7 _* w+ N5 \+ W
function form_theme_form($form, &$form_state)
" o( P, i% i! K; `& q{; g2 f# Y  M. G) z' d6 N" l( M
    $form['first_name'] = array
" ~5 A( N5 }& m/ x* O- U    (
, y" o+ M4 R1 k3 \- j        '#type' => 'textfield',: z. C0 K& ?6 K' K. W, f2 ]0 j4 q
    );
# D! X- [. q% Y; v    $form['last_name'] = array
) O/ n  P  \! M2 l/ n% I    (+ f+ k% H' T6 H# C( j# ^; G% s# U. C
        '#type' => 'textfield',
+ D7 x0 w+ w1 E* F" A) `    );
* g. ^1 H" h5 `. H5 y$ e1 s" `    $form['age'] = array
: A/ ^3 ~: S5 L) s    (' }& B1 E0 L) x( a( a# [
        '#type' => 'textfield',2 I% Z: G9 z$ g1 o3 ~
        '#maxlength' => 3,3 S) P& ^; X% K- ?
    );7 }1 `' e+ }; b7 ], Q
    // Get the path to the module! E" _6 b' a, k9 ?) `
    $path = drupal_get_path('module', 'form_theme');
2 q: p9 r$ @) Q% `; c1 L! }" C    // Attach the CSS and JS to the form
1 L# ?0 O/ W& [1 O$ k7 t  A, G7 h2 K, G    $form['#attached'] = array
, \8 g( K& [+ a3 U6 F    (3 D& t7 g& A: W6 `. ?& H
        'css' => array. g% p1 s1 \& J8 b. C" B
        (
" C* e  [- G. r) _. A  ^: {            'type' => 'file',) d+ w* x4 [$ b3 K' i
            'data' => $path . '/form_theme.css',8 V2 H4 {* J9 L8 V& t* o+ P) b8 r
        ),! G; i- p" ]2 d
        'js' => array
( p/ G1 I+ S2 r* N# E        (  u% `9 c. V. A5 g) |3 U
            'type' => 'file',
# Z. {) Y/ ~# L: T2 E0 j            'data' => $path . '/form_theme.js',
' ^) @' m1 [$ k        ),
1 F& h' @6 A' h, Q/ Y( |* d    );
% H' C3 D% {$ T" L9 G' m# G    return $form;& s, r2 E5 x. ]1 ]# Z5 `( O
}& Q  l- {+ T/ Z3 d) A- {; H$ M
?>
7 s/ ]& y" [2 q" u
# F) d; t$ N; A3 [
第三步:用hook_theme()注册一个主题函数
- ~% n2 w8 w7 ]  \: d0 B从Drupal6开始,主题函数就需要通过hook_theme()注册,但是在Drupal6和Drupal7中还是有些细微的区别。在Drupal7中,表单的主题函数不是使用“arguments”,而是使用仅仅只有“form”一个值的“render element”。在注册主题函数时,你必须让索引和你已经定义的表单函数保持一致。代码如下:/ `" D' O7 {0 X6 W4 U  _7 S

( \8 B- [7 J9 u! s<?php$ o# Q9 w8 `3 g/ u; @" H
function form_theme_theme()5 Z1 ~8 Y; p% o9 L; U( A
{! J, G& u0 ?6 H. S  ^( ?$ a+ \! c
    return array
* d. H4 P# m1 h/ t$ l) B    (/ o1 ]. j, k/ K! A/ V; ~" n
        'form_theme_form' => array
+ J* B* @4 E9 {5 M/ t        (
9 }) k* d; G. n( ?            'render element' => 'form'4 s- t" B9 D  E7 n& h
        ),
  w9 N/ n3 F! X: i' w. T! I  O! w4 _    );, Y6 {) i& G  K1 }" ~( f6 c- X
}
* X+ q7 Y& q2 @# f* O?>
. `8 E" I3 B! ~2 v4 j) Z: l4 c( x1 e

) P. \* [" C! p$ d& R# F正如你所见,我已经注册了一个主题函数。主题函数的命名十分重要,因为这个主题函数跟表单有相同的名称,Drupal在实现这个表单时会自动调用该主题函数。我也不需要添加#theme到我定义的表单$form中,这是多余的。
* K0 [/ }4 N. j' r8 y2 i! \+ F' V第四步:写主题函数
" B8 O: p/ v3 |在Drupal7中,写主题函数,有几个注意点。它们是:
, @3 N9 m9 ]. n5 g
  • 函数只有一个参数,命名为$variables的数组。$variables有一个form索引,该索引的值就包括所有你已定义的表单元素。
  • 所有的表单元素必须要作为参数传给drupal_render()函数。这个函数能将一个PHP数组转换成HTML,并且将Javascript和css添加进去。这些Drupal会自动帮你完成,你仅仅需要传递这些参数就行了。
  • 在写主题函数的最后,你必须将剩余的表单元素传给drupal_render_children()函数,这样才能将剩下的或隐藏的表单元素转换成HTML。这是跟Drupal6一个很大的不同。在Drupal6中,我们直接传递$form给drupal_render(),但是在Drupal7中,这样做就会导致死循环,而且不会出现任何错误提示。6 j' b8 p# a' [0 x- u8 p
主题函数是以“theme_”加上我们上面注册过“form_theme_form”命名的。代码如下:
. Y; V% T: c! Q- `3 I  w; b+ J3 \  a
<?php
9 b. {# S5 ?+ P4 X$ Sfunction theme_form_theme_form($variables)
& e5 W6 D# ~' p{
* l' {; b' a% d7 ]" w    // Isolate the form definition form the $variables array
, r( F: `8 E$ a* T/ f4 H    $form = $variables['form'];
+ N% v) n+ e. U( U0 Z    $output = '<h2>' . t('Please enter your information below') . '</h2>';
: }0 o8 l6 x1 J" k  c    // Put the entire structure into a div that can be used for  J1 j2 ?, |/ N: U% `0 M1 h
    // CSS purposes' g) r8 G- O( c+ ~2 V6 r
    $output .= '<div id="personal_details">';
# W* o0 X. b0 _2 x2 h, y; H    // Each of the pieces of text is wrapped in a <span>
. i% U8 l; O& d    // tag to allow it to be floated left. [0 ]2 c" c* {7 J
    $output .= '<span>' . t('My name is') . '</span>';7 C2 R6 H; i, Q2 M! w; d0 ~) Z9 u
    // Form elements are rendered with drupal_render()( K" C# k1 ?$ _4 o
    $output .= drupal_render($form['first_name']);
2 b  e" t. P& F4 x/ F5 J3 E8 C    $output .= drupal_render($form['last_name']);7 Q1 m& a8 p: q( X9 Y
    $output .= '<span>' . t('and I am') . '</span>';7 X/ S( r* o/ `8 z7 L- _
    $output .= drupal_render($form['age']);
/ ?6 ~/ N) e; A6 S+ P6 O, ~, x    $output .= '<span>' . t('years old.') . '</span>';
8 s3 R5 Q' }& j7 e* m    $output .= '</div>';4 c! V% a  h2 H5 f
    // Pass the remaining form elements through drupal_render_children()- H8 L# n5 J4 e4 H( Q8 l
    $output .= drupal_render_children($form);
4 y6 y& X+ K/ L+ M& |    // return the output: ^7 H9 R; ?. f/ G3 ~
    return $output;( p; G$ {5 ]% v" U/ d
}
6 x. }9 ?7 R6 a  a0 P  y9 F?>

: o% j/ W" {) W: m: D' R2 z
7 Y5 t+ ^6 c: k1 h到这里,我已经完成大部分的内容,定义表单,注册主题函数,实现主题函数。但是我还没添加CSS和Javascript。$ D9 F8 s! }( @* e. N3 {; ?3 k% Z
第五步:创建CSS和Javascript文件
, _2 I- E+ j9 B在第二步中我添加了CSS和JS路径,这两个文件都在form_theme模块的根目录。CSS代码如下:. S5 e/ f( x/ U, D

: @4 g+ F$ S0 w- ^+ O" x#personal_details span, #personal_details div
. q, f$ u; v9 ]7 Q{1 Z' p9 N. ]8 w! J
float:left;  K4 u0 W, u. F- ~
}$ y; X# b+ k' k  f9 m* z6 ]
. _% M/ u3 [+ t& h/ ^1 P5 t
#personal_details .form-item-first-name, #personal_details .form-item-last-name0 e* Z$ d& M. v5 b) h1 E* |
{0 L3 J5 M& u, H& N$ I' Q8 F
width:115px;1 B) x7 g3 }/ g  D
}
' j' c2 A( l- x+ l3 ~6 x8 Y7 ^5 s+ ]% G! J: j' ]! C1 l
#edit-first-name, #edit-last-name4 \' ?0 q6 \& i1 a5 b; b5 R) A+ w% h& L7 Q
{
, X6 y+ I5 S% \) k' T8 ?# B  k( awidth:100px;
/ `5 |- u  F. U4 p& A  W}
6 X- S2 u8 i# c" h1 z- d8 L/ v& X. j* S6 t1 v0 Q* b
#personal_details .form-item-age
. X( z4 G; C4 I" Y  p+ R{
3 _& L6 L# ?. b- C/ ~! Q9 \width:50px;+ S' ?, l( `' S/ h& ^$ q
}' Z9 t6 N6 n1 d% X
1 x# l% e: @' X+ ?
#edit-age* |2 H6 i& B. \9 o* u0 @
{
9 Q9 @7 B- L; S9 Y$ n- |( O: Uwidth:35px;7 @- t& \7 Q& k' q% z( l
}
" \7 ?+ T" d, P# C+ F4 W" ^" h6 p
#personal_details span
; a3 a, D& W9 O& ^& e{
+ ^; _( \1 x- h3 h1 A" ^0 fmargin-right:5px;+ t1 n# l; s+ v- H2 ?
padding-top:5px;0 F  j7 ~# [2 F7 \0 G8 w. R
}' a7 G! c4 f% S
* ~( S7 _* J8 ^' t$ H' J! l
Javascript代码如下:
. F3 z+ G: ^# D) m2 {. D
, J, b$ Y$ g1 J* F( `// We wrap the entire code in an anonymous function
/ M1 K9 U9 I, ~2 \" s! Q% H// in order to prevent namespace collisions, and to
. j/ }9 w- _4 ]) B% h+ I% O// allow for jQuery to be set in a safe mode where
2 ]7 \! c& z+ B// it will not collide with other javascript libraries.6 u9 j: w' k8 C9 u# k
// While this is the proper way to do it in Drupal 7,
/ Q" K" g. P( g// this method is actually good to use in Drupal 6 as
! Z' t# R8 S: v7 ^/ g// well, for the same reasons.
! E* L4 d: N' b' w4 ?; S(function($)
( g4 F: ]  b. d, r; c{2 k. T: j7 r, K1 x8 a- a# E
// In Drupal 6, each element of Drupal.behaviors
  [% K! q' J% n// was a function that was executed when the  d& o, [0 Q- [5 p% W$ ~6 k
// document was ready. In Drupal 7, each element
3 B; v0 I; f7 b; I  D; J2 f// of Drupal.behaviors is an object with an
! v# @1 g8 T( q$ f/ @4 j// element 'attach' (and optionally an element
0 \/ r$ U* ^) L1 f8 ^- e; f1 ~// 'detach'), which is executed when the document# ^& @4 e, O0 k8 ~- o+ _: O) T
// is ready
' ?2 d1 Y1 K- f3 h; c7 XDrupal.behaviors.formTheme = {
# v8 N: j2 {2 W4 Uattach:function() {5 I4 h/ [4 d/ e% N0 b9 ~& n
// First, define an empty array
2 S/ k3 `( ?5 j- q- ?, Zvar defaults = [];. z" j* a9 b9 |; D/ S
// Next, add three elements to the array,
' v1 k9 p$ E/ w! ?1 S# _// one for each of the form elements. The value
' Z6 E" M; X5 x1 L# m. f! \// is of the array element is set as the default
* `  A1 W; {8 x// text. This text is run through Drupal.t(),
4 B9 G$ i. w  y// which is the Drupal JavaScript equivalent
3 [3 `( J: Y2 B) k: r9 P// of the Drupal PHP t() function, and allows5 `3 H. W9 ]) U! ?/ F2 @
// for translating of text in a JavaScript document, y0 X% V- P* b! h6 t
defaults["#edit-first-name"] = Drupal.t("First Name");& ?' G+ R  T1 Y+ T
defaults["#edit-last-name"] = Drupal.t("Last Name");6 x+ Q. y& c0 d0 \$ y$ k$ R1 `* d, m. U
defaults["#edit-age"] = Drupal.t("Age");
! K: x( h) u* O- Y// Next we loop through each of the elements of the array
+ m  V  a  F2 p0 fvar element;  i; _! ?' O: ]& x
for(element in defaults)
2 l/ ^- Y! R7 \: I% C{
  B  N% C. _4 G: }, D- }  h, ]2 X! r* E// We wrap the body in the following if() statement
8 i& E1 k( E" O// as each element in an array will also have a5 q4 z+ s) z8 a# f
// prototype element. If you don't understand this,9 q: B( I% B4 p$ w$ f# B  y+ m
// don't worry. Just copy it. It will make your3 v6 x- c0 P1 _1 ]. H
// for(A in B) loops run better.% {6 [3 W1 e- g3 u# o* Y0 c: a
if(defaults.hasOwnProperty(element)) {2 a! F( \% g0 L
// 1) Set a placeholder in the form element
6 j9 h0 s6 R+ z& ^8 o// 2) Set the CSS text color to grey for the placeholder
' q* L8 N% ?* Z// 3) Attach an onfocus and onblur listener to each element& Q# }6 G. P/ U
$(element).val(defaults[element]).css("color", "grey").focus(function()
* Z& L5 Z1 R2 J- N5 n$ n{
: J9 x) h2 e% `! n1 a// This is entered on focus. It checks
5 t5 t' p; ]( H$ N+ t6 m, u2 u  L& G// if the value of the form element is9 V- [" z, {; s! u& M
// the default value of the placeholder,
  A5 e& c; ?/ U4 w& p3 X8 h// and if it is, it clears the value and* {+ C1 E$ E' B& I4 ]
// sets the text color to black,as the, w% E5 s5 P+ {- ~
// entered text will be the actual text  \; u3 M& b7 {6 H- K
// and not the greyed out placeholder text., s) R& B5 F0 p! d  J" u) W
var key = "#" + $(this).attr("id");
, q$ N5 W5 N3 n$ o7 G( e; Dif($(this).val() === defaults[key]) {
" I4 N5 A5 ~; }7 v$(this).css("color", "black").val("");
4 t3 N: Z: t8 A6 n% A  _2 W. C8 t, J+ q}0 D$ |, I) T) y. A
}).blur(function()1 }6 ^% {" P3 l. Y
{
# p5 A! ?/ {  j# o+ c) k. X, ~// This is entered on blur, when the element
# Q# @9 F! x; o" g6 ^6 ?// is exited out of. It checks if the element
: Q1 r& {; G" I1 V' t// is empty, and if it is, it sets the default
( _# g' u; a6 N( Q0 a3 Y; c# s  @// placeholder text back into the element, and
& L  o2 G- l3 E) h/ p// changes the text color to the grey placeholder# {' V8 f. V, A$ X
// text color.: _6 u6 C! F1 D
if($(this).val() == "") {
6 j& j8 C. k) C  m0 Tvar key = "#" + $(this).attr("id");& B- f/ P! u/ S5 H+ l
$(this).css("color", "grey").val(defaults[key]);
& |% j: u- |1 `}
  M1 [+ d" K( @. p( r% k});1 F0 |( \- W! k9 E+ d9 J& u* Y
}
/ U' {6 e# A  P+ l: l6 g. _}
% H* h7 K2 B& O8 o) y7 L8 f9 ^}! |" h% ^6 L% S! k* m
};
/ P' s" F1 N+ ]; N4 X}(jQuery));
" |. l$ k+ @& P+ e/ l9 o
  x  X/ v% j* T5 j) Q/ _/ b好了,你可以试试看。- S5 d+ |2 e) c9 ?
原文出自:http://junepeng.info/zh/node/28
' x  X5 @, }( J- U# {- v3 O; i% s- M6 c/ Q# m/ `
. z7 s* r( y* j4 M2 w

, A  V0 Z7 q% S2 O9 J3 |7 I. H+ _1 S; j1 }5 }3 v( D3 E, |& u2 a: u
: p7 N" R% d' n: h0 G
+ x" O  `" H( \/ b: h+ l! R

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

GMT+8, 6-18-2025 21:31 , Processed in 1.483492 second(s), 159 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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