Sunday, November 17, 2013

Further Adventures with Polymer and Bootstrap Panels


I had a nice, calming time with Polymer (the JavaScript flavor) last night. Having fought for much of the day with Bootstrap, I was happy to convert a bunch of panels like so:
<div id="price">
  <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> <!-- /#price -->
Into a much less noisy version that looks like:
<div id="price">
  <div class="container">
    <div class="col-md-10 col-md-offset-1 col-sm-4">
      <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>
      <!-- More pricing plans here -->
    </div> <!-- /.col-md-10 -->
  </div> <!-- /.container -->
</div> <!-- /#price -->
Aside from the containing col-md-10 (which I will worry about tomorrow), that is a very pleasant and, dare I say it, semantic bunch of content.

I left off last night wanting to be able to adjust the panel type and size. Both of those are fairly trivial modifications to the pricing-plan.html polymer-element definition that is referenced by my page:
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Test</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/bootstrap.min.css">
    <script src="scripts/polymer.min.js"></script>
    <link rel="import" href="pricing-plan.html">
  </head>
  <!-- html document here... -->
</html>
The fix is it add more published attributes (along with sane default values) to the element definition:
<polymer-element name="pricing-plan" attributes="name type size">
  <template>
    <div class="col-md-{{size}}">
      <div class="panel panel-{{type}}">
        <div class="panel-heading">
          <h3 class="panel-title">{{name}}</h3>
        </div>
        <div class="panel-body">
          <content></content>
        </div>
      </div>
    </div>
  </template>
  <script>
    Polymer('pricing-plan', {
      name: 'Plan',
      type: 'default',
      size: 4
    });
  </script>
</polymer-element>
With that, I can define my plans as:
<div id="price">
  <div class="container">
    <div class="col-md-10 col-sm-4">
      <pricing-plan name="Multi-Language">
        <ul><!-- ... --></ul>
      </pricing-plan>
      <pricing-plan name="I Only Like One">
        <ul><!-- ... --></ul>
      </pricing-plan>
      <pricing-plan name="Extras" type="primary" size="4">
        <ul><!-- ... --></ul>
      </pricing-plan>
    </div> <!-- class="col-md-10 col-md-offset-1 col-sm-4 " -->
  </div> <!-- /.container -->
</div> <!-- /#price -->
Which results in a nice list of plans:



Darn it. That was a little too easy. Darn you Polymer, I normally like to make things a little harder for myself. So I ask a bonus question tonight. How can I do this without requiring the web page to load the Bootstrap CSS and JavaScript? The answer, at least as far as I can tell from the FAQ is to add tags such that the browser can ignore dependedencies that are required multiple times.

Something like this seems to do the trick:
<polymer-element name="pricing-plan" attributes="name type size">
  <template><!-- ... --></template>
  <script>
    var ss = document.createElement("link");
    ss.type = "text/css";
    ss.rel = "stylesheet";
    ss.href = "css/bootstrap.min.css";
    document.getElementsByTagName("head")[0].appendChild(ss);

    Polymer('pricing-plan', {
      name: 'Plan',
      type: 'default',
      size: 4
    });
  </script>
</polymer-element>
(adapted from this StackOverflow solution)

Even if I add that <link> tag a hundred times, the browser should only make a single request for the duplicate resource. And, if I clear the browser cache and reload the page, that is exactly what I see:
127.0.0.1 - - [17/Nov/2013 23:54:16] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [17/Nov/2013 23:54:16] "GET /scripts/polymer.min.js HTTP/1.1" 200 -
127.0.0.1 - - [17/Nov/2013 23:54:17] "GET /pricing-plan.html HTTP/1.1" 200 -
127.0.0.1 - - [17/Nov/2013 23:54:17] "GET /scripts/polymer.min.js.map HTTP/1.1" 200 -
127.0.0.1 - - [17/Nov/2013 23:54:17] "GET /css/bootstrap.min.css HTTP/1.1" 200 -
That is not going to win me any style points, but I'll take it for now.


Day #938

No comments:

Post a Comment