ctools_ajax_sample.module 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. <?php
  2. /**
  3. * @file
  4. * Sample AJAX functionality so people can see some of the CTools AJAX
  5. * features in use.
  6. */
  7. // ---------------------------------------------------------------------------
  8. // Drupal hooks.
  9. /**
  10. * Implementation of hook_menu()
  11. */
  12. function ctools_ajax_sample_menu() {
  13. $items['ctools_ajax_sample'] = array(
  14. 'title' => 'Chaos Tools AJAX Demo',
  15. 'page callback' => 'ctools_ajax_sample_page',
  16. 'access callback' => TRUE,
  17. 'type' => MENU_NORMAL_ITEM,
  18. );
  19. $items['ctools_ajax_sample/simple_form'] = array(
  20. 'title' => 'Simple Form',
  21. 'page callback' => 'ctools_ajax_simple_form',
  22. 'access callback' => TRUE,
  23. 'type' => MENU_CALLBACK,
  24. );
  25. $items['ctools_ajax_sample/%ctools_js/hello'] = array(
  26. 'title' => 'Hello World',
  27. 'page callback' => 'ctools_ajax_sample_hello',
  28. 'page arguments' => array(1),
  29. 'access callback' => TRUE,
  30. 'type' => MENU_CALLBACK,
  31. );
  32. $items['ctools_ajax_sample/%ctools_js/tablenix/%'] = array(
  33. 'title' => 'Hello World',
  34. 'page callback' => 'ctools_ajax_sample_tablenix',
  35. 'page arguments' => array(1, 3),
  36. 'access callback' => TRUE,
  37. 'type' => MENU_CALLBACK,
  38. );
  39. $items['ctools_ajax_sample/%ctools_js/login'] = array(
  40. 'title' => 'Login',
  41. 'page callback' => 'ctools_ajax_sample_login',
  42. 'page arguments' => array(1),
  43. 'access callback' => TRUE,
  44. 'type' => MENU_CALLBACK,
  45. );
  46. $items['ctools_ajax_sample/%ctools_js/animal'] = array(
  47. 'title' => 'Animal',
  48. 'page callback' => 'ctools_ajax_sample_animal',
  49. 'page arguments' => array(1),
  50. 'access callback' => TRUE,
  51. 'type' => MENU_CALLBACK,
  52. );
  53. $items['ctools_ajax_sample/%ctools_js/login/%'] = array(
  54. 'title' => 'Post-Login Action',
  55. 'page callback' => 'ctools_ajax_sample_login_success',
  56. 'page arguments' => array(1, 3),
  57. 'access callback' => TRUE,
  58. 'type' => MENU_CALLBACK,
  59. );
  60. $items['ctools_ajax_sample/jumped'] = array(
  61. 'title' => 'Successful Jumping',
  62. 'page callback' => 'ctools_ajax_sample_jump_menu_page',
  63. 'access callback' => TRUE,
  64. 'type' => MENU_NORMAL_ITEM,
  65. );
  66. return $items;
  67. }
  68. function ctools_ajax_simple_form() {
  69. ctools_include('content');
  70. ctools_include('context');
  71. $node = node_load(1);
  72. $context = ctools_context_create('node', $node);
  73. $context = array('context_node_1' => $context);
  74. return ctools_content_render('node_comment_form', 'node_comment_form', ctools_ajax_simple_form_pane(), array(), array(), $context);
  75. }
  76. function ctools_ajax_simple_form_pane() {
  77. $configuration = array(
  78. 'anon_links' => 0,
  79. 'context' => 'context_node_1',
  80. 'override_title' => 0,
  81. 'override_title_text' => '',
  82. );
  83. return $configuration;
  84. }
  85. /**
  86. * Implementation of hook_theme()
  87. *
  88. * Render some basic output for this module.
  89. */
  90. function ctools_ajax_sample_theme() {
  91. return array(
  92. // Sample theme functions.
  93. 'ctools_ajax_sample_container' => array(
  94. 'arguments' => array('content' => NULL),
  95. ),
  96. );
  97. }
  98. // ---------------------------------------------------------------------------
  99. // Page callbacks
  100. /**
  101. * Page callback to display links and render a container for AJAX stuff.
  102. */
  103. function ctools_ajax_sample_page() {
  104. global $user;
  105. // Include the CTools tools that we need.
  106. ctools_include('ajax');
  107. ctools_include('modal');
  108. // Add CTools' javascript to the page.
  109. ctools_modal_add_js();
  110. // Create our own javascript that will be used to theme a modal.
  111. $sample_style = array(
  112. 'ctools-sample-style' => array(
  113. 'modalSize' => array(
  114. 'type' => 'fixed',
  115. 'width' => 500,
  116. 'height' => 300,
  117. 'addWidth' => 20,
  118. 'addHeight' => 15,
  119. ),
  120. 'modalOptions' => array(
  121. 'opacity' => .5,
  122. 'background-color' => '#000',
  123. ),
  124. 'animation' => 'fadeIn',
  125. 'modalTheme' => 'CToolsSampleModal',
  126. 'throbber' => theme('image', array('path' => ctools_image_path('ajax-loader.gif', 'ctools_ajax_sample'), 'alt' => t('Loading...'), 'title' => t('Loading'))),
  127. ),
  128. );
  129. drupal_add_js($sample_style, 'setting');
  130. // Since we have our js, css and images in well-known named directories,
  131. // CTools makes it easy for us to just use them without worrying about
  132. // using drupal_get_path() and all that ugliness.
  133. ctools_add_js('ctools-ajax-sample', 'ctools_ajax_sample');
  134. ctools_add_css('ctools-ajax-sample', 'ctools_ajax_sample');
  135. // Create a list of clickable links.
  136. $links = array();
  137. // Only show login links to the anonymous user.
  138. if ($user->uid == 0) {
  139. $links[] = ctools_modal_text_button(t('Modal Login (default style)'), 'ctools_ajax_sample/nojs/login', t('Login via modal'));
  140. // The extra class points to the info in ctools-sample-style which we added
  141. // to the settings, prefixed with 'ctools-modal'.
  142. $links[] = ctools_modal_text_button(t('Modal Login (custom style)'), 'ctools_ajax_sample/nojs/login', t('Login via modal'), 'ctools-modal-ctools-sample-style');
  143. }
  144. // Four ways to do our animal picking wizard.
  145. $button_form = ctools_ajax_sample_ajax_button_form();
  146. $links[] = l(t('Wizard (no modal)'), 'ctools_ajax_sample/nojs/animal');
  147. $links[] = ctools_modal_text_button(t('Wizard (default modal)'), 'ctools_ajax_sample/nojs/animal', t('Pick an animal'));
  148. $links[] = ctools_modal_text_button(t('Wizard (custom modal)'), 'ctools_ajax_sample/nojs/animal', t('Pick an animal'), 'ctools-modal-ctools-sample-style');
  149. $links[] = drupal_render($button_form);
  150. $links[] = ctools_ajax_text_button(t('Hello world!'), "ctools_ajax_sample/nojs/hello", t('Replace text with "hello world"'));
  151. $output = theme('item_list', array('items' => $links, 'title' => t('Actions')));
  152. // This container will have data AJAXed into it.
  153. $output .= theme('ctools_ajax_sample_container', array('content' => '<h1>' . t('Sample Content') . '</h1>'));
  154. // Create a table that we can have data removed from via AJAX.
  155. $header = array(t('Row'), t('Content'), t('Actions'));
  156. $rows = array();
  157. for($i = 1; $i < 11; $i++) {
  158. $rows[] = array(
  159. 'class' => array('ajax-sample-row-'. $i),
  160. 'data' => array(
  161. $i,
  162. md5($i),
  163. ctools_ajax_text_button("remove", "ctools_ajax_sample/nojs/tablenix/$i", t('Delete this row')),
  164. ),
  165. );
  166. }
  167. $output .= theme('table', array('header' => $header, 'rows' => $rows, array('class' => array('ajax-sample-table'))));
  168. // Show examples of ctools javascript widgets
  169. $output .= '<h2>'. t('CTools Javascript Widgets') .'</h2>';
  170. // Create a drop down menu
  171. $links = array();
  172. $links[] = array('title' => t('Link 1'), 'href' => $_GET['q']);
  173. $links[] = array('title' => t('Link 2'), 'href' => $_GET['q']);
  174. $links[] = array('title' => t('Link 3'), 'href' => $_GET['q']);
  175. $output .= '<h3>' . t('Drop Down Menu') . '</h3>';
  176. $output .= theme('ctools_dropdown', array('title' => t('Click to Drop Down'), 'links' => $links));
  177. // Create a collapsible div
  178. $handle = t('Click to Collapse');
  179. $content = 'Nulla ligula ante, aliquam at adipiscing egestas, varius vel arcu. Etiam laoreet elementum mi vel consequat. Etiam scelerisque lorem vel neque consequat quis bibendum libero congue. Nulla facilisi. Mauris a elit a leo feugiat porta. Phasellus placerat cursus est vitae elementum.';
  180. $output .= '<h3>'. t('Collapsible Div') .'</h3>';
  181. $output .= theme('ctools_collapsible', array('handle' => $handle, 'content' => $content, 'collapsed' => FALSE));
  182. // Create a jump menu
  183. ctools_include('jump-menu');
  184. $form = drupal_get_form('ctools_ajax_sample_jump_menu_form');
  185. $output .= '<h3>'. t('Jump Menu') .'</h3>';
  186. $output .= drupal_render($form);
  187. return array('markup' => array('#markup' => $output));
  188. }
  189. /**
  190. * Returns a "take it all over" hello world style request.
  191. */
  192. function ctools_ajax_sample_hello($js = NULL) {
  193. $output = '<h1>' . t('Hello World') . '</h1>';
  194. if ($js) {
  195. ctools_include('ajax');
  196. $commands = array();
  197. $commands[] = ajax_command_html('#ctools-sample', $output);
  198. print ajax_render($commands); // this function exits.
  199. exit;
  200. }
  201. else {
  202. return $output;
  203. }
  204. }
  205. /**
  206. * Nix a row from a table and restripe.
  207. */
  208. function ctools_ajax_sample_tablenix($js, $row) {
  209. if (!$js) {
  210. // We don't support degrading this from js because we're not
  211. // using the server to remember the state of the table.
  212. return MENU_ACCESS_DENIED;
  213. }
  214. ctools_include('ajax');
  215. $commands = array();
  216. $commands[] = ajax_command_remove("tr.ajax-sample-row-$row");
  217. $commands[] = ajax_command_restripe("table.ajax-sample-table");
  218. print ajax_render($commands);
  219. exit;
  220. }
  221. /**
  222. * A modal login callback.
  223. */
  224. function ctools_ajax_sample_login($js = NULL) {
  225. // Fall back if $js is not set.
  226. if (!$js) {
  227. return drupal_get_form('user_login');
  228. }
  229. ctools_include('modal');
  230. ctools_include('ajax');
  231. $form_state = array(
  232. 'title' => t('Login'),
  233. 'ajax' => TRUE,
  234. );
  235. $output = ctools_modal_form_wrapper('user_login', $form_state);
  236. if (!empty($form_state['executed'])) {
  237. // We'll just overwrite the form output if it was successful.
  238. $output = array();
  239. $inplace = ctools_ajax_text_button(t('remain here'), 'ctools_ajax_sample/nojs/login/inplace', t('Go to your account'));
  240. $account = ctools_ajax_text_button(t('your account'), 'ctools_ajax_sample/nojs/login/user', t('Go to your account'));
  241. $output[] = ctools_modal_command_display(t('Login Success'), '<div class="modal-message">Login successful. You can now choose whether to '. $inplace .', or go to '. $account.'.</div>');
  242. }
  243. print ajax_render($output);
  244. exit;
  245. }
  246. /**
  247. * Post-login processor: should we go to the user account or stay in place?
  248. */
  249. function ctools_ajax_sample_login_success($js, $action) {
  250. if (!$js) {
  251. // we should never be here out of ajax context
  252. return MENU_NOT_FOUND;
  253. }
  254. ctools_include('ajax');
  255. ctools_add_js('ajax-responder');
  256. $commands = array();
  257. if ($action == 'inplace') {
  258. // stay here
  259. $commands[] = ctools_ajax_command_reload();
  260. }
  261. else {
  262. // bounce bounce
  263. $commands[] = ctools_ajax_command_redirect('user');
  264. }
  265. print ajax_render($commands);
  266. exit;
  267. }
  268. /**
  269. * A modal login callback.
  270. */
  271. function ctools_ajax_sample_animal($js = NULL, $step = NULL) {
  272. if ($js) {
  273. ctools_include('modal');
  274. ctools_include('ajax');
  275. }
  276. $form_info = array(
  277. 'id' => 'animals',
  278. 'path' => "ctools_ajax_sample/" . ($js ? 'ajax' : 'nojs') . "/animal/%step",
  279. 'show trail' => TRUE,
  280. 'show back' => TRUE,
  281. 'show cancel' => TRUE,
  282. 'show return' => FALSE,
  283. 'next callback' => 'ctools_ajax_sample_wizard_next',
  284. 'finish callback' => 'ctools_ajax_sample_wizard_finish',
  285. 'cancel callback' => 'ctools_ajax_sample_wizard_cancel',
  286. // this controls order, as well as form labels
  287. 'order' => array(
  288. 'start' => t('Choose animal'),
  289. ),
  290. // here we map a step to a form id.
  291. 'forms' => array(
  292. // e.g. this for the step at wombat/create
  293. 'start' => array(
  294. 'form id' => 'ctools_ajax_sample_start'
  295. ),
  296. ),
  297. );
  298. // We're not using any real storage here, so we're going to set our
  299. // object_id to 1. When using wizard forms, id management turns
  300. // out to be one of the hardest parts. Editing an object with an id
  301. // is easy, but new objects don't usually have ids until somewhere
  302. // in creation.
  303. //
  304. // We skip all this here by just using an id of 1.
  305. $object_id = 1;
  306. if (empty($step)) {
  307. // We reset the form when $step is NULL because that means they have
  308. // for whatever reason started over.
  309. ctools_ajax_sample_cache_clear($object_id);
  310. $step = 'start';
  311. }
  312. // This automatically gets defaults if there wasn't anything saved.
  313. $object = ctools_ajax_sample_cache_get($object_id);
  314. $animals = ctools_ajax_sample_animals();
  315. // Make sure we can't somehow accidentally go to an invalid animal.
  316. if (empty($animals[$object->type])) {
  317. $object->type = 'unknown';
  318. }
  319. // Now that we have our object, dynamically add the animal's form.
  320. if ($object->type == 'unknown') {
  321. // If they haven't selected a type, add a form that doesn't exist yet.
  322. $form_info['order']['unknown'] = t('Configure animal');
  323. $form_info['forms']['unknown'] = array('form id' => 'nothing');
  324. }
  325. else {
  326. // Add the selected animal to the order so that it shows up properly in the trail.
  327. $form_info['order'][$object->type] = $animals[$object->type]['config title'];
  328. }
  329. // Make sure all animals forms are represented so that the next stuff can
  330. // work correctly:
  331. foreach ($animals as $id => $animal) {
  332. $form_info['forms'][$id] = array('form id' => $animals[$id]['form']);
  333. }
  334. $form_state = array(
  335. 'ajax' => $js,
  336. // Put our object and ID into the form state cache so we can easily find
  337. // it.
  338. 'object_id' => $object_id,
  339. 'object' => &$object,
  340. );
  341. // Send this all off to our form. This is like drupal_get_form only wizardy.
  342. ctools_include('wizard');
  343. $form = ctools_wizard_multistep_form($form_info, $step, $form_state);
  344. $output = drupal_render($form);
  345. if ($output === FALSE || !empty($form_state['complete'])) {
  346. // This creates a string based upon the animal and its setting using
  347. // function indirection.
  348. $animal = $animals[$object->type]['output']($object);
  349. }
  350. // If $output is FALSE, there was no actual form.
  351. if ($js) {
  352. // If javascript is active, we have to use a render array.
  353. $commands = array();
  354. if ($output === FALSE || !empty($form_state['complete'])) {
  355. // Dismiss the modal.
  356. $commands[] = ajax_command_html('#ctools-sample', $animal);
  357. $commands[] = ctools_modal_command_dismiss();
  358. }
  359. else if (!empty($form_state['cancel'])) {
  360. // If cancelling, return to the activity.
  361. $commands[] = ctools_modal_command_dismiss();
  362. }
  363. else {
  364. $commands = ctools_modal_form_render($form_state, $output);
  365. }
  366. print ajax_render($commands);
  367. exit;
  368. }
  369. else {
  370. if ($output === FALSE || !empty($form_state['complete'])) {
  371. return $animal;
  372. }
  373. else if (!empty($form_state['cancel'])) {
  374. drupal_goto('ctools_ajax_sample');
  375. }
  376. else {
  377. return $output;
  378. }
  379. }
  380. }
  381. // ---------------------------------------------------------------------------
  382. // Themes
  383. /**
  384. * Theme function for main rendered output.
  385. */
  386. function theme_ctools_ajax_sample_container($vars) {
  387. $output = '<div id="ctools-sample">';
  388. $output .= $vars['content'];
  389. $output .= '</div>';
  390. return $output;
  391. }
  392. // ---------------------------------------------------------------------------
  393. // Stuff needed for our little wizard.
  394. /**
  395. * Get a list of our animals and associated forms.
  396. *
  397. * What we're doing is making it easy to add more animals in just one place,
  398. * which is often how it will work in the real world. If using CTools, what
  399. * you would probably really have, here, is a set of plugins for each animal.
  400. */
  401. function ctools_ajax_sample_animals() {
  402. return array(
  403. 'sheep' => array(
  404. 'title' => t('Sheep'),
  405. 'config title' => t('Configure sheep'),
  406. 'form' => 'ctools_ajax_sample_configure_sheep',
  407. 'output' => 'ctools_ajax_sample_show_sheep',
  408. ),
  409. 'lizard' => array(
  410. 'title' => t('Lizard'),
  411. 'config title' => t('Configure lizard'),
  412. 'form' => 'ctools_ajax_sample_configure_lizard',
  413. 'output' => 'ctools_ajax_sample_show_lizard',
  414. ),
  415. 'raptor' => array(
  416. 'title' => t('Raptor'),
  417. 'config title' => t('Configure raptor'),
  418. 'form' => 'ctools_ajax_sample_configure_raptor',
  419. 'output' => 'ctools_ajax_sample_show_raptor',
  420. ),
  421. );
  422. }
  423. // ---------------------------------------------------------------------------
  424. // Wizard caching helpers.
  425. /**
  426. * Store our little cache so that we can retain data from form to form.
  427. */
  428. function ctools_ajax_sample_cache_set($id, $object) {
  429. ctools_include('object-cache');
  430. ctools_object_cache_set('ctools_ajax_sample', $id, $object);
  431. }
  432. /**
  433. * Get the current object from the cache, or default.
  434. */
  435. function ctools_ajax_sample_cache_get($id) {
  436. ctools_include('object-cache');
  437. $object = ctools_object_cache_get('ctools_ajax_sample', $id);
  438. if (!$object) {
  439. // Create a default object.
  440. $object = new stdClass;
  441. $object->type = 'unknown';
  442. $object->name = '';
  443. }
  444. return $object;
  445. }
  446. /**
  447. * Clear the wizard cache.
  448. */
  449. function ctools_ajax_sample_cache_clear($id) {
  450. ctools_include('object-cache');
  451. ctools_object_cache_clear('ctools_ajax_sample', $id);
  452. }
  453. // ---------------------------------------------------------------------------
  454. // Wizard in-between helpers; what to do between or after forms.
  455. /**
  456. * Handle the 'next' click on the add/edit pane form wizard.
  457. *
  458. * All we need to do is store the updated pane in the cache.
  459. */
  460. function ctools_ajax_sample_wizard_next(&$form_state) {
  461. ctools_ajax_sample_cache_set($form_state['object_id'], $form_state['object']);
  462. }
  463. /**
  464. * Handle the 'finish' click on the add/edit pane form wizard.
  465. *
  466. * All we need to do is set a flag so the return can handle adding
  467. * the pane.
  468. */
  469. function ctools_ajax_sample_wizard_finish(&$form_state) {
  470. $form_state['complete'] = TRUE;
  471. }
  472. /**
  473. * Handle the 'cancel' click on the add/edit pane form wizard.
  474. */
  475. function ctools_ajax_sample_wizard_cancel(&$form_state) {
  476. $form_state['cancel'] = TRUE;
  477. }
  478. // ---------------------------------------------------------------------------
  479. // Wizard forms for our simple info collection wizard.
  480. /**
  481. * Wizard start form. Choose an animal.
  482. */
  483. function ctools_ajax_sample_start($form, &$form_state) {
  484. $form_state['title'] = t('Choose animal');
  485. $animals = ctools_ajax_sample_animals();
  486. foreach ($animals as $id => $animal) {
  487. $options[$id] = $animal['title'];
  488. }
  489. $form['type'] = array(
  490. '#title' => t('Choose your animal'),
  491. '#type' => 'radios',
  492. '#options' => $options,
  493. '#default_value' => $form_state['object']->type,
  494. '#required' => TRUE,
  495. );
  496. return $form;
  497. }
  498. /**
  499. * They have selected a sheep. Set it.
  500. */
  501. function ctools_ajax_sample_start_submit(&$form, &$form_state) {
  502. $form_state['object']->type = $form_state['values']['type'];
  503. // Override where to go next based on the animal selected.
  504. $form_state['clicked_button']['#next'] = $form_state['values']['type'];
  505. }
  506. /**
  507. * Wizard form to configure your sheep.
  508. */
  509. function ctools_ajax_sample_configure_sheep($form, &$form_state) {
  510. $form_state['title'] = t('Configure sheep');
  511. $form['name'] = array(
  512. '#type' => 'textfield',
  513. '#title' => t('Name your sheep'),
  514. '#default_value' => $form_state['object']->name,
  515. '#required' => TRUE,
  516. );
  517. $form['sheep'] = array(
  518. '#title' => t('What kind of sheep'),
  519. '#type' => 'radios',
  520. '#options' => array(
  521. t('Wensleydale') => t('Wensleydale'),
  522. t('Merino') => t('Merino'),
  523. t('Corriedale') => t('Coriedale'),
  524. ),
  525. '#default_value' => !empty($form_state['object']->sheep) ? $form_state['object']->sheep : '',
  526. '#required' => TRUE,
  527. );
  528. return $form;
  529. }
  530. /**
  531. * Submit the sheep and store the values from the form.
  532. */
  533. function ctools_ajax_sample_configure_sheep_submit(&$form, &$form_state) {
  534. $form_state['object']->name = $form_state['values']['name'];
  535. $form_state['object']->sheep = $form_state['values']['sheep'];
  536. }
  537. /**
  538. * Provide some output for our sheep.
  539. */
  540. function ctools_ajax_sample_show_sheep($object) {
  541. return t('You have a @type sheep named "@name".', array(
  542. '@type' => $object->sheep,
  543. '@name' => $object->name,
  544. ));
  545. }
  546. /**
  547. * Wizard form to configure your lizard.
  548. */
  549. function ctools_ajax_sample_configure_lizard($form, &$form_state) {
  550. $form_state['title'] = t('Configure lizard');
  551. $form['name'] = array(
  552. '#type' => 'textfield',
  553. '#title' => t('Name your lizard'),
  554. '#default_value' => $form_state['object']->name,
  555. '#required' => TRUE,
  556. );
  557. $form['lizard'] = array(
  558. '#title' => t('Venomous'),
  559. '#type' => 'checkbox',
  560. '#default_value' => !empty($form_state['object']->lizard),
  561. );
  562. return $form;
  563. }
  564. /**
  565. * Submit the lizard and store the values from the form.
  566. */
  567. function ctools_ajax_sample_configure_lizard_submit(&$form, &$form_state) {
  568. $form_state['object']->name = $form_state['values']['name'];
  569. $form_state['object']->lizard = $form_state['values']['lizard'];
  570. }
  571. /**
  572. * Provide some output for our raptor.
  573. */
  574. function ctools_ajax_sample_show_lizard($object) {
  575. return t('You have a @type lizard named "@name".', array(
  576. '@type' => empty($object->lizard) ? t('non-venomous') : t('venomous'),
  577. '@name' => $object->name,
  578. ));
  579. }
  580. /**
  581. * Wizard form to configure your raptor.
  582. */
  583. function ctools_ajax_sample_configure_raptor($form, &$form_state) {
  584. $form_state['title'] = t('Configure raptor');
  585. $form['name'] = array(
  586. '#type' => 'textfield',
  587. '#title' => t('Name your raptor'),
  588. '#default_value' => $form_state['object']->name,
  589. '#required' => TRUE,
  590. );
  591. $form['raptor'] = array(
  592. '#title' => t('What kind of raptor'),
  593. '#type' => 'radios',
  594. '#options' => array(
  595. t('Eagle') => t('Eagle'),
  596. t('Hawk') => t('Hawk'),
  597. t('Owl') => t('Owl'),
  598. t('Buzzard') => t('Buzzard'),
  599. ),
  600. '#default_value' => !empty($form_state['object']->raptor) ? $form_state['object']->raptor : '',
  601. '#required' => TRUE,
  602. );
  603. $form['domesticated'] = array(
  604. '#title' => t('Domesticated'),
  605. '#type' => 'checkbox',
  606. '#default_value' => !empty($form_state['object']->domesticated),
  607. );
  608. return $form;
  609. }
  610. /**
  611. * Submit the raptor and store the values from the form.
  612. */
  613. function ctools_ajax_sample_configure_raptor_submit(&$form, &$form_state) {
  614. $form_state['object']->name = $form_state['values']['name'];
  615. $form_state['object']->raptor = $form_state['values']['raptor'];
  616. $form_state['object']->domesticated = $form_state['values']['domesticated'];
  617. }
  618. /**
  619. * Provide some output for our raptor.
  620. */
  621. function ctools_ajax_sample_show_raptor($object) {
  622. return t('You have a @type @raptor named "@name".', array(
  623. '@type' => empty($object->domesticated) ? t('wild') : t('domesticated'),
  624. '@raptor' => $object->raptor,
  625. '@name' => $object->name,
  626. ));
  627. }
  628. /**
  629. * Helper function to provide a sample jump menu form
  630. */
  631. function ctools_ajax_sample_jump_menu_form() {
  632. $url = url('ctools_ajax_sample/jumped');
  633. $form_state = array();
  634. $form = ctools_jump_menu(array(), $form_state, array($url => t('Jump!')), array());
  635. return $form;
  636. }
  637. /**
  638. * Provide a message to the user that the jump menu worked
  639. */
  640. function ctools_ajax_sample_jump_menu_page() {
  641. $return_link = l(t('Return to the examples page.'), 'ctools_ajax_sample');
  642. $output = t('You successfully jumped! !return_link', array('!return_link' => $return_link));
  643. return $output;
  644. }
  645. /**
  646. * Provide a form for an example ajax modal button
  647. */
  648. function ctools_ajax_sample_ajax_button_form() {
  649. $form = array();
  650. $form['url'] = array(
  651. '#type' => 'hidden',
  652. // The name of the class is the #id of $form['ajax_button'] with "-url"
  653. // suffix.
  654. '#attributes' => array('class' => array('ctools-ajax-sample-button-url')),
  655. '#value' => url('ctools_ajax_sample/nojs/animal'),
  656. );
  657. $form['ajax_button'] = array(
  658. '#type' => 'button',
  659. '#value' => 'Wizard (button modal)',
  660. '#attributes' => array('class' => array('ctools-use-modal')),
  661. '#id' => 'ctools-ajax-sample-button',
  662. );
  663. return $form;
  664. }