Creating a new TinyMCE form widget - forms

I'm using tinyMCE in my forms and have noticed that I only use two configurations : a very limited one, for things like comments, and a more complex one, for the administators of the site.
For the moment I do that by repeating this sort of code in each form :
//TinyMCE
$this->widgetSchema['comment'] = new sfWidgetFormTextareaTinyMCE(array(
'width' => 550,
'height' => 150,
'config' => '
theme_advanced_buttons1 : "bold,italic,separator,bullist,separator,link, sub,sup,separator,charmap",
theme_advanced_buttons2 : "",
theme_advanced_buttons3 : "",
theme_advanced_path : false,
language : "fr"
'
));
Could I (and how) create two widgets, say TinyMCEsmall and TinyMCEfull so that I don't have to repeat code ?

Like this:
class sfWidgetFormTextareaTinyMCESmall extends sfWidgetFormTextareaTinyMCE
{
protected function configure($options = array(), $attributes = array())
{
parent::configure($options, $attributes);
//assuming there are no options on the parent class that you need, call setOptions. If you need to retain some, make individual setOption calls.
$this->addOption('width', 550);
$this->addoption('height', 150);
$this->addOption('config', '
theme_advanced_buttons1 : "bold,italic,separator,bullist,separator,link, sub,sup,separator,charmap",
theme_advanced_buttons2 : "",
theme_advanced_buttons3 : "",
theme_advanced_path : false,
language : "fr"
');
}
}
Note that options you pass in will still take precedence.

sure, create a class that extends the sfWidgetFormTextareaTinyMCE and put your specifics in its constructor.
put it in let's say a var called myTinyMCE
and call at last in the constructor the parent::constructor(myTinyMCE)
where you give the setup as a parameter.
then in the form don't call the sfWidgetFormTextareaTinyMCE anymore, but your class you created...
class myClass extends sfWidgetFormTextareaTinyMCE {
public class __construct(){
myTinyMCE = array(
'width' => 550,
'height' => 150,
'config' => '
theme_advanced_buttons1 : "bold,italic,separator,bullist,separator,link, sub,sup,separator,charmap",
theme_advanced_buttons2 : "",
theme_advanced_buttons3 : "",
theme_advanced_path : false,
language : "fr"
'
);
parent::__construct(myTinyMCE);
}
}
more info on that can be found here How do I get a PHP class constructor to call its parent's parent's constructor

Related

Sysmfony 4.4 - Testing form with 'contraints' in options of TimeType generate an UndefinedOptionsException

I made a form in Symfony 4.4 with a TimeType field defined like this :
$builder
->add('planned_start', TimeType::class, [
'widget' => 'single_text',
'empty_data' => '',
'constraints' => [
new NotBlank([
'message' => 'worksheet.worker.planned_start.required_error'
])
]
])
Functional tests of my controller work perfectly and return the defined error if no valid is given.
But,when I'm testing the form directly, I get the following exeception like I can't put any constraint on the TimeType field
Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException: An error has occurred resolving the options of the form "Symfony\Component\Form\Extension\Core\Type\TimeType": The option "constraints" does not exist. Defined options are: "action",
"allow_file_upload", "attr", "attr_translation_parameters", "auto_initialize", "block_name", "block_prefix", "by_reference", "choice_translation_domain", "compound", "data", "data_class", "disabled", "empty_data", "error_bubbling", "help",
"help_attr", "help_html", "help_translation_parameters", "hours", "html5", "inherit_data", "input", "input_format", "label", "label_attr", "label_format", "label_translation_parameters", "mapped", "method", "minutes", "model_timezone", "placeholder",
"post_max_size_message", "property_path", "reference_date", "required", "row_attr", "seconds", "translation_domain", "trim", "upload_max_size_message", "view_timezone", "widget", "with_minutes", "with_seconds".
/var/www/vendor/symfony/form/ResolvedFormType.php:99
/var/www/vendor/symfony/form/FormFactory.php:76
/var/www/vendor/symfony/form/FormBuilder.php:94
/var/www/vendor/symfony/form/FormBuilder.php:244
/var/www/vendor/symfony/form/FormBuilder.php:195
/var/www/vendor/symfony/form/FormFactory.php:30
/var/www/tests/Form/WorksheetWorkerFormTypeTest.php:39
Here is how I test the form :
<?php
namespace App\Tests\Form\Type;
use App\Form\Type\TestedType;
use App\Form\WorksheetWorkerFormType;
use Doctrine\Persistence\ObjectManager;
use Symfony\Component\Form\PreloadedExtension;
use Symfony\Component\Form\Test\TypeTestCase;
// ...
class WorksheetWorkerFormTypeTest extends TypeTestCase
{
private $objectManager;
protected function setUp()
{
// mock any dependencies
$this->objectManager = $this->createMock(ObjectManager::class);
parent::setUp();
}
protected function getExtensions()
{
// create a type instance with the mocked dependencies
$type = new WorksheetWorkerFormType($this->objectManager);
return [
// register the type instances with the PreloadedExtension
new PreloadedExtension([$type], []),
];
}
public function testMinimal()
{
$form = $this->factory->create(WorksheetWorkerFormType::class);
$form->submit([
'planned_start' => '08:00',
'planned_end' => '16:00'
]);
$this->assertTrue($form->isValid());
}
}
Any Idea ?
Thanks

tinymce adding p tags automatically?

Im using tinymce and saving it to a database.
When I edit the saved content using tinymce and save again, it inserts a p tag at the beginning.
Editing the content over and over again leaves a large gap at the beginning of the content.
DOes anyone know a fix?
TinyMce automatically add "<p>" in new lines.
You can set this option in tinyMce initialization like this:
tinyMCE.init({
mode : "textareas",
theme : "advanced",
force_br_newlines : false,
force_p_newlines : false,
forced_root_block : '',
});
Hope it will help
Fonski
For me it worked by making "force_br_newlines : true" instead of false.
tinyMCE.init({
mode : "textareas",
theme : "advanced",
force_br_newlines : true,
force_p_newlines : false,
forced_root_block : ''
});
I hope it helps
I am sure that #Fonski answer is correct but thought I would update this for anyone else that did was confused as to where to put the code. I placed the following in my _config.php file to get it to work:
$defaultEditorConfig = HtmlEditorConfig::get('cms');
$defaultEditorConfig->setOptions(
array(
'mode' => 'textareas',
'theme' => 'advanced',
'force_br_newlines' => false,
'force_p_newlines' => false,
'forced_root_block' => ''
)
);
Note: If you just want to remove the p tag that automatically wraps image tags (etc) all you need to set is the 'forced_root_block' => '' option.
EDIT: This advice is for those using SilverStripe, I posted this thinking the questions was SilverStripe specific.
From tinymce.js v4.1.10 code:
newBlockName = (settings.force_p_newlines ? 'p' : '') || settings.forced_root_block;
So the key to avoid <p> seems to be as stated before
settings.force_p_newlines = false
and
settings.forced_root_block = ''

CKeditor : Configure plugin through CKeditor's configuration

I'm looking for any trick to configure my plugin with arguments in CKEditor's configuration. I have to pass some parameters that I can only pass when my view is displayed.
I want something like this (sample with jQuery adapter) :
jQuery('textarea.wysiwyg').ckeditor(function(){},{
'width' : '640px',
'resize_maxWidth' : '640px',
'extraPlugins' : 'my_plugin',
'toolbar' : [['Bold', 'Italic', '-', 'NumberedList', 'BulletedList'],['Link', 'Unlink','-','MyPlugin'],['Paste','PasteFromWord'],['Source']]
'my_plugin' : {
'param1' : 'value1',
'param2' : 'value2',
}
});
But I have'nt found yet any information about plugin configuration with CKEditor.
I answer to my own question :
Plugin method init receive editor as argument, editor contain config (which can be called editor.config) so you can access all configuration defined when you have created your ckeditor instance.
With my sample in my first post, you can access configuration in your plugin like this way :
CKEDITOR.plugins.add( 'my_plugin',
{
init: function( editor )
{
var param1 = editor.config.value1;
}
}
I think that it's not the best way to do because It adds some extra properties to CKEDITOR.config prototype. It could be better to have a property CKEDITOR.config.extraConfig which is a map of properties by plugins.
Pass the values to the plugin during editor initialization
jQuery('textarea.wysiwyg').ckeditor(function(){},
{
config.extraConfig : { 'param1' : 'value1', 'param2' : 'value2' }
});
and access the values in the plugin
CKEDITOR.plugins.add( 'my_plugin',
{
init: function( editor )
{
var param1 = editor.extraConfig.param1;
var param2 = editor.extraConfig.param2;
}
}

Lithium: Remove related documents in a remove-Filter of a model

I have a Games model which hasMany Avatars and Agents. When i remove the game, i want to clean up all the remaining data, so i also want to remove all Avatars and Agents with the corresponding game_id:
namespace app\models;
use app\models\Avatars;
use app\models\Agents;
class Games extends \lithium\data\Model
{
public static function __init($options = array()) {
parent::__init($options);
$self = static::_instance(__CLASS__);
Games::applyFilter('remove', function($self, $params, $chain) {
$conditions = array( 'game_id' => $params['conditions']['_id'] );
$message = new \app\extensions\helper\Message();
$debugString = var_export($conditions, true);
$message->addDebugMessage("params:{$debugString}");
//Output:
//params:array ( 'game_id' => '4f301f69a170c8cf52000002', )
if(!Agents::remove($conditions)) { $message->addErrorMessage('Es konnten nicht alle Agents geloescht werden.'); };
if(!Avatars::remove($conditions)) { $message->addErrorMessage('Es konnten nicht alle Avatare geloescht werden.'); };
return $chain->next($self, $params, $chain);
});
}
}
Though the game gets removed, agents and avatars remain in the MongoDB.
Does someone have a hint on this?
Example of agent in db
>db.agents.find()
{ "_id" : ObjectId("4f301f71a170c8391f000000"), "game_id" : ObjectId("4f301f69a170c8cf52000002"), "type" : "army", "subtype" : "deer", "units" : 5, "xPos" : 5, "yPos" : 5 }
I'd have to look, but I don't think remove() casts values. You'd need to do:
$conditions = array( 'game_id' => new MongoId($params['conditions']['_id']));

Changing the height of ckeditor from a zend form

I am trying to set the height of a ckeditor I am using. Here is what I currently have:
$this->addElement('textarea', 'text_field', array(
'filters' => array('StringTrim'),
'validators' => array(
array('StringLength', true, array(0, 3000)),
),
'decorators' => array('ViewHelper'),
'required' => false,
'attribs' => array('class' => 'ckeditor'),
'label' => 'Please enter text below',
'value' => isset($this->_text_data[0]['text']) ? $this->_text_data[0]['text'] : ''
));
This comes from my form, this is then called in my .phtml file by the following:
<?=$this->element->getElement('text_field')?>
I have looked everywhere and tried adding:
'height' => '100px',
and:
'config' => array(
'toolbar' => 'Full',
'width' => '550px',
'height' => '100px',
),
But neither of these have worked. The main reason I need this is I have a text area (using the ckeditor in order to allow the input information to be formatted in a particular way) which is quite long (the default height I am assuming) but it is only ever a few lines input into the box, hence the reason I want it smaller as it takes up too much space on the page.
Thanks in advance
Iain
I made a form element and a helper using ZendX_JQuery_View_Helper_UiWidget to create a CKEditor with the jQuery adapter. Here's the code of both files :
ZendExt_Form_Element_CKEditor :
class ZendExt_Form_Element_CKEditor extends ZendX_JQuery_Form_Element_UiWidget
{
/**
* Use formCKeditor view helper by default
* #var string
*/
public $helper = 'formCKEditor';
/**
* Default ckeditor options
*
* #var array
*/
public $jQueryParams = array(
'toolbar' => 'Basic'
);
}
And ZendExt_View_Helper_FormCKEditor :
class ZendExt_View_Helper_FormCKEditor extends ZendX_JQuery_View_Helper_UiWidget
{
static $set = false;
public function formCKEditor($name, $value = null, $params = null, $attribs = null)
{
$hTextA = new Zend_View_Helper_FormTextarea();
$hTextA -> setView($this -> view);
$xhtml = $hTextA -> formTextarea($name, $value, $attribs);
$xhtml .= '<script type="text/javascript">$(document).ready(function(){$("#' . $this->_normalizeId($name) . '").ckeditor(' . (!is_null($params) ? 'function(){},' . Zend_Json_Encoder::encode($params) : '') . ')});</script>';
if (self::$set == false) {
$this -> view -> headScript() -> appendFile($this -> view -> baseUrl() . '/js/ckeditor/ckeditor.js');
$this -> view -> headScript() -> appendFile($this -> view -> baseUrl() . '/js/ckeditor/adapters/jquery.js');
self::$set = true;
}
return $xhtml;
}
}
You can use it as any other ZF form element once you copied these 2 files into :
* libraries/ZendExt/Form/Element/ for ZendExt_Form_Element_CKEditor class
* libraries/ZendExt/View/Helper/ for ZendExt_View_Helper_FormCKEditor class
and added the ZendExt namespace in your configuration file (or if you already have a library of yours and want to use it, just put both files in it and change the name of the classes to reflect yours). Then, you'll have tel ZF that ZendExt/View/Helper is a directory to look in for view helpers (in a .ini config file it would look like : resources.view.helperPath.ZendExt_View_Helper = "ZendExt/View/Helper").
Then in your code, just call $ckEditor = new ZendExt_Form_Element_CKEditor(); to create a new CKEditor. You may then add all params you want to the element using $ckEditor -> setJQueryParam($key, $value); as specified in the documentation here : http://framework.zend.com/manual/fr/zendx.jquery.html . For example : $ckEditor -> setJQueryParam('height', '100px');. I understand it's not a jQuery component, but it was the easiest way to be able to make it as everything needed is available there.
To display it, in your view just do <?=$this -> ckEditor?> and you're good.
Make sure you put your ckeditor.js and adapters/jquery.js in your public directory under /js/ckeditor/ or change the path accordingly in the helper.
You'll need to specify the dimensions of the editor when you create it (i.e., in the Javascript part). CKEditor replaces the original form element with its own code, so your changes in the dimensions will be lost.
For instance, if you create it using the jQuery interface, it would be something like the following:
var config = {
width: '550px',
height: '100px'
};
// Initialize the editor.
$('.jquery_ckeditor').ckeditor(config);
Hope that helps...