Added options in Highcharts download/context buttons get repeated - button

I am adding a few options to my download/export/context buttons in Highcharts. However, the process is a bit complex, as this works as an API. A call is being received by one file, another file is being called where all the options for the graph is being produced, it comes back to the first file, where the graph is generated. Here, the additional options are introduced into the context buttons:
function drawGraph(selectedID, selectedCountries, selectedYears, per_capita, graphBorder, graphSource, graphDefinition, graphStyle, graphXAxis, renderToGraph, renderToDescription)
{
jQuery(document).ready(function() {
var options = {};
url = "xxx.com";
jQuery.getJSON(url, {selectedCountries: selectedCountries , selectedID: selectedID, selectedYears: selectedYears, per_capita: per_capita, graphBorder: graphBorder, graphSource: graphSource, graphDefinition: graphDefinition, graphStyle: graphStyle, graphXAxis: graphXAxis, renderToGraph: renderToGraph, type: "jsonp"})
.done(function(data)
{
//console.log(data);
options.chart = data["chart"];
options.tooltip = data["tooltip"];
options.series = data["series"];
options.title = data["title"];
options.subtitle = data["subtitle"];
options.yAxis = data["yAxis"];
options.xAxis = data["xAxis"];
options.legend = data["legend"];
options.exporting = data["exporting"];
options.plotOptions = data["plotOptions"];
options.credits = data["credits"];
if ((graphDefinition == "true") || (graphDefinition == "on"))
{
jQuery('#'+renderToDescription).html(data["description"]);
}
var chart = new Highcharts.Chart(options);
})
var buttons = Highcharts.getOptions().exporting.buttons.contextButton.menuItems;
// add "separator line"
buttons.push({
separator: true,
});
// add "Link to metadata"
buttons.push({
text: 'Metadata',
onclick: function () {
window.open('http://xxx/metadata.php?selectedID=' + selectedID + '&selectedDatasettype=1', "_blank");
}
});
}
// add "separator line"
buttons.push({
separator: true,
});
// add "Link to more data functions"
buttons.push({
text: 'Link to more data functions',
onclick: function () {
window.open('http://xxx/options.php?selectedID=' + selectedID + '&selectedDatasettype=1', "_blank");
}
});
});
}
And from the other end, I have the file which generates the JSON code:
$data_ = array( "chart" => array("renderTo" => $container, "type" => $graphStyle, "zoomType" => "xy", "marginTop" => $marginTop, "marginRight" => 20, "marginBottom" => 60, "marginLeft" => 80),
"title" => array("useHTML" => true, "text" => "<div style='text-align: center'>".str_replace("CO2", "CO<sub>2</sub>", $selectedDataset -> name)."</div>", "align" => "center", "style" => array("fontFamily" => "Helvetica", "fontSize" => "20px")),
"subtitle" => array("text" => "Original data source: <a href='" . $provider_url . "' style='font-family: Helvetica; color: #428bcc; text-decoration: none' target='_blank'>" . $selectedDataset -> data_provider . "</a>", "useHTML" => true),
"xAxis" => array("tickWidth" => 0, "showFirstLabel" => true, "showLastLabel" => true, "tickInterval" => $step),
"yAxis" => array("min" => $min, "title" => array("useHTML" => true, "text" => str_replace("CO2", "CO<sub>2</sub>", $yTitle), "fontWeight" => "bold", "align" => "high", "textAlign" => "left", "rotation" => 0, "y" => $yAxisY)),
"legend" => array("enabled" => $flagValues, "layout" => "vertical", "align" => "center", "verticalAlign" => "middle", "backgroundColor" => "#efefef", "borderWidth" => 0, "floating" => false, "x" => -185, "y" => 100, "title" => array("text" => ":: Legend ::"), "floating" => true, "draggable" => true, "zIndex" => 20),
"plotOptions" => array("series" => array("connectNulls" => true, "shadow" => false, "lineWidth" => 2, "marker" => array("enabled" => false))),
"tooltip" => array("shared" => true, "crosshairs" => true),
"credits" => array("text" => $copyright, "href" => "http://ede.grid.unep.ch", "position" => array("x" => 10, "y" => -20, "align" => "left"), "style" => array("fontSize" => "9px", "lineHeight" => "9px")),
"exporting" => array("buttons" => array("contextButton" => array("symbol" => "url(http://geodata.grid.unep.ch/images/button_download_4.png)", "x" => -10, "y" => 10))),
"series" => $data,
"protected" => $selectedDataset -> protected_,
"description" => $selectedDataset -> abstract,
"noData" => $flagValues);
header("content-type: application/json");
echo $_GET['callback']. '('. json_encode($data_) . ')';
Now, strangely enough, it seems that if a user from the same site chooses one graph after another, the additional context items are being added up. So, the first call, the separator line and the link to metadata are being added; for the second call, I see the separator line and the link to metadata two times... Very strange. No clue.
One thought: Can the contextButtons first be emptied for each call? And then the additional options added? Something like
Highcharts.getOptions().exporting.buttons.contextButton.menuItems.empty()
Thanks for any hints.

