Hoppa till huvudinnehåll
Menu

Den här sidan använder cookies. Om du fortsätter använda sidan så accepterar du användandet av cookies. Läs mer om cookies

Jag förstår

Koda egen Add-more knapp med Form API

 

Form API i Drupal 7 är ett väldigt användbart API som gör möjligt att koda egna formulär enkelt i Drupal. 

I denna lösning vill vi skapa ett fält "Namn" som man sedan ska kunna skapa X antal av genom att klicka på en knapp "Add more" och sedan kunna spara dessa X antal namn som en variabel i drupal.

Först skapar vi en fältgrupp (fieldset) där vi vill att vårt fält ska ligga. Det blir en wrapper runt det fältet vi vill ska kunna "Add more" av. Tex kan man göra ett fält som heter "Namn" där vi låter användare fylla i ett namn. Detta fältet kan man sedan skapa upp flera av genom att trycka på knappen "Add more". Vi skapar även en wrapper div till detta fieldset genom att ange den i #prefix och #suffix. Detta eftersom vi senare vill att Drupal ajax ska kunna hooka på ett element för att byta ut det mot ett nytt, mer om detta senare i artikeln.

  $form['name_fieldset'] = array(
    '#type' => 'fieldset',
    '#title' => t('Namn'),
    // Set up the wrapper so that AJAX will be able to replace the fieldset.
    '#prefix' => '<div id="name-fieldset-wrapper">',
    '#suffix' => '</div>',
  );

Nu kan vi skapa själva input fältet namn. 

$variable_my_names = variable_get('my_names');

  if (empty($form_state['number_of_names']) && count($variable_my_names) == 0) {
    $form_state['number_of_names'] = 1;
  }
  else {
    if (!isset($form_state['number_of_names'])) {
      $form_state['number_of_names'] = count($variable_my_names);
    }
  }

for ($i = 0; $i < $form_state['number_of_names']; $i++) {
  $form['name_fieldset'][$i]['my_name'] = array(
    '#type' => 'textfield',
    '#attributes' =>array('placeholder' => t('My name')),
    '#size' => 20,
    '#default_value' => (isset($variable_my_names[$i]['name']) ? $variable_my_names[$i]['name']:''),
  );
}

Som du ser vill vi skapa X antal av samma fält beroende på hur många gånger vi klickat på knappen "Add more". Det är här vi behöver tänka till lite extra. Jag nämnde förut att vi kommer spara dessa värden som varibler i drupals databastabell "variables". Så vi börjar alltså med att läsa ut dessa namn från databasen om vi redan har sparat detta formulär förut och vill lägga till/tabort/ändra ett eller flera namn. Dessa namn lägger vi i PHP variabeln $variable_my_names. Sedan kollar vi om en annan variabel $form_state['number_of_names'] är tom. Denna variabel spara hur många gånger vi tryckt på knappen "Add more". Vi första besöket till detta formulär kommer det dels inte finnas några redan sparade namn i databasen så $variable_my_names kommer vara tom och även $form_state['number_of_names'] kommer vara tom (eller inte ens existera). Detta gör att vi kommer tilldela $form_state['number_of_names'] värdet 1 vilket betyder att vi vill generera name en gång. Det ser vi sedan i for-loopen sedan. Där ser vi även att vi tilldelar default value från variabeln i databasen om det finns någon annars en tom sträng. Lägg även märke till variabeln $i som är alltså räknaren i for-loopen som gör att om vi sparat tex tre namn i databasen förut så kommer vi loopa tre gånger och skapa upp tre namn fält och då få tre olika namn från databasen genom att plocka ut olika från arrayen genom $1.

Nu skapar vi knappen "Add more".

$form['name_fieldset']['add_more'] = array(
    '#type' => 'submit',
    '#value' => t('Add more'),
    '#submit' => array('my_module_add_one'),
    '#ajax' => array(
      'callback' => 'my_module_callback',
      'wrapper' => 'name-fieldset-wrapper',
    ),
  );

Som du kanske känner igen så är detta typ en vanlig submit knapp, med en ajax array på. Den pekar ut en callback funktions som ska anropas när man trycker på den.

Nu skapar vi kanppen för att ta bort ett namn fält "Remove one".

if ($form_state['number_of_names'] > 1) {
    $form['name_fieldset']['remove_one'] = array(
      '#type' => 'submit',
      '#value' => t('Remove one'),
      '#submit' => array('my_module_remove_one'),
      '#ajax' => array(
        'callback' => 'my_module_callback',
        'wrapper' => 'name-fieldset-wrapper',
      ),
    );
  }

Detta är också en submit knapp med en ajax array till samma callback som "Add more" knappen hade. Vi ska nu kolla vad den funktionen gör samt de olika submit funktionerna gör.

function my_module_callback($form, $form_state) {
  return $form['name_fieldset'];
}

Som du ser så returnerar denna ajax callback funktion bara wrapper fältet vid både "Add more" och "Remove one". Detta för att vi i submit funktionerna säger hur många loopningar form ska göra när den rendrerar ut antalet name fält.

function my_module_add_one($form, &$form_state) {
  $form_state['number_of_names']++;
  $form_state['rebuild'] = TRUE;
}

Denna submit funktion för add more knappen säger vi att antalet name field ska loopas en extra gång, eftersom vi nu har tryckt på den knappen en extra gång. Detta indikerar vi genom att plussa på variabeln $form_state['number_of_names'] en till. Vi märker också formuläret med att bygga om sig genom att sättar variabeln $form_state['rebuild'] till TRUE.

function my_module_remove_one($form, &$form_state) {
  if ($form_state['number_of_names'] > 1) {
    $form_state['number_of_names']--;
  }
  $form_state['rebuild'] = TRUE;

Här vid submitfunktionen för "Remove one" gör vi då motsatsen, om $form_state['number_of_names'] är större än ett så gör vi minus ett. eftersom vi inte kan ha mindre än ett namn fält.

Nu till submit funktionen för att spara hela formuläret (Spara/Skicka)

function my_module_form_submit($form, &$form_state) {
  $names = array();
  foreach ($form_state['input']['name_fieldset'] as $name) {
    $names[] = array('name' => $name['my_name']);
  }

  variable_set('my_names', $names);

}

Här kommer vi att loopa alla namn som vi skrivit in i formuläret och bygga upp en array $names för att sedan lägga den arrayen i variabeln 'my_names' i Drupals variabel databastabell, notera att variabel_set kommer sköta serialiseringen automatiskt och även variable_get gör detta automatiskt, så vi inte behöver bry oss om hur den tar hand om arrayen till ett sträng fält i databastabellen.

 

Vi hjälper dig nå resultat. Kontakta oss Ring direkt på 08-20 90 04.