Jump to:

3444 Posts in 1030 Topics by 871 members

Template Questions

SilverStripe Forums » Template Questions » Clear/block all Javascript Requirements

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1
Go to End
Author Topic: 5615 Views
  • david_nash
    Avatar
    Community Member
    55 Posts

    Clear/block all Javascript Requirements Link to this post

    I'm creating a template and I don't want any of the existing javascript stuff to get loaded. I want to block/clear it all. Is this a bad idea?

    In my page.php init() function if I do Requirements::clear() nothing happens. Why would that be?

    At the moment I am manually explicitly blocking each javascript file. Here's the code if you want to do it (SS2.3):

    class Page_Controller extends ContentController {
       
       public function init() {
          parent::init();
          Requirements::block('jsparty/prototype.js');
          Requirements::block('jsparty/behaviour.js');
          Requirements::block('jsparty/prototype_improvements.js');
          Requirements::block('sapphire/javascript/Validator.js');
          Requirements::block('sapphire/javascript/i18n.js');
          Requirements::block('sapphire/javascript/lang/en_US.js');
       }
    ...
    }

    Is there an easier way?

    The reason I want to do this is because I like jquery. But when I add it as a requirement and then try to use it I think prototype is getting loaded later so if I try to use $('#MyID') it tells me it that is null, and I'm guessing it's because of prototype.

    What are your thoughts?

  • david_nash
    Avatar
    Community Member
    55 Posts

    Re: Clear/block all Javascript Requirements Link to this post

    I forged ahead despite the massive controversy my post created. Here's my thoughts:

    I couldn't use the built in Form/Input objects, because whenever I did that it would show a javascript error 'behaviour not defined'. This was coming from the validation js code.

    That wasn't too much of a problem, I like having more control over my HTML and it meant I could use jQuery's validation plugin, which I really like.

    But it did mean extra work - I had to code all the HTML forms and inputs by hand.

    There's no problem with using both prototype and jquery, as long as you use the Requirements class in the init() function of the controller. I was calling my javascript through the template in the head, and then the prototype.js was getting loaded just before the end of the body, which apparently is "best practise". But it also means that prototype was getting called last and over-riding the '$' object.

    Another way I could have got around this by using 'jQuery' instead of '$' in the js - but it seems crazy to me to be loading both prototype/scriptaculous and jquery when I only want jquery.

    I read that the next major release of SS will ditch prototype in favour of jquery. Until then I'll probably use this method - it does take longer but I think gives a leaner, more efficient site.

  • Willr
    Avatar
    Forum Moderator
    5502 Posts

    Re: Clear/block all Javascript Requirements Link to this post

    I read that the next major release of SS will ditch prototype in favour of jquery....

    AFAIK this is not quite correct, yes we are moving towards jQuery esp if Form Validation work as planned is completed for 2.4 but prototype will still be around for a few odd things while we slowly transition over to it.

    If you setup your jQuery file like - http://doc.silverstripe.com/doku.php?id=jquery#examples you should still be able to use $().

  • Louis
    Avatar
    Community Member
    1 Post

    Re: Clear/block all Javascript Requirements Link to this post

    Rather than block the JS entirely, I decided I'd follow what the userforms module does.

    First off, you can add to Page_Controller the following, which will disable not only prototype, but also its own Validator.js and the Behaviour script Form's Validator.php class adds. This means your forms have absolutely no JS validation, and no messy code is inserted at the bottom of the page that you don't want.

    class Page_Controller extends ContentController {
       
       function init() {
          // block prototype validation
          Validator::set_javascript_validation_handler('none');
          
          // load the jquery
          //Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery-packed.js');
          //Requirements::javascript(THIRDPARTY_DIR . '/jquery/plugins/validate/jquery.validate.min.js');

          parent::init();
       }

    I had to place this in Page_Controller, since I was borrowing the SearchField, and I saw no need to apply validation to a search field. The trade off, of course, is now I'm responsible for the validation methods, but I'd prefer that anyway.

    Now, inspecting UserDefinedForm.php, it appears that despite all the EditableFormField mentions, those are simple DataObjects, and that it actually uses the same basic Form used everywhere.

    So how does it do validation? Ignoring the customization bits, it uses jquery.validate.min.js, and code like the following:

          // Build actions
          $actions = new FieldSet(
             new FormAction("process", $this->SubmitButtonText)
          );
          
          // Do we want to add a clear form.
          if($this->ShowClearButton) {
             $actions->push(new ResetFormAction("clearForm"));
          }
          // return the form
          $form = new Form( $this, "Form", $fields, $actions, new RequiredFields(array_keys($fieldValidation)));
          $form->loadDataFrom($this->failover);
          
          $FormName = $form->FormName();

          // Set the Form Name
          $rules = $this->array2json($fieldValidationRules);
          $messages = $this->array2json($fieldValidation);
          

          // set the custom script for this form
          Requirements::customScript(<<<JS
             (function($) {
                $(document).ready(function() {
                   $defaults
                   $("#$FormName").validate({
                      errorClass: "required",   
                      messages:
                         $messages
                      ,
                      
                      rules:
                          $rules
                   });
                   $CustomDisplayRules
                });
             })(jQuery);
    JS
    );

    It continues to use the jQuery compatible-mode wrapper, because other code might use prototype for more than just form validation.

    Here's the documentation on that validate method: http://docs.jquery.com/Plugins/Validation#Validate_forms_like_you.27ve_never_been_validating_before.21

    Overall, jQuery's validation is both impressive and kind of scary-huge. I'll have to dig into it a touch more, but it looks easy enough.

    The best part about doing this? It feels like I'm running on the future, today. Even the forum module has been rewritten to use jQuery. And I don't have any ugly code at the bottom, or useless JS in every request.

    P.S. There's an ugly bug when you edit a posting on this forum with a code block in it. (Or at least when I just edited this post here, now.) It adds a <br> tag to the beginning of every line. It added a second one when I hit save, saw the <br>s in the edited post, and edited it again. Not fun, though easy to fix on my end. (Find/Replace)

  • Willr
    Avatar
    Forum Moderator
    5502 Posts

    Re: Clear/block all Javascript Requirements Link to this post

    P.S. There's an ugly bug when you edit a posting on this forum with a code block in it. (Or at least when I just edited this post here, now...

    Yea this was fixed very recently. ss.org probably just hasn't been updated with the fixed code. I shall do that now

  • Tama
    Avatar
    Community Member
    130 Posts

    Re: Clear/block all Javascript Requirements Link to this post

    Following on from this:

    Is it possible to block javascript on the website but not in the CMS?

    We're using a later version of jQuery which is conflicting with the Silverstripe version of jQuery.

    Adding this code to /mysite/Page.php stops Silverstripe from loading it's jQuery on the website and the CMS - which breaks the CMS:

       public function init() {
          parent::init();
          
          // Stop Silverstripe from loading it's own version of jQuery.
          Requirements::block(SAPPHIRE_DIR .'/thirdparty/jquery/jquery.js');
       }

  • Tama
    Avatar
    Community Member
    130 Posts

    Re: Clear/block all Javascript Requirements Link to this post

    As a follow up this specific problem seems to have come from having $SilverStripeNavigator included in our main Page.ss template.

    5615 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.