ChartJS with Symfony UX - Error: Canvas is already in use - symfony

I have error messages in my console when I render charts in my project Symfony 6.1.
Context :
I have a page with 4 charts displayed.
I make these with Symfony UX and ChartJS in my Controller Symfony.
The charts are displaying but errors in console.
Precision :
The number of charts is not important. I have same error with just one.
Error :
My function in controller :
public function homeCharts(
Request $request,
DueCaseRepository $dueCaseRepository,
EntityManagerInterface $entityManager,
ChartBuilderInterface $chartBuilder
): Response {
$this->denyAccessUnlessGranted('ROLE_ADMIN', null, 'Unable to access this page!');
/**
* en fonction du role => afficher le bon dashboard
*/
$user = $this->getUser();
$view = 'home/index_charts.html.twig';
/**
* Répartition du nombre de cases par Scope par défaut
*/
$chartNbCaseByScopeDefault = $dueCaseRepository->chartNbCaseByScopeDefault();
$labels = [];
$data = [];
foreach ($chartNbCaseByScopeDefault as $line) {
$labels[] = ($line["scope"] != null) ? $line["scope"] : "Undefined";
$data[] = $line["nb"];
}
$chart = $chartBuilder->createChart(Chart::TYPE_PIE);
if (!empty($data)) {
$maxValue = max($data);
} else {
$maxValue = 5;
}
$chart->setData([
'labels' => $labels,
'datasets' => [
[
'label' => 'Number of cases by Scope Default',
'hoverOffset' => 4,
'backgroundColor' => [
'rgba(255, 99, 132)',
'rgba(54, 162, 235)',
'rgba(255, 206, 86)',
'rgba(75, 192, 192)',
'rgba(153, 102, 255)',
'rgba(255, 159, 64)'
],
'data' => $data,
],
],
]);
$chart->setOptions([
'responsive' => true,
'maintainAspectRatio' => false,
'legend' => [
'labels' => [
'fontColor' => "#9ba6b5"
],
],
]);
/**
* Répartition du nombre de cases par Scope personnalisés
*/
$chartNbCaseByScopePerso = $dueCaseRepository->chartNbCaseByScopePerso();
$labels = [];
$data = [];
foreach ($chartNbCaseByScopePerso as $line) {
$labels[] = ($line["scope"] != null) ? $line["scope"] : "Undefined";
$data[] = $line["nb"];
}
$chart2 = $chartBuilder->createChart(Chart::TYPE_PIE);
if (!empty($data)) {
$maxValue = max($data);
} else {
$maxValue = 5;
}
$chart2->setData([
'labels' => $labels,
'datasets' => [
[
'label' => 'Number of cases by Scope perso',
'hoverOffset' => 4,
'backgroundColor' => [
'rgba(255, 99, 132)',
'rgba(54, 162, 235)',
'rgba(255, 206, 86)',
'rgba(75, 192, 192)',
'rgba(153, 102, 255)',
'rgba(255, 159, 64)'
],
'data' => $data,
],
],
]);
$chart2->setOptions([
'responsive' => true,
'maintainAspectRatio' => false,
'legend' => [
'labels' => [
'fontColor' => "#9ba6b5"
],
],
]);
/**
* Répartition du nombre de cases demandées/validées par mois
*/
$chartNbCaseRequested = $dueCaseRepository->chartNbCaseRequested();
$chartNbCaseValidated = $dueCaseRepository->chartNbCaseValidated();
$labels = [];
$data = [];
$data2 = [];
foreach ($chartNbCaseRequested as $line) {
if ($line["month"] !== null) {
$labels[] = $line["month"];
$data[] = $line["nb"];
foreach ($chartNbCaseValidated as $line2) {
if ($line["month"] == $line2["month"]) {
$data2[] = $line2["nb"];
}
}
}
}
$chart3 = $chartBuilder->createChart(Chart::TYPE_BAR);
if (!empty($data)) {
$maxValue = max($data);
} else {
$maxValue = 5;
}
$chart3->setData([
'labels' => $labels,
'datasets' => [
[
'label' => "Due cases requested",
'data' => $data,
'borderColor' => "#6c5ffc",
'borderWidth' => "0",
'backgroundColor' => "#6c5ffc"
], [
'label' => "Due cases validated",
'data' => $data2,
'borderColor' => "#05c3fb",
'borderWidth' => "0",
'backgroundColor' => "#05c3fb"
]
],
]);
$chart3->setOptions([
'scales' => [
'y' => [
'suggestedMin' => 0,
'suggestedMax' => $maxValue * 1.5,
],
],
'responsive' => true,
'maintainAspectRatio' => false,
'legend' => [
'labels' => [
'fontColor' => "#9ba6b5"
],
],
]);
/**
* Répartition du nombre de cases par country
*/
$chartNbCaseByCountry = $dueCaseRepository->chartNbCaseByCountry();
$labels = [];
$data = [];
foreach ($chartNbCaseByCountry as $line) {
$labels[] = ($line["country"] != null) ? $line["country"] : "Undefined";
$data[] = $line["nb"];
}
$chart4 = $chartBuilder->createChart(Chart::TYPE_POLAR_AREA);
if (!empty($data)) {
$maxValue = max($data);
} else {
$maxValue = 5;
}
$chart4->setData([
'labels' => $labels,
'datasets' => [
[
'label' => 'Number of cases by country',
'backgroundColor' => ['#6c5ffc', '#05c3fb', '#09ad95', '#1170e4', '#e82646'],
'hoverBackgroundColor' => ['#6c5ffc', '#05c3fb', '#09ad95', '#1170e4', '#e82646'],
'borderColor' => 'transparent',
'data' => $data,
],
],
]);
$chart4->setOptions([
'responsive' => true,
'maintainAspectRatio' => false,
'legend' => [
'labels' => [
'fontColor' => "#9ba6b5"
],
],
]);
return $this->render($view, [
'controller_name' => 'HomeController',
'user' => $user,
'chart' => $chart,
'chart2' => $chart2,
'chart3' => $chart3,
'chart4' => $chart4,
]);
}
My Twig file :
<div class="main-content mt-0 hor-content">
<div
class="side-app">
<!-- CONTAINER -->
<div
class="main-container container">
<!-- PAGE-HEADER -->
<div class="page-header">
<h1 class="page-title">
Dashboard charts
</h1>
</div>
<!-- PAGE-HEADER END -->
<div class="row">
<div class="col-12 col-sm-12">
<div class="card">
<div class="card-header">
<h3 class="card-title mb-0">Number of cases requested and validated by months</h3>
</div>
<div class="card-body">
{{ render_chart(chart3, {'data-controller': 'admin-chartjs-casesByMonth', 'id': 'casesByMonth'}) }}
</div>
</div>
</div>
<div class="col-6 col-sm-6">
<div class="card">
<div class="card-header">
<h3 class="card-title mb-0">Number of cases by prestation default</h3>
</div>
<div class="card-body">
{{ render_chart(chart, {'data-controller': 'admin-chartjs-casesByPresta', 'id': 'casesByPresta'}) }}
</div>
</div>
</div>
<div class="col-6 col-sm-6">
<div class="card">
<div class="card-header">
<h3 class="card-title mb-0">Number of cases by prestation client</h3>
</div>
<div class="card-body">
{{ render_chart(chart2, {'data-controller': 'admin-chartjs-casesByPrestaClient', 'id': 'casesByPrestaClient'}) }}
</div>
</div>
</div>
<div class="col-6 col-sm-6">
<div class="card">
<div class="card-header">
<h3 class="card-title mb-0">Number of cases by country</h3>
</div>
<div class="card-body">
{{ render_chart(chart4, {'data-controller': 'admin-chartjs-casesByCountries', 'id': 'casesByCountries'}) }}
</div>
</div>
</div>
</div>
</div>
<!-- CONTAINER END -->
</div>
</div>
I need your help please 😅
Thanks !
🙏🏻

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;
}

