how to generate pdf from yii2fullcalendar? - php

Im trying to generate a pdf file from month and day views of philipfrenzel-yii2fullcalendar with kartik-mpdf and I get this error
Invalid data received for parameter "events".
To do it, I've generated an actionIndexPdf($events) method in the controller and a index_pdf.php view file with the yii2fullcalendar widget receiving $events as parameter.
The problem is in the renderPartial of the action. It seems it has a problem with the array of events.
The code is as follows:
Controller CalendarioController.php
public function actionIndex() {
$calendario = Calendario::find()->all();
$events = [];
foreach ($calendario as $cal) {
$event = new \yii2fullcalendar\models\Event();
$event->id = $cal->id;
$event->title = $cal->pedido->cliente->nombre;
$event->id_pedido = $cal->pedido->id;
$event->sector = $cal->pedido->cliente->sector;
$event->direccion = $cal->pedido->cliente->direccion;
$event->telefono = $cal->pedido->cliente->telefono;
$event->textColor = '#302B16';
switch ($cal->pedido->estado) {
case 0:
$event->estado = 'Pendiente de entrega';
break;
case 1:
$event->estado = 'Entregado sin deuda';
break;
case 2:
$event->estado = 'Entregado con deuda';
break;
}
$event->start = $cal->pedido->fecha_solicitud;
$event->end = $cal->pedido->fecha_entrega;
$event->color = $cal->pedido->color;
$event->allDay = false;
$events[] = $event;
}
return $this->render('index', [
'events' => $events
]);
}
public function actionIndexPdf($events) {
die(var_dump($events));
Yii::$app->response->format = \yii\web\Response::FORMAT_RAW;
$formatter = \Yii::$app->formatter;
$pdf = new Pdf([
'mode' => Pdf::MODE_CORE, // leaner size using standard fonts
'format' => Pdf::FORMAT_LETTER,
'orientation' => Pdf::ORIENT_PORTRAIT,
'destination' => Pdf::DEST_BROWSER,
//Se renderiza la vista "pdf" (que abrirá la nueva ventana)
'content' => $this->renderPartial('index_pdf', ['events' => $events]),
'options' => [
// any mpdf options you wish to set
],
'cssFile' => '#vendor/kartik-v/yii2-mpdf/src/assets/kv-mpdf-bootstrap.min.css',
'cssInline' => 'body{
font-size:12px;
}',
]);
return $pdf->render();
}
View index_pdf.php
<?php
/* #var $this yii\web\View */
/* #var $searchModel app\models\CalendarioSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Calendario de Pedidos';
$this->params['breadcrumbs'][] = $this->title;
?>
<p>
<?= yii2fullcalendar\yii2fullcalendar::widget([
'events' => $events,
'id' => 'calendar',
'options' => [
'lang' => 'es',
],
'clientOptions' => [
'selectable' => false,
'editable' => true,
'droppable' => true,
'header' => [
'left' => 'prev,next,today',
'center' => 'title',
'right' => 'month,listDay',
],
'height' => 'auto',
'displayEventTime' => false,
],
]);
?>
</p>
button in index.php view
<p>
<?php
//Imprime el boton generar pdf
// die(var_dump($events));
echo Html::a('Generar PDF', ['index-pdf', 'events' => $events],
[
'class' => 'btn btn-success',
'target'=>'_blank',
'data-toggle'=>'tooltip',
// 'title'=>'Will open the generated PDF file in a new window'
]);
?>
</p>

You are trying to pass an array of data as a GET parameter on this line:
echo Html::a('Generar PDF', ['index-pdf', 'events' => $events],
I imagine that passing the events array is not a requirement for you, in that case, it would be much easier to have both methods generate the array.
Since you are using the same code to get the events on both methods, index and index_pdf, you could extract that code and call it in both methods to get the $events.
You could move the code out of the controller, into a helper class for example, but, for simplicity, I will just add an example using a method inside the same controller.
private function getCalendarEvents() {
$events = [];
foreach (Calendario::find()->each() as $cal) {
$event = new \yii2fullcalendar\models\Event();
$event->id = $cal->id;
$event->title = $cal->pedido->cliente->nombre;
$event->id_pedido = $cal->pedido->id;
$event->sector = $cal->pedido->cliente->sector;
$event->direccion = $cal->pedido->cliente->direccion;
$event->telefono = $cal->pedido->cliente->telefono;
$event->textColor = '#302B16';
switch ($cal->pedido->estado) {
case 0:
$event->estado = 'Pendiente de entrega';
break;
case 1:
$event->estado = 'Entregado sin deuda';
break;
case 2:
$event->estado = 'Entregado con deuda';
break;
}
$event->start = $cal->pedido->fecha_solicitud;
$event->end = $cal->pedido->fecha_entrega;
$event->color = $cal->pedido->color;
$event->allDay = false;
$events[] = $event;
}
return $events;
}
Then call it on both actions
public function actionIndex() {
return $this->render('index', [
'events' => $this->getCalendarEvents()
]);
}
public function actionIndexPdf() {
$events = $this->getCalendarEvents();
Yii::$app->response->format = \yii\web\Response::FORMAT_RAW;
$formatter = \Yii::$app->formatter;
$pdf = new Pdf([
'mode' => Pdf::MODE_CORE, // leaner size using standard fonts
'format' => Pdf::FORMAT_LETTER,
'orientation' => Pdf::ORIENT_PORTRAIT,
'destination' => Pdf::DEST_BROWSER,
//Se renderiza la vista "pdf" (que abrirá la nueva ventana)
'content' => $this->renderPartial('index_pdf', ['events' => $events]),
'options' => [
// any mpdf options you wish to set
],
'cssFile' => '#vendor/kartik-v/yii2-mpdf/src/assets/kv-mpdf-bootstrap.min.css',
'cssInline' => 'body{
font-size:12px;
}',
]);
return $pdf->render();
}
If passing the event array as a parameter is a requirement, you will probably need to serialize it to generate the link, and then deserialize it on the index_pdf action.

Related

Call to member function hello() on null zendframework 3

I'm getting error
Call to a member function buildCTCCompensationData() on null
in PayrollspendController.php on this line of code:
$compData = $this->payrollspendManager->hello($postData);
I have checked the module.config.php and __construct() method but not able to find the error. What is the issue in the code?
Please help me to resolve me the error
I have called the method properly
if any code is required will help
if want view file that will also give
Those who know zendframework help me to resolve issue
This is module.config.php
'dashboard_activity_payrollspend' => [
'type' => Literal::class,
'options' => [
'route' => '/dashboard/employer-details/activity-manage',
'constraints' => [
'action' =>'[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[a-zA-Z0-9_-]+',
],
'defaults' => [
'controller' => Controller\PayrollspendController::class,
'action' => 'add',
],
],
],
'controllers' => [
'factories' => [
Controller\PayrollspendController::class => Controller\Factory\PayrollspendControllerFactory::class
],
],
'service_manager' => [
'factories' => [
Service\PayrollspendManager::class => Service\Factory\PayrollspendManagerFactory::class
],
],
This is my controller PayrollspendController.php
<?php
namespace Dashboard\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Session\Container;
use Application\Entity\PyPayGroup;
use Application\Entity\PyPayPeriod;
//use Payroll\Form\SalaryVariationForm;
use Zend\Session\SessionManager;
use Application\Entity\CommonCompanyHeader;
use Dashboard\Form\PayrollspendForm;
class PayrollspendController extends AbstractActionController
{
private $entityManager;
private $sessionContainer;
private $pyPayPeriodClass;
private $pyPayGroupClass;
private $companyClass;
public function __construct($entityManager)
{
$this->entityManager = $entityManager;
$this->pyPayGroupClass = $this->entityManager->getRepository(PyPayGroup::class);
$this->pyPayPeriodClass = $this->entityManager->getRepository(PyPayPeriod::class);
$this->companyClass = $this->entityManager->getRepository(CommonCompanyHeader::class);
$this->commonTranslationManager = $commonTranslationManager;
$sessionManager = new SessionManager();
$this->sessionContainer = new Container('ContainerNamespace', $sessionManager);
$arrLabelId = [];
}
public function addAction()
{
if ($this->sessionContainer->empId == "") {
return $this->redirect()->toRoute('admin_user_login');
}
if (!in_array('PY', $this->sessionContainer->arrRole)) {
if (!in_array('py_admin', $this->sessionContainer->arrRole)) {
return $this->redirect()->toRoute('dashboard_ess_index');
}
}
$reportForm = new PayrollspendForm();
$payGroup = $this->pyPayGroupClass->findBy([
'ouCode' => $this->sessionContainer->ouCode,
'langCode' => $this->sessionContainer->langCode,
'pgActive' => 1
]);
$reportForm->buildPayGroupData($payGroup);
$company = $this->companyClass->findBy([
'ouCode' => $this->sessionContainer->ouCode,
'langCode' => $this->sessionContainer->langCode
]);
$reportForm->buildCompanyData($company);
$payPeriodData = ['' => 'Select'];
$reportForm->get('payPeriod')->setValueOptions($payPeriodData);
$postData = $this->getRequest()->getPost()->toArray();
$postData['ouCode'] = $this->sessionContainer->ouCode;
$postData['langCode'] = $this->sessionContainer->langCode;
$compData = $this->payrollspendManager->hello($postData);
$groupByData = [
'' => 'Select',
'location' => 'Location',
'department' => 'Department',
'cost-center' => 'Cost center'
];
$reportForm->get('groupby')->setValueOptions($groupByData);
return new ViewModel([
'reportData' => $compData,
'form' => $reportForm,
'ouCode' => $this->sessionContainer->ouCode,
'postData' => $postData,
'langCode' => $this->sessionContainer->langCode,
'arrLabels' => $this->arrLabels
]);
$resultData->setTerminal(true);
return $resultData;
}
}
This is PayrollspendControllerFactory.php
<?php
namespace Dashboard\Controller\Factory;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use Dashboard\Service\PayrollspendManager;
//use Application\Service\CommonTranslationManager;
use Dashboard\Controller\PayrollspendController;
class PayrollspendControllerFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container,$requestedName, array $options = null)
{
$entityManager = $container->get('doctrine.entitymanager.orm_default');
$payrollspendManager = $container->get(PayrollspendManager::class);
//$hrManager = $container->get(HrManager::class);
// $commonTranslationManager = $container->get(CommonTranslationManager::class);
return new PayrollspendController($entityManager);
}
}
This PayrollspendManager.php
<?php
namespace Dashboard\Service;
//use Application\Entity\DsAnnouncement;
//use Application\Entity\TmDomain;
// The AnnouncementManager service is responsible for adding new task.
class PayrollspendManager
{
/**
* Doctrine entity manager.
* #var Doctrine\ORM\EntityManager
*/
private $entityManager;
// Constructor is used to inject dependencies into the service.
public function __construct($entityManager)
{
$this->entityManager = $entityManager;
}
public function hello($postData)
{
$headerData = $this->getAllCTCCompensationHeader($postData);
$compData = $this->getAllCTCCompensationData($postData);
return [
'header' => $headerData,
'detail' => $compData
];
}
public function getAllCTCCompensationHeader($postData)
{
$queryBuilder = $this->entityManager->createQueryBuilder();
$queryBuilder->select('DISTINCT(pc.pyComPayitem) as payHeader')
->from(PyCompensationDetails::class, 'pc')
->innerJoin(PyPayItemPaygroupMap::class, 'ppipm', 'with', 'ppipm.payitemCode = pc.pyComPayitem
AND ppipm.ouCode = pc.ouCode
AND ppipm.langCode= pc.langCode
AND ppipm.pgCode= pc.pgCode')
->where('pc.ouCode = ?1')
->andWhere('pc.langCode = ?2')
->andWhere('pc.pgCode = ?3')
->andWhere('pc.isModified = ?4')
->setParameter('1', $postData['ouCode'])
->setParameter('2', $postData['langCode'])
->setParameter('3', $postData['payGroup'])
->setParameter('4', 0)
->orderBy('ppipm.orderofProcessing', 'ASC');
$compData = $queryBuilder->getQuery()->getResult();
$headerData = [
'0' => 'Employee Id',
'1' => 'Employee Name'
];
foreach ($compData as $compHeader) {
$headerData[] = $compHeader['payHeader'];
}
$headerData[] = 'PF';
$headerData[] = 'ESIC';
$headerData[] = 'Total';
return $headerData;
}
/**
* Get compensation detail data
*
* #param type $postData
* #return type
*/
public function getAllCTCCompensationData($postData)
{
$queryBuilder = $this->entityManager->createQueryBuilder();
$queryBuilder->select('pc.pyComEmpid, pc.amount, pc.pyComPayitem, pi.payitemDesc, hn.empFname, hn.empMname, hn.empLname')
->from(PyCompensationDetails::class, 'pc')
->innerJoin(HrEmpid::class, 'he', 'with', 'pc.ouCode = he.ouCode
and pc.langCode = he.langCode
and pc.pyComEmpid = he.empId'
)
->innerJoin(HrEmpName::class, 'hn', 'with', 'pc.ouCode = hn.ouCode
and pc.langCode = hn.langCode
and pc.pyComEmpid = hn.empId'
)
->innerJoin(PyPayItem::class, 'pi', 'with', 'pc.ouCode = pi.ouCode
and pc.langCode = pi.langCode
and pc.pyComPayitem = pi.payitemCode'
)
//->innerJoin(SmartlistData::class,'sd','with','sd.dataCode = pi.smartlistPayitemtype'
//)
->leftJoin(PyPayItemPaygroupMap::class, 'ppipm', 'with', 'ppipm.payitemCode = pi.payitemCode '
. 'AND ppipm.ouCode = pi.ouCode '
. 'AND ppipm.langCode= pi.langCode '
. 'AND ppipm.pgCode= pc.pgCode')
->where('pc.ouCode = ?1')
->andWhere('pc.langCode = ?2')
->andWhere('pc.pgCode = ?3')
->andWhere('pc.isModified = ?4')
->andWhere('he.smartlistEmpstatus != ?5')
->andWhere('pi.smartlistPayitemtype IN (94,99,100)')
->orderBy('ppipm.orderofProcessing', 'ASC')
->setParameter('1', $postData['ouCode'])
->setParameter('2', $postData['langCode'])
->setParameter('3', $postData['payGroup'])
->setParameter('4', 0)
->setParameter('5', 56);
// ->orderBy('pc.pyComEmpid');
// echo $queryBuilder->getQuery()->getSQL();
//exit;
$compData = $queryBuilder->getQuery()->getResult();
// echo '<pre>';
//print_r($compData);
// exit;
$data = [];
if (!empty($compData)) {
$total = 0;
foreach ($compData as $dataC) {
$data[$dataC['pyComEmpid']]['Employee Id'] = $dataC['pyComEmpid'];
$data[$dataC['pyComEmpid']]['Employee Name'] = sprintf('%s %s %s', $dataC['empFname'], $dataC['empMname'], $dataC['empLname']);
$data[$dataC['pyComEmpid']][$dataC['pyComPayitem']] = $dataC['amount'];
$statData = $this->getStatuoryData($postData, $dataC['pyComEmpid']);
//echo '<pre>';
// print_r($statData);
//exit;
if(isset($statData['pf']) && ($statData['pf'] == 1)){
$parameterData = $this->getParamaterData($postData, 'pf', $dataC['pyComEmpid']);
$data[$dataC['pyComEmpid']]['PF'] = $this->getPFData($postData, $parameterData);
} else {
$data[$dataC['pyComEmpid']]['PF'] = 0;
}
if(isset($statData['esic']) && ($statData['esic'] == 1)){
$parameterData = $this->getParamaterData($postData, 'esic', $dataC['pyComEmpid']);
$data[$dataC['pyComEmpid']]['ESIC'] = $this->getESICData($postData, $dataC['pyComEmpid']);
} else {
$data[$dataC['pyComEmpid']]['ESIC'] = 0;
}
$data[$dataC['pyComEmpid']]['Total'] = $this->getCTCCompensationSum($postData, $dataC['pyComEmpid'], $data[$dataC['pyComEmpid']]['PF'], $data[$dataC['pyComEmpid']]['ESIC']);
}
}
//echo "<pre>";
//print_r($data);
//exit;
return $data;
}
/**
* Get compensation sum
*
* #param array $postData
* #param string $pyComEmpid
* #return type
*/
public function getCTCCompensationSum($postData, $pyComEmpid, $pf, $esic)
{
$amountTotal = 0;
$queryBuilder = $this->entityManager->createQueryBuilder();
$queryBuilder->select('SUM(pc.amount) as amount')
->from(PyCompensationDetails::class, 'pc')
->where('pc.ouCode = ?1')
->andWhere('pc.langCode = ?2')
->andWhere('pc.pgCode = ?3')
->andWhere('pc.pyComEmpid = ?4')
->andWhere('pc.isModified = ?5')
->setParameter('1', $postData['ouCode'])
->setParameter('2', $postData['langCode'])
->setParameter('3', $postData['payGroup'])
->setParameter('4', $pyComEmpid)
->setParameter('5', 0);
$compData = $queryBuilder->getQuery()->getOneOrNullResult();
$amount = isset($compData['amount']) ? $compData['amount'] : 0;
$amountTotal = $amount + $pf + $esic;
return $amountTotal;
}
}
This is PayrollspendManagerFactory.php
<?php
namespace Dashboard\Service\Factory;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use Dashboard\Service\PayrollspendManager;
class PayrollspendManagerFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$entityManager = $container->get('doctrine.entitymanager.orm_default');
// Instantiate the service and inject dependencies
return new PayrollspendManager($entityManager);
}
}
This is PayrollspendForm
<?php
namespace Dashboard\Form;
use Zend\Form\Form;
use Zend\InputFilter\InputFilter;
//use Application\Entity\TmTask;
/**
* This form is used to collect post data.
*/
class PayrollspendForm extends Form
{
public $session;
public $entityManager;
public $ouCode;
public $langCode;
public function __construct()
{
// Define form name
parent::__construct('payrollspend-form');
// Set POST method for this form
$this->setAttribute('method', 'post');
$this->setAttribute('class', 'form-horizontal');
$this->setAttribute('id', 'payrollspend-form');
//$this->edit = $edit;
// $this->ouCode = $session->ouCode;
// $this->langCode = $session->langCode;
// $this->entityManager = $entityManager;
$this->addElements();
$this->addInputFilter();
}
protected function addElements()
{
$this->add([
'type' => 'select',
'name' => 'payPeriod',
'attributes' => [
'id' => 'payPeriod',
'class'=>'form-control'
]
]);
$this->add([
'type' => 'text',
'name' => 'payCalender',
'attributes' => [
'id' => 'payCalender',
'class'=>'form-control',
'disabled' => 'disabled'
]
]);
$this->add([
'type' => 'select',
'name' => 'companyCode',
'attributes' => [
'id' => 'companyCode',
'class'=>'form-control'
]
]);
$this->add([
'type' => 'select',
'name' => 'payGroup',
'attributes' => [
'id' => 'payGroup',
'class'=>'form-control'
]
]);
$this->add([
'type' => 'text',
'name' => 'startDate',
'attributes' => [
'id' => 'startDate',
'class' => 'form-control dpd1',
'data-date-format' => "dd-mm-yyyy"
]
]);
$this->add([
'type' => 'text',
'name' => 'endDate',
'attributes' => [
'id' => 'endDate',
'class' => 'form-control dpd1',
'data-date-format' => "dd-mm-yyyy"
]
]);
$this->add([
'type' => 'select',
'name' => 'groupby',
'attributes' => [
'id' => 'groupby',
'class'=>'form-control',
'placeholder'=>''
],
]);
$this->add([
'type' => 'submit',
'name' => 'submit',
'attributes' => [
'value' => 'Submit',
'id' => 'submitbutton',
'class' => 'btn btn-primary'
],
]);
}
private function addInputFilter()
{
$inputFilter = new InputFilter();
$this->setInputFilter($inputFilter);
}
public function buildPayGroupData($payGroup)
{
$payGroupData = [];
foreach($payGroup as $data){
$payGroupData[$data->pgCode] = $data->pgSdesc;
}
$this->get('payGroup')->setEmptyOption('select')->setValueOptions($payGroupData);
}
public function buildCompanyData($companys)
{
$companyData = ['' => 'Select'];
foreach($companys as $data){
$companyData[$data->companyCode] = $data->companyName;
}
$this->get('companyCode')->setValueOptions($companyData);
}
public function defaultDate()
{
$this->get('startDate')->setValue(date('d-m-Y'));
}
}
Assuming the call in PayrollspendController::addAction() is the problem.
$compData = $this->payrollspendManager->hello($postData);
This is because the $this->payrollspendManager variable has not been defined.
You can see in the PayrollspendControllerFactory::__invoke you have requested the service from the dependency injection container; but do not inject it into the constructor of the PayrollspendController.
// PayrollspendControllerFactory::__invoke()
$entityManager = $container->get('doctrine.entitymanager.orm_default');
$payrollspendManager = $container->get(PayrollspendManager::class);
return new PayrollspendController($entityManager);
You should update the factory :
return new PayrollspendController($entityManager, $payrollspendManager);
And also the constructor of the controller to allow the new argument (while you are there you can also type hint on the expected interface)
use \Doctrine\ORM\EntityManager;
use \Dashboard\Service\PayrollspendManager;
class PayrollspendController extends AbstractActionController
{
// ...
private $entityManager;
private $payrollspendManager;
public function __construct(
EntityManager $entityManager,
PayrollspendManager $payrollspendManager
){
$this->entityManager = $entityManager;
$this->payrollspendManager = $payrollspendManager;
}
// ...
}

