Drupal programmatically remove JavaScript - javascript

I am trying to disable the JavaScript when the user is using IE. Is there a way to accomplish this in template.php or a custom module?

As alternative to handling the content of $vars['scripts'], which is a string containing the HTML to output in the <head> tag, you could use the value returned from drupal_add_js(NULL, NULL, 'header'), which is similar to the following one:
$header_javascript = array(
'core' => array(
'misc/jquery.js' => array(
'cache' => TRUE,
'defer' => FALSE,
'preprocess' => TRUE,
),
'misc/drupal.js' => array(
'cache' => TRUE,
'defer' => FALSE,
'preprocess' => TRUE,
),
),
'module' => array(),
'theme' => array(),
'setting' => array(
array('basePath' => base_path()),
),
'inline' => array(),
);
The "module" index contains the reference to the JavaScript files added from the modules, "settings" contains all the JavaScript settings generally added by the modules, and "inline" contains inline JavaScript code.
It could help if you need to distinguish between the different JavaScript files, and (for example) not touch any JavaScript file that has been marked as "core."
The counterbalance is that to populate the content of $vars['scripts'] you need to duplicate part of the code used from drupal_get_js(). As you would need a customized code, you would not duplicate all the code of that function, but you still would duplicate part of it.
In Drupal 7, the variable $vars['scripts'] is not passed anymore to template_preprocess_page() (and similar preprocess functions implemented by modules or themes); it is passed to template_preprocess_html().

You can use the preprocess_page() hook in template.php.
function YOUR_THEME_preprocess_page(&$vars) {
if (isset($_SERVER['HTTP_USER_AGENT']) && (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false)) {
$vars['scripts'] = 'get a mac!';
}
}
Obviously you should do something more intelligent with the $vars['scripts'] content :)

Related

Converting old wordpress shortcode plugin to block

I have an old wordpress plugin built to show latest posts of choice. The plugin uses a shortcode with options. Now I am converting the plugin little bit so that it can be used as a gutenberg block. I kept the php code intact and trying to create a block which will have some settings (right side setting box for block). I don't want to show the posts in block editor like other blocks instead I will just show the data in frontend. So in admin, nothing will be visible rather than a placeholder text and the settings. In plugin's init.php I have this code (Please ignore coding mistakes here, I just put some part to get the idea):
final class Dcposts {
function dcposts_block_assets() {
register_block_type(
'dc/block-dcposts', array(
'style' => 'dcposts-style-css',
'editor_script' => 'dcposts-block-js',
'editor_style' => 'dcposts-block-editor-css',
'render_callback' => array($this, 'mytest')
)
);
}
public function mytest($attributes) {
return '[some_shortcode]'; // I will generate a dynamic shortcode with $attributes
}
}
This works fine. If I add the block, it shows the posts front-end. But I get an error message in admin: "Updating failed. The response is not a valid JSON response."while saving the page with the block; and also the shortcode executes in admin. How can I prevent this? Is this the right approach I am on? Please give me some idea.
The error message "Updating failed. The response is not a valid JSON response." occurs when your render_callback function returns different content than the Gutenberg Edit() function. For dynamic blocks, the save() function should return null.
The ServerSideRender block is ideal for migrating/integrating existing PHP functions into a Gutenberg block.
You are on the right path with registering your block dc/block-dcposts in PHP. Next, add a ServerSideRender component in the Edit function of your block declaration in JavaScript, eg:
index.js
import { registerBlockType } from '#wordpress/blocks';
import { __ } from '#wordpress/i18n';
import ServerSideRender from '#wordpress/server-side-render';
/**
* Registering our block in JavaScript
*/
registerBlockType('dc/block-dcposts', {
title: __('DCPosts', 'dc'),
description: __(
'What DCPosts does..',
'dc'
),
category: 'layout',
icon: 'star-filled',
edit: () => {
return (
<ServerSideRender
block="dc/block-dcposts"
/>
);
},
save: () => { return null } // Dynamic blocks should return null to avoid validation error.
});
plugin.php (simplified example)
function dc_block_dcposts($attributes){
return '<div>Dynamically rendered content</div>';
}
function dc_block_dcposts_init(){
register_block_type( 'dc/block-dcposts', array(
'render_callback' => 'dc_block_dcposts',
) );
};
add_action( 'init', 'dc_block_dcposts_init' );
Once you have the basic setup working, the next step could be migrating any attributes your PHP function requires. The attributes need to be defined in the block setup and then passed in via the ServerSideRender component to be recieved by your PHP function.

Include .js file in SuiteCRM (v. >7) doesn't work

I'm new in SuiteCRM world. I'm trying to include a new .js file in a module but it seems doesn't work.
I seen that in Sugar version 6.5 for include a .js file it's enough to do something like that
$viewdefs[$module_name]['EditView']['templateMeta']['includes'] =
array (
array (
'file' => 'modules/demo_demo_form/demo.js',
),
);
I also read that in the newer version(7>) it's changed the way to include a .js file.
I tried different ways* but seems doesn't work.
$js_groupings[$module_name]['modules/demo_demo_form/demo.js'] =
'include/modules/demo_demo_form/demo.js';
Any suggestions?
I think my previous answer to another similar question will help you
First, include your custom JS in the editviewdefs.php (example for Accounts module)
'includes' =>
array (
0 =>
array (
'file' => 'modules/Accounts/Account.js',
'file' => 'custom/modules/Accounts/myCustomFile.js',
),
),
Create the custom JS file custom/modules/Accounts/myCustomFile.js .
function yourCustomFunction(formElement){
console.log(formElement);
}
Then update the field you want to monitor for changes (contractsigned_c in the example) using the following code in the editviewdefs.php:
array (
'name' => 'contractsigned_c',
'label' => 'LBL_CONTRACTSIGNED',
'displayParams' =>
array (
'updateCallback' => 'yourCustomFunction(this)',
),
),
Now do a Repair and Rebuild inside the Admin/Repair section and voilĂ  it should work :)
You can add the JS function on the function display() if you want, its the samething, the function will be called right after native combo update. It will look like this combo_contractsigned_c.update(); yourCustomFunction(this)

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

