Symfony & Sonata : How to add javascript to entity admin form? - javascript

New to Symfony & Sonata I created an entity "Foo" with the associated App\Admin class :
<?php
namespace App\Admin;
final class FooAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('Zorg', ['class' => 'col-md-4'])
->add('name', TextType::class)
->end();
}
...
}
Everything works fine.
I can access the list, add and edit Foo.
I now would like to add a javascript script in the add and edit forms.
How can I do that? May I have to use assets and Encore?
Is there another/best way?
Thank you for your help

If you are using Encore then below should work:
# config/packages/sonata_admin.yaml
sonata_admin:
assets:
extra_stylesheets:
- build/app.css
extra_javascripts:
- build/runtime.js
- build/app.js

Related

using smarty template engine in registered javascript files with prestashop 1.7

I'm writing Prestashop 1.7.2.1 module.
In that module when I want to register a javascript file I connect to the hook actionFrontControllerSetMedia and use registerJavascript like so:
$this->context->controller->registerJavascript('module-tuxinmodcartype-carsearch-js','modules/'.$this->name.'/js/displaytop.js');
this loads the javascript properly but I can't use smarty template engine in those javascript files.
is there a way to do that ? :)
if not... should I just add all my javascript files inline ?
update
so I added this to my hook function:
Media::addJsDef(['tuxinmodcartype'=>array(
'car_companies'=>$this->tuxDb->getCompanyNamesArray()
)]);
and this my js file:
$(function() {
var options = {
data: tuxinmodcartype.car_companies,
list: {
match: {
enabled: true
}
}
};
$('#company-name-input').easyAutocomplete(options);
});
and I get the error ReferenceError: tuxinmodcartype is not defined
For accessing variables in javascript you can assign them in your controllers with:
Media::addJsDef(array(
'mymodule' => array(
'var1' => 'yes',
'var2' => 'no'
)
));
Then you can use them in your javascript or through console:
let var1 = mymodule.var1;
let var2 = mymodule.var2;
Building javascript files with smarty... I guess it's better to split javascript into more files and load them through controller based on conditions. Or use the above definition for variables to control execution path in your javascript.
Safer way to declare your vars without mymodule array,
Media::addJsDef(array('var1' => $myphpvar));
Media::addJsDef(array('var2' => $myphpvartwo));
this way you DONT need
let var1 = mymodule.var1;
Why this better? Because 'let var1' cause error in iphone safari browser.
You can simply do this in the tpl file:
<script>var = '{$var}';</script>
and use your var in the javascript file.
Source: https://www.prestashop.com/forums/topic/589645-unknown-tag-addjsdef-error/?tab=comments#comment-2490210

Liferay 7 CE - Osgi module (liferay mvc portlet) not load javascript files

I created a new liferay osgi module.
My controller has the following tag :
#Component(
immediate = true,
property = {
"com.liferay.portlet.display-category=Bla Modules",
"com.liferay.portlet.instanceable=true",
"javax.portlet.display-name=EventCalendar",
"javax.portlet.init-param.template-path=/",
"javax.portlet.expiration-cache=0",
"com.liferay.portlet.footer-portlet-javascript=fullcalendar_year.js,/js/custom/main.js",
"com.liferay.portlet.header-portlet-css=/css/fullcalendar_year.css,/css/fullcalendar.css",
"javax.portlet.init-param.view-template=/view.jsp",
"javax.portlet.resource-bundle=content.Language",
"javax.portlet.security-role-ref=administrator,power-user,user"
},
service = Portlet.class
However the property
com.liferay.portlet.footer-portlet-javascript
is not loading all js files, it only loades the files if only one is called, if it is more than one nothing is loaded.
Is this a bug or i am doing something wrong?
Finally i found the solution.
It must be declared in separate lines.
property = {
"com.liferay.portlet.display-category=XXXXAA Modules",
"com.liferay.portlet.instanceable=true",
"javax.portlet.display-name=XXXXAA",
"javax.portlet.init-param.template-path=/",
"javax.portlet.expiration-cache=0",
"com.liferay.portlet.footer-portlet-javascript=/js/moment.min.js",
"com.liferay.portlet.footer-portlet-javascript=/js/fullcalendar_year.js",
"com.liferay.portlet.footer-portlet-javascript=/js/calendarLanguages/pt.js",
"com.liferay.portlet.footer-portlet-javascript=/js/custom/main.js",
"com.liferay.portlet.header-portlet-css=/css/fullcalendar_year.css,/css/fullcalendar.css",
"javax.portlet.init-param.view-template=/view.jsp",
"javax.portlet.resource-bundle=content.Language",
"javax.portlet.security-role-ref=administrator,power-user,user"
}

Where to Include Sugarcrm