Create new record using 2amigos SelectizeDropDownList in Yii2

I am trying to implement the 2amigos SelectizeDropDownList widget in a form to add new values to a table directly within the dropdown.
I am using the model Book and the Model Author so basically want to be able to add a new author in the book form.
This is the book controller at the update function:
public function actionUpdate($id) {
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['index']);
} else {
return $this->render('update', [
'model' => $model,
'categories' => BookCategory::find()->active()->all(),
'publishers' => Publisher::find()->all(),
'copirights' => Copiright::find()->all(),
'authors' => Author::find()->all(),
]);
}
}
This is the form:
<?=
$form->field($model, 'author_id')->widget(SelectizeDropDownList::className(), [
// calls an action that returns a JSON object with matched
// tags
'loadUrl' => ['author/list'],
'value' => $authors,
'items' => \yii\helpers\ArrayHelper::map(\common\models\author::find()->orderBy('name')->asArray()->all(), 'id', 'name'),
'options' => [
'class' => 'form-control',
'id' => 'id'
],
'clientOptions' => [
'valueField' => 'id',
'labelField' => 'name',
'searchField' => ['name'],
'autosearch' => ['on'],
'create' => true,
'maxItems' => 1,
],
])
?>
And this is the function author controller:
public function actionList($query) {
$models = Author::findAllByName($query);
$items = [];
foreach ($models as $model) {
$items[] = ['id' => $model->id, 'name' => $model->name];
}
Yii::$app->response->format = \Yii::$app->response->format = 'json';
return $items;
}
The form works fine to load, filter, search and add new items.
But it is not inserting the new typed attribute in the author table.
Do I need to add something in the book controller?
How can I check if it is a new value or a change of an existing author?
Thanks a lot
I made it work with the following code, not sure the most elegant because i am checking the if the author_id is a number or a string.
In my case the author won't be a number anyway.
public function actionUpdate($id) {
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post())) {
$x = Yii::$app->request->post('Book');
$new_author = $x['author_id'];
if (!is_numeric($new_author)) {
$author = new Author();
$author->name = $new_author;
$author->save();
$model->author_id = $author->id;
}
if ($model->save()) {
return $this->redirect(['index']);
}
} else {
return $this->render('update', [
'model' => $model,
'categories' => BookCategory::find()->active()->all(),
'publishers' => Publisher::find()->all(),
'copirights' => Copiright::find()->all(),
'authors' => Author::find()->all(),
]);
}
}

