forked from yiisoft/yii
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathform.builder.txt
389 lines (295 loc) · 20.1 KB
/
form.builder.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
שימוש במערכת יצירת הטפסים
==================
בעת יצירת טפסי HTML, אנו בדרך כלל רואים שאנו כותבים הרבה קוד תצוגה שחוזר על עצמו שקשה להשתמש בו שוב פעם בפרוייקט נוסף. לדוגמא, לכל שדה טקסט, אנו צריכים לשייך אותו עם תוית טקסט ולהציג שגיאות אימות נתונים במידה והם קיימים.
בכדי לשפר את השימוש החוזר בקודים אלו, אנו יכולים להשתמש במערכת יצירת הטפסים הקיימת במערכת ה Yii מגרסא 1.1.0.
תפיסה בסיסית
--------------
מערכת יצירת הטפסים משתמשת באובייקט של [CForm] כדי לייצג את המפרט הדרוש לייצוג טופס HTML, הכולל אילו מודלים קשורים לטופס, אילו שדות נתונים נמצאים בטופס, וכיצד להציג את כל הטופס.
מפתחים בעיקר צריכים ליצור ולהגדיר את האובייקט [CForm], לאחר מכן לקרוא למתודת התצוגה שלו בכדי להציג את הטופס.
מפרט שדות הטופס מסודרים במונחים של אלמנטים של אובייקט הטופס בהיררכיה. בראש ההיררכיה, נמצא האובייקט [CForm]. האובייקט הראשי מתחזק את התתים שבו בשני אוספים שונים: [CForm::buttons] ו [CForm::elements]. הראשון מכיל את האלמנטים המיוצגים ככפתורים (כמו כפתור שליחה, כפתור איפוס), בזמן שהשני מכיל את שדות הזנת הטקסט, טקסט סטטי, ותתי טפסים. תת-טופס הינו אובייקט של [CForm] הנמצא באוסף של האלמנטים ([CForm::elements]) בטופס אחר. הוא יכול להכיל מודל משלו, [CForm::buttons] ו [CForm::elements].
כשמשתמשים שולחים טופס, הנתונים שהוזנו בכל השדות בכל ההיררכיה של הטופס נשלחים, כולל את השדות הנמצאים בתתי-טפסים. [CForm] מספק מתודות נוחות לשימוש שבעזרתן ניתן לצרף נתונים מסויימים למאפייני המודלים המתאימים ולבצע אימות נתונים על גביהם.
יצירת טופס פשוט
----------------------
בדוגמא הבאה, אנו מציגים כיצד להשתמש במערכת יצירת הטפסים כדי ליצור טופס התחברות.
קודם כל, אנו כותבים את הפעולה של ההתחברות:
~~~
[php]
public function actionLogin()
{
$model = new LoginForm;
$form = new CForm('application.views.site.loginForm', $model);
if($form-»submitted('login') && $form-»validate())
$this-»redirect(array('site/index'));
else
$this-»render('login', array('form'=»$form));
}
~~~
בקוד למעלה, אנו יוצרים אובייקט של [CForm] תוך כדי שימוש במפרט המצביע לנתיב `application.views.site.loginForm` (הסבר לגבי זה בהמשך).
האובייקט [CForm] מקושר עם המודל `LoginForm` כפי שתואר [ביצירת מודל](/doc/guide/form.model).
כפי שמוצג בקוד, במידה והטופס נשלח וכל השדות אומתו ללא שגיאות, אנו נעביר את המשתמש לעמוד `site/index`. אחרת, אנו נציג שוב פעם את קובץ התצוגה `login` ביחד עם הטופס.
הנתיב `application.views.site.loginForm` מתייחס לקובץ PHP הנמצא תחת התיקיה `protected/views/site/loginForm.php`. הקובץ צריך להחזיר מערך המכיל את הגדרות הנחוצות עבור [CForm], כפי שמוצג בקוד הבא:
~~~
[php]
return array(
'title'=»'Please provide your login credential',
'elements'=»array(
'username'=»array(
'type'=»'text',
'maxlength'=»32,
),
'password'=»array(
'type'=»'password',
'maxlength'=»32,
),
'rememberMe'=»array(
'type'=»'checkbox',
)
),
'buttons'=»array(
'login'=»array(
'type'=»'submit',
'label'=»'Login',
),
),
);
~~~
ההגדרות הינם מערך המכיל מפתחות וערכים המוגדרים למאפיינים של המחלקה [CForm]. המאפיינים החשובים ביותר להגדרה, כפי שכבר הזכרנו, [CForm::elements] ו [CForm::buttons]. כל אחד מהם מקבל מערך המגדיר רשימה של אלמנטים בטופס. אנו נסביר בהרחבה כיצד יש להגדיר אלמנטים של טופס בחלק הבא.
לבסוף, אנו כותבים את קובץ התצוגה `login`, שיכול להיות פשוט כפי שמוצג בקוד הבא,
~~~
[php]
«h1»Login«/h1»
«div class="form"»
«?php echo $form; ?»
«/div»
~~~
» Tip|טיפ: הקוד למעלה, `;echo $render` הוא זהה לקוד `;()echo $form-»render`. וזאת מכיוון שהאובייקט [CForm] מיישם את המתודה `toString__` אשר קוראת למתודה `()render` ומחזירה את התצוגה כסטרינג המייצג את אובייקט הטופס.
הגדרת אלמנטים בטופס
------------------------
בשימוש במערכת יצירת הטפסים, רוב העבודה שלנו משתנה מכתיבת קוד בקבצי התצוגה להגדרת אלמנטים בטופס. בחלק זה, אנו נתאר כיצד להגדיר את האלמנטים מאפיין [CForm::elements]. אנו לא נתאר אודות [CForm::buttons] מאחר והגדרותיו הם כמעט זהות ל [CForm::elements].
המאפיין [CForm::elements] מקבל מערך. כל אלמנט במערך מייצג אלמנט אחד בטופס שיכול להיות שדה נתונים, טקסט סטטי, או תת-טופס.
### הגדרת אלמנטים כשדות נתונים
אלמנט שדה נתונים בעיקר מכיל תוית, שדה נתונים, שדה עזרה ותצוגת שגיאה.
הוא חייב להיות מקושר למאפיין במודל מסויים. המפרט של אלמנט שדה נתונים מיוצג כאובייקט של [CFormInputElement]. הקוד הבא במערך [CForm::elements] מגדיר אלמנט שדה נתונים אחד:
~~~
[php]
'username'=»array(
'type'=»'text',
'maxlength'=»32,
),
~~~
קוד זה מציין שהמאפיין של המודל בשם `username`, ושדה הנתונים הוא מסוג `text` ושאורכו - `maxlength` הוא 32. אנו יכולים לציין אפשרויות נוספות במערך למעלה כל עוד שהם מאפיינים שניתנים לכתיבה במחלקה [CFormInputElement]. לדוגמא, אנו יכולים להגדיר את האפשרות [hint|CFormInputElement::hint] המציגה טקסט עזרה עבור שדה זה, או שניתן להגדיר את האפשרות [items|CFormInputElement::items] במידה והשדה הוא תיבת בחירה, תיבת בחירה מרובה, רשימת כפתורי בחירה, רשימת כפתורי רדיו.
האפשרות [type|CFormInputElement::type] דורשת יותר תשומת לב מהשאר. אפשרות זו מגדירה את סוג שדה הנתונים לתצוגה. לדוגמא, הסוג `text` מעיד על כך שיש צורך להציג שדה טקסט רגיל; הסוג `password` אומר שיש צורך להציג שדה סיסמא. [CFormInputElement] מזהה את הסוגים המובנים הבאים:
- text: שדה טקסט
- hidden: שדה מוסתר
- password: שדה סיסמא
- textarea: תיבת טקסט
- file: שדה קובץ
- radio: שדה כפתור רדיו
- checkbox: שדה כפתור בחירה
- listbox: שדה בחירה מרובה
- dropdownlist: שדה תיבת בחירה
- checkboxlist: שדה רשימת כפתורי בחירה
- radiolist: שדה רשימת כפתורי רדיו
מלבד הסוגים המובנים, האפשרות [type|CFormInputElement::type] יכולה לקבל שם של מחלקת וידג'ט או נתיב מקוצר עד אל הוידג'ט. המחלקה של הוידג'ט צריכה לירוש מהמחלקה [CInputWidget]. בעת התצוגה של האלמנט, אובייקט של הוידג'ט של השדה הנוכחי יווצר ויוצג. הוידג'ט יוגדר בהתבסס על המפרט הקיים באלמנט.
### הגדרת טקסט סטטי
בהרבה מקרים, מלבד שדות נתונים טופס מכיל קוד HTML שנועד לעיצוב הטופס. לדוגמא, יהיה צורך בקו אופקי בכדי להפריד בין חלקים בטופס; יש צורך בתמונה במקום מסויים בטופס בכדי לשפר את המראה החיצוני של הטופס. אנו יכולים להגדיר את קוד ה HTML הזה כטקסט סטטי באוסף האלמנטים של [CForm::elements]. בכדי לבצע זאת, אנו מגדירים אלמנט בתוך המאפיין [CForm::elements] בתור טקסט סטטי במיקום בו אנו רוצים להציג אותו בטופס. לדוגמא,
~~~
[php]
return array(
'elements'=»array(
......
'password'=»array(
'type'=»'password',
'maxlength'=»32,
),
'«hr /»',
'rememberMe'=»array(
'type'=»'checkbox',
)
),
......
);
~~~
בקוד המוצג למעלה, אנו מוסיפים קו אופקי בין השדה של הסיסמא - `password` לבין השדה של זכור אותי - `rememberMe`.
השימוש בטקסט סטטי הוא כשהטקסט המיקום שלו אינם רגילים. אם לכל שדה בטופס יהיה צורך בעיצוב באופן פרטני, יהיה צורך בלשנות את אופן התצוגה של הטופס, הסבר לפעולה זו יופיע בהמשך.
### הגדרת תתי-טפסים
תתי-טפסים נועדו בכדי לחלק טופס ארוך לכמה טפסים חלקים הקשורים אחד לשני לוגית. לדוגמא, אנו יכולים לחלק את טופס ההרשמה לשני תת-טפסים: פרטי התחברות ופרטי פרופיל.
כל תת-טופס חייב/לא חייב להיות משוייך למודל. בדוגמא של טופס ההרשמה, אם אנו שומרים את פרטי ההתחברות של המשתמש ואת פרטי הפרופיל של המשתמש בשני טבלאות שונות (ולכן שני מודלים נפרדים), לכן כל תת טופס יהיה משוייך למודל שלו. במידה ואנו שומרים את כל הפרטים באותה הטבלה, לכן לאף אחד מתתי-הטפסים לא יהיה מודל מאחר והם משותפים עם המודל של הטופס הראשי.
תת-טופס מיוצג כאובייקט של [CForm]. בכדי להגדיר תת-טופס, אנו צריכים להגדיר את המאפיין [CForm::elements] עם אלמנט שסוגו הוא `form`:
~~~
[php]
return array(
'elements'=»array(
......
'user'=»array(
'type'=»'form',
'title'=»'Login Credential',
'elements'=»array(
'username'=»array(
'type'=»'text',
),
'password'=»array(
'type'=»'password',
),
'email'=»array(
'type'=»'text',
),
),
),
'profile'=»array(
'type'=»'form',
......
),
......
),
......
);
~~~
כמו בהגדרת הטופס הראשי, אנו בעיקר צריכים להגדיר את המאפיין [CForm::elements] של תתי-הטפסים.
במידה ותת הטופס צריך להיות משוייך עם מודל, ניתן להגדיר את המאפיין [CForm::model] שלו גם כן.
לפעמים, אנו נרצה לייצג טופס המשתמש במחלקה אחרת ולא ברירת המחדל [CForm]. לדוגמא, כפי שנציג בעוד רגע בחלק זה, אנו יכולים להרחיב את המחלקה [CForm] בכדי להתאים אישית את אופן הצגת הטופס.
על ידי הגדרת סוג האלמנט כ `form`, תת הטופס אוטומטית מיוצג כאובייקט שהמחלקה שלו היא זהה למחלקה של טופס האב. אם נגדיר את סוג האלמנט למשהו כמו `XyzForm` (סטרינג המסתיים ב `Form`), אז תת-הטופס יהיה מיוצג על ידי האובייקט של המחלקה `XyzForm`.
גישה לאלמנטים בטופס
-----------------------
גישה לאלמנטים בטופס הינה פשוטה כגישה לאלמנטים מערך. המאפיין [CForm::elements] מחזיר אובייקט של [CFormElementCollection], היורש מהמחלקה [CMap] ומאפשר גישה לאלמנטים שבו כמערך רגיל. לדוגמא, בכדי לגשת לאלמנט `username` בדוגמא של טופס ההתחברות שהוצג, אנו יכולים להשתמש בקוד הבא:
~~~
[php]
$username = $form-»elements['username'];
~~~
ובכדי לגשת לאלמנט של `email` בדוגמא של טופס ההרשמה, אנו יכולים להשתמש ב
~~~
[php]
$email = $form-»elements['user']-»elements['email'];
~~~
מאחר ו [CForm] מיישם את הממשק של `array access` עבור המאפיין [CForm::elements], ניתן לפשט את הקוד למעלה בצורה הבאה:
~~~
[php]
$username = $form['username'];
$email = $form['user']['email'];
~~~
יצירת שרשור טפסים
----------------------
כבר הצגנו את התתי-טפסים. אנו קוראים לטופס עם תתי-טפסים טופס משורשר. בחלק זה, אנו משתמשים בטופס של הרשמת משתמשים בכדי להציג כיצד ליצור טופס משורשר המקושר לכמה מודלים.
אנו מניחים שפרטי המשתמשים מאוחסנים במודל `User`, בזמן שמידע אודות פרופיל המשתמש נמצא תחת המודל `Profile`.
אנו קודם יוצרים את פעולת ההרשמה `register` בצורה הבאה:
~~~
[php]
public function actionRegister()
{
$form = new CForm('application.views.user.registerForm');
$form['user']-»model = new User;
$form['profile']-»model = new Profile;
if($form-»submitted('register') && $form-»validate())
{
$user = $form['user']-»model;
$profile = $form['profile']-»model;
if($user-»save(false))
{
$profile-»userID = $user-»id;
$profile-»save(false);
$this-»redirect(array('site/index'));
}
}
$this-»render('register', array('form'=»$form));
}
~~~
בקוד למעלה, אנו יוצרים את הטופס בעזרת שימוש בהגדרות הנמצאות ב `application.views.user.registerForm`.
לאחר השליחה של הטופס ואימות הנתונים עבר בהצלחה, אנו מנסים לשמור את המודלים של `User` ו `Profile`.
אנו שולפים את המודלים של המשתמש והפרופיל על ידי גישה למאפיין `model` תחת האובייקט של תת הטופס.
מאחר ואימות הנתונים נעשה כבר, אנו קוראים ל `$user-»save(false)` בכדי לדלג על האימות. אנו עושים את אותו הדבר עם המודל של הפרופיל.
לאחר מכן, אנו כותבים את קובץ הגדרות הטופס תחת הנתיב `protected/views/user/registerForm.php`:
~~~
[php]
return array(
'elements'=»array(
'user'=»array(
'type'=»'form',
'title'=»'Login information',
'elements'=»array(
'username'=»array(
'type'=»'text',
),
'password'=»array(
'type'=»'password',
),
'email'=»array(
'type'=»'text',
)
),
),
'profile'=»array(
'type'=»'form',
'title'=»'Profile information',
'elements'=»array(
'firstName'=»array(
'type'=»'text',
),
'lastName'=»array(
'type'=»'text',
),
),
),
),
'buttons'=»array(
'register'=»array(
'type'=»'submit',
'label'=»'Register',
),
),
);
~~~
בקוד המוצג למעלה, בעת הגדרת כל תת-טופס, אנו מגדירים את המאפיין [CForm::title] השייך לו.
לוגיקת התצוגה ברירת המחדל של הטופס תעטוף כל תת-טופס בתוך מעטפת אשר תשתמש במאפיין זה בכדי להציג את הכותרת של הטופס.
לבסוף, אנו כותבים את קובץ התצוגה הפשוט של ההרשמה `register`:
~~~
[php]
«h1»הרשמה«/h1»
«div class="form"»
«?php echo $form; ?»
«/div»
~~~
התאמה אישית של תצוגה הטופס
------------------------
היתרון בשימוש של מערכת יצירת הטפסים היא ההפרדה מהלוגיקה (הגדרות הטופס נמצאות בקובץ נפרד) והתצוגה (מתודת [CForm::render]). כתוצאה מכך, אנו יכולים להתאים את התצוגה של הטופס באופן אישי על ידי דריסה של המתודה [CForm::render] או לספק קובץ תצוגה חלקי אשר מציג את הטופס. בשני האפשרויות ניתן להשאיר את הגדרות הטופס ללא שינוי ולהשתמש באותו הקוד בצורה קלה.
כשדורסים את המתודה [CForm::render], יש לרוץ על גבי האלמנטים של [CForm::elements] ו [CForm::buttons] ולקרוא למתודה [CFormElement::render] עבור כל כל אלמנט. לדוגמא,
~~~
[php]
class MyForm extends CForm
{
public function render()
{
$output = $this-»renderBegin();
foreach($this-»getElements() as $element)
$output .= $element-»render();
$output .= $this-»renderEnd();
return $output;
}
}
~~~
כמו כן אנו יכולים ליצור קובץ תצוגה `form_` בכדי להציג את הטופס:
~~~
[php]
«?php
echo $form-»renderBegin();
foreach($form-»getElements() as $element)
echo $element-»render();
echo $form-»renderEnd();
~~~
בכדי להשתמש בקובץ התצוגה, ניתן פשוט לקרוא:
~~~
[php]
«div class="form"»
$this-»renderPartial('_form', array('form'=»$form));
«/div»
~~~
במידה ותצוגה כללית לא נראית טוב בטופס מסויים (לדוגמא, הטופס צריך דקורציה מיוחדת ולא רגילה עבור אלמנטים מסויימים), אנו יכולים לבצע את הפעולות הבאות בקובץ תצוגה:
~~~
[php]
אלמנטים של UI מורכבים כאן
«?php echo $form['username']; ?»
אלמנטים של UI מורכבים כאן
«?php echo $form['password']; ?»
אלמנטים של UI מורכבים כאן
~~~
בשיטה האחרונה,זה נראה שמערכת יצירת הטפסים לא מועילה לנו כל כך, אנו עדיין צריכים לכתוב כמות קוד דומה לטופס שאנו משתמשים בעת שימוש בקוד רגיל. למרות, שהטופס מוגדר בעזרת קובץ הגדרות בנפרד אשר עוזר למפתחים להתמקד יותר בלוגיקה.
«div class="revision"»$Id: form.builder.txt 1849 2010-03-01 15:54:34Z qiang.xue $«/div»