How to include js and css in Zend Form Elements? - zend-framework

I create my own zend form element - App_Form_Element_Wysiwyg
<?php
class App_Form_Element_Wysiwyg extends Zend_Form_Element_Xhtml
{
/**
* Default form view helper to use for rendering
* #var string
*/
public $helper = 'wysiwyg';
}
Then I create helper for wysiwyg - App_View_Helper_Wysiwyg
<?php
class App_View_Helper_Wysiwyg extends Zend_View_Helper_FormTextarea
{
public function wysiwyg($name, $value = null, $attribs = null)
{
// Here I want to include js and css for wysiwyg editor
...
$xhtml = '<textarea name="' . $this->view->escape($name) . '"'
. ' id="' . $this->view->escape($id) . '"'
. $disabled
. $this->_htmlAttribs($attribs) . '>'
. $this->view->escape($value) . '</textarea>';
return $xhtml;
}
}
How can I include js and css files for wysiwyg editor?

The headScript() helper lets you add or manipulate script tags in the header. So within your helper you can do:
$this->view->headScript()->appendFile('/path/to/file.js');
then just ensure your layout is calling the helper somewhere in the head section:
<?=$this->headScript()?>
to output the HTML. There is also the headStyle() helper which works in a similar way and can be used for your CSS.
Relevant docs:
HeadScript
HeadStyle

Related

TYPO3: Extend ctype textmedia with subheader

I want to add the subheader to the ctype 'textmedia' (TYPO3 9.5 & 10.4).
I followed this stackoverflow answer:
TYPO3 8 show layout selection in backend preview for textmedia
to register my Hook
typo3conf/ext/my-extension/Classes/Hooks/PageLayoutView/TextMediaCustomPreviewRenderer.php
Then I added the subheader
<?php
namespace aaa\bbb\Hooks\PageLayoutView;
use \TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface;
use \TYPO3\CMS\Backend\View\PageLayoutView;
/**
* Contains a preview rendering for the page module of CType="textmedia"
*/
class TextMediaCustomPreviewRenderer implements PageLayoutViewDrawItemHookInterface
{
/**
* Preprocesses the preview rendering of a content element of type "textmedia"
*
* #param \TYPO3\CMS\Backend\View\PageLayoutView $parentObject Calling parent object
* #param bool $drawItem Whether to draw the item using the default functionality
* #param string $headerContent Header content
* #param string $subheaderContent Subheader content
* #param string $itemContent Item content
* #param array $row Record row of tt_content
*/
public function preProcess(
PageLayoutView &$parentObject,
&$drawItem,
&$headerContent,
&$subheaderContent,
&$itemContent,
array &$row
) {
if ($row['CType'] === 'textmedia') {
if ($row['bodytext']) {
$itemContent .= $parentObject->linkEditContent($parentObject->renderText($row['bodytext']), $row) . '<br />';
}
if ($row['assets']) {
$itemContent .= $parentObject->linkEditContent($parentObject->getThumbCodeUnlinked($row, 'tt_content', 'assets'), $row) . '<br />';
$fileReferences = BackendUtility::resolveFileReferences('tt_content', 'assets', $row);
if (!empty($fileReferences)) {
$linkedContent = '';
foreach ($fileReferences as $fileReference) {
$description = $fileReference->getDescription();
if ($description !== null && $description !== '') {
$linkedContent .= htmlspecialchars($description) . '<br />';
}
}
$itemContent .= $parentObject->linkEditContent($linkedContent, $row);
unset($linkedContent);
}
}
$drawItem = false;
}
}
}
I get the errror:
Fatal error: Declaration of aaaa\bbb\Hooks\PageLayoutView\TextMediaCustomPreviewRenderer::preProcess(TYPO3\CMS\Backend\View\PageLayoutView &$parentObject, &$drawItem, &$headerContent, &$subheaderContent, &$itemContent, array &$row) must be compatible with TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface::preProcess(TYPO3\CMS\Backend\View\PageLayoutView &$parentObject, &$drawItem, &$headerContent, &$itemContent, array &$row) in /kunden/1111/rp-hosting/2222/333/typo3cms/projekt1/typo3conf/ext/my-sitepackage/Classes/Hooks/PageLayoutView/TextMediaCustomPreviewRenderer.php on line 23
What do I have to do to make it compatible with
TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface::preProcess(TYPO3\CMS\Backend\View\PageLayoutView &$parentObject, &$drawItem, &$headerContent, &$itemContent, array &$row)
You got it a bit wrong. You do not add the subheader in your process() arguments. In general, the arguments must be the same as the class that they extend. You can add the subheader inside the if ($row['CType'] === 'textmedia') {} by adding the value in the itemContent
$itemContent .= $row['subheader'];
Personally i would avoid to do it this way. My preferred choice is to call the StandAlone View and assign a template for preview. Is easier to maintain and program it.