Symfony form not shown in template

In a Symfony 3.4 project, I just created a new form type ProductSearchType. The form fields are not shown in twig template. There are only the <form> tags, but nothing between them.
FormType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class, [
'required' => false,
'label' => 'Name',
])
->add('sizes', EntityType::class, [
'required' => false,
'label' => 'Bauform',
'class' => ProductSize::class,
])
->add('description', TextType::class, [
'required' => false,
'label' => 'Beschreibung',
])
->add('price', EntityType::class, [
'required' => false,
'label' => 'Preiskategorie',
'class' => ProductPrice::class,
])
->add('booster', EntityType::class, [
'required' => false,
'label' => 'Hörverlust',
'class' => ProductBooster::class,
])
->add('brand', EntityType::class, [
'required' => false,
'label' => 'Marke',
'class' => ProductBrand::class,
]);
}
Action:
public function index(Request $request): Response
{
$products = $this->getDoctrine()->getRepository(Produkt::class)
->findBy([
'showOnEmptySearch' => true,
], [
'sortOnEmptySearch' => 'asc',
]);
$searchForm = $this->createForm(ProductSearchType::class);
$searchForm->handleRequest($request);
$params = [
'products' => $products,
'search_form' => $searchForm->createView(),
];
return $this->render('Products/index.html.twig', $params);
}
Twig part:
{% block template_filter %}
<h1>
Suche
</h1>
<div class="filter_box">
{{ form(search_form) }}
</div>
{% endblock %}
I recommend to follow the documentation. On your example:
$searchForm = $this->createForm(ProductSearchType::class); should be:
$searchForm = $this->createForm(ProductSearchType::class)->getForm();.
Also on twig;
{{ form_start(search_form) }}
{{ form_widget(search_form) }}
{{ form_end(search_form) }}
Here is the documentation link. Welcome to Stackoverflow.
If you get answer to your question, don't forget to mark this answer as Accepted Answer.