I finally found an approach which seems to work well. This is, loop through the array of menuItems of the contextButton. Check if the item already exists, replace its function. Otherwise, use the standard push-option.
Hopes this helps someone else in a similar situation.
var buttons = [];
buttons = Highcharts.getOptions().exporting.buttons.contextButton.menuItems;
flag_metadata = false;
flag_link_functions = false;
for (var x in Highcharts.getOptions().exporting.buttons.contextButton.menuItems)
{
if (buttons[x].id == "Metadata")
{
buttons[x].onclick = function () {
window.open('http://ede.grid.unep.ch/mod_metadata/metadata.php?selectedID=' + selectedID + '&selectedDatasettype=1', "_blank");}
flag_metadata = true;
}
if (buttons[x].id == "Link")
{
buttons[x].onclick = function () {
window.open('http://ede.grid.unep.ch/options.php?selectedID=' + selectedID + '&selectedDatasettype=1', "_blank");}
flag_metadata = true;
}
}
if (flag_metadata == false)
{
// add "separator line"
Highcharts.getOptions().exporting.buttons.contextButton.menuItems.push({
separator: true,
id: 'sep1',
});
// add "Link to metadata"
Highcharts.getOptions().exporting.buttons.contextButton.menuItems.push({
id: 'Metadata',
text: 'Metadata',
onclick: function () {
window.open('http://ede.grid.unep.ch/mod_metadata/metadata.php?selectedID=' + selectedID + '&selectedDatasettype=1', "_blank");
}
});
// add "separator line"
Highcharts.getOptions().exporting.buttons.contextButton.menuItems.push({
separator: true,
id: 'sep2',
});
// add "Link to more data functions"
Highcharts.getOptions().exporting.buttons.contextButton.menuItems.push({
id: 'Link',
text: 'Link to more data functions',
onclick: function () {
window.open('http://ede.grid.unep.ch/options.php?selectedID=' + selectedID + '&selectedDatasettype=1', "_blank");
}
});
}

Related

How to add text that there are no search results for such entered word to a custom block?

I have a view that searches for indexed entity fields using context filters. I added a custom block to the view like this:
{{ drupal_block('result_entity_product_categories', {arguments}) }}
This block displays categories that match the entered word in the search. If you enter something for which there are no search results, for example, bbbbb, I need to display something like this:
Sorry
No results for: "bbbbb"
But here are some of our most popular products
P.S. The option to add text to the No Results Behavior view setting is not suitable. It is necessary to add text in the custom block.
The build() method code of my custom block:
public function build() {
$configuration = $this->getConfiguration();
$term = $configuration['arguments']['0'] ?: '';
if (empty($term)) {
return '';
}
$index = $this->entityTypeManager->getStorage('search_api_index')->load('entity_product_index');
$parse_mode = $this->parseModeManager->createInstance('terms');
$parse_mode->setConjunction('AND');
$search_query = $index->query();
$search_query->setParseMode($parse_mode)
->keys($term);
$search_result = $search_query->execute();
$rows = [];
foreach ($search_result->getResultItems() as $item) {
if (($node = $item->getOriginalObject()->getEntity()) && ($node instanceof NodeInterface)) {
$categoryKey = $node->get('field_entity_product_category')->getString();
if ($categoryKey) {
++$rows[$categoryKey];
}
}
}
$build['container'] = [
'#type' => 'container',
'#attributes' => [
'class' => ['category-counter-wrapper'],
],
];
foreach ($rows as $key => $count) {
if ($node = $this->entityTypeManager->getStorage('node')->load($key)) {
$build['container'][$key] = [
'#type' => 'container',
'#attributes' => [
'class' => ['item'],
],
'label' => [
'#type' => 'container',
'#markup' => $node->getTitle(),
'#attributes' => [
'class' => ['label'],
],
],
'count' => [
'#type' => 'container',
'#markup' => $count,
'#attributes' => [
'class' => ['count'],
],
],
'link' => [
'#type' => 'link',
'#url' => Url::fromUserInput($node->get('field_custom_url')->getString(), ['query' => ['text' => $term]]),
'#attributes' => [
'class' => ['link'],
],
],
];
}
}
return $build;
}