Auto complete/Suggest in Wordpress Form

I'm placing a search form of 6 fields on my home page which includes a text box field named course. I want to show course suggestions while user typing. One more is, I want to show/hide some fields according to the option of first field dropdown. Any help would be appreciated.
You can use jQuery Auto Suggest which is included with WordPress : wp_enqueue_script
With this you can write a form that does a Ajax lookup to the the Ajax URL handler. Which you can add_action onto. AJAX in Plugins
So you can ajax lookup and then on the action side you can just perform a get_posts to match titles, or a raw sql Query. And return what is needed. edit your functions.php.
add_action('wp_enqueue_scripts', 'se_wp_enqueue_scripts');
function se_wp_enqueue_scripts() {
wp_enqueue_script('suggest');
}
add_action('wp_head', 'se_wp_head');
function se_wp_head() {
?>
<script type="text/javascript">
var se_ajax_url = '<?php echo admin_url('admin-ajax.php'); ?>';
jQuery(document).ready(function() {
jQuery('#se_search_element_id').suggest(se_ajax_url + '?action=se_lookup');
});
</script>
<?php
}
add_action('wp_ajax_se_lookup', 'se_lookup');
add_action('wp_ajax_nopriv_se_lookup', 'se_lookup');
function se_lookup() {
global $wpdb;
$search = like_escape($_REQUEST['q']);
$query = 'SELECT ID,post_title FROM ' . $wpdb->posts . '
WHERE post_title LIKE \'' . $search . '%\'
AND post_type = \'post_type_name\'
AND post_status = \'publish\'
ORDER BY post_title ASC';
foreach ($wpdb->get_results($query) as $row) {
$post_title = $row->post_title;
$id = $row->ID;
$meta = get_post_meta($id, 'YOUR_METANAME', TRUE);
echo $post_title . ' (' . $meta . ')' . "\n";
}
die();
}
Use ajax for both. You may have to write some mysql query to retrieve the required fields(post titles or whatever it is) from the table.

Zend Framework translate language text

I have some translation code which is working fine.
<?php echo $this->translate("54"); ?>
Outputs
Hello World
is it possible to output instead of above
<div class='lang' id='54'>Hello World</div>
Later using jquery I would like to manipulate the div.
create a custom view helper named MyTranslate extends \Zend\I18n\View\Helper\Translate then override the _invoke method :
public function __invoke($message, $textDomain = null, $locale = null)
{
$t = parent::__invoke($message, $textDomain , $locale);
//change the value of $t however you wnat
return $t;
}
if you don't what to change your code where ever you have used translate register this new view helper as translate and not my_translate
If you use Zend1, you can use a view helper like this:
Create a Helper directory in your library
for example, in my case I have this directory:
library/DoyDoy/Helper/
Create your helper like this:
library/DoyDoy/Helper/TranslateID.php
<?php
class DoyDoy_Helper_TranslateID extends Zend_View_Helper_Abstract
{
public function translateID($id)
{
return '<div class=\'lang\' id=\'' . $id . '\'>'. $this->view->translate($id) . '</div>';
}
}
Add your Helper in the bootstrap:
protected function _initDoyDoyView(){
$this->bootstrap('view');
$view = $this->getResource('view');
$view->addHelperPath('DoyDoy/Helper/', 'DoyDoy_Helper');
}
In your view, call the helper like this:
<?php echo $this->translateID("54");?>
This should display:
<div class='lang' id='54'>Hello World</div>
I hope it will help you :)

Zend Framework 2 form element error-class + custom ViewHelper to render form