I have been working on some custom code for a sugar module and am fairly unclear where to put my javascript code to be called in module.
Currently I have put my custom JS in include/javascript/popup_parent_helper.js
This works fine in developer mode but does not work when that is turned off and unfortunately dveloper mode runs SUPER slow
I have done a lot of research and I am getting some conflicting results.
Some tell me that I should include it in:
/modules/[ModuleName]/
Others say that it should to in:
/custom/modules/[ModuleName/
and some further in adding js as a directory
Please help me clarify proper structure for this and where I need to make my proper include statement
Clarifications:
We are using SugarCrm 6.5x
In this case the JS is only being used for one module.
It is being used in the Quick Create View and the Edit View
If the javascript should be accessible by any module, you can create a new JSGrouping and pull in your custom js file using the following technique:
http://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_7.6/Extension_Framework/JSGroupings/#Creating_New_JSGroupings
It sounds like you want it to be isolated to your custom module, so you should probably extend the view desired. If you are extending the record view, create a new file called record.js at custom/modules/-your_module-/clients/base/views/record/
({
extendsFrom: 'RecordView',
initialize: function(options) {
this._super('initialize', [options]);
this.doSomething();
},
doSomething: function(){
console.log("Help you I will");
},
...
})
https://developer.sugarcrm.com/2014/02/10/extending-sugar-7-record-view/
I had also faced similar issue (JS should be work for edit and quickcreate form) but after making some RnD I achieved it as per following way:
\custom\modules\<modulename>\views\view.edit.php
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
require_once('include/MVC/View/views/view.edit.php');
class {moduleName}ViewEdit extends ViewEdit {
public function __construct() {
parent::ViewEdit();
$this->useForSubpanel = true; // this variable specifies that these changes should work for subpanel
// / $this->useModuleQuickCreateTemplate = true; // quick create template too
}
function display(){ ?>
<?php
$jsscript = <<<EOQ
<script>
Your JS code
</script>
EOQ;
parent::display();
echo $jsscript; //echo the script
}
}
?>

Models in Zend Framework

I am new to zend framework. I have created "models" folder in application directory. Inside models folder I created a class Application_Models_Albums which extends Zend_Db_Table_Abstract.
Now when I use the following code in IndexController. I get error:
$albums = new Application_Models_Albums();
$this->view->albums = $albums->fetchAll();
Error: Fatal error: Class 'Application_Models_Albums' not found in
H:\Documents\IIS Server
Root\localhost\learning\zf1\application\controllers\IndexController.php
on line 13
Please help. How can I load models in zend framework?
You need to name your model Albums. and save in models/albums.php
The auto-loader will figure out where to load it from by the name. so even though the model is named albums, you call it by new Application_Models_Albums()
The autoloader find it in application/models/albums.php
similarly the Zend_Db_Table_Abstract class is located in Zend/Db/Table/Abstract.php
edit
IF you cant get the autoloader to work, you can do it the quick and easy way by just adding models/ to your include path. I've done this before and it works fine.
Something like set_include_path(get_include_path().PATH_SEPERATOR."models/") in your index.php
Your model class name should be Application_Model_Albums - with Model in singular.
See http://framework.zend.com/manual/en/zend.loader.autoloader-resource.html for more info on Zend Autoloader.
you need to require your model class-
require_once 'PathToModel\Application_Models_Albums.php';
some people create autoloader classes to deal with this, YMMV
It sounds like your Bootstrap or application.ini needs to specify the namespace as 'Application_'.
In Bootstrap.php:
protected function _initAutoloader()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
'basePath' => APPLICATION_PATH,
'namespace' => 'Kwis_',
));
return $autoloader;
}
Alernatively, in configs/application.ini:
appnamespace = "Application_"
You could also extend Zend_Controller_Action and add a method like this:
protected $_tables = array();
protected function _getTable($table)
{
if (false === array_key_exists($table, $this->_tables)) {
require_once(APPLICATION_PATH.'/modules/'.$this->_request->getModuleName().'/models/'.$table.'.php');
$this->_tables[$table] = new $table();
}
return $this->_tables[$table];
}

updating javascript in the body tag using zend framework