Icons Control | Elementor

what does {{{ iconHTML.value }}} stands for in the _content_template?
the render is working fine but there's a reference error: iconHTML is not defined.
This is from the elementor controls documentation but i cant seem understand what should I substitute in {{{ iconHTML.value }}}
add_action( 'elementor/widgets/widgets_registered', function( $widget_manager ) {
class Icons_Control_Test_Widget extends \Elementor\Widget_Base {
public function get_name() {
return 'icons_test_widget';
}
public function get_title() {
return __( 'Icons Test Widget', 'text-domain' );
}
protected function _register_controls() {
$this->start_controls_section(
'section_icon',
[
'label' => __( 'Icon', 'text-domain' ),
]
);
$this->add_control(
'icon',
[
'label' => __( 'Icon', 'text-domain' ),
'type' => \Elementor\Controls_Manager::ICONS,
'default' => [
'value' => 'fas fa-star',
'library' => 'solid',
],
]
);
$this->end_controls_section();
}
protected function render() {
$settings = $this->get_settings_for_display();
?>
<div class="my-icon-wrapper">
<?php \Elementor\Icons_Manager::render_icon( $settings['icon'], [ 'aria-hidden' => 'true' ] ); ?>
</div>
<?php
}
protected function _content_template() {
?>
<div class="my-icon-wrapper">
{{{ iconHTML.value }}}
</div>
<?php
}
}
// register widget
$widget_manager->register_widget_type( new Icons_Control_Test_Widget() );
} );
The elementor itself does not say what that means. For me, iconHTML does not work at all and I have to create the appropriate element myself. My solution doesn't cause logs either.
<div>
<i aria-hidden="true" class="{{{ settings.icon_control_name.value }}}"></i>
</div>
EDIT
Just use renderIcon from elementor.helpers.renderIcon. Eg.
<div class="icon_wrapper">
<# var iconHTML = elementor.helpers.renderIcon( view, settings.icons_controller, { 'aria-hidden': true }, 'i' , 'object' ); #>
<!--- And now it's working --->
{{{ iconHTML.value }}}
</div>
Thanks for #rotemee from issue https://github.com/elementor/elementor/issues/15707

