How to create custom simple form and
validate and submit hook for this form
enter data in a custom table

Code With Travel
5 min readJan 28, 2020

--

To achieve this, create a custom module loremipsum it requires 3 files which are loremipsum.info.yml, loremipsum.routing.yml, src\Form\LoremipsumDataForm.php. The steps were listed below, how to validate the email field using AJAX.

Step 1: Create loremipsum.info.yml

name: 'Lorem Ajax Demo'
type: module
description: 'Lorem Ajax Demo Example plugin'
core: 8.x
package: 'Custom'

Now make loremipsum.install file and add the following code. This will make a custom table.

<?phpfunction loremipsum_schema() {
$schema['loremipsum'] = array(
'fields' => array(
'id'=>array(
'type'=>'serial',
'not null' => TRUE,
),
'name'=>array(
'type' => 'varchar',
'length' => 40,
'not null' => TRUE,
),
'mobilenumber'=>array(
'type' => 'varchar',
'length' => 40,
'not null' => TRUE,
),
'email'=>array(
'type' => 'varchar',
'length' => 40,
'not null' => TRUE,
),
'age'=>array(
'type' => 'varchar',
'length' => 25,
'not null' => TRUE,
),
'gender'=>array(
'type' => 'varchar',
'length' => 40,
'not null' => TRUE,
),
'website'=>array(
'type' => 'varchar',
'length' => 25,
'not null' => TRUE,
),
),
'primary key' => array('id'),
);
return $schema;}

Now Create loremipsum.routing.yml

loremipsum.loremipsum_form:
path: '/loremipsum/form/loremipsum'
defaults:
_form: '\Drupal\loremipsum\Form\LoremipsumDataForm'
_title: 'LoremipsumDataForm'
requirements:
_access: 'TRUE'

Code for LoremipsumDataForm.php

<?phpnamespace Drupal\loremipsum\Form;use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Database\Database;
use Symfony\Component\HttpFoundation\RedirectResponse;
/**
* Class loremipsumForm.
*
* @package Drupal\loremipsum\Form
*/
class LoremipsumDataForm extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'loremipsum_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('loremipsum.api_settings');
$site_name = $config->get('loremipsum_site_name');
$conn = Database::getConnection();
$record = array();
if (isset($_GET['num'])) {
$query = $conn->select('loremipsum', 'm')
->condition('id', $_GET['num'])
->fields('m');
$record = $query->execute()->fetchAssoc();
}
$form['candidate_name'] = array(
'#type' => 'textfield',
'#title' => t('Candidate Name:'),
'#required' => TRUE,
//'#default_values' => array(array('id')),
'#default_value' => (isset($record['name']) && $_GET['num']) ? $record['name']:'',
);
$form['mobile_number'] = array(
'#type' => 'textfield',
'#title' => t('Mobile Number:'),
'#default_value' => (isset($record['mobilenumber']) && $_GET['num']) ? $record['mobilenumber']:'',
);
$form['candidate_mail'] = array(
'#type' => 'email',
'#title' => t('Email ID:'),
'#required' => TRUE,
'#default_value' => (isset($record['email']) && $_GET['num']) ? $record['email']:'',
);
$form['candidate_age'] = array (
'#type' => 'textfield',
'#title' => t('AGE'),
'#required' => TRUE,
'#default_value' => (isset($record['age']) && $_GET['num']) ? $record['age']:'',
);
$form['candidate_gender'] = array (
'#type' => 'select',
'#title' => ('Gender'),
'#options' => array(
'Female' => t('Female'),
'male' => t('Male'),
),
'#default_value' => (isset($record['gender']) && $_GET['num']) ? $record['gender']:'',
);
$form['web_site'] = array (
'#type' => 'textfield',
'#title' => t('web site'),
'#default_value' => (isset($record['website']) && $_GET['num']) ? $record['website']:'',
);
$form['submit'] = [
'#type' => 'submit',
'#value' => 'save',
//'#value' => t('Submit'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
$name = $form_state->getValue('candidate_name');
if(preg_match('/[^A-Za-z]/', $name)) {
$form_state->setErrorByName('candidate_name', $this->t('your name must in characters without space'));
}
// Confirm that age is numeric.
if (!intval($form_state->getValue('candidate_age'))) {
$form_state->setErrorByName('candidate_age', $this->t('Age needs to be a number'));
}
if (strlen($form_state->getValue('mobile_number')) < 10 ) {
$form_state->setErrorByName('mobile_number', $this->t('your mobile number must in 10 digits'));
}
parent::validateForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$field=$form_state->getValues();
$name=$field['candidate_name'];
$number=$field['mobile_number'];
$email=$field['candidate_mail'];
$age=$field['candidate_age'];
$gender=$field['candidate_gender'];
$website=$field['web_site'];
if (isset($_GET['num'])) {
$field = array(
'name' => $name,
'mobilenumber' => $number,
'email' => $email,
'age' => $age,
'gender' => $gender,
'website' => $website,
);
$query = \Drupal::database();
$query->update('loremipsum')
->fields($field)
->condition('id', $_GET['num'])
->execute();
drupal_set_message("succesfully updated");
$form_state->setRedirect('loremipsum.display_table_controller_display');
}else
{
$field = array(
'name' => $name,
'mobilenumber' => $number,
'email' => $email,
'age' => $age,
'gender' => $gender,
'website' => $website,
);
$query = \Drupal::database();
$query ->insert('loremipsum')
->fields($field)
->execute();
drupal_set_message("succesfully saved");
$form_state->setRedirect('loremipsum.display_table_controller_display');
}
}
}