How to create multiple meta fields in gutenberg block

I need to create a wordpress Gutenberg block that will allow me to insert some data as name and surname, company name, the best sentence from the references.
So far I managed to create a Gutenberg block that is saving one text field.
dc-references-block.php
// register custom meta tag field
function dcr_register_post_meta() {
register_post_meta( 'page', 'dc_references_block_field', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
) );
}
add_action( 'init', 'dcr_register_post_meta' );
function dcr_enqueue() {
wp_enqueue_script(
'dc-references-block-script',
plugins_url( 'dc-references-block.js', __FILE__ ),
array( 'wp-blocks', 'wp-element', 'wp-components' )
);
}
add_action( 'enqueue_block_editor_assets', 'dcr_enqueue' );
dc-references-block.js
( function( wp ) {
var el = wp.element.createElement;
var registerBlockType = wp.blocks.registerBlockType;
var TextControl = wp.components.TextControl;
registerBlockType( 'dc-references-block/dc-references-block', {
title: 'Title',
icon: 'edit',
category: 'common',
attributes: {
blockValue: {
type: 'string',
source: 'meta',
meta: 'dc_references_block_field'
}
},
edit: function( props ) {
var className = props.className;
var setAttributes = props.setAttributes;
function updateBlockValue( blockValue ) {
setAttributes({ blockValue });
}
return el(
'div',
{ className: className },
el( TextControl, {
label: 'write here name of company',
value: props.attributes.blockValue,
onChange: updateBlockValue
}
)
);
},
save: function() {
return null;
}
} );
} )( window.wp );
Whenever I try to add a second text field or textarea to the block I get an error "site does not support this block".
Could anyone explain to me how to, in this situation, add correctly more then one text field and textarea to a block?
It would be better if you included the code that did not work. In any case, I changed your code by adding another text input and a textarea (with relevant entries in attributes and meta).
Here is the modified code. Also, I have changed some of the code to be more readable.
Javascript
( function( wp ) {
const el = wp.element.createElement;
const registerBlockType = wp.blocks.registerBlockType;
const TextControl = wp.components.TextControl;
const TextareaControl = wp.components.TextareaControl;
registerBlockType( 'dc-references-block/dc-references-block', {
title: 'Title',
icon: 'edit',
category: 'common',
attributes: {
blockValue: {
type: 'string',
source: 'meta',
meta: 'dc_references_block_field'
},
// Add two new attributes
name: {
type: 'string',
source: 'meta',
meta: 'dc_references_block_field_name'
},
desc: {
type: 'string',
source: 'meta',
meta: 'dc_references_block_field_desc'
}
},
edit: function( props ) {
const className = props.className;
const setAttributes = props.setAttributes;
// Original element with onChange event as an anonymous function
const text = el( TextControl, {
label: 'write here name of company',
value: props.attributes.blockValue,
key: 'companyName',
onChange: function( value ) {
setAttributes( { name: value } );
}
} );
//Add two new elements
const secondText = el( TextControl, {
label: 'Write your name',
value: props.attributes.name,
key: 'username',
onChange: function( value ) {
setAttributes( { name: value } );
}
} );
const textArea = el( TextareaControl, {
label: 'Write a description',
value: props.attributes.desc,
key: 'desc',
onChange: function( value ) {
setAttributes( { desc: value } );
}
} );
return el(
'div',
{ className: className },
// Children of the main div as an array
[ text, secondText, textArea ]
);
},
save: function() {
return null;
}
} );
}( window.wp ) );
PHP
register_post_meta( 'page', 'dc_references_block_field', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
) );
// register two new meta corresponding to attributes in JS
register_post_meta( 'page', 'dc_references_block_field_name', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
) );
register_post_meta( 'page', 'dc_references_block_field_desc', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
) );

fullcalendar d'ont display data with contains datetime

