3

I am trying to build a form which takes the food item and the no. of servings and calculates the total calories for that particular food and displays it to the user.

User, can add another food by filling out the form again and the calculated calories for the second food is added to the first and the total calories are also displayed. He can add as many food items as he wants and the form shows the total calories of all those food items.

I want to display this information to user in a table. table will have the following columns.. food item, servings, calories and in the last row the total calories of all those food items. I also want to have a another column with a "delete" button to delete that particular food item from the table and refresh the table without that particular food item.

The main problem am facing is, How can I show this table on the same page as that of the form ?

I have been saving all the user submitted info in session variables and I am being able to create and show such table on another page (for example, when user adds many food items and clicks "Done" button, its redirected to another page and the table is shown there.) But I dont want the user to be redirected. I mean if he wants to add another food item to the table, he has to navigate to the form page again and that's not convenient to the user.

To learn how to write forms, I followed this guide, http://drupal.org/node/262422. So my form is in a file, say..myform.module. Now, I have all the data to create an HTML table (Am saving all the food details given by the user in session variables), but how can I make it displayed on the same page as that of the form ?

or in other words, path to my form is, http://localhost/d7/?q=calorie_consume , I also want the table to be showed on the same path or page. How can I do it?

Where should I put the code for creating the table inside myform.module file ?

So how can I achieve this ? Or is there some other approach to creating such calculators that am not aware of ?

Thanks in advance.

1 Answer 1

4

If you're saving your data in $_SESSION vars, I think the easiest way would be to check for the existence of your session data when you build up the form. Then you can show the table at the top of the form if the user has already submitted data, and the normal part of the input form directly underneath. A basic example:

function my_form($form, &$form_state) {
  if (isset($_SESSION['my_var'])) {
    $form['table'] = array(
      '#markup' => 'Your table markup based on session data here'
    );
  }

  $form['input'] = array(
    '#type' => 'textfield',
    '#title' => 'Title'
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Submit'
  );
}

function my_form_submit($form, &$form_state) {
  $_SESSION['my_var'][] = $form_state['values']['input'];

  $form_state['rebuild'] = TRUE;
}

You'll probably need to put some sort of mechanism to clear that session var at some point, if you want users to be able to reset their submission.

A more complete example with functionality to remove items:

function MYMODULE_form($form, &$form_state) {
  // If we have some session data set, build a table
  if (isset($_SESSION['MYMODULE_data'])) {
    $header = array('Food', 'Calories');
    $options = array();
    $total = 0;
    foreach ($_SESSION['MYMODULE_data'] as $item) {
      $options[$item['identifier']] = array(
        $item['food'],
        $item['calories']
      );

      // Keep a running total
      $total += $item['calories'];
    }

    // Add the total row
    $options[] = array('Total calories', $total);

    $form['existing_data'] = array(
      '#type' => 'tableselect',
      '#options' => $options,
      '#header' => $header
    );

    $form['remove_item'] = array(
      '#type' => 'submit',
      '#value' => 'Remove Selected',
      '#submit' => 'MYMODULE_form_remove_item'
    );
  }

  $form['food'] = array(
    '#type' => 'textfield',
    '#title' => 'Food'
  );

  $form['calories'] = array(
    '#type' => 'textfield',
    '#title' => 'Calories'
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Submit'
  );

  return $form;
}

function MYMODULE_form_remove_item($form, &$form_state) {
  $remove = array_filter($form_state['values']['existing_data']);
  foreach ($remove as $key) {
    unset($_SESSION['MYMODULE_data'][$key]);
  }
  $form_state['rebuild'] = TRUE;
}

function my_form_submit($form, &$form_state) {
  // this example will just use the food name as the identifier
  $_SESSION['MYMODULE_data'][] = array(
    'identifier' => $form_state['values']['food'],
    'food' => $form_state['values']['food'],
    'calories' => $form_state['values']['calories']
  );

  $form_state['rebuild'] = TRUE;
}

I haven't tested that but it should give you a good starting point even if there are a few bugs.

3
  • Thank you so much for the answer. Is there a way to add that "delete" button to each row of the table as I mentioned in my question ? May 5, 2012 at 14:39
  • Rather than a delete button on each row (which would require a fair bit more coding), why not use a tableselect type instead? Then your users can choose multiple items in the table to delete in a single go. I'll whip some example code up and put it in the answer
    – Clive
    May 5, 2012 at 14:48
  • @akshaynhegde I've added an example with a tableselect, hope it helps
    – Clive
    May 5, 2012 at 14:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.