Zend_Dojo_Form in a layout - zend-framework

I have a Zend_Dojo_Form which I have moved from my view (where it works fine) to my layout, as it's something that will be useful on every page. However in the layout the form no longer works - none of the dijit elements appear and it behaves just as a normal HTML form would.
Here's the relevant part of my bootstrap:
protected function _initView()
{
Zend_Layout::startMvc(array(
'layoutPath' => '../application/layouts',
'layout' => 'default'
));
$view = new Zend_View();
$view->setEncoding('UTF-8')
->doctype('HTML5');
// init Dojo
Zend_Dojo::enableView($view);
$view->dojo()->enable()
->setCdnVersion('1.5')
->requireModule('dojo.data.ItemFileWriteStore')
[...]
->addStyleSheetModule('dijit.themes.tundra');
// assign the view to the viewRenderer, so it will be used by the MVC actions
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
$viewRenderer->setView($view);
return $view;
}
there are no errors (JS or ZF), the form just doesn't work as it should.
I assume I need to Dojo enable the Layout view in some way. I tried changing the layout part of the bootstrap method above to this:
$layout = Zend_Layout::startMvc(array(
'layoutPath' => '../application/layouts',
'layout' => 'default'
));
$view = $layout->getView();
Zend_Dojo::enableView($view);
$layout->setView($view);
but that didn't make any difference.
I found this question which sounds very similar to my problem, but the accepted answer just shows including the dojo helper in the layout, which I am doing already.

This is most probably due to that you have the layout as suggested in the docs:
<?php echo $this->doctype() ?>
<html>
<head>
<?php echo $this->headTitle() ?>
<?php echo $this->headMeta() ?>
<?php echo $this->headLink() ?>
<?php echo $this->headStyle() ?>
<?php if ($this->dojo()->isEnabled()){
$this->dojo()->setLocalPath('/js/dojo/dojo.js')
->addStyleSheetModule('dijit.themes.tundra');
echo $this->dojo();
}
?>
<?php echo $this->headScript() ?>
</head>
<body class="tundra">
<?php echo $this->layout()->content ?>
<?php echo $this->inlineScript() ?>
</body>
</html>
The problem is the echo $this->dojo() must be after the $this->form->render() otherwise the required modules won't have been registered in Zend_Dojo.

Related

ZF2 How to set search form in layout

What is the right way to set a (search) form with Zend Framework 2 in the layout.ptml who is visible on any page of the website?
Thanks in advance.
Nick
It is really simple to set any variables to all layouts in ZF2 by EventManager, just attach the EVENT_RENDER event such as:
class Module
{
public function onBootstrap($e)
{
$app = $e->getParam('application');
$app->getEventManager()->attach(MvcEvent::EVENT_RENDER, array($this, 'setFormToView'), 100);
}
public function setFormToView($event)
{
$form = new MyForm();
$viewModel = $event->getViewModel();
$viewModel->setVariables(array(
'form' => $form,
));
}
}
For view in layout use:
<?php if ($user = $this->identity()): ?>
<?php echo 'Login with user' . $this->escapeHtml($user->nome); ?>
| <?php echo $this->translate('Sair'); ?>
<?php else: ?>
<?php
echo $this->form()->openTag($form);
echo "<h5>Forneça seu login e senha </h5>";
echo $this->formRow($form->get('username'));
echo $this->formRow($form->get('password'));
echo $this->formRow($form->get('rememberme'));
echo $this->formSubmit($form->get('submit'));
echo $this->form()->closeTag();
?>
<?php endif; ?>

how to, hidden field value not showing up on request in zend framework?

