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

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,微信登陆

搜索

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

[复制链接]
发表于 10-13-2011 02:13 | 显示全部楼层 |阅读模式
Drupal7表单定制和Drupal6大致相同,但是也有一些区别。这次我就来说说Drupal7是如何定制表单的。新建一个“form_theme”模块,然后创建一个表单,显示如下:
: K/ K( l4 H/ A" gMy name is [FORM INPUT] [FORM INPUT] and I am [FORM INPUT] years old.
8 N7 e8 g2 {0 @6 @; E这三个表单元素的默认值依次显示“First name”,“Last name”和“Age”,当用户点击某个INPUT时,该表单元素的值为空,然后你就能随意书写了。$ A# \8 Z' A: ], m2 c+ g
这个简易的功能涉及到:8 c" U3 c$ C) T7 |5 k
  • 主题化表单
  • 给表单添加JQuery(JavaScript)
  • 给表单添加CSS
    % e- e+ I7 R6 P7 ^
这个教程的主要目的是学习如何主题化表单,我不会对一些与主题化不相关的代码做过多地介绍。同样地,如果你想看懂这篇教程,你必须先知道:, P6 j' E6 r, m: |3 \5 K
  • 怎样在Drupal7中创建一个模块
  • 怎样在Drupal中使用drupal_get_form()创建一个表单
    - u+ h! @* t' I7 G0 |# O
我也不会对教程中的CSS和JQuery代码做过多的讲解,你可以直接复制并粘贴到本地去试验。呵呵,我的目的是如何将CSS和JQuery添加进Drupal中。
8 i& x- K9 @( V开始吧!
0 @; Y. t- T4 b4 N8 {第一步:使用hook_menu()为表单注册一个路径
+ i$ H5 G' @/ u2 B( ^3 a- \我需要先注册一个页面路径好展现表单,下面是hook_menu()的实现:
. j9 J3 a* u* I% e) _. }0 E8 i- V
<?php
$ w( i. M2 j; ?; }5 `' C# U, D( Vfunction form_theme_menu(): d* A/ p0 G7 L, \3 i- d1 m( K5 h! S
{
  \- `+ C" e- V* s1 D    $menu['form_theme'] = array
' Z5 w6 {/ u( X; _    (. E+ q4 ^6 C; b# Y( {
        'title' => 'Theming Forms',
" e2 c- _7 i# r        'description' => 'Practicing theming forms in Drupal 7',
+ B  g7 X! W# E% ~* y: J  o# @        'page callback' => 'drupal_get_form',
1 ]0 T4 Q( \  F: x  X        'page arguments' => array('form_theme_form'),2 A. n+ S5 A+ f$ q+ f
        'access callback' => TRUE,
/ r4 X, h% J# i, e, D    );# }0 i7 ~7 T3 Q2 f3 q; s. Q
    return $menu;
0 e: s4 C/ P# S7 ]# S2 w}
( E9 Z! @+ i+ K# V8 f/ g. s1 J3 ??>
! r3 K- b+ y# y. F7 P7 r
6 h7 `; _0 R+ S" z/ y/ N
第二步:定义表单" e6 X+ d( D0 E
在我的表单里,我需要三个textfield,表单定义如下:
& ~3 }5 E* a4 L) P3 ?% M) f0 N4 I3 _5 |" i: L- p$ v# w: U. {
<?php% A+ s5 a. P3 \3 j6 l0 [
$form['first_name'] = array
* L4 o/ Y; T6 D(7 {3 j6 f% z8 A0 Q
    '#type' => 'textfield',
; l, q) b3 _* U# d1 N- ]8 a) d);
% V9 d. s' T4 [0 `' U$form['last_name'] = array8 r! f0 S6 K  l- ^& \! |
(
2 i4 o# \% x+ e! U1 D) V; `/ x    '#type' => 'textfield',0 y  e) T" y5 \4 d$ N7 f- g
);
+ I- ~  V6 R8 e1 A  C: ^2 a  w1 k$form['age'] = array
& @8 g8 k% u0 O# f/ Z) p& r3 F(
" h8 |, q. `- n' x3 C; h: I5 z    '#type' => 'textfield',0 m1 \( N  v- P& E6 I' h; r
    '#maxlength' => 3,9 g0 ~7 p7 S  R! h  V" b% z, h! G
);+ L' a- D8 Q/ n' a7 d9 C0 \
?>

  I, N7 W+ [" l( S
" [3 y* ^2 p, s" y嘿嘿,代码十分简洁吧。我已经创建了这些表单元素,它们没什么修饰或其它配置。
! y0 X% U! x9 X. f' D然后,我需要添加CSS和Javascript到该表单。Drupal7有个新属性,#attached,我能通过它添加,代码如下:; k! ^- d% H/ \3 Y1 l7 H

  K# G/ R! W3 q; J, g7 M. l' k  S7 H<?php5 o: Z, G5 I$ G
// Get the path to the module
6 F- ~+ ~# J; R( a5 Q" }1 b+ h$path = drupal_get_path('module', 'form_theme');
; ]. e  Z$ j4 s// Attach the CSS and JS to the form9 O9 t( Z# w& F# [2 p' J
$form['#attached'] = array$ _/ B  J  c$ q' o4 h
(
( _  O3 Z5 R1 e    'css' => array
% q' p' s% h, b7 Z    (
) f8 m0 x: Y" r7 j( }* n        'type' => 'file',4 |4 s$ `8 X8 N- K! e, Y) h
        'data' => $path . '/form_theme.css',( F( m1 H5 |2 T
    ),
8 Y- u; l+ ^" K, X    'js' => array
' b0 q! H: d3 Z4 @, m$ D" r    (
" U7 s' c. X# X! }) C        'type' => 'file',
/ H4 T7 r4 _1 k$ ^. v& [        'data' => $path . '/form_theme.js',
3 y1 K/ B$ F* }$ K4 I! J  N( H    ),- u7 m8 ?$ q# Y
);' W5 I% A$ T+ S" Q7 k
?>

+ P" X1 C- X! D7 J# Q& F: S: `' }9 k0 f0 ~  M4 b6 o
这种方法相比drupal_add_js()和drupal_add_css()有个很大的好处,就是其它模块可以在该模块的样式和脚本的基础上做修改。
' ~. s  a- m* E( f1 f. b* z1 f最后,返回我的$form表单,代码如下:
/ `1 Z5 ~8 W& T3 |) \2 J8 `
; _1 H+ T" p7 x<?php0 k2 P  J$ d# Q9 r
function form_theme_form($form, &$form_state)
  U( N" D0 q0 [( u; b{3 N1 P7 Q6 p% q. x$ D6 A9 q
    $form['first_name'] = array
* ~* `2 |- G& D  h7 H0 }    (( C- l' J/ ?1 H) a
        '#type' => 'textfield',! S, V. q8 w/ x# a- k4 k
    );, ~7 N: r4 n  n) P
    $form['last_name'] = array  @7 |' {2 }  J+ c
    (
$ \( D( @: R& Q0 L        '#type' => 'textfield',$ A" t2 u1 o# p, R
    );3 C) |9 n4 `/ _$ f" `! e6 T5 I
    $form['age'] = array! R5 b: o1 b: Y
    (4 ]. `/ K0 p! G0 z2 \" H
        '#type' => 'textfield',
2 Y; b5 z9 E* Z+ H        '#maxlength' => 3,' V& d% B9 u3 H
    );9 S* W1 i% b, @
    // Get the path to the module
1 T+ E4 X2 n, B5 u' x; s    $path = drupal_get_path('module', 'form_theme');# M) }" [: F4 I& K0 R7 X5 D, O: h
    // Attach the CSS and JS to the form- H1 m1 A0 k7 M
    $form['#attached'] = array  {7 _' x* \# \: v5 T) G* E; F
    (' Y: T7 k) E- f$ K8 i. T5 x
        'css' => array- L% Y% }, V6 M( E" H
        (
' ?8 Z$ |3 L. r: w0 S" l            'type' => 'file',9 Q2 \# r) u- w! }
            'data' => $path . '/form_theme.css',, b9 ]9 u& E1 {- g' k6 F6 u
        ),
! M; d2 k6 @5 q7 R7 ~  `1 H& @/ p        'js' => array
4 t& ~( B% w4 }. E  g        (. w  l+ K( n# o8 G1 ]
            'type' => 'file',
" E; X% W! a" b/ ~3 }            'data' => $path . '/form_theme.js',
( Y$ O9 f4 A) ?$ ~4 Y$ V0 }4 G        ),. w+ w! I' N- j5 W& f" [; Z
    );
' ^5 L' C2 b9 g' a" ?) M    return $form;
- e( P/ n. `, @3 ]0 h- N8 s7 b}
4 K4 }4 x% u- E' v5 I$ ~?>
' H- e! U  {+ R
' r* f0 b& Z. Q
第三步:用hook_theme()注册一个主题函数
' h# m9 ~6 X3 \) I' q( I$ C; ]7 ]从Drupal6开始,主题函数就需要通过hook_theme()注册,但是在Drupal6和Drupal7中还是有些细微的区别。在Drupal7中,表单的主题函数不是使用“arguments”,而是使用仅仅只有“form”一个值的“render element”。在注册主题函数时,你必须让索引和你已经定义的表单函数保持一致。代码如下:% K' h  B9 J# a! e

, W5 C% x4 Y; f0 u7 N, w% D3 I- ]+ a<?php
2 _+ S" w5 B0 ~% Qfunction form_theme_theme()/ M* D0 `" Q/ ~! I
{
, \/ M% y* d! Z+ W6 `4 A* V    return array
6 n; P4 W1 K/ e. H8 u    (. S3 O" D) [+ c' l; p
        'form_theme_form' => array
( A# T) }! A, v) H! e" b! K; k        (
6 m4 ~0 H; D6 G# Z6 B0 q            'render element' => 'form'
% \2 Q/ n" ~7 o6 g! j        ),
- i4 d3 \+ @1 s& ~- q    );1 N+ Q6 ]3 ^) U4 I3 b4 |& }
}3 o2 ~* p+ L+ |$ a; t
?>

0 ]' k# F8 v% e( g' f# w- L2 w( F7 J6 J" }) u% }
正如你所见,我已经注册了一个主题函数。主题函数的命名十分重要,因为这个主题函数跟表单有相同的名称,Drupal在实现这个表单时会自动调用该主题函数。我也不需要添加#theme到我定义的表单$form中,这是多余的。
3 g9 O; x2 i% m4 r: t7 w第四步:写主题函数
4 q$ P4 }4 _2 @: n在Drupal7中,写主题函数,有几个注意点。它们是:
# u# t5 P2 \2 ~, W
  • 函数只有一个参数,命名为$variables的数组。$variables有一个form索引,该索引的值就包括所有你已定义的表单元素。
  • 所有的表单元素必须要作为参数传给drupal_render()函数。这个函数能将一个PHP数组转换成HTML,并且将Javascript和css添加进去。这些Drupal会自动帮你完成,你仅仅需要传递这些参数就行了。
  • 在写主题函数的最后,你必须将剩余的表单元素传给drupal_render_children()函数,这样才能将剩下的或隐藏的表单元素转换成HTML。这是跟Drupal6一个很大的不同。在Drupal6中,我们直接传递$form给drupal_render(),但是在Drupal7中,这样做就会导致死循环,而且不会出现任何错误提示。& ?8 Q. E4 Y4 a' }# K6 p
主题函数是以“theme_”加上我们上面注册过“form_theme_form”命名的。代码如下:, W2 z% y, k& g4 p. F8 A' W

* Q8 d2 m  s; B* ^% i<?php/ R% w( C0 q4 r, I2 P) a
function theme_form_theme_form($variables)
5 M' y: H4 x9 T6 B8 |- `2 K. U' d! N6 F{
2 J- I) w4 H2 k    // Isolate the form definition form the $variables array
- W. D4 E! x, }9 h    $form = $variables['form'];: d, ^6 t; o5 p0 v, `. s7 b
    $output = '<h2>' . t('Please enter your information below') . '</h2>';
7 p2 x9 T1 u0 C1 g" m2 ?1 e0 [0 ?    // Put the entire structure into a div that can be used for
9 `9 P8 U6 ^" m/ \/ X4 E( m" L    // CSS purposes0 h8 A# N4 _: R* w# G
    $output .= '<div id="personal_details">';
4 Q6 h) G4 w0 G' ^% J1 [    // Each of the pieces of text is wrapped in a <span>$ D# F2 h, J( C' y4 |
    // tag to allow it to be floated left/ ], i- `8 A3 \1 F. C0 ]
    $output .= '<span>' . t('My name is') . '</span>';
+ \; k  V9 G+ d* }- j+ V& b    // Form elements are rendered with drupal_render()
0 g7 }; T! j  l6 F  n' c/ `    $output .= drupal_render($form['first_name']);
0 G3 h5 A% s7 Z' A    $output .= drupal_render($form['last_name']);6 f7 ?3 P' d: t) p
    $output .= '<span>' . t('and I am') . '</span>';* L6 f# q8 s9 Y$ f( j0 z; |: B
    $output .= drupal_render($form['age']);8 i+ z/ d; V# {: O- G& `* l
    $output .= '<span>' . t('years old.') . '</span>';1 B6 e* A8 ^5 A
    $output .= '</div>';
