/[drupal]/contributions/sandbox/frando/fapi4/fapi4.module
ViewVC logotype

Contents of /contributions/sandbox/frando/fapi4/fapi4.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.7 - (show annotations) (download) (as text)
Wed Sep 5 13:37:08 2007 UTC (2 years, 2 months ago) by frando
Branch: MAIN
CVS Tags: HEAD
Changes since 1.6: +10 -9 lines
File MIME type: text/x-php
FAPI4 at Froscon: Move all the Iterator and traversing stuff out of the DrupalElement class into a DrupalIterator class. Makes the code much more readable and understandable.
1 <?php
2 /**
3 * BUGGY CONCEPT CODE!
4 *
5 * This is code for a object oriented Forms and Rendering API in Drupal 7.
6 */
7
8 // The heart.
9 require_once drupal_get_path('module', 'fapi4') .'/classes.inc';
10 require_once drupal_get_path('module', 'fapi4') .'/fapi.classes.inc';
11
12 function fapi4_init() {
13 // This is useless here, but imagine the following line living in some other module,
14 // e.g. in hook_init(): This replaces hook_form_alter
15 connect('Fapi4TestForm', 'construct', 'fapi4_alter_the_form');
16 // Yet TODO: Altering all forms.
17 }
18
19 function fapi4_menu() {
20 $items['fapi4'] = array(
21 'title' => 'FAPI4 test page',
22 'description' => "foo",
23 'page callback' => 'fapi4_page_callback',
24 'access arguments' => array('access administration pages'),
25 );
26
27 return $items;
28 }
29
30 function fapi4_page_callback() {
31 $output = '';
32
33 // Some dynamical data, like a node or user data.
34 // drupal_element will pass this to the build method.
35 $data = array(
36 'value1' => 'foo',
37 'value2' => 'bar'
38 );
39
40 // Get our form. This either creates a new object or loads one from cache.
41 // (This is still a little buggy)
42 $form = Form::load('Fapi4TestForm', $data);
43 // This always works instead:
44 // $form = new Fapi4TestForm();
45 // $form->invoke('build', $data);
46
47 $output .= $form->render();
48
49 q($form)->descendants()->filter('#FormWidget=asdf');
50
51 // Some traversing tests.
52 $output .= "<pre>";
53 $output .= "foreach q(\$form->group1)->siblings() :\n";
54 foreach (q($form->group1)->siblings() as $element) {
55 $output .= ' '. $element->__toString() ."\n";
56 }
57 $output .= "foreach q(\$form)->group1->siblings()->children() :\n";
58 foreach (q($form->group1)->siblings()->children() as $element) {
59 $output .= ' '. $element->__toString() ."\n";
60 }
61 $output .= "foreach q(\$form)->descendants() :\n";
62 foreach (q($form)->descendants('#has_error=0') as $element) {
63 $output .= ' '. $element->__toString() ."\n";
64 }
65 $output .= "</pre>";
66
67
68 return $output;
69 }
70
71 // Our form.
72 class Fapi4TestForm extends DrupalForm {
73
74 // This is called only once and then cached. So only static data here.
75 // (think of D5 hook_menu $may_cache)
76 public function construct() {
77 $this->group1 = new Fapi4TestWidget();
78 $this->group1->textfield1 = new DrupalTextfield(array('title' => 'Textfield 1'));
79 $this->group1->addChild('textfield2', new DrupalTextfield(array('title' => 'Textfield 2')));
80
81 $this->group2 = new Fapi4TestWidget();
82 $this->group2->text3 = new DrupalTextfield(array('title' => 'text3'));
83 $this->group2->text4 = new DrupalTextfield(array('title' => 'text4'));
84
85 $this->textfieldA = new DrupalTextfield(array(
86 'title' => 'Yet another textfield (A)',
87 'description' => 'It even has a description'
88 ));
89 }
90
91 // This is called no matter whether the form was cached or not.
92 public function build($data) {
93 $this->group2->text3['default_value'] = $data['value1'];
94 $this->group2->text4['default_value'] = $data['value2'];
95 parent::build();
96 }
97
98 public function submit() {
99 $debuginfo = 'submit method called. <br> STEP: '. $this['step'];
100
101 switch ($this['step']) {
102 case 1:
103 $debuginfo .= " - Add some more text fields";
104 $this->group2->addChild('text5', new DrupalTextfield(array(
105 'title' => 'text5',
106 'description' => 'added by submit method for step 1'
107 )));
108 $this->group2->addChild('text6', new DrupalTextfield(array(
109 'title' => 'text6',
110 'description' => 'added by submit method for step 1'
111 )));
112 $this->submit['value'] = t('On to step 2!');
113 break;
114 case 2: {
115 $debuginfo .= " - don't render group1 one again and alter some stuff";
116 // don't unset (that would also destroy values etc.)! just not render it again.
117 $this->group1['render'] = FALSE;
118 $this->submit['value'] = t('Finish!');
119 break;
120 }
121 case 3: {
122 $debuginfo .= "<br>The final step. We now do what we want to do with the form values and ";
123 $debuginfo .= "then call \$this->redirect(). Here, we just redirect to the empty form again.";
124 $debuginfo .= '<br>received form values from all steps: <br>';
125 foreach ($this->descendants() as $e) {
126 $debuginfo .= $e->__toString() . ' - <em>' . (isset($e['value']) ? $e['value'] : 'No value') . "</em><br>";
127 }
128 drupal_set_message($debuginfo);
129 $this->redirect();
130 }
131 }
132
133 drupal_set_message($debuginfo);
134 }
135 }
136
137 // This replaces hook_form_alter.
138 function fapi4_alter_the_form($form) {
139 // Here, you could work with all the traversing function + foreach magic (jQuery style).
140 // e.g. foreach ($form->['some_element']->siblings() as $element) etc.
141 $form->group1['description'] = ' altered by a construct callback';
142 }
143
144 // A non-input widget.
145 class Fapi4TestWidget extends DrupalWidget {
146 // This is the place to set default properties,
147 // add required children, add callbacks, etc.
148 // This is actually a callback for the 'init' signal, which is always registered (by DrupalWidget)
149 public function construct() {
150 $this['description'] = 'Some test widget';
151 }
152
153 // let's render the children as an ul list, and print the element's description and name.
154 protected function theme() {
155 $output = "<strong>{$this['name']}</strong>";
156 $output .= "<div class='description'>{$this['description']}</div>";
157 if ($this->hasChildren()) {
158 $output .= "<ul>";
159 $output .= $this->renderChildren('<li>', '</li>');
160 $output .= "</ul>";
161 }
162 return $output;
163 }
164
165 public function preRender() {
166 // this is invoked before the widget is rendered.
167 }
168 }
169
170

  ViewVC Help
Powered by ViewVC 1.1.2