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

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,微信登陆

搜索

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

[复制链接]
发表于 10-13-2011 02:13 | 显示全部楼层 |阅读模式
Drupal7表单定制和Drupal6大致相同,但是也有一些区别。这次我就来说说Drupal7是如何定制表单的。新建一个“form_theme”模块,然后创建一个表单,显示如下:
! R* }# d0 i8 ZMy name is [FORM INPUT] [FORM INPUT] and I am [FORM INPUT] years old.5 e* V* l3 c- x1 C! q1 w2 L4 _
这三个表单元素的默认值依次显示“First name”,“Last name”和“Age”,当用户点击某个INPUT时,该表单元素的值为空,然后你就能随意书写了。
) }7 A1 p# p( t& U这个简易的功能涉及到:. g- a9 G' C1 W2 ^$ u" D2 Q( o
  • 主题化表单
  • 给表单添加JQuery(JavaScript)
  • 给表单添加CSS
    - y% z0 R. l2 m" R/ J$ G; Y
这个教程的主要目的是学习如何主题化表单,我不会对一些与主题化不相关的代码做过多地介绍。同样地,如果你想看懂这篇教程,你必须先知道:
2 l" @$ O0 S1 _
  • 怎样在Drupal7中创建一个模块
  • 怎样在Drupal中使用drupal_get_form()创建一个表单
    $ _1 P  a* y, P- Y
我也不会对教程中的CSS和JQuery代码做过多的讲解,你可以直接复制并粘贴到本地去试验。呵呵,我的目的是如何将CSS和JQuery添加进Drupal中。
* x4 S4 H  u1 Q/ c8 _$ e# E开始吧!
# p  n- J6 d5 l6 ]) ~第一步:使用hook_menu()为表单注册一个路径
& s8 u* a! W) X3 L$ @" v. S我需要先注册一个页面路径好展现表单,下面是hook_menu()的实现:: r; E8 w! @3 r" y