Yii2: How to render Pjax content outside of Gridview, triggered with Gridview button

Issue
For those with this issue, I'll save you some headache.
In summary: It is critical that the Pjax linkSelector must point to an < a > anchor element or you will receive an uncaught jquery error.
The issue I was having was updating content outside of the Gridview Widget using Pjax. I added a custom button using Html::button, but the pjax was failing for unknown reason.
When testing pjax on the gridview widget using the native buttons using 'class'=>'yii\grid\ActionColumn', the pjax would refresh just fine which caused me some confusion. What I didn't realize is that the pjax linkSelector only works on < a > elements, the linkSelector will not work on < button > element generated when using Html::button(...); .
Recieved this error: Uncaught $.fn.pjax or $.pjax.click requires an anchor element.
View
File Location: app/views/default/pjax-example.php
[Code for Pjax]
<?php Pjax::begin([
'id'=>'p0',
'timeout' => false,
//Selector must target the <a> anchor.
'linkSelector'=>'.action-select',
]); ?>
<?php Pjax::end(); ?>
[Code for Gridview Widget]
$data = [
['step_id' => 1, 'step_name' => 'Step A'],
['step_id' => 2, 'step_name' => 'Step B'],
['step_id' => 3, 'step_name' => 'Step C'],
];
$dataProvider = new ArrayDataProvider([
'allModels' => $data,
'sort' => [
'attributes' => ['id', 'name'],
],
]);
echo GridView::widget([
'dataProvider' => $dataProvider,
'tableOptions' => [
'class' => 'table',
],
'columns' => [
'step_id',
'step_name',
[
'class' => 'yii\grid\DataColumn',
'label' => 'Button-1',
'format'=> 'raw',
'value' => function ($url, $data) {
return Html::a(
'<span class="glyphicon glyphicon-flash"></span>',
Url::to(['default/select', 'id'=>$data['step_id']]),
[
'class' => 'btn btn-danger btn-xs action-select',
'data-pjax'=> 'p0', // We must specify the pjax ID.
]
);
},
],
[
'class' => 'yii\grid\ActionColumn',
'template' => '{select}',
'header' => 'Button-2',
'buttons' => [
'select' => function ($url, $data) {
return Html::Button(
'<span class="glyphicon glyphicon-pencil"></span>',
['value' => Url::to(['default/select', $data['step_id']]),
'class' => 'btn btn-danger btn-xs action-select',
'data-pjax'=> 'p0',
]);
},
],
],
],
]);
Controller
File Location: app/controllers/defaultController.php
public function actionSelect()
{
$random_val = 'Rand_01: ' . rand(10,100);
return $random_val;
}
public function actionPjaxExample()
{
$random_val = 'Rand_02: ' . rand(10,100);
return $this->render('pjax-example', [
'random_val' => $random_val
]);
}
I am using this code without a link selector. And also without data-pjax=0
views/tranlate/index.php
<?php Pjax::begin(['id' => 'translate-grid', 'timeout' => false, 'enablePushState' => true]) ?>
# here you form
<?php $form = ActiveForm::begin(['action'=> Url::current(),'id'=>'edit-form']) ?>
<?= $form->field($model, 'word')->textInput() ?>
<?php ActiveForm::end() ?>
<?= GridView::widget([
'id' => 'data-grid',
'dataProvider' => $dataProvider,
'columns' => [
[
'attribute' => 'title',
'format' => 'raw',
'value' => function ($model) {
return Html::a($name, [
'id' => $model->id
]);
},
],
]
]) ?>
<?php Pjax::end() ?>
controllers/TranalteController.php
public function actionIndex($id = false)
{
$searchModel = new TranslateSearch();
$model = $id ? $this->findModel($id) : new Translate();
if ($model->load(Yii::$app->request->post())) {
if ($model->save()) {
return $this->redirect(Yii::$app->request->getReferrer());
}
}
return $this->render('index', [
'model' => $model,
'searchModel' => $searchModel,
'dataProvider' => $searchModel->search(Yii::$app->request->get()),
]);
}