Hi friends i'am using maddhatter fullcalendar in my project laravel 5.6,when i fetch my data in calendar its work by data contains format y-m-d but when i change my format to datetime my camlendar does not display anything this my code:
$events = Agenda::where('code_commercial', $code)->get();
$event_list = [];
foreach ($events as $event) {
$event_list[] = Calendar::event(
$event->description,
true,
date_format(date_create($event->date_debut), "Y-m-d H:i:s"),
date_format(date_create($event->date_fin), "Y-m-d H:i:s")
// new \DateTime($event->date_debut),
// new \DateTime($event->date_fin),
// Carbon::createFromFormat('Y-m-d H:i:s', $event->date_debut)->toDateTimeString(),
// Carbon::createFromFormat('Y-m-d H:i:s', $event->date_fin)->toDateTimeString()
);
}
and this is my configuration for fullcalendar :
$calendar_details = Calendar::addEvents($event_list, [ //set custom color
fo this event
'color' => '#800',
])->setOptions([ //set fullcalendar options
'firstDay' => 1,
'selectable' => true,
'defaultView' => 'agendaWeek',
'allDay' => false,
'slotLabelFormat' => 'HH:mm:ss',
'editable' => true,
'eventLimit' => true,
// 'minTime' => '07:00:00',
// 'maxTime' => '22:00:00',
// 'slotDuration' => '01:30:00',
])
please any help thanks for you

Wordpress stripping attributes even when explicitly allowed

I've looked through every guide on allowing HTML tags and attributes to Wordpress posts, but it's still stripping the allow attribute from iframes. When echoing the allowedposttags global, it looks like iframe[allow] is set to true. TinyMCE's settings show that extended_valid_elements is set to allow all *[*]. The POST data to the Wordpress update endpoint is not stripped. I'd really appreciate any help in identifying the problem. Here's the plugin I put together based on a few guides:
<?php
/**
* Plugin Name:Allow Tags
* Description: Allows one to add "invalid" and custom HTML elements to the Wordpress editor.
* Version: 0.1
* Author: Sam Hill
* with help from http://www.engfers.com/2008/10/16/how-to-allow-stripped-element-attributes-in-wordpress-tinymce-editor/ and many other sources
*/
class AllowTags {
public static $instance = null;
public static function get_instance() {
if ( null == self::$instance ) {
self::$instance = new self;
}
return self::$instance;
}
private function __construct() {
add_filter('wp_kses_allowed_html', 'custom_wpkses_post_tags', 10, 2 );
add_filter('tiny_mce_before_init', 'tinymce_allow_iframe');
add_action('init', 'allow_iframe_attributes', 10, 2);
}
}
AllowTags::get_instance();
function tinymce_allow_iframe($init) {
$options = '*[*]';
$init['valid_elements'] = $options;
$init['extended_valid_elements'] = $options;
$init['verify_html'] = false;
return $init;
}
function custom_wpkses_post_tags($allowed, $context){
if (is_array($context)) {
return $allowed;
}
if ($context === 'post') {
$allowed['iframe'] = array(
'src' => true,
'height' => true,
'width' => true,
'frameborder' => true,
'allowfullscreen' => true,
'allow' => true
);
}
return $allowed;
}
function allow_iframe_attributes( $string ) {
global $allowedposttags;
$allowedposttags['iframe'] = array(
'allow' => true,
'align' => true,
'frameborder' => true,
'height' => true,
'width' => true,
'sandbox' => true,
'seamless' => true,
'scrolling' => true,
'srcdoc' => true,
'src' => true,
'class' => true,
'id' => true,
'style' => true,
'border' => true,
);
return $string;
}
}

Add button to Drupal ckeditor

I'm just learning Drupal and would like to add a button to the CKEditor. I've tried a few techniques and I'm never able to get a new button to appear. Here's the module I have so far.
Can anyone tell me why this code doesn't work?
Here's a list of other files besides the ones included:
image.png (/sites/all/modules/excel_to_html/images/image.png) - icon
excel_to_html.info (/sites/all/modules/excel_to_html/excel_to_html.info)
excel_to_html.module
location : /sites/all/modules/excel_to_html/excel_to_html.module
<?php
function excel_to_html_ckeditor_plugin() {
return array(
'plugin_name' => array(
'name' => 'excel_to_html',
'desc' => t('Plugin description'),
'path' => drupal_get_path('module', 'excel_to_html') .'/plugins/excel_to_html/',
'buttons' => array(
array('label' => 'Button label', 'icon' => '/images/image.png'),
)
)
);
}
plugin.js
location : /sites/all/modules/excel_to_html/plugins/excel_to_html/plugin.js
(function() {
CKEDITOR.plugins.add('excel_to_html',
{
icons: 'images/image.png',
init: function(editor)
{
editor.addCommand('excel_convert',
{
exec : function(editor)
{
alert('testing button!');
//var selected_text = editor.getSelection().getSelectedText();
}
});
editor.ui.addButton('excel_to_html',
{
label: 'Convert Excel to table',
command: 'excel_convert',
icon: this.path + 'images/image.png'
});
},
afterInit: function (editor)
{
alert('done');
}
});
})();

Resources