i have a simple form that has a textarea ans a hidden field
$textarea = new Zend_Form_Element_Textarea('post');
$textarea->setRequired(true);
$textarea->setLabel('');
$hidden = new Zend_Form_Element_Hidden('post_id');
$hidden->setLabel('');
$hidden->setValue('1');
$submit = new Zend_Form_Element_Submit('submit');
$submit->setLabel('test');
$this->addElement($textarea);
$this->addElement($hidden);
$this->addElement($submit);
$this->setDecorators(array(
'FormElements',
array('HtmlTag', array('tag' => 'div', 'class' => 'form_class')),
'Form'
));
in my view i do
<?php echo $this->form->getElement('post')->render(); ?>
<?php echo $this->form->getElement('submit')->render(); ?>
then in my controller
$request = $this->getRequest();
if( $request->isPost() && $form->isValid($request->getParams()))
{
Zend_Debug::dump($request->getParams());
}
what happens is that i get
array(8) {
["module"] => string(6) "testr"
["controller"] => string(8) "posts"
["action"] => string(9) "post"
["post"] => string(10) "testgfdgfg"
["submit"] => string(26) "submit"
}
but no post_id
this is a bit wired and i cant figure it out. Ive looked for any code that might screw this up but nothing. I've also tried to echo the hidden field in the view, but i still get nothing on the request
any ideas?
thanks
In your view do
<?php echo $this->form->getElement('post'); ?>
<?php echo $this->form->getElement('post_id'); ?>
<?php echo $this->form->getElement('submit');?>
You are simply not echoing post_id element like you did with post and submit . Also you don't need to call render() since php magic function __toString() proxy render() in all Zend_Form_Element_XXX .
In View part you are just set two elements only
<?php echo $this->form->getElement('post')->render(); ?>
<?php echo $this->form->getElement('submit')->render(); ?>
WHERE form->getElement('post_id')->render(); ?>
<?php echo $this->form->getElement('post')->render(); ?>
<?php echo $this->form->getElement('submit')->render(); ?>
<?php echo $this->form->getElement('post_id')->render(); ?>
Try once with this.
I think it will work.

zend framework two step view

I am new to zendframework . I am trying to implement two step view lay out:
Bootstrap.php(view/Bootstrap.php)
<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
public function _initRoutes()
{
$options = array(
'layout' => 'layout',
'layoutPath' => '/layout/layout.phtml',);
$layout = Zend_Layout::startMvc($options);
}
}?>
layout.phtml(application/view/scripts/layout/layout.phtml)
<?php
include "header.php";
?>
// view contents goes here.
<?php
$this->layout()->content;
?>
// footer goes here.
<?php
include "footer.phtml";
?>
i am a absolute beginner step by step explanation is more appreciated .Thanks.
The easiest way to enable layouts is to run the Zend_Tool command from the command line zf enable layout, this will add the line
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
to your application.ini and build the directory for the layout and the default file layout.phtml.
Alternatively you can specify your layout path and default layout name with 2 lines in your application.ini file:
resources.layout.layoutPath = APPLICATION_PATH "/layouts" //path to layout
resources.layout.layout = master //name of layout without extension
other layout/view options may be set in your application.ini to be callled in your view:
;View Settings
;*************
resources.view[]=
resources.view.charset = "UTF-8"
resources.view.encoding = "UTF-8"
resources.view.doctype = "HTML5"
resources.view.language = "en"
resources.view.contentType = "text/html; charset=UTF-8"
then in your bootstrap.php you can call on these resources to initialize your view:
/**
* initialize the registry and asign application.ini to config namespace
*/
protected function _initRegistry() {
//make application.ini configuration available in registry
$config = new Zend_Config($this->getOptions());
Zend_Registry::set('config', $config);
}
/**
* initialize the view and return it
* #return \Zend_View
*/
protected function _initView() {
//Initialize view
$view = new Zend_View();
//add custom view helper path
$view->addHelperPath('/../library/Application/View/Helper');
//set doctype for default layout
$view->doctype(Zend_Registry::get('config')->resources->view->doctype);
//set default title
$view->headTitle('Our Home');
//set head meta data
$view->headMeta()->appendHttpEquiv('Content-Type', Zend_Registry::get(
'config')->resources->view->contentType);
//set css includes
$view->headLink()->setStylesheet('/css/normalize.css');
$view->headLink()->appendStylesheet('/css/blueprint/src/liquid.css');
$view->headLink()->appendStylesheet('/css/blueprint/src/typography.css');
$view->headLink()->appendStylesheet(
'/javascript/mediaelement/build/mediaelementplayer.css');
$view->headLink()->appendStylesheet('/css/main.css');
$view->headLink()->appendStylesheet('/css/nav.css');
$view->headLink()->appendStylesheet('/css/table.css');
//add javascript files
$view->headScript()->setFile('/javascript/mediaelement/build/jquery.js');
//add it to the view renderer
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
'ViewRenderer');
$viewRenderer->setView($view);
//Return it, so that it can be stored by the bootstrap
return $view;
}
I also included a convenience method _initRegistry() to make config options available everywhere with minimal code.
The layout in ZF is a simple html page with placeholder added for dynamic or configured options:
<?php
echo $this->doctype() . "\n"; //placeholder assigned in bootstrap $view->doctype
?>
<html>
<head>
<title></title>
<?php echo $this->headMeta() . "\n" //placeholder assigned in bootstrap ?>
<?php echo $this->headLink() . "\n" //placeholder assigned in bootstrap ?>
<?php echo $this->headscript(). "\n" //placeholder assigned in bootstrap?>
</head>
<body>
<section class="container">
<header class="block">
<hgroup id="header" class ="column span-24">
<h1>Our Page</h1>
</hgroup>
<nav>
<div id="nav" class="column span-24">
<?php echo $this->layout()->nav //custom placeholder ?>
</div>
</nav>
</header>
<section class="block">
<div id="main" class="column span-18 border">
<div id="flash">
<?php
//flash messenger display location
if (count($this->messages) > 0) {
printf("<h3 id='flash'>%s</h3>", $this->messages[0]);
}
?>
</div>
<?php echo $this->layout()->content; //placeholder for redering views ?>
</div>
<aside id="sidebar" class="column span-4 last">
<?php echo $this->layout()->search //custom placeholder ?>
<div id="subNav">
<?php echo $this->layout()->subNav //custom placeholder ?>
</div>
<div id="adminMenu">
<?php echo $this->layout()->adminMenu //custom placeholder ?>
</div>
</aside>
</section>
<footer class="block">
<div id="footer" class="column span-24">
<p>Created by <em>Your Name</em> with Zend Framework. &COPY; </p>
</div>
</footer>
</section>
</body>
</html>
<?php echo $this->inlineScript() ?> //javascript includes at bottom of page
Hope this helps.
Well first off, youre initializing the layout in a method that would seem to be for your routing - probably a bad idea. Secondly if youre using the full stack with Zend_Application then you can use the provided Zend_Application_Resource_Layout and set all your options from configuration.
Additionally you dont want to use a raw include statement to pull in content you should use $this->render('thetemplate.phtml') from within your layout file. Check out the Zend_Layout Quickstart for more info on that.

