0

I have asked a related question before, but I still have problems.

I am building a PrestaShop module. PS Version 1.6.10 and I want to use jQuery UIs Menu and Dialog.

TLDR: My code is working fine in front office. But not in back office. Depending on how many jQueryUI modules I include, I get different errors. If I include it in a way where there are no errors, my menus don't do what they're supposed to. Dialog works fine, but Menu doesn't (It partially works, see image).

enter image description here


The content I display has been completely moved into a separate file, so the html code that we see in front and back office are identical, because they both reference the same file. Since the front office works perfectly fine, the error should not be within my code.

However, I can't get it to work in back office, here's everything I've tried:


1.) Not including any Jquery Modules [results in errors in the console and nothing works]

Now I get errors in the console:

Uncaught TypeError: $(...).dialog is not a function

Uncaught TypeError: $(...).menu is not a function


2.) Including all Jquery Modules from Google [results in errors in the console and nothing works]

This is what I do to make it work in front office. I add the google hosted jquery UI library to hookHeader. For back office I am pasting the same code in hookBackOfficeHeader.

$this->context->controller->addCSS('https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css');
$this->context->controller->addJS('https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js');

But I get these errors:

errors with google hosted library


3.) Including all Jquery Modules from Pretashop [results in errors in the console and nothing works]

Next I try to include ALL the jQuery UI libraries that come with prestashop, using this code:

    $all_plugins = scandir ( dirname(dirname(dirname(__FILE__))).'/js/jquery/ui' );
    foreach($all_plugins as $file)
    {
        if( substr( $file, 0, 10 ) === "jquery.ui.")
        {
            $comp =  explode('.',$file);
            $this->context->controller->addJqueryUI('ui.'.$comp[2]);
        }
    }   

This script executes just fine, but now I get these errors:

errors when all jquery ui libraries are included


4.) Including from PS, but skipping the effect libraries [results in NO errors but the UI still doesn't work]

    $all_plugins = scandir ( dirname(dirname(dirname(__FILE__))).'/js/jquery/ui' );
    foreach($all_plugins as $file)
    {
        if( substr( $file, 0, 10 ) === "jquery.ui." 
        && substr( $file, 0, 17 ) !== "jquery.ui.effect-" )
        {
            $comp =  explode('.',$file);
            $this->context->controller->addJqueryUI('ui.'.$comp[2]);
        }
    }   

Finally, I get no more errors! But now Menu won't work. I mean it works in terms of styling the element, and it's correctly hiding the sub menus. But when I hover over the menu nothing happens and the little arrow to the side is also gone... Just like in the picture at the very top.


5.) Only including those Jquery Modules that are absolutely needed [results in NO errors but the UI still doesn't work]

    $this->context->controller->addJqueryUI('ui.dialog');
    $this->context->controller->addJqueryUI('ui.menu');

If I do this, I get the same result: No more errors in the console, but the hover effect doesn't work (just like in the picture above).


Why is this happening, and how can I fix it?


as requested, here's the rest of my code:

modules/mymodule/controllers/admin/AdminMyMenuController.php

class AdminMyMenuControllerextends ModuleAdminController {

            public function display()
            {
                
                $this->context->smarty->assign(array(
                        
                        'mymenu_html_code' => $this->getMenuHtmlCode(),
                        
                    ));
                parent::display();
            }


            public function getMenuHtmlCode($vars)
            {
                return
                    '<ul>
                    
                        <li>
                        <div><small>'.$var0.'</small></div>
                            <ul>
                                <li class="ui-widget-header">Test Menu:</li>
                                <li class="ui-state-disabled"><div><b>'.$var1.'</b></div></li>
                                <li class="ui-state-disabled">'.$var2.'</li>
                                <li class="ui-state-disabled">'.$var3.'</li>
                                <li><div>
                                '.$var4.'
                                <i class="icon-pencil"></i> edit</div></li>
                                
                                <li><div><i class="icon-trash"></i> delete</div>
                                    <ul>
                                        <li class="ui-state-disabled">Sure?</li>
                                        <li>
                                            <form method="POST">
                                                <input type="hidden" name="id_menu" value="'.$id.'">
                                                <input type="hidden" name="delete" value="delete">
                                                <div id="delete_menu" onclick="$(this).parent().submit();"><i class="icon-check"></i> Yes!</div>
                                            </form>
                                        </li>
                                    </ul>
                                </li>
                            </ul>
                        </li>
                    </ul>'; 
            }

modules/mymodule/js/back.js

$(document).ready(function(){
    $( "td.mymenu ul" ).menu();
});
Community
  • 1
  • 1
oliver_siegel
  • 1,666
  • 3
  • 22
  • 37
  • 2
    Is this menu in your own controller/module settings page or are you trying to modify the main left menu of backoffice? Without some minimal sample code of the menu, so we could reproduce this, it's gonna be hard to help you. – TheDrot Aug 19 '17 at 09:52
  • I added some of my code. It should be correct since it's from the same file that I'm using for front office. And I'm creating my own controller. – oliver_siegel Aug 21 '17 at 00:52
  • 1
    Where do you include the back.js for back office? In getMenuHtmlCode where do you get the $var0 an so on? As TheDrot mentioned, is this for the left menu of the backoffice or only for your controller only? Where is mymenu_html_code used? There is a lot of code missing to get proper help. – sadlyblue Aug 21 '17 at 09:48
  • back.js included via hookBackOfficeHeader(). Not using the left menu, only my controller. The $vars don't matter, since when I take them out the same thing happens. `mymenu_html_code` is just placed in the template file, so that it shows this code. Has somebody successfully used .menu() in a backoffice controller? I'm about to build a minimal demo... – oliver_siegel Aug 22 '17 at 06:19

2 Answers2

1

Using only required components is the way to go (#5), also you might not want to load components on every backoffice page but only in your controller, so move the code from displayBackOfficeHeader hook to your controller's setMedia() method.

public function setMedia()
{
    parent::setMedia();
    $this->addJqueryUI('ui.dialog');
    $this->addJqueryUI('ui.menu');
}

You have to use ui-menu-item class on <li> menu items in order for the hover to work properly.

public function getMenuHtmlCode($vars)
{
    return '<ul>
                <li class="ui-menu-item">
                    <div><small>'.$var0.'</small></div>
                        <ul>
                        ...';
}

Also again I have to say it, you have MVC in Prestashop for a reason. Do not generate HTML in controllers or models. You have templates for a reason.

TheDrot
  • 4,246
  • 1
  • 16
  • 26
  • Yay, thanks that'll definitely fix it! And before I forget: Thanks for pointing out that I should have really put all that in a template, my bad, not sure why I didn't... However: Shouldn't all the classes be added to the `
  • ` tags by me calling `$("ul").menu();` on the parent ul tag?? I mean that's working without problems in the front controller?!
  • – oliver_siegel Aug 22 '17 at 18:05
  • 1
    @olli Well by going through the ui.menu js code it looks like if your `
  • ` contains an anchor it will add the class, otherwise no. Are you loading the same ui menu library on frontend?
  • – TheDrot Aug 22 '17 at 18:43
  • 1
    I used `
  • test
  • ` and it added `ui-menu-item` class to the `li`. Could be that prestashop's ui menu library is outdated and it only works when you have `` tag inside. So I guess you'll have to add classes to `li` manually. – TheDrot Aug 22 '17 at 18:52