8 h3 I1 Q- v3 Q, t<?php
% a6 R: @4 O! \; F8 I% ?function form_theme_menu()
8 Q* S; M) o6 H{. h7 d" f0 Q* {8 s4 e1 U9 V4 p
    $menu['form_theme'] = array6 f/ _9 x" s3 F  E$ K* X& g
    (
& u1 I& l! M: [2 S        'title' => 'Theming Forms',
% G4 x" z5 [1 g3 P7 `        'description' => 'Practicing theming forms in Drupal 7',
2 {1 o/ ^9 n5 F0 X8 _0 u' a7 p5 j        'page callback' => 'drupal_get_form',
7 e- l" o3 @3 f1 _" N        'page arguments' => array('form_theme_form'),
" c  ~0 A2 R2 r8 p, l7 E4 \        'access callback' => TRUE,
1 s$ k2 C1 O1 ]. s" c    );) I+ B' X9 n/ u  {6 [$ n0 k! M
    return $menu;
+ B/ u( {8 B9 Q}+ u8 J) f9 V7 T
?>

% H# X1 K1 A% P3 \/ p& n; y- N2 ^- E5 F4 y5 r/ \( ]* u4 I
第二步:定义表单
5 H6 b  W3 W- E: R; J在我的表单里,我需要三个textfield,表单定义如下:
; U$ i* ?( l0 x3 N3 Y, m
; c9 ^' ~8 b4 ]+ h5 P<?php/ I, H: n+ {* D% \
$form['first_name'] = array
+ u. S* `  ]$ n, X0 Z: a() Y# Q4 P$ K  _
    '#type' => 'textfield',! z" F0 D+ Q+ E7 S
);
  G# U9 n  U' k" O$ M$form['last_name'] = array% @3 C  z& i" J8 m( n
(: _7 c' S! W  w  [, r0 F7 N8 [
    '#type' => 'textfield',
0 |( g6 V/ {1 H* D1 k0 @, W);
7 r# y5 [2 U5 n, h6 c& r) H$form['age'] = array! g6 D9 q7 z$ ?3 ~
(8 k6 M% _5 r$ Y; Z7 A  W1 X
    '#type' => 'textfield',
9 t* Q. a0 \. `$ Q, \    '#maxlength' => 3,
* }6 U) l/ U/ C3 u! h5 [);
  E- Y$ O' O! b* X' m( g?>
* C+ u4 Q& G; j2 q& ]0 f
+ O- K6 X- \+ g% b
嘿嘿,代码十分简洁吧。我已经创建了这些表单元素,它们没什么修饰或其它配置。1 ~  x8 T! d# \2 E: O0 H
然后,我需要添加CSS和Javascript到该表单。Drupal7有个新属性,#attached,我能通过它添加,代码如下:
! l  A) s/ g/ G1 c2 Q* t$ |4 T. j. y: G
<?php
+ q$ v2 Q, {/ x& ^' @7 h- T+ c// Get the path to the module6 {$ t- @- A8 k* U3 `
$path = drupal_get_path('module', 'form_theme');
1 s1 H( j0 y) U* \" _7 R. t; R0 T// Attach the CSS and JS to the form
, S- M. C& b' }8 K  k! D( k$form['#attached'] = array
& b8 Y( E6 [. c' _3 K7 X' ]: p(: T2 b4 C8 A; j/ _8 C- [
    'css' => array2 O# J- s2 U. \" V
    (5 p$ I% s& |( q9 c, ~' R! v
        'type' => 'file',
* I8 S' F4 t8 |6 N9 t/ R6 @        'data' => $path . '/form_theme.css',  [$ A+ F( Y3 t+ ]- K7 c
    ),& T3 k! e: U* ?3 [6 a( e; v* v9 Y9 ~3 H
    'js' => array
1 b$ Y, x2 `1 H% Q8 ]6 D. g    (
8 F7 s  A) f6 M0 `) e. Y) Y        'type' => 'file',8 m; ^2 }2 i& D
        'data' => $path . '/form_theme.js',
/ X) t+ _$ M, A    ),
; i( k' G  u) v! n! ~* \);% _" s$ R  Q2 ^# A
?>

% Q8 |' n* |5 L4 d" d
( R! J7 X$ |3 ?* ?* i这种方法相比drupal_add_js()和drupal_add_css()有个很大的好处,就是其它模块可以在该模块的样式和脚本的基础上做修改。- C) P6 L) m- T0 o) E1 W6 Y
最后,返回我的$form表单,代码如下:
% u7 _0 j1 S( h% g+ |) D( N" p' F$ c- s, C% q' s) c3 T5 E
<?php
4 E$ b! s6 q# wfunction form_theme_form($form, &$form_state)5 A5 H$ C! k2 D
{
6 ^; r) X$ \+ C# z    $form['first_name'] = array  ~3 q2 |" g' D+ _
    (: o, ?/ u- L- I4 T$ N3 V' q
        '#type' => 'textfield',
; [& B" N0 X; V. Q: w    );1 K' ^2 {$ Q8 m) s; D
    $form['last_name'] = array
" ~5 b- _/ P# I; X    (
) J4 ?( }2 F) @: t. i        '#type' => 'textfield',4 w  C2 r8 ]) ^$ b- s
    );
* N+ V7 C& W1 a" V7 S    $form['age'] = array
+ K3 \4 O1 v: k, t5 Y" a- S8 q; {8 S    (* i2 M3 Y9 v: ^" Y/ O6 T4 L: B
        '#type' => 'textfield',0 w( e& w  s3 h% K' @
        '#maxlength' => 3,
2 K0 h. h9 o9 T5 w    );
. |$ o% h- E/ x3 A* L    // Get the path to the module
: g* j' U& O0 @0 W    $path = drupal_get_path('module', 'form_theme');+ P! L7 {: x5 t
    // Attach the CSS and JS to the form