view render in zend not working properly as expected

My zend layout and scripts are detecting fine. but when in init function of my IndexController I write $this->view->render("header.phtml") It does not show anything one the screen, whereas when I write echo ($this->view->render("header.phtml"); it displays my header.phtml file. Here is my IndexController
class IndexController extends Zend_Controller_Action
{
public function init()
{
$layout = $this->_helper->layout();
//$this->view = $this->getResource('View');
echo ($this->view->render("header.phtml"));
//echo"<pre>";
//var_dump($this->view);
//var_dump(APPICATION_PATH);
}
public function indexAction()
{
// action body
echo "In default index con";
}
}
Also when Igive my url to/mypath/index It does not display the simple line "I'm in index controller" which I'm just echoing. In my bootstrap here is my Zend_Layout settings.
Zend_Loader::loadClass('Zend_View');
$this->view = new Zend_View();
$this->view->setEncoding('UTF-8');
$this->view->setScriptPath($this->root .'/application/default/views/scripts');
$viewRenderer=new Zend_Controller_Action_Helper_ViewRenderer();
// Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
// $view->setScriptPath($this->root.'/'.$theme.'/views/scripts/');
//$view->setScriptPath($this->root.'/application/default/views/scripts/');
$this->view->addScriptPath($this->root.'/application/admin/views/scripts');
$this->view->addScriptPath($this->root.'/application/business/views/scripts');
// $this->view->setHelperPath($this->root .'/application/default/views/helpers');
$this->layout = Zend_Layout::startMvc(
array(
'layoutPath' => $this->root . '/application/default/views/'.$crt_theme.'/layouts',
'layout' => 'layout'
)
);
$this->registry->set("theme", $crt_theme);
variable $crt_theme is set to 'default'.
Rob' answer is correct although you may need some more information as you appear to be working hard at making this complicated. ZF when used as an MVC has a place to put layouts and defaults for using them.
If you are using the Zend_Tool command line interface start with the commmand: zf enable layout and the tool will add the default directory and a default layout.phtml to your project.
in the application.ini it will add the line:
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
and at that path it will add the file layout.phtml
If you need to change the name of the default layout add this line with the name of your script without the .phtml
resources.layout.layout = master
There are as many ways as you can think of to use this file, but here is an example of how I use it.
I like to set my project defaults in my application.ini file so if I need to change anything it's easy.
View Settings
;*************
resources.view[]=
resources.view.charset = "UTF-8"
resources.view.encoding = "UTF-8"
resources.view.doctype = "HTML5"
resources.view.language = "en"
resources.view.contentType = "text/html; charset=UTF-8"
then in my bootstrap I setup the view I want use, I do it here so that if I have multiple layouts (i usually do) it's easy to change css or js files in one place.
protected function _initView() {
//Initialize view
$view = new Zend_View();
$view->addHelperPath('/../library/Application/View/Helper');
$view->doctype(Zend_Registry::get('config')->resources->view->doctype);
$view->headTitle('Our Home');
$view->headMeta()->appendHttpEquiv('Content-Type', Zend_Registry::get(
'config')->resources->view->contentType);
$view->headLink()->setStylesheet('/css/normalize.css');
$view->headLink()->appendStylesheet('/css/blueprint/src/liquid.css');
$view->headLink()->appendStylesheet('/css/blueprint/src/typography.css');
$view->headLink()->appendStylesheet(
'/javascript/mediaelement/build/mediaelementplayer.css');
$view->headLink()->appendStylesheet('/css/main.css');
$view->headLink()->appendStylesheet('/css/nav.css');
$view->headLink()->appendStylesheet('/css/table.css');
//add javascript files
$view->headScript()->setFile('/javascript/mediaelement/build/jquery.js');
$view->headScript()->appendFile('/javascript/modernizr.js');
//add it to the view renderer
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
'ViewRenderer');
$viewRenderer->setView($view);
//Return it, so that it can be stored by the bootstrap
return $view;
}
Notice all of those headLink(), headScript() and docType() entries, these are where the data is set for placeholders, that will be used in the layout.
Now the layout, the actual content from your other action based scripts will typically be rendered by the placeholder $this->layout()->content
<?php
echo $this->doctype() . "\n";//placeholder
?>
<html>
<head>
<title></title>
<?php echo $this->headMeta() . "\n" ?><!-- displays all meta data passed -->
<?php echo $this->headLink() . "\n" ?><!-- displays all links passed -->
<?php echo $this->headscript(). "\n"?><!-- displays all scripts passed -->
</head>
<body>
<section class="container">
<header class="block">
<hgroup id="header" class ="column span-24">
<h1>Our Home</h1>
</hgroup>
<nav>
<div id="nav" class="column span-24">
<?php echo $this->layout()->nav ?> <!-- Custom Placeholder -->
</div>
</nav>
</header>
<section class="block">
<div id="main" class="column span-18 border">
<div id="flash">
<?php
//flash messenger display location
if (count($this->messages) > 0) {
printf("<h3 id='flash'>%s</h3>", $this->messages[0]);
}
?>
</div>
<?php echo $this->layout()->content; ?><!-- Default placeholder, where views are rendered -->
</div>
<aside id="sidebar" class="column span-4 last">
<?php echo $this->layout()->search ?><!-- Custom placeholder -->
<div id="subNav">
<?php echo $this->layout()->subNav ?> <!-- Custom placeholder -->
</div>
<div id="adminMenu">
<h4>Administration Links</h4>
<?php echo $this->layout()->adminMenu ?> <!-- Custom placeholder -->
</div>
</aside>
</section>
<footer class="block">
<div id="footer" class="column span-24">
<p>Created with Zend Framework. &COPY; </p>
</div>
</footer>
</section>
<?php echo $this->inlineScript() ?><!-- placeholder -->
</body>
</html>
Hope this helps!
[Edit]
One more thing, this always seems to be the next question. "How do I change my layout from the default in my controller/action?"
to change the layout from your controller you would typically do it with a preDispatch() method and just pass the name of your new layout to the layout helper.
$this->_helper->layout->setLayout('myOtherLayout');
doing just this will change the layout for every action in the controller. To be more selective you can use a conditional, like:
if ($this->getRequest()->getActionName() == 'player') {
$this->_helper->layout->setLayout('player');//reset layout
//add 2 new headscripts
$this->view->headScript()->appendFile(
'http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js'
);
$this->view->headScript()->appendFile(
'/javascript/mediaplayer/jwplayer.js'
);
}
render() is working as intended; it returns a string that you should then echo.
It is very unusual to be rendering directly in a controller however. At a minimum, you should be rendering your header and footer from views/scripts/index/index.phtml, though using Zend_Layout would be even better. If you are using Zend_Application, then you can start using Zend_Layout simply by adding:
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
to your application/config/application.ini file. You then need to create a application/layouts/scripts/layout.phtml file which could look something like this:
<?php
$this->headMeta()->appendHttpEquiv('Content-Type', 'text/html;charset=utf-8');
$this->headTitle()->setSeparator(' - ');
$this->headTitle('My website');
?>
<!DOCTYPE html>
<html>
<head>
<?php echo $this->headMeta(); ?>
<?php echo $this->headTitle(); ?>
<!-- Other <head> elements and view helpers here -->
</head>
<body>
<div id="content">
<?php echo $this->layout()->content; ?>
</div>
</body>
</html>