Can't find value in select2 ajax loading in yii2

I use select2 ajax loading. I get the code from this link: http://demos.krajee.com/widget-details/select2. When I enter words into field, it display all data/value, but it can't automatic select data/value according to words that I enter into field. So, my select2 always select the first data/value and display all value. What's the problem? These are the codes:
_form.php
$url = Url::to(['/paket/jsonlist']);
$cityDesc = empty($model->no_induk) ? '' : Penerima::findOne($model->no_induk)->nama;
echo $form->field($model, 'no_induk')->widget(Select2::classname(), [
'initValueText' => $cityDesc, // set the initial display text
'options' => ['placeholder' => 'Search for a city ...'],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 1,
'language' => [
'errorLoading' => new JsExpression("function () { return 'Waiting for results...'; }"),
],
'ajax' => [
'url' => $url,
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }')
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(no_induk) { return no_induk.text; }'),
'templateSelection' => new JsExpression('function (no_induk) { return no_induk.id; }'),
],
]);
my controller:
public function actionJsonlist($q = NULL, $id = NULL)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$out = ['results' => ['id' => '', 'text' => '']];
if(!is_null($q))
{
$query = new \yii\db\Query;
$mainQuery = $query->select('no_induk AS id, nama AS text')
->from('penerima')
->limit(20);
$command = $mainQuery->createCommand();
$data = $command->queryAll();
$out['results'] = array_values($data);
}
elseif ($id > NULL)
{
$out['results'] = ['id' => $id, 'text' => \frontend\models\Penerima::find($id)->nama];
}
return $out;
}
Could be you use the attribute name and not the vars
echo $form->field($model, 'no_induk')->widget(Select2::classname(), [
'initValueText' =>'cityDesc', // set the initial display text
or
echo $form->field($model, 'no_induk')->widget(Select2::classname(), [
'initValueText' =>$model->cityDesc, // set the initial display text

Yii2: how to add model and model id in mPDF

I need to generate pdf from my view, Im using kartik mPDF,
Controller :
public function actionInvoicesPrint()
{
$pdf = new Pdf([
'mode' => Pdf::MODE_CORE, // leaner size using standard fonts
'content' => $this->renderPartial('view', ['model' => $model, 'mode' => Pdf::MODE_CORE,
'format'=> Pdf::FORMAT_A4,
'orientation'=> Pdf::ORIENT_POTRAIT,
'destination'=> Pdf::DEST_BROWSER]),
]);
return $pdf->render();
}
Getting error Undefined variable: model. I tried as shown above but getting same error.
View:
public function actionView($id)
{
$searchModel = new InvoicesSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$data = Invoices::findOne($id);
return $this->render('view', [
'model' => $this->findModel($id),
'dataProvider' => $dataProvider,
'searchModel' => $searchModel,
'data' => $data,
]);
}
In your actionInvocePrint you don't have a $model assigned
below is a sample of a my working pdf (kartik mPDF like your )
$model = $this->findModel($id);
// get your HTML raw content without any layouts or scripts
//$this->layout = 'pdfmain';
$content = $this->renderPartial('_mpdf_report_scheda', [
'model' => $model,
'imglink' => $imglink,
]);
if ($print ) {
$setJS = 'this.print();';
}
else {
$setJS ='';
}
// setup kartik\mpdf\Pdf component
$pdf = new Pdf([
// set to use core fonts only
'mode' => Pdf::MODE_BLANK,
// A4 paper format
'format' => Pdf::FORMAT_A4,
// portrait orientation
'orientation' => Pdf::ORIENT_PORTRAIT,
// stream to browser inline
'destination' => Pdf::DEST_BROWSER,
// your html content input
'content' => $content,
As you can see in this portion of code ..the model is obtained before all and then with this $model is defined a renderPartial with the proper view ..
for passing the $id you action should be
public function actionInvoicesPrint($id)
and for this you URL call should be
Url::to(['/your-controller/Invoices-print' , 'id' => $your_id]);
Complete Working Solution
public function actionInvoicesPrint($id)
{
$model = $this->findModel($id);
$searchModel = new InvoicesSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$data = Invoices::findOne($id);
$content = $this->renderPartial('view', ['model' => $model,'dataProvider' => $dataProvider,'searchModel' => $searchModel,'data'=> $data]);
$pdf = new Pdf([
// set to use core fonts only
'mode' => Pdf::MODE_BLANK,
// A4 paper format
'format' => Pdf::FORMAT_A4,
// portrait orientation
'orientation' => Pdf::ORIENT_PORTRAIT,
// stream to browser inline
'destination' => Pdf::DEST_BROWSER,
// your html content input
'content' => $content,
]);
return $pdf->render();
}
IN view to trigger controller actionInvoicesPrint()
<?php
echo Html::a('<i class="fa glyphicon glyphicon-hand-up"></i> Privacy Statement', ['/invoices/invoices-print', 'id' => $model->id], [
'class'=>'btn btn-danger',
'target'=>'_blank',
'data-toggle'=>'tooltip',
'title'=>'Will open the generated PDF file in a new window'
]);
?>

Handling a complex Symfony2 form with multiple entities relationship

I have a form (still not finished and is missing many fields) that is handled as a wizard with steps, in which fields from multiple entities are handled. This is the form itself:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('tipo_tramite', 'entity', array(
'class' => 'ComunBundle:TipoTramite',
'property' => 'nombre',
'required' => TRUE,
'label' => "Tipo de Trámite",
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('q')
->where('q.activo = :valorActivo')
->setParameter('valorActivo', TRUE);
}
))
->add('oficina_regional', 'entity', array(
'class' => 'ComunBundle:OficinaRegional',
'property' => 'nombre',
'required' => TRUE,
'label' => "Oficina Regional",
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('q')
->where('q.activo = :valorActivo')
->setParameter('valorActivo', TRUE);
}
))
->add('procedencia_producto', 'entity', array(
'class' => 'ComunBundle:ProcedenciaProducto',
'property' => 'nombre',
'required' => TRUE,
'label' => "Procedencia del Producto"
))
->add('finalidad_producto', 'entity', array(
'class' => 'ComunBundle:FinalidadProducto',
'property' => 'nombre',
'required' => TRUE,
'label' => "Finalidad del Producto"
))
->add('condicion_producto', 'entity', array(
'class' => 'ComunBundle:CondicionProducto',
'property' => 'nombre',
'required' => TRUE,
'label' => "Condición del Producto"
))
->add('lote', 'integer', array(
'required' => TRUE,
'label' => "Tamaño del Lote"
))
->add('observaciones', 'text', array(
'required' => FALSE,
'label' => "Observaciones"
));
}
I have a question regarding how to handle the parameter data_class in this case so I do not have to do magic in the controller. When I say magic I mean the following:
public function empresaAction()
{
$entity = new Empresa();
$form = $this->createForm(new EmpresaFormType(), $entity);
return array( 'entity' => $entity, 'form' => $form->createView() );
}
public function guardarEmpresaAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
/** #var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->container->get('fos_user.user_manager');
/** #var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */
$dispatcher = $this->container->get('event_dispatcher');
/** #var $mailer FOS\UserBundle\Mailer\MailerInterface */
$mailer = $this->container->get('fos_user.mailer');
$request_empresa = $request->get('empresa');
$request_sucursal = $request->get('sucursal');
$request_chkRif = $request->get('chkRif');
$request_estado = $request_empresa[ 'estado' ];
$request_municipio = $request->get('municipio');
$request_ciudad = $request->get('ciudad');
$request_parroquia = $request->get('parroquia');
$user = $userManager->createUser();
$event = new GetResponseUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);
if (null !== $event->getResponse())
{
return $event->getResponse();
}
$entity = new Empresa();
$form = $this->createForm(new EmpresaFormType(), $entity);
$form->handleRequest($request);
$success = $url = $errors = "";
if ($form->isValid())
{
if ($request_sucursal != NULL || $request_sucursal != "")
{
$padreEntity = $em->getRepository('UsuarioBundle:Empresa')->findOneBy(array( "padre" => $request_sucursal ));
if (!$padreEntity)
{
$padreEntity = $em->getRepository('UsuarioBundle:Empresa')->findOneBy(array( "id" => $request_sucursal ));
}
if ($request_chkRif != NULL || $request_chkRif != "")
{
$rifUsuario = $request_empresa[ 'tipo_identificacion' ] . $request_empresa[ 'rif' ];
}
else
{
$originalRif = $padreEntity->getRif();
$sliceRif = substr($originalRif, 10, 1);
$rifUsuario = $originalRif . ($sliceRif === false ? 1 : $sliceRif + 1);
}
$entity->setPadre($padreEntity);
}
else
{
$rifUsuario = $request_empresa[ 'tipo_identificacion' ] . $request_empresa[ 'rif' ];
}
$user->setUsername($rifUsuario);
$user->setRepresentativeName($request_empresa[ 'razon_social' ]);
$user->setEmail($request_empresa[ 'usuario' ][ 'email' ]);
$user->setPlainPassword($request_empresa[ 'usuario' ][ 'plainPassword' ][ 'first' ]);
$pais = $em->getRepository('ComunBundle:Pais')->findOneBy(array( "id" => 23 ));
$user->setPais($pais);
$estado_id = $request_estado ? $request_estado : 0;
$estado = $em->getRepository('ComunBundle:Estado')->findOneBy(array( "id" => $estado_id ));
$user->setEstado($estado);
$municipio_id = $request_municipio ? $request_municipio : 0;
$municipio = $em->getRepository('ComunBundle:Municipio')->findOneBy(array( "id" => $municipio_id ));
$user->setMunicipio($municipio);
$ciudad_id = $request_ciudad ? $request_ciudad : 0;
$ciudad = $em->getRepository('ComunBundle:Ciudad')->findOneBy(array( "id" => $ciudad_id ));
$user->setCiudad($ciudad);
$parroquia_id = $request_parroquia ? $request_parroquia : 0;
$parroquia = $em->getRepository('ComunBundle:Parroquia')->findOneBy(array( "id" => $parroquia_id ));
$user->setParroquia($parroquia);
...
}
else
{
$errors = $this->getFormErrors($form);
$success = FALSE;
}
return new JsonResponse(array( 'success' => $success, 'errors' => $errors, 'redirect_to' => $url ));
}
Since the 'data_classonEmpresaFormTypeis set toUsuarioBundle\Entity\Empresa` then I need to handle any extra parameter as example above show with getter/setter and that's a lot of work for complex/big forms.
In the sample form, the fields tipo_tramite will persist in the class ComunBundle\Entity\Producto but the field oficina_regional will persist in the class ComunBundle\Entity\SolicitudUsuario and so with others who are not placed even here but they are in the form, in total should persist as 3 or 4 entities including relationships in many cases, how do you handle this?
I know there is CraueFormFlowBundle that maybe cover this process/flow but not sure if it is the solution to go.
Any advice?
Just worked with multi-step form few days ago. I think you need embedded forms here. Anyway can suggest you another nice bundle for creating wizard: SyliusFlowBundle. IMO it's more flexible and easier to understand than CraueFormFlowBundle.
BTW why do you want to store all in one form? We've used one form for each step, and I liked this approach.

Categories