7 l9 g3 J5 X4 Q0 W* }    $form['#attached'] = array7 f" i5 K& r: x
    (
; L/ I1 ~2 ~9 O& H& V+ w        'css' => array
. Y8 D) {- `& q4 Z5 [5 Y        (' h3 J; w% k, K8 F" p& `
            'type' => 'file',
2 P6 |1 \( l* F, v7 u, ]            'data' => $path . '/form_theme.css',
! q: H% m, c8 A# |        ),
6 m1 Y; @8 Y. i8 u0 u        'js' => array
' f( A. j# w2 z4 u9 f  Z) ?! l; O        (5 H: Q( H" R+ z& E8 R1 F8 k* _4 t+ S, |
            'type' => 'file',$ s$ _% U0 p) L) n2 [
            'data' => $path . '/form_theme.js',9 v; t$ X& F$ w8 ?8 [, `: n
        ),2 ~0 F; d" N- T0 k2 A8 h" k' k2 k# H
    );
' m% J5 \- @6 o8 {4 `    return $form;0 p/ Z& N9 f; H. Z9 C! ^& [7 ]9 @  _
}9 e4 o0 ?& u( Y( f
?>

$ }/ {; q! E4 Z* l1 l! n) h; [2 Z# t. E5 `- A
第三步:用hook_theme()注册一个主题函数( L. _  p9 x; z! U
从Drupal6开始,主题函数就需要通过hook_theme()注册,但是在Drupal6和Drupal7中还是有些细微的区别。在Drupal7中,表单的主题函数不是使用“arguments”,而是使用仅仅只有“form”一个值的“render element”。在注册主题函数时,你必须让索引和你已经定义的表单函数保持一致。代码如下:
8 C+ q3 @* X- s+ r: C7 G/ A4 {1 r* i6 K5 h' g' u! Z
<?php
& V7 T8 V# |8 C+ u; ~" Vfunction form_theme_theme()
+ {! z- }$ e- W6 e0 R7 t3 ?( K{
) \2 `& \2 }* q. O- M1 ^    return array  ?( L: @6 \3 f" l1 G3 y$ C
    (0 m$ `1 Q. V& s
        'form_theme_form' => array
, W$ d. \# j) ^$ V# U" N        (
* s9 s' f2 W7 A8 w            'render element' => 'form'
. X8 J* d' C* U" y0 Q        ),
' }8 g$ f/ Z/ Q0 v/ U    );$ V' O3 R& w; m/ k
}
: B) ?- U" f0 Y2 v( c?>

0 b% H9 [2 _: ^' @; V0 s5 }
- t4 p6 D( P1 J* |3 A1 c正如你所见,我已经注册了一个主题函数。主题函数的命名十分重要,因为这个主题函数跟表单有相同的名称,Drupal在实现这个表单时会自动调用该主题函数。我也不需要添加#theme到我定义的表单$form中,这是多余的。( z; H6 l" o) U- {/ p  h
第四步:写主题函数
$ z7 u/ w6 y& W: `在Drupal7中,写主题函数,有几个注意点。它们是:* q; e7 ?" R; V
  • 函数只有一个参数,命名为$variables的数组。$variables有一个form索引,该索引的值就包括所有你已定义的表单元素。
  • 所有的表单元素必须要作为参数传给drupal_render()函数。这个函数能将一个PHP数组转换成HTML,并且将Javascript和css添加进去。这些Drupal会自动帮你完成,你仅仅需要传递这些参数就行了。
  • 在写主题函数的最后,你必须将剩余的表单元素传给drupal_render_children()函数,这样才能将剩下的或隐藏的表单元素转换成HTML。这是跟Drupal6一个很大的不同。在Drupal6中,我们直接传递$form给drupal_render(),但是在Drupal7中,这样做就会导致死循环,而且不会出现任何错误提示。
    ; L2 n: r8 A. |+ o
主题函数是以“theme_”加上我们上面注册过“form_theme_form”命名的。代码如下:
1 {/ Y7 l7 @* z; P9 f" Z4 V4 \
<?php
4 ~9 P' D* E, p& Ufunction theme_form_theme_form($variables)' p/ M* v* _5 q$ e: I
{
& N; B9 x$ K  c4 F    // Isolate the form definition form the $variables array  J1 h& O1 B1 e2 ~* _
    $form = $variables['form'];
6 D6 l* S' J8 c% p% P    $output = '<h2>' . t('Please enter your information below') . '</h2>';& r9 k8 G7 P1 M# |
    // Put the entire structure into a div that can be used for
0 E2 S2 K( u& Z- x9 p4 C    // CSS purposes
. `- ?0 \: c6 N    $output .= '<div id="personal_details">';5 ~, Z4 @3 i+ ]2 ]
    // Each of the pieces of text is wrapped in a <span>
. h4 L* g! `" z4 b  n    // tag to allow it to be floated left  K* e$ ?' {8 h" W" A  k  _0 |, J
    $output .= '<span>' . t('My name is') . '</span>';
: z2 Y- ]* o1 l. N; K    // Form elements are rendered with drupal_render()! b$ N" A0 T* V$ F7 D
    $output .= drupal_render($form['first_name']);
. R. ?% y7 k. k( A/ |    $output .= drupal_render($form['last_name']);
# u: U+ T; W3 E3 z0 M$ Q    $output .= '<span>' . t('and I am') . '</span>';
. o; Y& N. S+ a$ }% U3 N$ E8 H4 r    $output .= drupal_render($form['age']);
3 u1 F1 Y+ p3 ^4 Q# {    $output .= '<span>' . t('years old.') . '</span>';% ^0 D' _3 U+ f( q$ G' z, C
    $output .= '</div>';5 J0 r1 D! X0 f2 O5 ^
    // Pass the remaining form elements through drupal_render_children()
1 D  B* {0 p+ y. {& f2 l/ T7 @    $output .= drupal_render_children($form);. \0 g( d8 v, y5 K
    // return the output) o1 ?8 p+ D4 J9 q& v: o
    return $output;
) W1 P: R; [* y3 P& C0 T}2 N4 A; v2 g* [  `
?>

; I2 _" ~! K( P% J- F( l4 ?
: a6 N1 L( Y: i- ~1 t6 I到这里,我已经完成大部分的内容,定义表单,注册主题函数,实现主题函数。但是我还没添加CSS和Javascript。
7 X9 W8 c% \% y0 w$ ~1 J第五步:创建CSS和Javascript文件5 l0 J% O5 i/ U4 P- y' g8 D' `
在第二步中我添加了CSS和JS路径,这两个文件都在form_theme模块的根目录。CSS代码如下:5 I7 [* p4 T* f) b

& H/ G3 I8 p4 N* l  \$ s) V#personal_details span, #personal_details div# E7 i# B, q/ I. s5 S
{
1 m; y% B3 p  @2 ~9 e  O: ^; P8 j, Mfloat:left;
7 ]6 g( A4 V( `}$ h% S! X6 h7 z/ l$ ~, T* L
4 K0 H3 A1 }8 p4 i- ?9 E+ G$ ]1 r* a
#personal_details .form-item-first-name, #personal_details .form-item-last-name! U2 {; }9 G( F0 g
{( Y% o7 E3 n/ G' I8 }
width:115px;$ O0 Q. ?) D4 d' @/ o* ~5 V
}
: h5 G- |- u) B1 \0 ?, T3 H1 {
( g) w8 L! Z  g. Z9 |' d#edit-first-name, #edit-last-name
: m! y( W3 I: p3 T$ T{+ c; Q" j- c! \1 }4 I/ O. |- y9 m2 R
width:100px;: K: M. B- n8 J" n+ N" C
}
  }& {4 g: N0 H% `* [5 \$ T& R5 u2 N; ?& [4 H! z
#personal_details .form-item-age# `) Z2 k! L$ m+ K5 j7 I
{) C4 Q% }; h" P( M5 j
width:50px;
. N' _1 x/ S/ o* J; q' R: U- e}
7 d6 `6 h3 x5 N) T' d% t, J+ e$ U1 h1 C" N& d
#edit-age+ }1 W/ b1 T1 q$ `! _# I$ g
{8 @) S7 n0 l6 }
width:35px;) N" h0 E5 `7 h, s% J2 s
}
5 l8 ?4 T5 T: @* q& d9 n
8 T! F; B" \* c& H# p5 r#personal_details span
8 A( {0 l7 K2 P# v( U0 o{' p8 L/ R4 @2 L8 n' ~- n; p
margin-right:5px;+ z$ i( ~' }5 _; L3 \/ p1 F
padding-top:5px;
3 L) w/ H8 t1 C0 B6 b3 n9 l}
+ D' e' N  h  Y; ?0 E& c, a5 F& }% @& P
Javascript代码如下:  L/ w& R% R+ v5 r