Once fields are saved we redirect to it another page. So for that, we need to add one route in routing.yml

loremipsum.display_table_controller_display:
path: '/loremipsum/hello/table'
defaults:
_controller: '\Drupal\loremipsum\Controller\DisplayTableController::display'
_title: 'display'
requirements:
_permission: 'access content'

In above code we call display() method of DisplayTableController.

So let’s move to src folder and make DisplayTableController.php

Add the following code to DisplayTableController.php.

<?phpnamespace Drupal\loremipsum\Controller;use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Database\Database;
use Drupal\Core\Url;
/**
* Class DisplayTableController.
*
* @package Drupal\loremipsum\Controller
*/
class DisplayTableController extends ControllerBase {
public function getContent() {
// First we'll tell the user what's going on. This content can be found
// in the twig template file: templates/description.html.twig.
// @todo: Set up links to create nodes and point to devel module.
$build = [
'description' => [
'#theme' => 'loremipsum_description',
'#description' => 'foo',
'#attributes' => [],
],
];
return $build;
}
/**
* Display.
*
* @return string
* Return Hello string.
*/
public function display() {
/**return [
'#type' => 'markup',
'#markup' => $this->t('Implement method: display with parameter(s): $name'),
];*/
//create table header
$header_table = array(
'id'=> t('SrNo'),
'name' => t('Name'),
'mobilenumber' => t('MobileNumber'),
//'email'=>t('Email'),
'age' => t('Age'),
'gender' => t('Gender'),
//'website' => t('Web site'),
'opt' => t('operations'),
'opt1' => t('operations'),
);
//select records from table
$query = \Drupal::database()->select('loremipsum', 'm');
$query->fields('m', ['id','name','mobilenumber','email','age','gender','website']);
$results = $query->execute()->fetchAll();
$rows=array();
foreach($results as $data){
$delete = Url::fromUserInput('/loremipsum/form/delete/'.$data->id);
$edit = Url::fromUserInput('/loremipsum/form/loremipsum?num='.$data->id);
//print the data from table
$rows[] = array(
'id' =>$data->id,
'name' => $data->name,
'mobilenumber' => $data->mobilenumber,
//'email' => $data->email,
'age' => $data->age,
'gender' => $data->gender,
//'website' => $data->website,
\Drupal::l('Delete', $delete),
\Drupal::l('Edit', $edit),
);
}
//display data in site
$form['table'] = [
'#type' => 'table',
'#header' => $header_table,
'#rows' => $rows,
'#empty' => t('No users found'),
];
return $form;
}}

Here we also give facilities of delete and edit records.

For the delete record, we make a new form that we ask confirmation to the user.

So go to routing.yml file and add code following code.

loremipsum.delete_form:
path: '/loremipsum/form/delete/{cid}'
defaults:
_form: '\Drupal\loremipsum\Form\DeleteForm'
_title: 'DeleteForm'
requirements:
_access: 'TRUE'

Now make DeleteForm.php in src/Form. The code for DeleteForm.php is as follows.

<?phpnamespace Drupal\loremipsum\Form;use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Url;
use Drupal\Core\Render\Element;
/**
* Class DeleteForm.
*
* @package Drupal\loremipsum\Form
*/
class DeleteForm extends ConfirmFormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'delete_form';
}
public $cid;public function getQuestion() {
return t('Do you want to delete %cid?', array('%cid' => $this->cid));
}
public function getCancelUrl() {
return new Url('loremipsum.display_table_controller_display');
}
public function getDescription() {
return t('Only do this if you are sure!');
}
/**
* {@inheritdoc}
*/
public function getConfirmText() {
return t('Delete it!');
}
/**
* {@inheritdoc}
*/
public function getCancelText() {
return t('Cancel');
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, $cid = NULL) {
$this->id = $cid;
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$query = \Drupal::database();
$query->delete('loremipsum')
->condition('id',$this->id)
->execute();
$form_state->setRedirect('loremipsum.display_table_controller_display');
}
}

--

--

Responses (1)