This is my third question this week (and overall) - hope I don't get banned here :D
Anyway, searched around and couldn't find an exact explanation to solve my issue(s).
A. I've searched around and found a custom ViewHelper to render my forms. What it does is recursively get all fieldsets and when it gets to the element level, it goes like this:
public function renderElement($element) {
$html = '
<div class="row">' .
'<label class="col-md-12" for="' . $element->getAttribute('id') . '">' . $element->getLabel() . '</label>' .
$this->view->formElement($element) .
$this->view->FormElementErrors($element) .
'<div class="clearfix" style="height: 15px;"></div>';
return $html . PHP_EOL;
}
Form renders ok, except:
1) How can I add an error class to the form element? (like if I use formRow helper in my view, it automatically ads an 'input-error' class, while also keeping the initial class specified in my fieldset when creating the element - 'attributes' => array('class' => 'some-class')), so the element's class attribute becomes "some-class input-error" in case it's invalid.
2) How can I set a class for the 'ul' containing the error messages (the 'ul' rendered by $this->view->FormElementErrors($element))? Hope this is a one-liner and I don't have to go message-by-message and compose the html for the error messages list, but if not so be it (I don't know how to do that either).
B. Let's say that sometimes I don't use this custom ViewHelper to render my form. Zend's formRow view helper can be handy sometimes. This brings me to the following code in my view:
echo $this->formRow($this->form->get('user_fieldset')->get('user_name'));
I've noticed this automatically adds 'input-error' class on my element (in case it's invalid) which is perfect, BUT how can I also tell formRow to give a class to the 'ul' that's displaying the error messages?
I'd go even further and ask how I can turn this:
echo $this->formLabel($this->form->get('user_fieldset')->get('user_name'));
echo $this->formInput($this->form->get('user_fieldset')->get('user_name'));
echo $this->formElementErrors($this->form->get('user_fieldset')->get('user_name'), array('class' => 'form-validation-error'));
into something that ads an error-class to the element as well, not just to the error messages list, but if anyone answers to point A I think it's the same issue.
I've managed to do it like this:
public function renderElement($element) {
// FORM ROW
$html = '<div class="form-group">';
// LABEL
$html .= '<label class="form-label" for="' . $element->getAttribute('id') . '">' . $element->getLabel() . '</label>';
// ELEMENT
/*
- Check if element has error messages
- If it does, add my error-class to the element's existing one(s),
to style the element differently on error
*/
if (count($element->getMessages()) > 0) {
$classAttribute = ($element->hasAttribute('class') ? $element->getAttribute('class') . ' ' : '');
$classAttribute .= 'input-error';
/*
* Normally, here I would have added a space in my string (' input-error')
* Logically, I would figure that if the element already has a class "cls"
* and I would do $element->getAttribute('class') . 'another-class'
* then the class attribute would become "clsanother-class"
* BUT it seems that, even if I don't intentionally add a space in my string,
* I still get "cls another-class" as the resulted concatenated string
* I assume that when building the form, ZF2 automatically
* adds spaces after attributes values? so you/it won't have to
* consider that later, when you'd eventually need to add another
* value to an attribute?
*/
$element->setAttribute('class', $classAttribute);
}
$html .= $this->view->formElement($element);
/*
* Of course, you could decide/need to do things differently,
* depending on the element's type
switch ($element->getAttribute('type')) {
case 'text':
case 'email': {
break;
}
default: {
}
}
*/
// ERROR MESSAGES
// Custom class (.form-validation-error) for the default html wrapper - <ul>
$html .= $this->view->FormElementErrors($element, array('class' => 'form-validation-error'));
$html .= '</div>'; # /.form-group
$html .= '<div class="clearfix" style="height: 15px;"></div>';
return $html . PHP_EOL;
}
I'm not to fond of this, but I suppose there is no shorter way. I thought ZF2 shoud have something like:
if ($element->hasErrors()) { $element->addClass('some-class'); }
right out of the box. That's the answer I would have expected, that it would simply be a method I missed/couldn't find. But it turns out that ZF2 doesn't have quite anything in the whole world that you might need right out of the box, you end up having to write the (more or less) occasional helpers.
Anyway, if someone ever needs it here's the entire RenderForm view helper:
namespace User\View\Helper;
use Zend\View\Helper\AbstractHelper;
class RenderForm extends AbstractHelper {
public function __invoke($form) {
$form->prepare();
$html = $this->view->form()->openTag($form) . PHP_EOL;
$html .= $this->renderFieldsets($form->getFieldsets());
$html .= $this->renderElements($form->getElements());
$html .= $this->view->form()->closeTag($form) . PHP_EOL;
return $html;
}
public function renderFieldsets($fieldsets) {
foreach ($fieldsets as $fieldset) {
if (count($fieldset->getFieldsets()) > 0) {
$html = $this->renderFieldsets($fieldset->getFieldsets());
} else {
$html = '<fieldset>';
// You can use fieldset's name for the legend (if that's not inappropriate)
$html .= '<legend>' . ucfirst($fieldset->getName()) . '</legend>';
// or it's label (if you had set one)
// $html .= '<legend>' . ucfirst($fieldset->getLabel()) . '</legend>';
$html .= $this->renderElements($fieldset->getElements());
$html .= '</fieldset>';
// I actually never use the <fieldset> html tag.
// Feel free to use anything you like, if you do have to
// make grouping certain elements stand out to the user
}
}
return $html;
}
public function renderElements($elements) {
$html = '';
foreach ($elements as $element) {
$html .= $this->renderElement($element);
}
return $html;
}
public function renderElement($element) {
// FORM ROW
$html = '<div class="form-group">';
// LABEL
$html .= '<label class="form-label" for="' . $element->getAttribute('id') . '">' . $element->getLabel() . '</label>'; # add translation here
// ELEMENT
/*
- Check if element has error messages
- If it does, add my error-class to the element's existing one(s),
to style the element differently on error
*/
if (count($element->getMessages()) > 0) {
$classAttribute = ($element->hasAttribute('class') ? $element->getAttribute('class') . ' ' : '');
$classAttribute .= 'input-error';
$element->setAttribute('class', $classAttribute);
}
$html .= $this->view->formElement($element);
// ERROR MESSAGES
$html .= $this->view->FormElementErrors($element, array('class' => 'form-validation-error'));
$html .= '</div>'; # /.row
$html .= '<div class="clearfix" style="height: 15px;"></div>';
return $html . PHP_EOL;
}
}
User is my module. I've created a 'viewhelper.config.php' in it's config folder:
return array(
'invokables' => array(
'renderForm' => 'User\View\Helper\RenderForm',
),
);
and in Module.php:
public function getViewHelperConfig() {
return include __DIR__ . '/config/viewhelper.config.php';
}
Then, in your view simply call:
$this->renderForm($form);
Of course, if you don't have many view helpers, you could not create a separate config file just for that, leave Module.php alone and simply add:
'view_helpers' => array(
'invokables' => array(
'renderForm' => 'User\View\Helper\RenderForm',
),
),
to any configuration file.
I use getMessages() method to check if an element has an validation message. for eg.
<div class="form-group <?=($this->form->get('user_fieldset')->get('user_name')->getMessages())?'has-error':'';?>">
...
</div>
This question seems to be very old and you must have solved it by yourself. :)