Hi not sure if this is possible or not but I want to programaticaly update the <body> tags to change the onload function in my zend framework application.
The App is using layouts so the body tag currently looks like this <body class="trandra">
However in one of my views I have a map from google being loaded and it needs the following in the body tag this particular view <body onload="initialize()" onunload="GUnload()">
As you can understand I don't want this to be hardcoded in my layout as this will cause all matter of nightmares with the different views.
How can this be done programaticaly, if at all it is possible? Im using the headScript functions to add the javascript so is there an equivalant for the body tag?
Thanks in advance...
Approach one - Use a layout variable
One idea would be the following:
<body class="trandra" <?php echo $this->layout()->bodyScripts ?>>
And in your view:
<?php
$this->layout->bodyScripts =
'onload="initialize()" onunload="GUnload()"';
Approach two - Additional JS-file that adds event handlers
Another approach, which is less obtrusive and doesn't affect the HTML whatsoever is to add an additional JS-file in the view that requires the onload- and onunload-handlers. It could look something like this:
<?php
$this->headScript()->appendScript(
'/path/to/javascripts/loadGMaps.js');
In your loadGMaps.js (using prototype)
Event.observe(window, 'load', function onLoadHandler() {
// Code for initializing Google maps here
});
Event.observe(window, 'unload', function onUnloadHandler() {
// Code for unloading Google maps here
});
Instead of putting your Javascript directly in the code, you could also use an non-obstrusive approch : plugging in the javascript when the page is fully loaded.
Have a look, for instance, at a function called addOnLoadEvent (can be found on many websites ^^ )
If you are using a JS Framework, it certainly has that kind of feature :
for jQuery : http://docs.jquery.com/Events/ready#fn
for prototype : http://www.prototypejs.org/api/event/observe
If you register the "plugging-in" with headScript, there should be no need to modify the tag directly.
Developed something like this recently, I've blogged about it here: http://www.evilprofessor.co.uk/311-zend-framework-body-tag-view-helper/
Demo on site and code is available via github.
I'm no expert on the Zend framework, so I don't know if there is any build in functions for this, but you could do something like this:
In layout-file:
body_params?>>
And then in your controller, you set or add to the body_params:
$this->view->body_params='onload="initialize()" onunload="GUnload()"';
I know this is an old thread, but I was looking through some of the suggested solutions and came up with one of my own playing off of some of the ideas I had seen. What I did was I extended Zend_View in my own library files (I'm using a vanilla MVC layout but similar things can be done using a bootstrap.php rather than the Bootstrap class described below)
class Custom_View extends Zend_View
{
protected $bodyAttrs = array();
public function _setBodyAttr($attrName,$attrValue=null) {
$attrName = strtolower(strval($attrName));
if(!(in_array($attrName, HTML::getValidBodyAttrs()))) {
throw new Zend_Exception(__METHOD__." attrName '$attrName' is not a valid BODY attribute!");
}
$this->bodyAttrs[$attrName] = strval($attrValue);
}
public function _getBodyAttrsAsString() {
$bodyAttrs = "";
if(count($this->bodyAttrs) > 0) {
$attrs = array();
foreach($this->bodyAttrs as $_k => $_v) {
array_push($attrs,sprintf("%s=\"%s\"", $_k, $_v));
}
$bodyAttrs = " " . implode(" ", $tags);
}
return $bodyAttrs;
}
}
// some useful tag definitions for HTML
class HTML
{
// HTML attributes as described by W3C
public static $BODY_ATTRIBUTES = array('alink','background','bgcolor','link','text','vlink');
public static $GLOBAL_ATTRIBUTES = array('accesskey','class','contenteditable','contextmenu','dir','draggable','dropzone','hidden','id','lang','spellcheck','style','tabindex','title');
public static $WINDOW_EVENT_ATTRIBUTES = array('onafterprint','onbeforeprint','onbeforeunload','onerror','onhaschange','onload','onmessage','onoffline','ononline','onpagehide','onpageshow','onpopstate','onredo','onresize','onstorage','onundo','onunload');
public static $MOUSE_EVENT_ATTRIBUTES = array('onclick','ondblclick','ondrag','ondragend','ondragenter','ondragleave','ondragover','ondragstart','ondrop','onmousedown','onmousemove','onmouseout','onmouseover','onmouseup','onmousewheel','onscroll');
public static $KEYBOARD_EVENT_ATTRIBUTES = array('onkeydown','onkeypress','onkeyup');
public static $FORM_EVENT_ATTRIBUTES = array('onblur','onchange','oncontextmenu','onfocus','onformchange','onforminput','oninput','oninvalid','onreset','onselect','onsubmit');
public static $MEDIA_EVENT_ATTRIBUTES = array('onabort','oncanplay','oncanplaythrough','ondurationchange','onemptied','onended','onerror','onloadeddata','onloadedmetadata','onloadstart','onpause','onplay','onplaying','onprogress','onratechange','onreadystatechange','onseeked','onseeking','onstalled','onsuspend','ontimeupdate','onvolumechange','onwaiting');
public static function getValidBodyAttrs() {
return array_merge(self::$BODY_ATTRIBUTES,self::$GLOBAL_ATTRIBUTES,self::$WINDOW_EVENT_ATTRIBUTES,self::$MOUSE_EVENT_ATTRIBUTES,self::$KEYBOARD_EVENT_ATTRIBUTES);
}
}
after creating this file I added a method _initView to the Bootstrap.php file pointed to by the index.php and application.ini at the root of the application directory:
protected function _initView()
{
// Custom_View extends Zend_View
$view = new Custom_View();
// Add it to the ViewRenderer
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper( 'ViewRenderer' );
$viewRenderer->setView($view);
return $view;
}
The new, extended Zend_View now allows adding your body tags along with some simple checking for validity. Modify your layout's body tag to get the attributes:
<body<?= $this->_getBodyAttrs(); ?>>
Once you have this set up you can add your body tags to any given view
in the controller with
$this->view->_setBodyAttr('key','val');
or in the view with
$this->_setBodyAttr('key','val');

Categories