Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Monday, November 28, 2016

Dear future ReactJS using self, thanks to IE11, you will need to know about babel-pollyfil

Hello future self. This is a quick note on how to use the babel-polyfill.
Perhaps it is so far enough into the future that all browsers now support all of ES6 or better natively. Just in case you're still needing to support the few stubborn Internet Explorer 11 (IE11) users then you'll find this helpful.

It is November 2016 and we now use polyfills to make browsers support futures that they otherwise would not.  Here's how to use the babel-polyfill to help to make your project IE11 compatible.

In my case the specific issue was that my production code was shipping with calls to Object.assign(). Unfortunately IE11 has no idea what .assign() is. In the meantime Chrome just worked, this is how I used the polyfill approach with babel-polyfill to trick IE11 into doing Object.assign().

1. Install it with npm

This command is run in the directly that contains the package.json file:
npm i babel-polyfill --save-dev

2. Edit your webpack.config.js file to make use of it

The snippet below shows how the babel-polyfill is added to the entry array.

module.exports = {
  ...,
  entry: [
    'webpack-hot-middleware/client',
    'babel-polyfill',
    './app/client.js'
  ],

3. Import it into your project

Here's what importing babel-polyfill looks like in my project file which is located at app/client.js:
import 'react-toolbox/lib/commons.scss';
import React from 'react';
import ReactDOM from 'react-dom';
import 'babel-polyfill';
import App from './App.js';

There you go future self, if you found this helpful, you're welcome. I still need to check if this fixes IE10 compatibility issues.

Friday, February 12, 2016

Using Requirejs to load Jquery UI from a CDN

This post discusses how to use Require.js to load an external library.

One big benefit of Require.js is that it allows a developer to reliably load javascript modules without introducing dependency related conflicts. I needed to include Jquery UI into Plone 5 (which now manages the loading of javascript modules and dependencies using Require.js). If you're curious you can read more about use of Require.js in Plone.

In Plone 4.x you basically use the plain old javascript approach (with a bit of jquery magic) to load and run your scripts. Loading and using the Jquery UI datepicker might look like this:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script>
 $(document).ready(function(){
    $(function() {
    $( ".my-calendar-box" ).datepicker(
        { dateFormat: "dd/mm/yy" }
        );
  });
   
 });
</script>

With the introduction of Require.js in Plone 5 the code above would now look something like this:

<script>
require.config({
    "paths": {
      "jquery-ui": "//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min"
    }
});
require([ "jquery", "jquery-ui" ], function( $ ) {
       $(".my-calendar-box").datepicker(
        {
            dateFormat: "dd/mm/yy"
        }
        );
});
</script>

Note that when we define the path to "jquery-ui" the ".js" is removed from the end of the path. We can now call our newly defined "jquery-ui" module by using a require() call.
Plone 5 ships with some common modules such as jquery so we only need to  require "jquery".

If you want to get a list of all the javascript modules that Require.js has already loaded, run the following command on the javascript console of your Require.js powered app:
require.s.contexts._.defined

It is more common to put all your require.js related code in a separate ".js" file and then load that file. I have notes on doing something like that with SemanticUI.

Monday, December 14, 2015

Semantic UI + Plone + RequireJS (just a gist)

I wanted a way to include a jquery plugin in a Plone 5 add-on that I'm working on, but I really wanted to find the simplest way, without using bundles and registering resources with Plone's Genericsetup mechanism.
I was able to pull it off with standard page templates and static resources and it ended up being very close to the way it would be done without all the additional framework related code.

Perhaps I will go into more detail about this approach at a later date. But, following the principle of release early, release often, I'm posting a gist of what I've been doing.

Here's a screenshot of a page that's using the ratings component provided by SemanticUI (a jquery plugin).



I've posted the code with some explanatory notes as a github gist available here: https://gist.github.com/pigeonflight/69313231ad8c8a38082f

Hopefully it will save someone lots of time.

Monday, May 18, 2015

Baby steps in learning ReactJS

As a way to better understand my process of learning a new technology I've captured the first two days of my journey of learning ReactJS


Day 1  - Thursday April 30, 2015

What I did on this day


Notes
At this point my aim is to get a general grasp of what ReactJS is, I'm focusing on understanding the mechanics of the framework. I think my next step will be to follow along more closely with the "Thinking in ReactJS" presentation.

Impressions:
ReactJS flies in the face of convention and eschews the idea of templates, favouring what they call views, also very counter-intuitively they "redraw" the DOM for every update yet in benchmarks are able to outperform AngularJS. To achieve this they use a virtual DOM and only render to the real DOM on an "as needed" basis.

Day 2 - Friday May 1, 2015

What I did on this day

  • Back on the ReactJS website and then decide to work my way through the Thinking in react tutorial again. 

Notes
In following the tutorial the first example failed because the code was out of date. This slowed me down for about 5 minutes. It turns out that React.renderComponent() is now replaced with React.render() so I was working with a slightly dated tutorial, after replacing switching the code to use React.render() instead of React.renderComponent() I was able to make my way through the tutorial.

After an hour of following the tutorial I had the static version working and started to learn about React's concept of "state". I decided to break for a while and grab a snack.

What I know now


  • ReactJS is about building components, usually from existing HTML and Javascript
  • They provide a HTML like syntax called JSX which simplifies the creation of these components
  • I'm learning some of ReactJS's methods such as render()
Two days in, I think I know enough to tentatively try this in a new project. I'm sure I'll gain a lot more facility with a week or two of usage.

Parting thoughts 

So far I've spent 3 to 5 hours on this journey and things are starting to make sense. My feeling at the moment is that I first needed to capture the overall concept of what React does, the virtual DOM and React's JSX syntax. Once I was fine with that I needed to use it in a trivial example, in my case the static version from Thinking in React tutorial. I'm confident about being able to do that now.

Next I'll spending time getting comfortable with idea of working with state.

Saturday, July 13, 2013

Fixed a disappearing TinyMCE on Plone 4.3

I recently linked the disappearance of the TinyMCE visual editor on Plone 4.3 to a conflict between Products.Carousel and collective.carousel. I'm still doing more investigation into this issue, but I figure it may save someone some trouble.

On two Plone sites, both running the latest Plone 4.3.1, I had the same scenario, on both sites I switched from collective.carousel to Products.Carousel. While I haven't pin pointed all the reasons, what made me suspicious was an error in the javascript console that mentioned the absence of resizeCarousel() ( a javascript method that is used by collective.carousel).

The bottom line, probably due to the order of loading the various .js files TinyMCE stopped working.

In both cases, removing collective.carousel  cleared up the conflict and fixed the disappearing TinyMCE.

My take away is to pay more attention to the javascript console. Also, in general, I need to better understand strategies for more robust management of javascript dependencies.

Monday, June 10, 2013

A vertical image slider with jQuery and Plone's Products.Carousel

My goal was to create a vertical sliding effect to allow a visitor to experience tall images in a small area.
The images were made too tall for the viewing area and then, using jQuery's animate, were made to slide upwards through the viewing area. I used Products.Carousel but I'm sure a similar effect could be achieved with collective.carousel.

Products.Carousel is a Plone add-on that provides a point and click interface for managing banners, this makes it possible to appoint non-technical persons as banner administrators. Products.Carousel also builds on Plone's built-in workflow support so banners can be scheduled for publication and expiration among other things.

(Products.Carousel has a simple javascript event system with basic documentation (see: http://plone.org/products/carousel/#carousel-events), so it is possible to take advantage of event listeners to do fancier stuff).

The Structure

The viewing area is wrapped with the css selector span.carousel-image 
The carousel images can be selected based on a general selector such as .carousel img or based on the unique id associated with the slider

The Implementation

The key ideas are as follows:
  • We add custom css to match the viewing area class (called "carousel-image") to size we configure for the carousel.
  • We make the source images taller than the carousel viewing area.
  • We add custom css that enforces the height of the carousel images so they inherit the viewing area size.
  • We add custom javascript which will slide the image through the viewing area and is triggered upon changing of slides.

The CSS

To save on further explanation I've included annotations that explain the key CSS (There is other supporting CSS but it is more incidental to the functionality). In this example the carousel has the unique id "carousel-14937891799".

/*
 rule for image, overrides the default image size and enforces
the height of the carousel images to 400px tall
 */
#carousel-1493789179 img {
width: 961px;
height: 400px;
position:relative;
}
/* rule for the span on top of the image.
switches it to behave like a block then makes the viewing area only
200px tall while preventing overflow
 */
.carousel-image {
height: 200px;
overflow: hidden;
display: block;
}

The Javascript

I had to use a CSS Inspector (the one that comes with Chrome) to determine the ideal displacement of the image which worked out to be 197px. Here's the jQuery animate syntax.
jQuery('.carousel img').animate({top:"-=197px"},9000);

A simple and complete script might look like this (In my case I just added the line to a existing jquery custom script that runs on load).:

jQuery(document).ready(function () { 
     jQuery('.carousel img').animate({top:"-=197px"},9000); 
)}; 
update: I decided to make use of Products.Carousel's event system, as a result I added the following lines of code to my custom javascript:

jQuery(document).ready(function () {

    $("#carousel-1493789179 img").animate({top: "-=197px"})
/* reset the slides to the top just before animation */
    $('.carousel').bind('beforeAnimate',

        function () {

             jQuery('.carousel img').css('top','0px');

        });

/* initiate slide up animation after a new slide has been displayed (ie. on new animation) */

    $('.carousel').bind('afterAnimate',

        function () {

            jQuery('.carousel img').animate({top:"-=197px"},6000);

         });

)};

Parting Thoughts

There are some weaknesses with this approach, for example it assumes that all banner images will always be 400px high. When there are multiple images in the Carousel the sliding up effect is lessened, this can be improved by tying the slide up effect to a Carousel event. It would also be good to add some easing for a smoother scroll effect.

Currently the script is fired even if there is no carousel present, making it detect the presence of a carousel first is a sensible next feature.

It might be useful to package this as an add-on for Products.Carousel so that it is 100% site administrator friendly in the future.

For the record, this was easier to do, back in the day with Flash, but then Android and iOS users would not be able to see it, plus my primary machine is now a Chromebook so there isn't much of an option for using the Flash IDE anyway. I would still be left to do the integration work so that mortals could manage the system when we're done.

Saturday, June 1, 2013

Products.pipbox 1.0b2 was breaking Javascript functionality on my Plone 4.3 site


Recently I had an extended battle with a Plone site that I upgraded to Plone 4.3. The site started life as a Plone 3 site and went through a series of upgrades and now runs on Plone 4.3.
After upgrading I noticed that my carousel (image slider) was no longer sliding. In fact none of the core javascript functionality, such as the drop down menus on the edit bar, was working.

The culprit turned out to be Products.pipbox 1.0b2. I had installed it in the Plone 3 days and left it there. It was fine until the Plone 4.3 upgrade where it started to give trouble (most likely some kind of Javascript conflict). Back in the day pipbox was used to manage ajax pop ups and similar stuff but a lot of that has been integrated into Plone since Plone 4.0. So really I have no use for it so I uninstalled it and all was well again.

Since removing pipbox fixed the problem, I didn't do any further analysis around the specifics of the conflict. I'm noting this in my blog in case someone else comes across a similar issue. Now I can get back to my little AngularJS side project :).

Tuesday, May 14, 2013

Zero to bootstrap in under 60 seconds (not counting initial setup)

I needed to move quickly so I spun up a workspace at http://c9.io and installed the yeoman.io tools.

One time setup

npm install -g yo grunt-cli bower

Cloud9 IDE ships with tools for node.js, python and other platforms, quite useful since yeoman.io depends on node. I wanted to use the bootstrap generator so I installed it.

npm install -g generator-bootstrap

That's the end of the one time setup which took all of 6 minutes.

Day to day usage

I decided to start a bootstrap project, which was as easy as answering a few questions after running the command:

yo bootstrap

Zero to bootstrap  in under 60 seconds (not counting initial setup).


Thursday, September 15, 2011

3 must read books for newbie web designers

 http://www.20thingsilearned.com
This is both a technology demostration and valuable education resource. The book makes excellent use of the new HTML5 technologies why teaching valuable lessons about the web, the internet and web browsers. 



A series of tutorials that will walk you from beginner to advanced in the essential web technologies of HTML and CSS.



http://eloquentjavascript.net
I'll be honest and say that this is one that I haven't read yet, but it's on my reading list because the outline is really good. I think it will make teaching javascript a bit easier for me.








Once you've covered the basic technologies then you want to learn the processes associated with web management so head to:

 http://webstyleguide.com/


After that you'll want to learn a bit about content management systems and web languages. I have a preference for Plone and Python.

Background on these web books
Some one recently asked me about learning Web Development. In answering them I came up with what I consider an very good web learning roadmap.

Saturday, March 27, 2010

Note to Self - Using Prototype.js to dynamically insert spans within an a tag

update: I've updated the code snippet below because blogger was stripping out some of the code (note to self, may be worth looking to a new blogging platform in 2011).
For a project where I did not have access to JQuery and had no control over the generated HTML, I found myself needing to use Prototype.js.

The goal:

Starting with a list base menu in the form below:
http://img.skitch.com/20100327-xw7ukhjm4dh23m7bpjs2smp8yr.jpg

Make it "magically grow" span tags within the a tags:
http://img.skitch.com/20100327-cbdgirw3trptg728wb9edwiyrr.jpg

(You might recognize this as the code used by the sliding door menu technique, which is what I needed).
I was not able to do this successfully with Prototype's .insert() and .wrap() functions, the never put the spans in the right place, the problem is compounded by smart web browsers which don't allow you to add "broken" tags dynamically via javascript see discussion of the issue in this ruby forum.

Here's what worked (I've highlight the key code
):



So I'll need to pay more attention to innerHTML.
Argh!!! this is so much easier with JQuery.

Sign up for my upcoming Plone 5 Book & Video tutorials

plone 5 for newbies book and videos