Zend_navigation & Zend_translate href attribute dont switch with language change

I have a zend framework project with zend version 1.12.
I´m using zend_navigation with a xml file and zend_translation with the gettext adapter.
This code creates the main menu:
echo '<ul class="nav1">';
foreach ($this->container as $page) {
// check if it is active (not recursive)
$isActive = $page->isActive(false);
$liClass = $isActive ? ' class="active"' : '';
echo '<li ' . $liClass . '>' . $this->menu()->htmlify($page);
// subnavigation in second layer
if (sizeof($page) > 0) {
echo '<ul class="subNavHead">';
foreach ($page as $subpage) {
$isActive = $subpage->isActive(false);
$liClass = $isActive ? ' class="active"' : '';
echo '<li ' . $liClass . '>' . $this->menu()->htmlify($subpage) . '</li>';
}
echo '</ul>';
}
echo '</li>';
}
echo '</ul>';
And here is my language selector class:
class AW_Controller_Plugin_LangSelector extends Zend_Controller_Plugin_Abstract {
public function preDispatch(Zend_Controller_Request_Abstract $request) {
$lang = $request->getParam('lang', '');
if ($lang !== 'de' && $lang !== 'en' && $lang !== 'pl')
$request->setParam('lang', 'de');
switch ($request->getParam('lang')) {
case 'de':
$locale = 'de';
break;
case 'en':
$locale = 'en';
break;
case 'pl':
$locale = 'pl';
break;
default :
$locale = 'de';
break;
}
$zl = new Zend_Locale();
$zl->setLocale($locale);
Zend_Registry::set('Zend_Locale', $zl);
$translate = Zend_Registry::get('Zend_Translate');
$translate->setLocale($zl);
}
}
When I change the language with a select box the text on my site change the language, but the navigation targets don´t change. The navigationlabels changes too.
When I am in default language :
www.example.de/de/controller/action
And then I switch the language to English
-> the href attributes of my navigation are still on the old value (www.example.de/de/controller/action) but they should have www.example.de/en/controller/action
Where is my problem? Have I forget to re-render the menu?
I believe you are saying that the labels ('Home', 'Contact Us') are changing, but the links ('/', '/contact-us') aren't. The way Zend_Menu uses Zend_Translate only for the menu labels.
If your menu is created by MVC instead of URIs, you can make it take your language values by adding the line
$page->setParam('lang', Zend_Registry::get('Zend_Locale')->getLocale());
This would go in your navigation render, between "foreach ($page as $subpage) {" and "echo".
If your menu is using URIs, you can do a substitution on the page HREF at the same point.
Now, if I've misunderstood your question, and it's not translating links OR labels in the menu, then check and see if your menu is executing before your plugin's preDispatch.