% b7 u3 C* q7 j7 S( |# }5 c/ P3 u$ E- r2 o    // Pass the remaining form elements through drupal_render_children()
8 |1 r# ?0 ]1 Y# U" F5 K6 o2 x2 S. V    $output .= drupal_render_children($form);
. `7 h! n) e4 Z: T8 {    // return the output) A# R! D$ @- r# d6 @' Y
    return $output;
; n  i3 h6 t! ]7 V}; j. B7 j! p; {  v8 b, x
?>

6 _% K  k' E9 x+ x+ H3 G) P1 h/ S% L) l" D4 V
到这里,我已经完成大部分的内容,定义表单,注册主题函数,实现主题函数。但是我还没添加CSS和Javascript。! {$ Z- d& \2 ?# L, m$ O& D5 b8 _
第五步:创建CSS和Javascript文件: d: H& n2 L7 M1 ]! E# a- z) }: \
在第二步中我添加了CSS和JS路径,这两个文件都在form_theme模块的根目录。CSS代码如下:1 d8 n& K8 r3 y% Z/ u
9 h1 @0 O+ `2 X" o% D5 q. @
#personal_details span, #personal_details div" S8 U9 [* @6 w& s
{1 C2 m/ _+ s' H  k, k
float:left;9 A) X" k1 P& {$ E
}' S  l0 q, x; t6 P$ ~) X6 b2 H

