I have this code at the moment to echo out all my database entries, I am wondering what it looks like in ZF to echo out the entries if the first value of the db entry is a.
Code:
<table>
<?php foreach($this->clubs as $clubs) : ?>
<tr>
<td><a href="<?php echo $this->url(array('controller' => 'club-description', 'action' => 'index', 'club_id' => $clubs->id));?>">
<?php echo $this->escape($clubs->club_name);?></a></td>
<td><?php echo $this->escape($clubs->rating);?></td>
</tr>
<?php endforeach; ?>
</table>
Thanks
Rik
So, based on your comment it sounds like you want to group the clubs by letter on the page. Assuming they are being ordered alphabetically in your database query, the simplest way to do this is to keep a variable which stores the first letter of the last club in the loop. Then, on each iteration, you compare the first letter of the current club with the first letter of the previous club. If they are different, you output a new heading.
With your code this would look something like this:
<?php
$previousLetter = false;
?>
<table>
<?php foreach($this->clubs as $clubs) : ?>
<?php
$firstLetter = substr($clubs->_club_name, 0, 1);
if ($firstLetter != $previousLetter) {
?>
<tr>
<td><?php echo $firstLetter; ?></td>
</tr>
<?php } ?>
<tr>
<td><a href="<?php echo $this->url(array('controller' => 'club-description', 'action' => 'index', 'club_id' => $clubs->id));?>">
<?php echo $this->escape($clubs->club_name);?></a></td>
<td><?php echo $this->escape($clubs->rating);?></td>
</tr>
<?php $previousLetter = $firstLetter; ?>
<?php endforeach; ?>
</table>
Related
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 recently read this post on how to do a CakePHP 3.x POST without forms (doing updates on the Index.ctp page, rather than using Add.ctp or Edit.ctp).
I have 2 issues:
Modifying POST to accept select statements from an array?
My index.ctp is as follows:
<?php foreach ($resources as $resource): ?>
<tr>
<td><?= $this->Number->format($resource->id) ?></td>
<td><?= h($resource->brand) ?></td>
<td><?= h($resource->model) ?></td>
<td><?= h($resource->subtype) ?></td>
<td><?= $this->Form->postButton('Change Type',['controller'=>'Users', 'action'=>'change_resource', $resource->id, $resource->type->name])?></td>
<td><?= $resource->has('studio') ? $this->Html->link($resource->studio->name, ['controller' => 'Studios', 'action' => 'view', $resource->studio->id]) : '' ?></td>
<td><?= h($resource->created) ?></td>
<td><?= h($resource->modified) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $resource->id]) ?>
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $resource->id]) ?>
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $resource->id], ['confirm' => __('Are you sure you want to delete # {0}?', $resource->id)]) ?>
</td>
</tr>
<?php endforeach; ?>
And then the action as described in the linked StackOverflow post in the corresponding Controller:
public function change_resource($id,$existing_type)
{
$resources = TableRegistry::get('Resources');
$resource = $resources->get($id);
$resource->type = ($existing_type == '')?'$resource->$type->name';
$resources->save($resource);
return $this->redirect($this->referer());
}
Currently I'm getting a syntax error of
unexpected ';' on line 124,
which refers to the $resource->type line in the Controller method. If I remove that line, I get:
unexpected $resources on line 125
which I expect given the ; is removed so it thinks they're all on the same line.
Modifying POST for non-select inputs (eg. varchar/int/text)
I would like to be able to do a POST for the entire table, not just one input. However, while 2 of the inputs are selects from other tables in the form of arrays, the rest are all standard inputs (mostly varchar). I'm wondering how to modify the above controller to do this. Additionally, if I want to do POST for more than one input, do I require separate methods for every single input, or can I put it all in one method?
Please note that your ternary operator syntax is incorrect. You're missing out the colon (:)
Refer to Ternary Operator Example
Syntax: (expr1) ? (expr2) : (expr3)
$resource->type = ($existing_type == '') ? $resource->$type->name : <other statement>;
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>
i am new to ZF i want to create ajax link that will go to "task" controller and "ajax" action
do something like this
$registry = Zend_Registry::getInstance();
$DB = $registry['DB'];
$sql = "SELECT * FROM task ORDER BY task_name ASC";
$result = $DB->fetchAll($sql);
than put the result in this div
<div id="container">container</div>
this is my view where i am doing this
<?php echo $this->jQuery()->enable(); ?>
<?php echo $this->jQuery()->uiEnable(); ?>
<div id="container">container</div>
<?php
echo $this->ajaxLink("Bring All Task","task/ajax",array('update' => '#container'));
?>
i dont know the syntax how i will do this , retouch my code if i am wrong i searched alot but all in vain plz explain me thanking you all in anticipation also refer me some nice links of zendx_jquery tutorial
This should work:
class IndexController extends Zend_Controller_Action
{
/**
* Homepage - display result of ajaxRequest
*/
public function indexAction()
{
}
/**
* Print result of database query
*/
public function ajaxAction()
{
// disable rendering of view and layout
$this->_helper->layout()->disableLayout();
$registry = Zend_Registry::getInstance();
$db = $registry['DB'];
// get select object to build query
$select = $db->select();
$select->from('task')->order('task_name ASC');
// echo result or what ever..
$this->view->tasks = $db->fetchAll($select);
}
}
// index.phtml (view)
<?php
echo $this->jQuery()->enable();
echo $this->jQuery()->uiEnable();
// create link to ajaxAction
$url = $this->url(array(
'controller' => 'index',
'action' => 'ajax',
));
?>
<div id="container">container</div>
<?php
echo $this->ajaxLink(
"Bring All Task", $url, array('update' => '#container')
);
?>
and in your ajax.phtml
<?php if ($this->tasks): ?>
<table>
<tr>
<th>task ID</th>
<th>task Name</th>
</tr>
<?php foreach($this->tasks as $task) : ?>
<tr>
<td><?php echo $task['task_id']; /* depending on your column names */ ?>
</td>
<td><?php echo $this->escape($task['task_name']); /* to replace " with " and so on */ ?>
</td>
</tr>
<?php endforeach; ?>
</table>
<?php else: ?>
No tasks in table.
<?php endif; ?>
regarding db you have to setup it first somewhere earlier in your code, for example front controller index.php or bootstrap.php, for example:
$db = Zend_Db::factory('Pdo_Mysql', array(
'host' => '127.0.0.1',
'username' => 'webuser',
'password' => 'xxxxxxxx',
'dbname' => 'test'
));
Zend_Registry::set('DB', $db);
I am NEW to ZF .i used zend paginator in my first project .its working fine that is switching b/w pages with right result but the problem is that i have other links too in that view have a look to my view
<?php include "header.phtml"; ?>
<h1><?php echo $this->escape($this->title);?></h1>
<h2><?php echo $this->escape($this->description);?></h2>
Register
<table border="1" align="center">
<tr>
<th>User Name</th>
<th>First Name</th>
<th>Last Name</th>
<th>Action</th>
</tr>
<?php
foreach($this->paginator as $record){?>
<tr>
<td><?php echo $record->user_name;?></td>
<td><?php echo $record->first_name;?></td>
<td><?php echo $record->last_name;?></td>
<td>
Edit
|
Delete
</td>
</tr>
<?php } ?>
</table>
<?php echo $this->paginationControl($this->paginator, 'Sliding', 'pagination.phtml'); ?>
<?php include "footer.phtml"; ?>
as i said the pagination renders and working fine but when i click on these links
<a id="edit_link" href="edit/id/<?php echo $record->id;?>">Edit</a>
or
<a id="delete_link" href="del/id/<?php echo $record->id;?>">Delete</a>
or
Register
it is not calling the required action instead it make my url like this
(initial link) http://localhost/zend_login/web_root/index.php/task/list
after clicking any of the above link its like this
http://localhost/zend_login/web_root/index.php/task/list/page/edit/id/8
http://localhost/zend_login/web_root/index.php/task/list/page/edit/id/edit/id/23
http://localhost/zend_login/web_root/index.php/task/list/page/edit/id/edit/id/register http://localhost/zend_login/web_root/index.php/task/list/page/edit/id/edit/id/del/id/12
note its not happening when the page renders first time but when i click on any pagination link its doing so initialy its going to the reguired action and displaying a view...any help HERE IS THE ACTION
public function listAction(){
$registry = Zend_Registry::getInstance();
$DB = $registry['DB'];
$sql = "SELECT * FROM task ORDER BY task_name ASC";
$result = $DB->fetchAll($sql);
$page=$this->_getParam('page',1);
$paginator = Zend_Paginator::factory($result);
$paginator->setItemCountPerPage(3);
$paginator->setCurrentPageNumber($page);
$this->view->assign('title','Task List');
$this->view->assign('description','Below, are the Task:');
$this->view->paginator=$paginator;
}
Try:
// controller
$this->view->controllerName = $this->getRequest()->getControllerName();
// view script
Edit
|
Delete
or
Edit
|
Delete
Second example uses baseUrl() view helper that's using front controller's baseUrl setting. If you don't set baseUrl in your frontController it's trying to guess. As you're not using bootstrap functionality to set baseUrl you may do the following in index.php (not required):
$frontController = Zend_Controller_Front::getInstance();
$frontController->setBaseUrl('/');
Third possibility using url() view helper:
<a href="<?php echo $this->url(array(
'controller' => $controllerName,
'action' => 'edit',
'id' => $record_->id
)); ?>">Edit</a>
|
<a href="<?php echo $this->url(array(
'controller' => $controllerName,
'action' => 'del',
'id' => $record_->id
));?>">Delete</a>
add this in your action
$request = $this->getRequest();
$this->view->assign('url', $request->getBaseURL());
and replace your links in view with this
Add a Task
Edit
Delete