' H8 r" E4 ?# k) R5 b// We wrap the entire code in an anonymous function
1 ]% B$ ]  B/ ~  a// in order to prevent namespace collisions, and to
) _0 X! B" _2 B* S, r// allow for jQuery to be set in a safe mode where
4 T* }8 b2 v' w: [+ r$ M( |// it will not collide with other javascript libraries.+ }3 T3 K3 c3 c* x1 @8 m
// While this is the proper way to do it in Drupal 7,3 u: L+ D, t' z4 U
// this method is actually good to use in Drupal 6 as) k& K8 r. m* k+ ~
// well, for the same reasons.
% `: R9 j0 k8 ^5 d(function($)8 L! K# q0 V+ K% t. z( {
{
* j; ?( Z4 K- i! O0 j6 k$ O// In Drupal 6, each element of Drupal.behaviors; k  y- M9 _* n9 w! W& R  L) ]& G- M
// was a function that was executed when the
( }( d2 |) {; z2 V; r- Y) N// document was ready. In Drupal 7, each element/ o9 v# p! b* H: |
// of Drupal.behaviors is an object with an4 N. F. G" V7 Z* {: D$ o
// element 'attach' (and optionally an element
3 u) \# w& i  D/ d// 'detach'), which is executed when the document
9 V6 r' `/ b. w// is ready& s! m* y0 R$ ]
Drupal.behaviors.formTheme = {. u+ {, H- e$ ~2 n/ Y; V0 j
attach:function() {/ S* d- h- M1 l5 V7 C& m8 v( i
// First, define an empty array
* l8 x1 d3 e8 M* l$ Zvar defaults = [];3 ?3 V( G. o6 k8 X
// Next, add three elements to the array,4 e9 Q& U6 i# \: Y: n- n
// one for each of the form elements. The value1 S! n7 H; E2 i& g" h; A
// is of the array element is set as the default
' @/ r$ T6 P& e, i; L// text. This text is run through Drupal.t(),: T7 y% w, C# i* b# }7 R5 D- f
// which is the Drupal JavaScript equivalent
5 T# a( S' g/ X4 w9 E// of the Drupal PHP t() function, and allows/ F1 h; q: N  J2 G+ W. ^8 b5 E6 a& @
// for translating of text in a JavaScript document
5 z/ x) r4 a- S4 @. Wdefaults["#edit-first-name"] = Drupal.t("First Name");3 s5 b# [1 I" A; S& n
defaults["#edit-last-name"] = Drupal.t("Last Name");
: Q; q" c6 I: s* Q/ r" F) Idefaults["#edit-age"] = Drupal.t("Age");
$ N$ h& Y# J2 W/ a// Next we loop through each of the elements of the array' P; i: y8 }- R# Z5 S7 a
var element;5 q( n( O- D# G, l& d
for(element in defaults)2 u) K% g& w- h1 G
{. e7 |. }: p: O, `5 n- s: X
// We wrap the body in the following if() statement( {  J4 A+ b; u4 o: U
// as each element in an array will also have a
8 P, ^6 R( G! }, O" |// prototype element. If you don't understand this,
- Q! _. b! t* G# T# k; Y* V// don't worry. Just copy it. It will make your
8 D8 g& q8 \* U/ X* o; v// for(A in B) loops run better.
8 |0 _3 d. W# T& [' C6 {# d/ fif(defaults.hasOwnProperty(element)) {
3 \. d, }+ F1 n* }// 1) Set a placeholder in the form element
( k7 Q# a' z% G2 c5 |5 z// 2) Set the CSS text color to grey for the placeholder
6 f/ }5 |$ C; R' H1 A: |: n// 3) Attach an onfocus and onblur listener to each element
9 D( y% m+ B& R; y. k$(element).val(defaults[element]).css("color", "grey").focus(function()
& k) N: P: ?+ L( x" y, ~{' P/ r. r& Q- N& _" Z& A  q
// This is entered on focus. It checks
, e+ @% ^! Y( n( Y. I// if the value of the form element is1 }9 H8 W/ T6 F1 L0 F: s# G, ]
// the default value of the placeholder,
; ~; q( L  i5 w/ _0 i1 |// and if it is, it clears the value and
* }# R4 H/ [! d4 y9 P$ k0 t// sets the text color to black,as the
; g' @& @% ~" F2 g1 j// entered text will be the actual text
, d+ [% e+ t. W6 s// and not the greyed out placeholder text.' Q0 o6 m9 n. A4 P' b/ T
var key = "#" + $(this).attr("id");
, y0 U* p! R" t' ~/ D4 C" Nif($(this).val() === defaults[key]) {
" [+ u$ ~6 }( D/ q8 n( B2 D- i  [8 ?$(this).css("color", "black").val("");
& l. @8 Z9 @! b0 V5 M# r/ l& M- k}
9 b8 Q- _9 G, r& E% U- ~: [- `}).blur(function(), n1 D) W. B! u
{" O) G% c5 w( s  j5 R# f+ \
// This is entered on blur, when the element2 q3 J4 H* U# j  C/ ^4 k* U
// is exited out of. It checks if the element
9 f+ D# w* z9 I7 I// is empty, and if it is, it sets the default
0 N& R2 F6 F; T4 j// placeholder text back into the element, and
" W  G: n# f3 {0 ]2 `0 q// changes the text color to the grey placeholder
2 o  G; M  v8 R6 M0 g) Q// text color.2 ?2 K% G  C( L1 v3 G" V8 T
if($(this).val() == "") {# x1 {0 ~& s7 @) C9 O9 t
var key = "#" + $(this).attr("id");
9 w. _" n$ F+ K9 n$(this).css("color", "grey").val(defaults[key]);
; E8 z% R/ g$ `7 B$ [2 s! C5 J8 @/ `}8 b0 g; `$ ~4 T# [- }7 B
});
( G" ]0 K  ~9 i- _  H4 T}
' q4 d3 @8 C  ~6 I}8 L8 i" n; N$ C+ Z$ k8 |8 Y5 u/ P
}
! w9 N/ j$ X: x3 N};7 f' J9 l. ~; q8 |
}(jQuery));" Y: T* y4 b+ i# K

' G" q& _, ?- I/ R1 M好了,你可以试试看。
( Y0 ~9 R) Y- T; c& S原文出自:http://junepeng.info/zh/node/28  @0 ^# k1 I5 Y# p2 S) @
: h8 D9 S! u0 j
' r, g( e  b5 ?* U' j# d/ s# ^; ^0 {

6 E% S9 S& R$ k2 J3 o" E! M, x+ @
4 _, n8 p9 m! M
# b% v% z/ c& S6 n1 H  }8 a0 U6 B8 {! B9 [% _* q7 O" j$ f

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

GMT+8, 12-8-2025 20:51 , Processed in 0.233617 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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