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

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,微信登陆

搜索

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

[复制链接]
发表于 10-13-2011 02:13 | 显示全部楼层 |阅读模式
Drupal7表单定制和Drupal6大致相同,但是也有一些区别。这次我就来说说Drupal7是如何定制表单的。新建一个“form_theme”模块,然后创建一个表单,显示如下:
: f+ g. \+ K2 a0 oMy name is [FORM INPUT] [FORM INPUT] and I am [FORM INPUT] years old.; J+ M  m7 B7 P  b4 `
这三个表单元素的默认值依次显示“First name”,“Last name”和“Age”,当用户点击某个INPUT时,该表单元素的值为空,然后你就能随意书写了。" o- v8 v6 u$ X, z
这个简易的功能涉及到:1 S4 d6 V7 m3 v: [9 f# L
  • 主题化表单
  • 给表单添加JQuery(JavaScript)
  • 给表单添加CSS
    & M0 g. B7 D3 x- @8 ]
这个教程的主要目的是学习如何主题化表单,我不会对一些与主题化不相关的代码做过多地介绍。同样地,如果你想看懂这篇教程,你必须先知道:+ `, m! T% D, l0 k! R* h* [( u
  • 怎样在Drupal7中创建一个模块
  • 怎样在Drupal中使用drupal_get_form()创建一个表单
    # a( e# [4 G; a' L5 Q. n
我也不会对教程中的CSS和JQuery代码做过多的讲解,你可以直接复制并粘贴到本地去试验。呵呵,我的目的是如何将CSS和JQuery添加进Drupal中。# ^% A% m2 p* V! {  |( P  B
开始吧!6 o5 r* c! F) [. o# h: ^7 K
第一步:使用hook_menu()为表单注册一个路径
; S$ I* h& K$ `. b6 S! L我需要先注册一个页面路径好展现表单,下面是hook_menu()的实现:- z: {2 b2 z+ W  s1 ^; ~$ K; ~
0 @( q5 U9 M' v' r/ W; \, l( U
<?php
. k2 E  a2 f; T* Qfunction form_theme_menu()3 M# X% b$ ]$ `1 R, M) z9 \3 Z! ?9 L( |4 f
{
' J0 ]! B% s4 K" l/ M    $menu['form_theme'] = array
- j2 ~, Q+ h5 P) A2 s0 p    (! K$ k6 H1 r9 M  l/ y
        'title' => 'Theming Forms',
/ L4 h% p6 R4 F, U2 g: A( G        'description' => 'Practicing theming forms in Drupal 7',+ J9 p  `, Z6 w1 _# L
        'page callback' => 'drupal_get_form',, Z  X5 O) `' ?2 {/ [/ j7 K
        'page arguments' => array('form_theme_form'),1 S& I0 c( y) {2 O, G# o
        'access callback' => TRUE,
9 p4 |& }; J* a# }. o5 h5 r) M    );% h0 E9 Q1 o$ }& o9 A
    return $menu;2 P8 i6 K8 U) _
}
4 S& _' Z/ ?; m& M- v4 G" a( V% g?>

) C( O& }9 h0 g* I! ]
+ a+ O2 e8 X, R9 T- u第二步:定义表单4 K9 P, u. z- z( x
在我的表单里,我需要三个textfield,表单定义如下:! W. Q( U* m; j# u$ s; z
% d4 N2 A7 Y2 x/ t8 E; g
<?php0 d% _$ R" k$ Y6 g4 u$ Z( @) s
$form['first_name'] = array
2 M0 F* v1 o) z( Y& }2 K* E; W/ u(
, t# e0 n8 ~" r$ d5 f    '#type' => 'textfield',
( ?. P& b0 t, M* P);$ Z$ @/ U7 l/ N. q, f; N8 u5 D
$form['last_name'] = array
; U5 N$ N0 Y+ s) B" ?0 o6 b& E(
) `) P- g2 i8 f! B+ j2 S    '#type' => 'textfield',9 E4 C8 W& h; I/ P4 ?4 W
);# F0 R+ F) i3 F! o0 Y/ K+ W( j
$form['age'] = array  t8 u( d8 P5 G6 \
() k/ P, j$ o) ^5 ~- d$ }
    '#type' => 'textfield',
2 w9 A; a8 c; {% ^# c1 R. Y    '#maxlength' => 3,
& d' V3 i, Q9 T; J0 ]- t, S);
' w& h" }! t5 p' p" g/ c8 q8 _; F?>
7 c$ T7 n8 d0 Y3 ?

$ s* \6 e5 d" b& v嘿嘿,代码十分简洁吧。我已经创建了这些表单元素,它们没什么修饰或其它配置。
& A: c8 ^! A+ }$ M# j" S然后,我需要添加CSS和Javascript到该表单。Drupal7有个新属性,#attached,我能通过它添加,代码如下:
* f6 @' E+ Q% k, n9 h4 w' ]( ^1 l
<?php
  ~9 o  r1 h6 K% ]  }) F- _// Get the path to the module
" k$ c/ S; A9 P: _0 O$ m. Q$path = drupal_get_path('module', 'form_theme');- u( G. s* E, ^0 U2 e: `+ o6 [1 W
// Attach the CSS and JS to the form
& H4 T+ x+ O" }/ T; H' I$form['#attached'] = array
& X8 f2 c; y) H3 B9 m/ U(
" _$ x6 c3 I9 ^* m    'css' => array# T% {0 a6 }5 E0 _8 n* C6 G
    (
: {; J  m# E# E2 V; l6 y7 r4 f- j0 M/ \        'type' => 'file',  a9 |9 j5 k# x* d
        'data' => $path . '/form_theme.css',# Y+ j' c+ E+ p& t
    ),% \" W# R2 O# i! C/ h# z6 ]
    'js' => array
: l7 P& ^& {1 X. T6 Q8 B/ b' i    (/ C1 z- ?4 B( w7 Q4 B3 S
        'type' => 'file',
$ z  H, i) o# h7 g( j  ~& c        'data' => $path . '/form_theme.js',' U9 p, b2 B% L8 i/ P
    ),
: n' i3 q8 K: ]+ ]5 B# R);
9 i1 u; `5 v, C% b* a2 P( A?>
' v% Z  O' f# w# L- P
: x+ Y9 H8 ?4 t$ H# x
这种方法相比drupal_add_js()和drupal_add_css()有个很大的好处,就是其它模块可以在该模块的样式和脚本的基础上做修改。* }5 f5 y9 x9 i+ o! r! D! B7 m
最后,返回我的$form表单,代码如下:5 N5 Z" U8 V0 k5 a. Q- }; E

, N! o3 M: x9 r! z. }3 m<?php
6 }1 T% n0 Q( W2 qfunction form_theme_form($form, &$form_state)6 V  u* D! V2 |) |% U9 o/ b
{
9 T7 m% {1 q- o2 I$ M    $form['first_name'] = array
' R  k3 W# F8 L& Q& T    (
, T5 r& Q) |  B) _# W8 B        '#type' => 'textfield',9 y% S# Q/ d3 A! W3 U1 @$ t' l
    );
0 t6 H  `4 S: {2 c% ]# V    $form['last_name'] = array
! v. b/ J. j0 K; h/ t! ^/ h/ b    (
: a6 ^; m3 g- C) n7 i        '#type' => 'textfield',
7 u/ E& G( m+ V8 U3 L- h6 V7 |( k    );! f& C8 l% E0 T/ a( {
    $form['age'] = array
) ~" g/ \: V0 i, k/ n8 u    (
$ G# T# ?- s( R1 ]        '#type' => 'textfield',) ^4 p& p) y0 @2 U% W6 _, U
        '#maxlength' => 3,) e7 b% J4 Q, `  n
    );
" ~3 _& z1 D! }4 [: z( H" V! p0 n    // Get the path to the module  ^7 r9 h( N- h
    $path = drupal_get_path('module', 'form_theme');
; q* F# W! [" N. ?9 i( a' P& p! i    // Attach the CSS and JS to the form: u+ L% f  Z7 h& o( O. t
    $form['#attached'] = array& r# [; m9 H7 I
    (: q  Z% `6 r4 r" B
        'css' => array  E0 ~4 T6 @9 U) O/ f& h
        (: O9 H! l& v. `& n/ c, ]5 F$ m
            'type' => 'file',8 G0 B$ w9 o, G6 x
            'data' => $path . '/form_theme.css',! J7 g- `  x' d: q* J9 D" Y
        ),
: s' T# q! L* ]- `5 |) [' N        'js' => array, O# a+ i6 @' a2 x( ~
        (
0 ]9 C! F  C5 Z$ M4 c            'type' => 'file',1 [: |/ X6 a3 ^$ V
            'data' => $path . '/form_theme.js',
9 I. X* g% k- O9 j        ),
7 K. x( V/ j+ W- ?/ {! c! w    );- d% V+ \" {5 ]) O( G! ]
    return $form;! B4 `, c6 Q0 d* ]6 Q; H
}5 x2 z' _* L9 L, u; q! ?0 a
?>
3 u. p- y4 G- ^" C' L, l
2 M7 U  q2 A4 [8 ]8 L$ p' f8 G
第三步:用hook_theme()注册一个主题函数
3 }1 ?# Y3 ^% z从Drupal6开始,主题函数就需要通过hook_theme()注册,但是在Drupal6和Drupal7中还是有些细微的区别。在Drupal7中,表单的主题函数不是使用“arguments”,而是使用仅仅只有“form”一个值的“render element”。在注册主题函数时,你必须让索引和你已经定义的表单函数保持一致。代码如下:- d8 V! ?  V; L, `( g3 z) [! u

/ r% H4 w7 r1 \- D9 I<?php6 @; T' q$ x! l
function form_theme_theme()
* ]& S* ], {6 x: U: \: Q$ f5 ]* r{6 p/ F* Y; H# a# j% K
    return array& p0 I. @9 \) w3 h; X
    (% r1 E& b. d* V; {& S9 v
        'form_theme_form' => array3 A* \+ T$ d& M) Z& r
        (
( g8 v+ t7 ?! c* [) |  l            'render element' => 'form'2 j0 n3 J, `; U
        ),
, r6 t1 d# p+ z6 t. n5 \6 N    );
0 c1 m( @' P3 L3 t' D3 `5 z! m}
1 o: x! L1 {8 i2 k7 m# D?>
* @( A. I' K6 {& [" o9 F
) c; `" E5 W& M% Y
正如你所见,我已经注册了一个主题函数。主题函数的命名十分重要,因为这个主题函数跟表单有相同的名称,Drupal在实现这个表单时会自动调用该主题函数。我也不需要添加#theme到我定义的表单$form中,这是多余的。* N' s9 L1 o+ }! u
第四步:写主题函数/ s+ {& k$ Y# t2 l: N& X
在Drupal7中,写主题函数,有几个注意点。它们是:2 `. F' k# L) l) S
  • 函数只有一个参数,命名为$variables的数组。$variables有一个form索引,该索引的值就包括所有你已定义的表单元素。
  • 所有的表单元素必须要作为参数传给drupal_render()函数。这个函数能将一个PHP数组转换成HTML,并且将Javascript和css添加进去。这些Drupal会自动帮你完成,你仅仅需要传递这些参数就行了。
  • 在写主题函数的最后,你必须将剩余的表单元素传给drupal_render_children()函数,这样才能将剩下的或隐藏的表单元素转换成HTML。这是跟Drupal6一个很大的不同。在Drupal6中,我们直接传递$form给drupal_render(),但是在Drupal7中,这样做就会导致死循环,而且不会出现任何错误提示。- A7 F4 [% Z8 G" L9 |: }, f2 j0 M
主题函数是以“theme_”加上我们上面注册过“form_theme_form”命名的。代码如下:
, ]- b- W# L  q6 S* `7 A! ?( H
/ y, J, _: _. D) M" J+ O) t<?php
# Q9 o8 p  e/ q- cfunction theme_form_theme_form($variables)9 D4 z" m1 ?6 H0 {% H7 [1 k; D
{
6 O. c% ]8 c# B: ?; C  _    // Isolate the form definition form the $variables array
0 [3 [/ M/ P( J4 V# S- N# w6 E    $form = $variables['form'];/ V6 u8 Z+ H* p) Z" b& r
    $output = '<h2>' . t('Please enter your information below') . '</h2>';( o& k; Y, @& N9 m' H+ L
    // Put the entire structure into a div that can be used for' a+ q/ A/ d' U& D
    // CSS purposes
" K+ \# g, i% U) Z0 ~+ L8 z    $output .= '<div id="personal_details">';
: v  J6 Q( Y, Y! P8 i1 m0 b7 z, y    // Each of the pieces of text is wrapped in a <span>( S& k. ^" `. g* c3 r+ P$ x* s& b
    // tag to allow it to be floated left
8 z' Y+ K: x( E7 `5 s    $output .= '<span>' . t('My name is') . '</span>';* ?7 ^' G, V2 c2 o
    // Form elements are rendered with drupal_render()
2 O3 i3 E7 P7 o) o# G; c    $output .= drupal_render($form['first_name']);( t6 h7 _; U- \$ B$ e' K, c1 b
    $output .= drupal_render($form['last_name']);
3 f; `- W8 \4 w* k% A# D    $output .= '<span>' . t('and I am') . '</span>';
: x' G3 \. y: Y4 M    $output .= drupal_render($form['age']);. a7 q2 o/ e* ^) N  Y: z
    $output .= '<span>' . t('years old.') . '</span>';" v2 Y/ h: u- ?) i7 ^6 \( K
    $output .= '</div>';
0 ?% x' o! g/ R" Z6 F    // Pass the remaining form elements through drupal_render_children()/ {5 K6 l2 f0 ?/ f$ _
    $output .= drupal_render_children($form);
. g9 F$ o4 e% ^5 Y    // return the output
5 i; L* z1 p1 U    return $output;7 K3 U* v$ E6 ~3 h7 t
}
6 T1 E5 K$ {. @2 i9 C& k$ l?>
* N+ N( q( C' ]3 q

* i2 `; U: R; c* d2 s; d' h到这里,我已经完成大部分的内容,定义表单,注册主题函数,实现主题函数。但是我还没添加CSS和Javascript。' B1 m' n. B) G( r
第五步:创建CSS和Javascript文件
+ r% r+ Z5 `3 l9 @在第二步中我添加了CSS和JS路径,这两个文件都在form_theme模块的根目录。CSS代码如下:3 z2 ]! K) p3 ?: Z- u7 i

, N& A/ w5 e& F! ~4 G5 e. Q#personal_details span, #personal_details div; {/ W, G  N, A/ X9 s
{
4 ]" D! s) t/ `2 b$ S, ufloat:left;" t, z& }0 _, o! Q4 {% K
}
! K6 c3 y: r( W. s* ~& M- [5 `( a; T
#personal_details .form-item-first-name, #personal_details .form-item-last-name6 U) M+ e& W% ~1 ^" P3 m
{6 i1 A/ m& h5 `9 v4 b
width:115px;
& `; q) G; a8 A7 J* }, a( i}0 q5 @' ~1 o! o
7 D- G9 E2 t! ]' R3 A$ n0 s0 C: i* [. [7 d
#edit-first-name, #edit-last-name
0 [1 H, g9 [& H/ ^. K6 m{) M4 w! A4 N. M7 N& ^) u
width:100px;/ C# M8 r: T( l( f' }4 ]
}, A8 F9 o+ J6 L1 Q1 V
! o" g0 Q) z2 H
#personal_details .form-item-age* P$ [* ?4 {% s( k, n7 u
{9 o9 Z& Z2 K1 C: a6 z# i3 g6 E3 H) S
width:50px;
( T) ?# l3 r9 p8 ^2 ^}
" C6 o0 \) r) U
8 K- f: n8 s; D4 ^* f#edit-age
7 E! F6 H- Q& Q  G3 @7 x{
$ U+ p. m8 ^1 J. F( ^; [$ ywidth:35px;$ ?; t1 O# V! `" a
}
; u- j* K% Q( j+ i' H8 R( ^5 a
2 b. I$ g3 r( s9 J1 P' A& A#personal_details span2 D  j4 ?9 `+ n3 [) K. v
{
# w/ b: x0 e+ i8 @margin-right:5px;
" b& E4 E) n: b' X* d$ c- \% ^padding-top:5px;8 s( R# y5 m# O3 }
}
  S& i& x) Q& ?8 _) j; o: @) E2 |1 v/ h0 H+ Q7 \. C) F
Javascript代码如下:! X: E( G; _  Z  S2 @( A6 n4 K
, T6 \8 I- X; m$ @$ [- A& @6 T
// We wrap the entire code in an anonymous function& Q* b; O# S7 _* c; w% S$ H1 `
// in order to prevent namespace collisions, and to
* t5 N2 \7 p( C  O% M5 {  q5 H9 \" u// allow for jQuery to be set in a safe mode where
* \# o9 r7 E0 y' b- M" c// it will not collide with other javascript libraries.0 E. H$ p) |6 m! h: f$ ]/ r, _! R
// While this is the proper way to do it in Drupal 7,
( y2 Z' [6 ^$ B3 s0 ]1 r// this method is actually good to use in Drupal 6 as
7 H2 J4 R6 _  ?# V* E8 k// well, for the same reasons.
/ S* E+ r- e( T! |, @+ l6 i% T3 l(function($)
. V6 b% g8 Z) h( n- W{/ F1 x6 \% _* f& l$ @; n3 V& q
// In Drupal 6, each element of Drupal.behaviors7 s4 M" E; ]" \, j3 i$ w' }# }
// was a function that was executed when the
2 n; X( o- H  N1 v' K7 E// document was ready. In Drupal 7, each element, H* J% Q4 @* ^( y/ |8 m
// of Drupal.behaviors is an object with an
% n9 [; k1 T1 q0 V// element 'attach' (and optionally an element, \; T6 _! d% G' ~
// 'detach'), which is executed when the document
, i0 O1 k) E# V$ H! \// is ready, I2 @! A( R5 B" N! Z/ r( d. _
Drupal.behaviors.formTheme = {4 S3 C2 w! w- J3 M( T- l2 U3 Z
attach:function() {
* L- j' R" _$ g6 O0 N// First, define an empty array
- E& g$ w- j! L+ h7 |var defaults = [];
' u8 n; |; _8 `- D* E' e// Next, add three elements to the array,: R' V" l& |0 [5 r4 M
// one for each of the form elements. The value# k; p, W! O& M6 i4 v& T: _
// is of the array element is set as the default
( D! V7 @; t- p& k8 `( l" v, B// text. This text is run through Drupal.t(),( R' v. ~5 {2 S# m, A5 g
// which is the Drupal JavaScript equivalent5 U2 F' l; g8 b# G
// of the Drupal PHP t() function, and allows
( W9 c% C, U  l* r6 ~9 V9 @- h// for translating of text in a JavaScript document! Z" w) Q: y0 U0 z1 U) K8 }' K. B
defaults["#edit-first-name"] = Drupal.t("First Name");
8 P: S* R* c, m1 ddefaults["#edit-last-name"] = Drupal.t("Last Name");( c  W7 I" r/ v* }( m: f
defaults["#edit-age"] = Drupal.t("Age");+ Z8 Q3 h5 p2 @( z/ i6 E
// Next we loop through each of the elements of the array# ~# t2 v" b; b6 A6 m% _+ v
var element;( C2 r$ L% x, b& \3 |& E
for(element in defaults)
! G8 B9 f6 c" @& @+ c1 y9 \{
0 {$ h$ d' a: \+ O' r+ Y% v8 x* ?// We wrap the body in the following if() statement
1 [& W, M5 G- x4 c// as each element in an array will also have a& a/ \. [# S/ u; ~& p6 w4 v- e: `
// prototype element. If you don't understand this,
8 h) X; i. Q& ~. H2 H( n/ k// don't worry. Just copy it. It will make your
' P, e8 h/ z7 g  U/ r1 Z// for(A in B) loops run better.
( r) |) q8 G& d# Tif(defaults.hasOwnProperty(element)) {
+ P9 W0 e$ b% d, x& Z8 T// 1) Set a placeholder in the form element
3 m9 _) [. I: ]// 2) Set the CSS text color to grey for the placeholder
4 i* i$ M" _% a4 k9 m: J// 3) Attach an onfocus and onblur listener to each element
. T. n1 R$ v& K  n$(element).val(defaults[element]).css("color", "grey").focus(function()
9 W( i; G' k; \% t) v5 z3 j{
6 G- q. n4 [1 j2 [' m& p& p3 Q3 V  m/ U// This is entered on focus. It checks0 J' M6 ^8 W- B: s/ ?2 U
// if the value of the form element is: N* u; f& \. e% U( P. e' K' h
// the default value of the placeholder,
+ M: H/ H' n# n! z3 F: r// and if it is, it clears the value and
$ m. W/ c% Z: x7 H" a! ]// sets the text color to black,as the
4 f; x  ]  l1 [& w// entered text will be the actual text
; r+ l& h" U6 o// and not the greyed out placeholder text.. Q' w! C( P* t: [/ C" [
var key = "#" + $(this).attr("id");
; ]$ k8 P( }$ \4 d4 ?3 S4 g; [if($(this).val() === defaults[key]) {) h+ j: J% C& t, H7 ?- o
$(this).css("color", "black").val("");
. a3 b2 N# o: d/ t! V, D}
- V, c7 P- x: |: T$ F}).blur(function()
' K* H6 k1 i: E; b% j{
* n9 `0 f- d; V8 v+ Y// This is entered on blur, when the element
) h2 _# G5 ^: U; g// is exited out of. It checks if the element
" a/ Q( G$ C; a% I+ b' Z// is empty, and if it is, it sets the default
9 u- a1 B& @% @5 a1 j; N// placeholder text back into the element, and% |+ r: l8 w" ~) x
// changes the text color to the grey placeholder, T" Q( m2 }. J/ f2 f
// text color.  Z, A% _" W) F( [. S3 \
if($(this).val() == "") {
% h- s1 z2 J( Z' z- s* M- Xvar key = "#" + $(this).attr("id");
, c% E  F& h) |4 W4 G: U$(this).css("color", "grey").val(defaults[key]);: H& ?( i2 T3 a0 j
}
* e: y( t$ G. h# J# I5 Y! q; W; C});5 g; H: T  o1 x- g
}
7 N+ [6 O  P7 a6 B1 c" |}3 j1 ?: m2 i: t5 q6 w# d7 V8 F
}
' l2 _2 l" B% Q};
" D0 b3 I% X3 e; U! g5 K+ h}(jQuery));
: |: X( _, n6 Q0 j8 J$ U$ ]/ f# t& V  k/ F6 t% t
好了,你可以试试看。
0 @3 E% H0 B) D原文出自:http://junepeng.info/zh/node/28  o9 f1 R4 x, ]( P' ^/ q

. ]; ^6 b+ [. P* z/ Y5 t( [9 U2 [  f! Z. }# z# f0 `

! L: Y. h$ ?" S5 E  }, @/ R1 M2 u# ~6 P. X& V7 b  z; ~6 b. F

& c7 F0 l# Z1 a( V, e( D5 s7 ]% b! ]+ m; Z9 Z! {

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

GMT+8, 4-19-2025 12:07 , Processed in 1.134297 second(s), 162 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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