Rendering only the <form> tag

Is there any way that i can render ONLY the start <form> tag of a Zend_Form object?
print $this->registerForm->renderForm();
renders <form></form>, and i only need <form>
Edit:
After Asleys possible solution i wrote this for My_Form class
public function renderFormOpen() {
return str_replace('</form>', '', $this->renderForm());
}
public function renderFormClose() {
return '</form>';
}
Still looking for at ZF way of doing thins, even though i don't think there is any - after going through the code in the ZF library.
You could write an custom form-decorator that uses a custom view-helper that only renders the open form tag. But I think this would be overkill.
Just "hardcode" the form-tags and fill the attributes with the data provided by the form-variable in your view.
<!--in your view-template -->
<form action="<?php echo $this->form->getAction() ?>"
enctype="<?php echo $this->form->getEnctype() ?>"
method="<?php echo $this->form->getMethod() ?>"
id="<?php echo $this->form->getId() ?>"
class="<?php echo $this->form->getAttrib('class') ?>" >
<!--in case your products are represented as elements -->
<?php foreach ($this->form->getElements() as $element): ?>
<?php echo $element ?>
<?php endforeach; ?>
<!--in case your products are represented as displayGroups -->
<?php foreach ($this->form->getDisplayGroups() as $displayGroup): ?>
<?php echo $displayGroup ?>
<?php endforeach; ?>
<!--in case your products are represented as subforms -->
<?php foreach ($this->form->getSubforms() as $subform): ?>
<?php echo $subform ?>
<?php endforeach; ?>
<!--in case your products are rendered by a view helper -->
<?php foreach ($this->products as $product): ?>
<?php echo $this->renderProduct($product) ?>
<?php endforeach; ?>
</form>
Just for fun the overkill way
// Get your products form
$form = new Form_Products();
// Add custom prefix path
$form->addPrefixPath('Foobar_Form_Decorator', 'Foobar/Form/Decorator', 'decorator');
// Set OnlyOpenTagForm-ViewHelper for FormDecorator
$form->getDecorator('Form')->setHelper('OnlyOpenTagForm');
// copy Zend/View/Helper/Form to Foobar/Form/Decorato/OnlyOpenTagForm.php
// In OnlyOpenTagForm.php
// replace Zend_View_Helper_Form with Foobar_View_Helper_OnlyOpenTagForm
// replace method "form" with onlyOpenTagForm"
// replace
if (false !== $content) {
$xhtml .= $content
. '</form>';
}
// with:
if (false !== $content) {
$xhtml .= $content;
}
Done! - The Java-Guys will love it ;)
You can render just the open form tag by passing false to the form decorator like so:
<?php echo $this->form->renderForm(false) ?>
Which will output something like:
<form id="post" enctype="multipart/form-data" method="post" action="/post">
Additonally you can pass a string to the form decorator to be enclosed by the form tags like so:
<?php echo $this->form->renderForm('Some Text') ?>
Which outputs something like:
<form id="post" enctype="multipart/form-data" method="post" action="/simchas/post">Some Text</form>
Hope this helps...
You could do something like this:
echo $this->form->getDecorator('Form')->setElement($this->form)->render(false);