I have seen this: https://waltherlalk.com/blog/dynamic-form-input-fields and have been active in this: Dynamically add form field rows - cakePHP. I have reached the stage where the setup is as per the original tutorial with changes made as per the Stackoverflow post from monsur.hoq.
The form is working fine but, upon saving, it only saves the 'student' part of the data: nothing is sent to grades. The add part of my controller currently looks like this:
public function add()
{
$student = $this->Students->newEntity();
if ($this->request->is('post')) {
$student = $this->Students->patchEntity($student, $this->request->data);
if ($this->Students->save($student)) {
$this->Flash->success(__('The student has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The student could not be saved. Please, try again.'));
}
}
$this->set(compact('student'));
$this->set('_serialize', ['student']);
}
All code is as per bake or the tutorial shaped by the monsur.hoq post.
If anyone could help me to arrive at a working Cakephp3 example of the Walther Lalk tutorial I'd be very grateful.
The debugging toolbar shows the following SQL being produced on submitting the form:
INSERT INTO students (name, created, modified)
VALUES
(
'Test Two', '2016-09-13 16:04:07',
'2016-09-13 16:04:07'
)
All that serves to do is confirm the problem. Debugging in PHP Storm on form submission reveals the following:
$_POST = {array} [3]
_method = "POST"
name = "Test Four"
Grade = {array} [1]
0 = {array} [3]
id = ""
subject = "Maths"
grade = "3"
The add.ctp is as follows:
<nav class="large-3 medium-4 columns" id="actions-sidebar">
<ul class="side-nav">
<li class="heading"><?= __('Actions') ?></li>
<li><?= $this->Html->link(__('List Students'), ['action' => 'index']) ?></li>
<li><?= $this->Html->link(__('List Grades'), ['controller' => 'Grades', 'action' => 'index']) ?></li>
<li><?= $this->Html->link(__('New Grade'), ['controller' => 'Grades', 'action' => 'add']) ?></li>
</ul>
</nav>
<div class="students form large-9 medium-8 columns content">
<?= $this->Form->create($student) ?>
<fieldset>
<legend><?= __('Add Student') ?></legend>
<?php
echo $this->Form->input('name');
?>
</fieldset>
<fieldset>
<legend><?php echo __('Grades');?></legend>
<table id="grade-table">
<thead>
<tr>
<th>Subject</th>
<th>Grade achieved</th>
<th> </th>
</tr>
</thead>
<tbody></tbody>
<tfoot>
<tr>
<td colspan="2"></td>
<td class="actions">
Add grade
</td>
</tr>
</tfoot>
</table>
</fieldset>
<script id="grade-template" type="text/x-underscore-template">
<?php echo $this->element('grades');?>
</script>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
<script>
$(document).ready(function() {
//I changed undescore default template settings
_.templateSettings = {
interpolate: /\{\{(.+?)\}\}/g
}
var
gradeTable = $('#grade-table'),
gradeBody = gradeTable.find('tbody'),
gradeTemplate = _.template($('#grade-template').remove().text()),
numberRows = gradeTable.find('tbody > tr').length;
gradeTable
.on('click', 'a.add', function(e) {
e.preventDefault();
$(gradeTemplate({key: numberRows++}))
.hide()
.appendTo(gradeBody)
.fadeIn('fast');
})
.on('click', 'a.remove', function(e) {
e.preventDefault();
$(this)
.closest('tr')
.fadeOut('fast', function() {
$(this).remove();
});
});
if (numberRows === 0) {
gradeTable.find('a.add').click();
}
});
</script>
Change from CakePHP 2 to CakePHP 3 fields name conventions,
Grade.{$key}.grade to grades.{$key}.grade
Create View/Elements/grades.ctp file with the following contents.
https://waltherlalk.com/blog/dynamic-form-input-fields
<?php
$key = isset($key) ? $key : '<%= key %>';
?>
<tr>
<td>
<?= $this->Form->hidden('grades.{$key}.id') ?>
<?= $this->Form->text('grades.{$key}.subject'); ?>
</td>
<td>
<?= $this->Form->select("grades.{$key}.grade",
[
'A+',
'A',
'B+',
'B',
'C+',
'C',
'D',
'E',
'F'
],
[
'empty' => '-- Select grade --'
]); ?>
</td>
<td class="actions">
Remove grade
</td>
</tr>
Related
I'm working with Codeigniter, on a sales targets' form for salesmen.
They have to input values for each product, locality, year, etc.
Product and locality are already get with existing database: no need to set rules (see controller).
When I checked the post (with enable_profiler of Codeigniter), I get this:
The problem is these datas don't insert into the database table.
I read and tested a lot, but always blocked.
Here is my model:
public function add($params)
{
$this->db->insert($this->table, $params);
return $this->db->insert_id();
}
My controller:
$this->load->library('form_validation');
$this->form_validation->set_rules('year', 'Year', 'required|integer');
$this->form_validation->set_rules('prevision', 'Prevision', 'required');
$this->form_validation->set_rules('value', 'Value', 'required|integer');
if ($this->form_validation->run()) {
$params = array(
'year' => $this->input->post('year'),
'prevision' => $this->input->post('prevision'),
'locality_id' => $this->input->post('locality'),
'product' => $this->input->post('product'),
'value' => $this->input->post('value'),
);
$this->Objectif_model->add($params);
redirect('admin/objectif');
} else {
$this->layout('admin/objectif/add');
}
And my view with inputs:
<?php foreach ($products as $product) : ?>
<tr class="form-group">
<td class="bg-warning">
<?= $product->grp_product; ?>
</td>
<td class="bg-warning product">
<?= $product->code; ?>
</td>
<?php foreach ($localities as $locality ) : ?>
<td>
<input type="text" class="form-control valeur" placeholder="Value k€" name="value[]" data-validation="number" data-validation-ignore="./" data-validation-optional="true" />
<input type="text" name="year[]" />
<input type="text" name="prevision[]" />
<input type="text" name="product[]" value="<?= $product->code ?>" />
<input type="text" name="localite_id[]" value="<?= $locality->id ?>" />
</td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
Hope you will help me.
I find my answer.
In my controller, I had to pass each post in a variable and made a loop.
//action post in a var for each data
$id = $this->input->post('id');
$prev = $this->input->post('prevision');
$year= $this->input->post('year');
$locality_id = $this->input->post('locality_id');
$product = $this->input->post('product');
$value= $this->input->post('value');
if ($this->form_validation->run()) {
$count_id = count($id);
if (isset($id)) {
for ($i = 0; $i < $count_id; $i++) {
$obj[$i] = array(
'id' => $id[$i],
'prevision' => $prev,
'year' => $year,
'locality_id' => $locality_id[$i],
'product' => $product[$i],
'value' => $value[$i]*1000
);
} // endfor
if (isset($obj)) {
$this->Objectif_model->add_obj($obj);
} // endif
}// endif isset
}// endif form validation
I have worked with partials and now I'd like to have something like an info box which shall be filled with additional information.
I'm a bit confused how to give the data to the placeholder.
What I did:
I have an additional layoutfile. layout2.phtml
<?php $this->placeholder('content')->captureStart(); ?>
<div class="row">
<div class="col-md-8">
<?= $this->content; ?>
</div>
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">additional part info</h3>
</div>
<div class="panel-body">
<strong>Approval Status</strong><p>
<strong>Alerts</strong> <p>
there are
<?= $this->AnzahlAlerts?> Alerts at the moment<p>
<strong>MoM</strong><p>
<p>see MoM here</p>
</div>
</div>
</div>
</div>
<?php
$this->placeholder('content')->captureEnd();
echo $this->partial('layout/layout',
['content'=>$this->placeholder('content')]);
?>
The placeholderbox will be shown like I wanted.
But I won't get the value of $this->AnzahlAlerts. I thought it must be given to the viewmodell, so I tried as follows:
controller/showAction
return new ViewModel([
'unitid' => $unit,
'part' => $part,
'dcls' => $this->table->fetchPartDcl($part,$dclid),
'pads' => $this->padtable->fetchPadPart($part, $unit),
'heritage' => $this->table->getHeritage($part, $projectid), //$this->unitpartTable->fetchHeritage($part)
'AnzahlAlerts' => $this->padtable->countAlert($part)
]);
My **onDispatchAction** here for completion:
public function onDispatch(MvcEvent $e)
{
$response = parent::onDispatch($e);
$this->layout()->setTemplate('layout/layout2');
return $response;
}
My Questions are, what is the error, and where is the postion to give the value AnzahlAlerts?
EDIT: count records
This is my modelfunction:
public function countAlert($partnumber)
{
$statment = "SELECT count(*) as AnzahlAlerts
from t_part_alert
WHERE t_part_alert.Part_Number = '" . $partnumber. "';";
// AND t_unit_part.UnitID =" . $unitid;
return $this->tableGateway->adapter->query($statment, "execute");
}
Just because it my be the problem.
You call and print a partial like so:
<?= $this->partial('partial/file/alias') ?>
This causes a partial to be rendered within the current partial where you called it. The name in the view_manager config is partial/file/alias.
If you wanted to pass variables to the partial file, you would have to pass an array as the second parameter, like so:
<?= $this->partial(
'partial/file/alias',
[
'param1' => 'value1',
'param2' => 'value2',
]
) ?>
The keys of the array become parameters in the called partial. So in the partial you can print a variable like so:
<?= $param1 ?>
When wanting to fill the 2nd partial with data, starting at the controller, you should pass the data you want to the first partial and from there fill the second.
Another option, the more difficult way, is to pre-render the partials in the Controller and then return the rendered whole from the Controller function.
Personally, I'm opposed to this as you would then not be separating concerns (viewing vs handling).
But of course, it's possible ;)
Full example from Controller into 2nd partial
class AwesomeController
{
public function demoAction()
{
// do stuff to create the values
return [
'key1' => 'value1',
'key2' => 'value2',
'fooKey1' => 'barValue1',
'fooKey2' => 'barValue2',
];
}
}
So now there's 4 values. These get passed to demo.phtml. However, the last 2 values are for the sub-partial, so we must call that. We even loop that, because we want to show them more than once!
<div class="row">
<div class="col-8 offset-2">
<table class="table table-striped table-bordered">
<tr>
<th><?= $this->translate('Key 1') ?></th>
<td><?= $this->escapeHtml($key1) // <-- Look, the key from Controller is now a variable! This is ZF magic :) ?></td>
</tr>
<tr>
<th><?= $this->translate('Key 2') ?></th>
<td><?= $this->escapeHtml($key2) ?></td>
</tr>
<?php for ($i = 0; $i < 3; $i++) : ?>
<?= $this->partial(
'custom/partial',
[
'value1' => $fooKey1, // <-- Look, the key from Controller is now a variable! This is ZF magic :)
'value2' => $fooKey2,
]
) ?>
<?php endfor ?>
</table>
</div>
</div>
Now, the above bit calls for the partial with name custom/partial. This must be registered. Example config below (place in module.config.php from your module):
'view_manager' => [
'template_map' => [
'custom/partial' => __DIR__ . '/../view/partials/demo-child.phtml',
// -- ^^ name -- ^^ location
],
'template_path_stack' => [
__DIR__ . '/../view',
],
],
File demo-child.phtml
<tr>
<th><?= $this->translate('Value 1') ?></th>
<td><?= $this->escapeHtml($value1) // <-- Look, from above partial - ZF magic :) ?></td>
</tr>
<tr>
<th><?= $this->translate('Value 2') ?></th>
<td><?= $this->escapeHtml($value2) ?></td>
</tr>
I am trying to cancel validation in embedded forms based on a value from main form.
By default, embedded forms fields have validator option set to 'required'=>true. So it gets validated like that. If user leave any field blank, the form does not pass validation and blank fields get marked in template (different style).
What I am trying to do is to change option:"required" to false for all fields in embedded form.
I tried to do that in post validator callback method, but it seems that it is not possible that way.
The main form code:
class TestForma extends sfForm
{
public function configure()
{
$this->setWidgets(array(
'validate_items' => new sfWidgetFormChoice(array(
'choices' => array('no' => 'No', 'yes' => 'Yes'),
'multiple' => false,'expanded'=>true,'default' => 'no')),
));
$this->setValidators(array('validate_items' => new sfValidatorPass()));
$this->widgetSchema->setNameFormat('testforma[%s]');
$subForm = new sfForm();
for ($i = 0; $i < 2; $i++)
{
$form = new ItemForma();
$subForm->embedForm($i, $form);
}
$this->embedForm('items', $subForm);
$this->validatorSchema->setPostValidator(
new sfValidatorCallback(array('callback' => array($this, 'postValidate')))
);
}
Post-validator code:
public function postValidate($validator,$values)
{
$validatorSchema = $this->getValidatorSchema();
if($values['validate_items']=='no')
{
$itemsValidatorSchema = $validatorSchema['items'];
$itemsFieldsValidatorSchemes = $itemsValidatorSchema->getFields();
foreach($itemsFieldsValidatorSchemes as $itemValidatorScheme)
{
$itemValidatorScheme['color']->setOption('required',false);
$itemValidatorScheme['shape']->setOption('required',false);
}
}
return $values;
}
Embedded form class:
class ItemForma extends sfForm
{
public function configure()
{
$this->setWidgets(array(
'color' => new sfWidgetFormInputText(),
'shape' => new sfWidgetFormInput(),
));
$this->setValidators(array(
'color' => new sfValidatorString(array('required'=>true)),
'shape' => new sfValidatorEmail(array('required'=>true)),
));
$this->widgetSchema->setNameFormat('items[%s]');
}
}
Template code:
<form action="<?php echo url_for('weather/formiranje')?>" method="post">
<?php
foreach($form->getErrorSchema()->getErrors() as $e)
{
echo $e->__toString();
}
?>
<table>
<tfoot>
<tr>
<td colspan="2">
<input type="submit" value="OK" />
</td>
</tr>
</tfoot>
<tbody>
<tr><th>Main form</th></tr>
<tr><td><?php echo $form['validate_items']->renderLabel() ?>
<span class="<?php echo $form['validate_items']->hasError() ? 'rowError' : ''?>">
<?php echo $form['validate_items'] ?></span>
</td></tr>
<tr><td> </td></tr>
<tr><th>Embedded forms</th></tr>
<?php
foreach($form['items'] as $item)
{
?>
<tr>
<td><span class="<?php echo $item['color']->hasError() ? 'rowError' : ''?>">
<?php echo $item['color']->renderLabel() ?>
<?php echo $item['color'] ?></span>
</td>
</tr>
<tr>
<td><span class="<?php echo $item['shape']->hasError() ? 'rowError' : ''?>">
<?php echo $item['shape']->renderLabel() ?>
<?php echo $item['shape'] ?></span>
</td></tr>
<?php
}
echo $form['_csrf_token'];
?>
</tbody>
</table>
</form>
The way you organised it won't work because the post validator is run after all the field validators, so they've already been checked and marked as failed. (because the fields were required).
You could try the same approach you have here but with setting a preValidator instead of a postValidator. I think it should work then.
If it still won't work as expected what I would do is to change the default settings on the embedded form's fields to 'required' = false and use the postValidator. In the validator you could check whether or not you need to validate the embedded fields. If you need to validate them you can check if their values are set and if not you can throw errors for those fields. (I hope this is explained clearly)
Another thing you could try is to re-run the validation for the chosen fields. So something like that in your postValidator:
$itemValidatorScheme['color']->setOption('required',false);
$itemValidatorScheme['color']->clean($values['name_of_the_field']);
I have a module which is used to add banner images through admin panel. I have created the module successfully. My module edit page has two tabs. One for adding general informations of banner and second one for adding images. The general information tab is working fine now.
I need to have a button 'add banner image' in my second tab initially. When clicked on it, it should load an file type button.We can use this button for loading the image. We can use 'add banner image' in any number of times for loading the image. This is just similar to the add custom option for a product. I need that exact same functionality here.
I have searched a lot. But couldnt find how to add 'add banner image' button to my second tab. Please help me to solve this issue. Give me an idea of how can impliment this functionality. Sorry for my bad english.Thanks
I have created a similar functionality where I can add postcode ranges in my custom module using below code.
In my Module_name/Block/Adminhtml/Regions/Edit/Tab/Form.php I have added.
$fieldset->addField('postcodes', 'text', array(
'name'=>'postcodes',
'class'=>'requried-entry'
));
$form->getElement('postcodes')->setRenderer(
$this->getLayout()->createBlock('zones/adminhtml_regions_edit_tab_postcodes')
);
This will add postcodes field in my tab with renderer adminhtml_regions_edit_tab_postcodes
In my Module_name/Block/Adminhtml/Regions/Edit/Tab/Postcodes.php I have added the button with the code.
class Ripples_Zones_Block_Adminhtml_Regions_Edit_Tab_Postcodes
extends Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Price_Group_Abstract
{
public function __construct()
{
$this->setTemplate('zones/postcodes.phtml');
}
protected function _prepareLayout()
{
$button = $this->getLayout()->createBlock('adminhtml/widget_button')
->setData(array(
'label' => Mage::helper('zones')->__('Add Postcode Range'),
'onclick' => 'return addPostCodeRange.addItem()',
'class' => 'add'
));
$button->setName('add_postcode_range_button');
$this->setChild('add_button', $button);
return parent::_prepareLayout();
}
}
This will add a button on my tab with the onclick function addPostCodeRange.addItem().
After this I have added a phtml file in design/adminhtml/default/default/template/zones/postcodes.phtml
<?php $_htmlId = $this->getElement()->getHtmlId() ?>
<?php $_htmlName = 'postcodes';?>
<tr>
<td class="label">Postcode Range</td>
<td colspan="10" class="grid">
<table cellspacing="0" class="data border" id="postcodes_table">
<col width="50" />
<col width="50" />
<col width="1" />
<thead>
<tr class="headings">
<th><?php echo Mage::helper('zones')->__('From') ?></th>
<th><?php echo Mage::helper('zones')->__('To') ?></th>
<th class="last"><?php echo Mage::helper('catalog')->__('Action') ?></th>
</tr>
</thead>
<tbody id="<?php echo $_htmlId ?>_container"></tbody>
<tfoot>
<tr>
<td colspan="3" class="a-right"><?php echo $this->getAddButtonHtml() ?></td>
</tr>
</tfoot>
</table>
<script type="text/javascript">
//<![CDATA[
var tierPriceRowTemplate = '<tr>'
+ '<td><input type="text" value="{{from}}" class="custgroup required-entry" name="<?php echo $_htmlName ?>[{{index}}][from]" id="postcodes_row_{{index}}_from" />'
+ '</td>'
+ '<td><input type="text" value="{{to}}" class="custgroup required-entry" name="<?php echo $_htmlName ?>[{{index}}][to]" id="postcodes_row_{{index}}_to" />'
+ '</td>'
+ '<td class="last"><input type="hidden" name="<?php echo $_htmlName ?>[{{index}}][delete]" class="delete" value="" id="postcodes_row_{{index}}_delete" />'
+ '<button title="<?php echo Mage::helper('zones')->__("Delete Range") ?>" type="button" class="scalable delete icon-btn delete-product-option" id="postcodes_row_{{index}}_delete_button" onclick="return addPostCodeRange.deleteItem(event);">'
+ '<span><span><span><?php echo Mage::helper('zones')->__("Delete") ?></span></span></span></button></td>'
+ '</tr>';
var addPostCodeRange = {
template: new Template(tierPriceRowTemplate, new RegExp('(^|.|\\r|\\n)({{\\s*(\\w+)\\s*}})', "")),
itemsCount: 0,
addItem : function () {
var data = {
from: '',
to: '',
readOnly: false,
index: this.itemsCount++
};
if(arguments.length >= 2) {
data.from = arguments[0];
data.to = arguments[1];
}
if (arguments.length == 3) {
data.readOnly = arguments[2];
}
Element.insert($('<?php echo $_htmlId ?>_container'), {
bottom : this.template.evaluate(data)
});
$('postcodes_row_' + data.index + '_from').value = data.from;
$('postcodes_row_' + data.index + '_to').value = data.to;
if (data.readOnly == '1') {
['from', 'to', 'delete'].each(function(idx){
$('postcodes_row_'+data.index+'_'+idx).disabled = true;
});
$('postcodes_row_'+data.index+'_delete_button').hide();
}
},
disableElement: function(el) {
el.disabled = true;
el.addClassName('disabled');
},
deleteItem: function(event) {
var tr = Event.findElement(event, 'tr');
if (tr) {
Element.select(tr, '.delete').each(function(elem){elem.value='1'});
Element.hide(tr);
Element.addClassName(tr, 'no-display template');
}
return false;
}
};
<?php $collection = Mage::getModel('zones/regions')->getCollection()->addFieldToFilter('regions_id',array('eq' => $this->getRequest()->getParam('id'))); ?>
<?php foreach ($collection as $_item): ?>
<?php $postcodes = unserialize($_item['postcodes']); ?>
<?php foreach ($postcodes as $postcode): ?>
addPostCodeRange.addItem( '<?php echo $postcode['from'] ?>', '<?php echo $postcode['to'] ?>');
<?php endforeach; ?>
<?php endforeach; ?>
//]]>
</script>
</td></tr>
This file contains the function. I have added two textboxes on function call. You can add file field in this function.
Hope this helps.
I'm using Codeigniter, styled with Bootstrap 3 to build a website.
I can't stylize the text-fields built by the PHP/Form Helper, as I'm not sure where to use the tags, every solution I've tried has resulted in either an extra text field, or just the addon appearing, or nothing at all.
Controller
public function __construct ()
{
parent::__construct();
}
public function index ()
{
// Fetch all users
$this->data['users'] = $this->user_m->get();
// Load view
$this->data['subview'] = 'admin/user/index';
$this->load->view('admin/_layout_main', $this->data);
}
public function edit ($id = NULL)
{
// Fetch a user or set a new one
if ($id) {
$this->data['user'] = $this->user_m->get($id);
count($this->data['user']) || $this->data['errors'][] = 'User could not be found';
}
else {
$this->data['user'] = $this->user_m->get_new();
}
// Set up the form
$rules = $this->user_m->rules_admin;
$id || $rules['password']['rules'] .= '|required';
$this->form_validation->set_rules($rules);
// Process the form
if ($this->form_validation->run() == TRUE) {
$data = $this->user_m->array_from_post(array('name', 'email', 'password'));
$data['password'] = $this->user_m->hash($data['password']);
$this->user_m->save($data, $id);
redirect('admin/user');
}
// Load the view
$this->data['subview'] = 'admin/user/edit';
$this->load->view('admin/_layout_main', $this->data);
}
public function delete ($id)
{
$this->user_m->delete($id);
redirect('admin/user');
}
public function login ()
{
// Redirect a user if he's already logged in
$dashboard = 'admin/dashboard';
$this->user_m->loggedin() == FALSE || redirect($dashboard);
// Set form
$rules = $this->user_m->rules;
$this->form_validation->set_rules($rules);
// Process form
if ($this->form_validation->run() == TRUE) {
// We can login and redirect
if ($this->user_m->login() == TRUE) {
redirect($dashboard);
}
else {
$this->session->set_flashdata('error', 'That email/password combination does not exist');
redirect('admin/user/login', 'refresh');
}
}
// Load view
$this->data['subview'] = 'admin/user/login';
$this->load->view('admin/_layout_modal', $this->data);
}
public function logout ()
{
$this->user_m->logout();
redirect('admin/user/login');
}
public function _unique_email ($str)
{
// Do NOT validate if email already exists
// UNLESS it's the email for the current user
$id = $this->uri->segment(4);
$this->db->where('email', $this->input->post('email'));
!$id || $this->db->where('id !=', $id);
$user = $this->user_m->get();
if (count($user)) {
$this->form_validation->set_message('_unique_email', '%s should be unique');
return FALSE;
}
return TRUE;
}
}
View
<div class="modal-body">
<?php echo validation_errors(); ?>
<?php echo form_open();?>
<div class="container">
<div class="modal-header">
<h3>Log in</h3>
<p>Please log in using your credentials</p>
</div>
<table class="table">
<tr>
<td>Email</td>
<td><?php echo form_input('email'); ?></td>
</tr>
<tr>
<td>Password</td>
<td><?php echo form_password('password'); ?></td>
</tr>
<tr>
<td></td>
<td><?php echo form_submit('submit', 'Log in', 'class="btn btn-primary"'); ?></td>
</tr>
</table>
<div class="modal-footer">
© <?php echo date('Y'); ?> <?php echo $meta_title; ?>
</div>
<?php echo form_close();?>
</div>
</div>
</div>
Bootstrap
<form class="form-signin" role="form">
<h2 class="form-signin-heading">Please sign in</h2>
<input type="text" class="form-control" placeholder="email" required autofocus value="<?php echo set_value('email') ?>">
<input type="password" class="form-control" placeholder="password" required value"<?php echo set_value('password') ?>">
<label class="checkbox">
<input type="checkbox" value="remember-me"> Remember me
</label>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
You just pass everything as an array to form_input
<?php echo form_input(['name' => 'email', 'id' => 'email', 'class' => 'form-control', 'value' => set_value('email')]); ?>
Here's your entire form as presented,
<?php echo form_open('controller/method', ['class' => 'form-signin', 'role' => 'form']); ?>
<h2 class="form-signin-heading">Please sign in</h2>
<?php echo form_input(['name' => 'email', 'id' => 'email', 'class' => 'form-control', 'value' => set_value('email'), 'placeholder' => 'Email']); ?>
<?php echo form_password(['name' => 'password', 'id' => 'password', 'class' => 'form-control', 'placeholder' => 'Password']); ?>
<label class="checkbox">
<?php echo form_checkbox(['name' => 'remember_me', 'value' => 1]); ?>
</label>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
<?php echo form_close(); ?>