Saturday, November 16, 2013

Polymer and Bootstrap


Tonight, I step a little outside my comfort zone and program in... JavaScript.

Well, OK, not too far outside my comfort zone, but since I turned 3D Game Programming for Kids over to my editor, it has been a good streak of pure Dart blogging. But, for my next book to come in Dart and JavaScript flavors, I necessarily need to have a good feel for coding Polymer in JavaScript. Since I have yet to do that, now seems a good time to start.

I like to start simple and dumb, but never seem to manage it. One could argue that those are the same things, but I manage to do both quite often, thank you very much! By "simple," I mean limiting newish features and coupling. By "dumb," I mean that I am probably going to be misusing Polymer. I think the <ice-code-editor> tag that I created in Dart was pretty cool, but it was pretty complicated given the underlying editor. Tonight, I start with <pricing-plans>, which will not be simple because of external coupling.

I wound up spending a lot of time on the pricing plans section of the Patterns in Polymer landing page. Since I have other books that I might like to sell in a similar fashion, maybe the <pricing-plans> tag isn't too dumb. But it probably is...

The thing that was giving me grief was fiddling with various Bootstrap panel class values:
<div id="price" class="list-spread-narrow">
  <div class="container">
    <div class="col-md-10 col-md-offset-1 col-sm-4 ">
      <div class="panel panel-default col-md-3">
        <div class="panel-heading">
          <h3 class="panel-title">Multi-Language</h3>
        </div>
        <div class="panel-body">
          <ul>
            <li>Get the <strong>JavaScript</strong> version!</li>
            <li>Get the <strong>Dart</strong> version!</li>
            <li>Private <strong>GitHub repository</strong> access to see how
            it's done.</li>
          </ul>
        </div>
      </div> <!-- /.panel1 -->
      <!-- More panels here -->
  </div> <!-- /.container -->
</div> <!-- /.list-spread-narrow -->
After a while, that stuff starts to get to me. Since this tends to be very repetitive, perhaps this is something that I can extract out? I have no real idea if it is a good idea to couple Bootstrap and Polymer, but there is one way to find out!

So I do the usual Polymer thing by including the library and a reference to the element that I am going to create in the <head> section of my HTML document:
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Test</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta content="text/html; charset=UTF-8" http-equiv="content-type">
    <link rel="stylesheet" href="css/bootstrap.min.css">
    <!-- 1. Load Polymer before any code that touches the DOM. -->
    <script src="scripts/polymer.min.js"></script>
    <!-- 2. Load a component -->
    <link rel="import" href="pricing-plan.html">
  </head>
  <body>
  <!-- pricing plans here.... ->
  </body>
</html>
For my first pass, I define pricing-plan.html as:
<polymer-element name="pricing-plan" noscript>
  <template>
     <div class="panel panel-default col-md-3">
       <div class="panel-heading">
         <h3 class="panel-title">Multi-Language</h3>
       </div>
       <div class="panel-body">
         <content></content>
       </div>
     </div> <!-- /.panel1 -->
  </template>
</polymer-element>
I have pulled in the repetitive panel definition, but not the actual list of features. Those are specific to each panel, so I will need to include that content where the <content> tag is in my template. Back in the main document, I can use this tag as:
<pricing-plan>
  <ul>
    <li>Get the <strong>JavaScript</strong> version!</li>
    <li>Get the <strong>Dart</strong> version!</li>
    <li>Private <strong>GitHub repository</strong> access to see how
      it's done.</li>
  </ul>
</pricing-plan>
That is a lot cleaner and easier to follow. Especially given that I did not have too much work to make it happen:



The last thing that I would like to do tonight is the ability to specify the name of the pricing plan. For this one, it would be "Multi-language." For that, I need to drop the noscript declaration from my <polymer-element> definition. In its place, I need a very simple script that creates a simple Polymer object:
  <script>
    Polymer('pricing-plan');
  </script>
That allows me to declare a list of public attributes for my element. The only attribute that I need is name so my entire <polymer-element> becomes:
<polymer-element name="pricing-plan" attributes="name">
  <template>
     <div class="panel panel-default col-md-3">
       <div class="panel-heading">
         <h3 class="panel-title">{{name}}</h3>
       </div>
       <div class="panel-body">
         <content></content>
       </div>
     </div> <!-- /.panel1 -->
  </template>
  <script>
    Polymer('pricing-plan');
  </script>
</polymer-element>
Back in the main HTML document, I can make use of this as:
<pricing-plan name="Multi-Language">
  <ul>
    <li>Get the <strong>JavaScript</strong> version!</li>
    <li>Get the <strong>Dart</strong> version!</li>
    <li>Private <strong>GitHub repository</strong> access to see how
      it's done.</li>
  </ul>
</pricing-plan>
That is some simplified HTML!

I still might like the ability to make those columns a little wider or more narrow, depending on how many pricing plans I have. Ooh! And I still need to be able specify one as being the primary entry. Grist for tomorrow.



Day #937

No comments:

Post a Comment