Add function to JSON object with php

Is there any way to add function to JSON object with php?
i have an array in php like this :
$aoData = array(
array('name' => 0, 'value' => "id"),
array('name' => 1, 'value' => "title"),
array('name' => 2, 'value' => "cat"),
array('name' => 3, 'value' => "img"),
array('name' => 4, 'value' => "des"));
and i want add a function like this:
array('name' => 5, 'value' => function(){return "hi"})
and use this function in my jquery.
is there any way for this?
Update
in data table i need to set aoColumnDefs in php.
"aoColumnDefs":
[{
"aTargets": [ img ],
"mData": "thumb_img",
"mRender": function ( data, type, full )
return '<img src="../up/thumb/'+data+'">';
},
{etc}
]
so i need set function as a Json function or another way ...
JSON does not allow function definition for security and compatibility reasons, and as a proof, I don't see any other way than storing a string and use a form of eval (that is using eval or creating a Function with a body). I'd strongly recommend not to do it though.
In order for it to be JSON, and for any JSON library to work with it, no, it is not possible.
JSON is a language and platform independent, portable data serialization scheme and, therefore, has a limited set of things which can be represented within. Functions, given that they are language and platform specific, are not portable.
It is possible to use PHP to "manually" output a JavaScript object which has methods:
<?php
$foo = '{name: 5, value: function () { return "hi";}}'
?>
var js_object = <? echo $foo; ?>;
This is messy and error prone, however, and would not be JSON.
So yeah...
JS Object is not the same as JSON.
Some libs or frameworks will want to add functions to the JS Object.
For example primevue has a menu structure with functions in the Object:
const items = {
label: 'New',
icon: 'pi pi-plus',
command: (event) => {
// event.originalEvent: Browser event
// event.item: Menuitem instance
}
}
;
Nice, but what if you want this data provided from DB via php...?
this works:
const func = 'items.command = function(event){ console.log(event) }'
eval(func)
So we could do something with this.
This means doing something with the JSON when it is loaded into Javascript and turn some strings into functions with eval.
This is of course a security risk.
But somehow we'll need to change the JSON into a JS Object.
Better maybe is to not have info of the end platform in the DB.
The solution I'm using is that I'm pre-defining what commands can be added to the JS Object and use codes to tell the reader what I want added.
switch (add) {
case '[login]':
items.command: () => {
auth.destroyToken()
this.$router.push({ name: 'login' })
}
break;
}
Not as "free", but for security that's a good thing.
You can't add the function as value, but you can add the return value of the function as value of the json object.
So in the example you gave, the value will just be "hi" (if you type return correctly).
I don't see the reason for adding a function into a JSON object, because you can probebly do the same with JQuery and if you can't then use AJAX to get results from the serverside.

Pass $(this) into a CakePHP styled script using jquery helper

Please forgive me if this has ever been asked before, it's very hard to search for since the operative word is 'this'.
I have a click event bound to a set of divs with the same class, each one needs the same behavior. In jQuery, I would simply use $(this) to reference the clicked element. I can't seem to figure out how to get CakePHP to use $(this) as the update element.
My code: (the 'update' param is the one in question)
$this->Js->get('.bookmark')->event('click',
$this->Js->request(
array('controller' => 'bookmarks', 'action' => 'add', $event['Event']['id']),
array('async' => true, 'update' => 'this')
)
);
Thank you
My personal opinion - don't use the CakePHP JsHelper. Don't get me wrong, I love CakePHP and am a CakePHP fanboy, but - in some cases it's just easier to use the "normal" way.
As an example, the HTML helper can create divs too, but I've never found the reason to use it over just typing <div>.
I've used this before for select lists (I modified it for your example, so I'm not 100% sure it works), I don't see why it wouldn't work for click
Put this at the bottom of the view
$this->Js->get('#addBookmarkDiv')->event('click', //put the div name that contains the input you're checking to see if it's clicked
$this->Js->request(array(
'controller'=>'bookmarks',
'action'=>'add'
), array(
'update'=>'#putdivhere', //div you want to update, possibly a div that displays bookmarks?
'async' => true,
'method' => 'post',
'dataExpression'=>true,
'data'=> $this->Js->serializeForm(array(
'isForm' => false,
'inline' => true
))
))
);
Now, in your controller do what you have to do, and add the following
function add(){
//do what ever it is you want to do with the sent data
$this->set('bookmarks',$bookmarks);
$this->layout = 'ajax';
}
Then, create a view for add with something like.
//add.ctp
<?php foreach ($bookmarks as $bookmark): ?>
<li><?php echo $bookmark; ?></li
<?php endforeach; ?>
Well, it looks like I was overlooking that fact that I could embed javascript in the JsHelper functions. That and the fact that $(this) is out of scope inside the $.ajax function. So, this is the solution that worked for me. As you can see, the second parameter to the event method is a mixture of javascript and PHP, and it's strung together in the first instance using concatenation.
$this->Js->get('.bookmark')->event('click',
'var el = $(this);'.
$this->Js->request(
array('controller' => 'bookmarks', 'action' => 'add', $event['Event']['id']),
array('async' => true, 'complete' => '$(el).addClass("bookmarked")')
)
);

Categories