. o% K5 Z6 z! M+ E4 W5 p1 p#personal_details .form-item-first-name, #personal_details .form-item-last-name7 g% \# Z" i! r% U0 ]( J$ E
{
( b) E3 g5 }; v" e' `width:115px;
* L& N# D8 ?& @3 d, V, H$ N}/ P7 t% c. h& Q( c1 y4 |

% B6 {3 U4 r6 @#edit-first-name, #edit-last-name7 U. N4 O5 p* X+ J( {" ]8 t
{
) V. ^$ j/ W) w0 k8 F3 cwidth:100px;, f' H: q5 |0 L: L4 S' X3 J$ i: {
}
$ x5 n! _: n) c9 I6 y
" @6 ]* }8 P2 k; H; I5 K#personal_details .form-item-age
8 p7 m: \, H7 z2 `$ [{
1 T1 Z. K( k/ ?8 K+ I% X5 U0 Zwidth:50px;0 @: e7 a9 Y% V8 K( }+ `
}
5 X. e) A: J! R' |  n5 q, _6 d) u6 l
/ e. L6 T* K* G9 M#edit-age$ h$ N7 ^0 R* j7 N8 C
{/ o9 `0 i1 a$ Y/ q. k* N
width:35px;
3 a& a; S! T, Z# s- U4 M}
' T8 }9 r' d( A( N8 c7 x- {
3 _3 f; y( Y* O4 d7 G9 p# l$ t" W#personal_details span
% X2 T6 e* J7 k' |1 a9 a. R* B7 g{
3 L- J. X! D( I! x& y- j2 rmargin-right:5px;
* v( d, }4 X  a7 fpadding-top:5px;
/ \% l$ b5 j" `; k0 _7 |}
, b  O% o; Q% h8 W+ Y8 R
# K- N" O- F5 b6 t7 G. K# C" uJavascript代码如下:
* g& D1 l# N9 B* F+ Y$ @4 z' B( Q; Y% n1 z8 i, d0 I% S( Q. ]
// We wrap the entire code in an anonymous function9 E  E2 R2 K  q) {* z
// in order to prevent namespace collisions, and to& j- j" J) l+ J) K# B+ d8 m$ H3 U
// allow for jQuery to be set in a safe mode where+ x; {) V7 ^7 |! E5 p" d' d8 ^1 P
// it will not collide with other javascript libraries., i& @# o2 N! [1 f4 M( R
// While this is the proper way to do it in Drupal 7,2 q* S% l6 w$ P5 B) g
// this method is actually good to use in Drupal 6 as
$ {$ A  ^* |& L1 f// well, for the same reasons.  c5 D2 e, x8 A/ ~$ D
(function($)4 [' A5 n8 A& N$ j( J9 {( g
{
! t$ L& c" X1 q( X; S9 Q// In Drupal 6, each element of Drupal.behaviors! u& |) p7 z4 o! R: u
// was a function that was executed when the
, Z, F, H/ y! M( H" }2 U6 c// document was ready. In Drupal 7, each element
/ [( }* A( Q/ T$ N% }// of Drupal.behaviors is an object with an
' K$ ^' g, W2 B8 {$ x// element 'attach' (and optionally an element
7 y; f7 c+ z/ b9 u4 `% t6 v4 l// 'detach'), which is executed when the document% L6 o/ k" c2 x2 {
// is ready/ U9 w: m% [% E  t
Drupal.behaviors.formTheme = {0 E& _5 v/ W! y4 s, e
attach:function() {
1 k# }# P. {0 [- ]$ |" L. e' {6 i// First, define an empty array+ N. x9 f2 o+ w" r/ E& Z
var defaults = [];* ^' `, H+ j! S/ E
// Next, add three elements to the array,
* O/ }) V/ W, ?/ G1 ?// one for each of the form elements. The value3 N0 x/ ]- x0 ?
// is of the array element is set as the default
0 W5 c% _$ @! L// text. This text is run through Drupal.t(),' z% X! S& Q* |9 {# |/ u  M5 R, }# W
// which is the Drupal JavaScript equivalent  N# D9 s$ v6 _+ ?" k$ S4 m
// of the Drupal PHP t() function, and allows
* n( f) j$ {1 o" m6 v// for translating of text in a JavaScript document
& G  U$ g; h4 u1 {3 |/ B2 Bdefaults["#edit-first-name"] = Drupal.t("First Name");- S6 w& |5 a4 J" e# ~$ `
defaults["#edit-last-name"] = Drupal.t("Last Name");
' P1 s0 Y# L4 u( j# B$ q" ]2 ndefaults["#edit-age"] = Drupal.t("Age");
" m: o0 n* b( }- g// Next we loop through each of the elements of the array( P. H! O- A% s% W) m% a
var element;' c" G- E) N- i5 G5 w
for(element in defaults)3 C; `7 ~5 v* \, e) l
{
) D( |* q. O) ~// We wrap the body in the following if() statement
# u3 h2 g8 D9 J' Y0 x+ [// as each element in an array will also have a
; n/ ]- }' m# L9 p4 I$ {% c/ B- y// prototype element. If you don't understand this,
7 ], e2 c" d/ \" F$ L( j' _// don't worry. Just copy it. It will make your
4 f4 j+ m" u5 \/ P. |- ^// for(A in B) loops run better.
" x0 |8 H" t1 `' z" B( ?if(defaults.hasOwnProperty(element)) {8 F/ J1 Z+ W' h. {1 x* X
// 1) Set a placeholder in the form element, X; q/ M  h( S" _) p
// 2) Set the CSS text color to grey for the placeholder
0 h0 o1 d' u! G( g// 3) Attach an onfocus and onblur listener to each element: k  V. n; r% Q
$(element).val(defaults[element]).css("color", "grey").focus(function()- Z  T" P; B  p- b9 F
{9 j# N1 K1 e* n' j, t6 G& `/ j, m
// This is entered on focus. It checks
, f; J+ k! S. |// if the value of the form element is6 j5 U7 G- W2 D7 l: K  o
// the default value of the placeholder,
6 \) I+ a% F- z' ^2 ~// and if it is, it clears the value and7 N- x3 P, D/ l5 z3 E' \: s
// sets the text color to black,as the
* f& l6 k4 `+ e// entered text will be the actual text. `, ~' h0 b- s) M* ~3 Q4 T3 [
// and not the greyed out placeholder text.3 y6 b! b7 w$ C6 \+ y& y
var key = "#" + $(this).attr("id");9 s6 @' f2 A! U+ T: ~
if($(this).val() === defaults[key]) {
+ p: t! ]) [% q% q$(this).css("color", "black").val("");
6 f1 `; |3 F1 g) Q" X( c}
6 ?; o; I7 C# ^8 x) j& e}).blur(function()
# s! J7 `6 ~: H{
( m( s2 r* ~* I// This is entered on blur, when the element
. P5 A2 x$ p% p8 D. i2 D9 R// is exited out of. It checks if the element
; p9 P3 O/ e, B1 |7 `// is empty, and if it is, it sets the default7 H' Q) F& x" ]* j& y
// placeholder text back into the element, and
( {/ R& _! v5 {& B3 {$ J// changes the text color to the grey placeholder
9 K# C5 U+ p5 }2 t5 d- ^// text color.. A7 G, Z- r, J) i7 \0 \* ]( ]
if($(this).val() == "") {+ `9 _1 L, M0 _: u# O8 f* o5 M; f
var key = "#" + $(this).attr("id");
( ~2 D+ y7 O5 m1 A$ K; l$(this).css("color", "grey").val(defaults[key]);
" Q8 q* v: |4 C/ R}
! K6 O( `) w! K});
4 X, H3 z4 x7 K9 X: ?/ L% |}
$ h7 j+ M9 u! q3 Y  o}) y8 C3 E- I0 U# U+ I- Q
}
9 E3 B- F8 O! P: H- [* i4 K};* y* m6 g; R' C. Y1 [
}(jQuery));0 @. X; D7 K' d: f

2 U1 U) d0 f' t# {% ~# y& ?好了,你可以试试看。# e$ m( a: u- X5 j7 \
原文出自:http://junepeng.info/zh/node/28, A3 Z* ^( P+ O6 W" w
: B3 V& Y" `# o. q

" b$ q; T  k$ X, [$ |! ]* Q/ ?. v) d% S3 d, y4 D1 U- S2 t

1 O# @6 K0 {8 a4 H2 Y- x7 P! o8 Y* `; s: S! V: D% _
+ n" Q, B) ^* q0 C% Y+ e/ f# j

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

GMT+8, 7-6-2025 03:55 , Processed in 0.339539 second(s), 159 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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