symfony test undefined function

i have problem with my test. I don't know why my function is undefined. I add use statetment, phpstorm see this class. But when run test error with undefined.
namespace tests\AppBundle\Parser;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use AppBundle\Parser\CommissionDataParser;
class CommissionDataParserTest extends WebTestCase
{
public function testGroupOrdersByWeek()
{
$orders = [
0 => [
'date' => '2016-01-10',
'client_id' => '2',
'client_type'=> 'natural',
'operation_type' => 'cash_in',
'operation_sum' => '200.00',
'operation_currency' => 'EUR',
],
1 => [
'date' => '2016-01-05',
'client_id' => '1',
'client_type'=> 'legal',
'operation_type' => 'cash_out',
'operation_sum' => '300.00',
'operation_currency' => 'EUR',
],
2 => [
'date' => '2016-01-11',
'client_id' => '1',
'client_type'=> 'natural',
'operation_type' => 'cash_out',
'operation_sum' => '30000',
'operation_currency' => 'JPY'
]
];
$expected = [
0 => [
'date' => '2016-01-05',
'client_id' => '2',
'client_type'=> 'natural',
'operation_type' => 'cash_in',
'operation_sum' => '200.00',
'operation_currency' => 'EUR',
],
1 => [
'date' => '2016-01-10',
'client_id' => '1',
'client_type'=> 'legal',
'operation_type' => 'cash_out',
'operation_sum' => '300.00',
'operation_currency' => 'EUR',
],
2 => [
'date' => '2016-01-11',
'client_id' => '1',
'client_type'=> 'natural',
'operation_type' => 'cash_out',
'operation_sum' => '30000',
'operation_currency' => 'JPY'
]
];
$um = new CommissionDataParser();
$result = $um->groupOrdersByWeek($orders);
$this->assertEquals($expected, $result, '**** -->>>>> result array wrong');
}
there is function that i want to test: i put small part of this class, for example
namespace AppBundle\Parser;
class CommissionDataParser
{
public function getData($file)
{
$orders = $this->extractOrders($file);
if (is_array($orders)) {
$orders = $this->groupOrdersByWeek($orders);
}
// ...
}
public function extractOrders($file)
{
$orders = [];
$data = [];
//$lines = explode(PHP_EOL, file_get_contents($file));
if (($handle = fopen($file, "r")) !== FALSE) {
while (($row = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($row);
if ($num !== 6) {
return 'Badly structured file';
} else if ($num == 0) {
return 'file is empty';
}
$data[] = $row;
}
fclose($handle);
}
foreach ($data as $row)
{
$orders[] = [
'date' => $row[0],
'client_id' => $row[1],
'client_type' => $row[2],
'operation_type' => $row[3],
'operation_sum' => $row[4],
'operation_currency' => $row[5]
];
}
return $orders;
}
In first, you must check that your phpunit uses app/autoload.php as bootstrap. Open your phpunit.xml.dist file in your project root, and find this line:
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.8/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="app/autoload.php"
>
If u see this line bootstrap="app/autoload.php" in your file, then all right.
Next, check that your file CommissionDataParser.php physically located in this directory AppBundle\Parser. Full path to this file must be YOUR_PROJECT_ROOT\src\AppBundle\Parser\CommissionDataParser.php
If you did everything correctly then it should work. At least I was able to run your code.
yes really have :) i take a picture for example : )

Resources