Javascript: Difference between revisions
 (Created page with "=== Basics ===     {| class="wikitable" ! Jquery |}<!--    ================================================================================================================...")  | 
				No edit summary  | 
				||
| Line 4: | Line 4: | ||
{| class="mw-collapsible mw-collapsed wikitable"  | |||
! Bootstrap  | |||
|-  | |||
|  | |||
{| class="mw-collapsible mw-collapsed wikitable"  | |||
! Single Page Application  | |||
|-  | |||
| css:  | |||
<pre>  | |||
  .mdm-scrollable-div  | |||
  {  | |||
    height: 100%;   | |||
    overflow: auto;  | |||
  }  | |||
</pre>  | |||
html:  | |||
<pre>  | |||
  <-- header -->  | |||
  <div class="frame" id="frame1top">  | |||
    <div class="mdm-scrollable-div">  | |||
      ...  | |||
    </div>  | |||
  </div>  | |||
  <-- footer -->  | |||
</pre>  | |||
js:  | |||
<pre>  | |||
  // We need to adjust layout on resize, in ready handler, and programmatically as needed.  | |||
  $(window).resize(adjustLayout).resize();  | |||
  $( document ).ready(function() {  | |||
    // We need to adjust in ready handler, on resize, and programmatically as needed  | |||
    adjustLayout();  | |||
    /* your other page load code here*/  | |||
  });  | |||
  function adjustLayout(){  | |||
      // ----------------------  | |||
      // Fundamental dimensions  | |||
      var hh = $('#theheader').outerHeight();  | |||
      var fh = $('#thefooter').outerHeight();  | |||
      var workspace_height = $(window).height() - hh - fh;  | |||
      var workspace_width = $(window).width();   | |||
      // ----------------------  | |||
      var cols = 1;  | |||
      var col_gap = 16;  | |||
      // Margin is based on percent of one column width, so it goes to zero before column width does.  :-)  | |||
      // Width is based on total width minus margins, then split between columns.  | |||
      var margin = ($(window).width() / cols) * .04;  | |||
      var w = ($(window).width() - (margin * (cols + 1))) / cols;  | |||
      var h1 = workspace_height;  | |||
      $('#frame1top').css({  | |||
          display:'block',   | |||
          position:'absolute',  | |||
          left: margin * 1 + w * 0,  | |||
          top: hh,  | |||
          width: w,  | |||
          height: h1  | |||
      });  | |||
  }  | |||
</pre>  | |||
|}  | |||
{| class="mw-collapsible mw-collapsed wikitable"  | |||
! Button handlers  | |||
|-  | |||
| Buttons can be represented with labels; in that case, use a click handler:  | |||
<pre>  | |||
    jQuery('<label id="'+cycle.apsID+'" class="btn">MahButt</label>')  | |||
    .appendTo('#'+chartid+'-apsbar')  | |||
    .on('click', function(){  | |||
      $(location).attr('href','/v1/parameters/'+this.id+'.html');  | |||
    });  | |||
</pre>  | |||
You can also get the checked state, and prevent the button from being pressed, among other things:  | |||
<pre>  | |||
      jQuery('<label id="'+cycle.run+'" ...  | |||
      .on('click', function(e){  | |||
        var run = this.id;  | |||
        // Look for the (label->input)  | |||
        if (this.firstChild.checked)  | |||
        ...  | |||
        // To prevent checked/pressed state if desired:  | |||
        e.stopPropagation();  | |||
      }    | |||
</pre>  | |||
Button bars are represented by labels wrapped around inputs:  | |||
<pre>  | |||
    <div class="btn-group live-buttons" data-toggle="buttons"><div class="btn-group"><label class="btn"><input type="checkbox">text...  | |||
</pre>  | |||
In that case use a change handler on the input:  | |||
<pre>  | |||
      var label = jQuery('<label class="btn btn-sm btn-'+color+'"></label>').appendTo(action_button_bar);  | |||
      var input = jQuery('<input class="run-'+cmd+'" type="checkbox" autocomplete="off" value="'+cycle.run+'">').appendTo(label)  | |||
      .on('change', cycle.owned? function(){  | |||
        patchPick(this.value,'{ "action" : "run-hold"       }');  | |||
      } : function() {  | |||
        patchPick(this.value,'{ "action" : "run-buy"        }');  | |||
      });  | |||
      var text = jQuery('<span class="glyphicon glyphicon-'+glyph+'"></span> <span class="hidden-xs">'+cmd+'</span>').appendTo(label);  | |||
</pre>  | |||
If you just need clicks from the button bar, you do NOT NEED input:  | |||
<pre>  | |||
    <div class="btn-group live-buttons" data-toggle="buttons"><div class="btn-group"><label class="btn">text...  | |||
</pre>  | |||
Then you can put the change handler right on the label:  | |||
<pre>  | |||
    var applybar = jQuery('<div id="applybar-'+cycle.run+'" class="btn-group pull-right" data-toggle="buttons" />');  | |||
    var apply_button = jQuery('<label id="apply-'+cycle.run+'" class="btn btn-sm btn-moneygreen"><span class="glyphicon glyphicon-ok"></span><span class="hidden-xs"> Apply</span></input></label>')  | |||
    .on('click', function(e) {      | |||
        // Do work  | |||
        e.stopPropagation();  | |||
    })  | |||
    .appendTo(applybar)  | |||
    ;  | |||
</pre>  | |||
|}  | |||
{| class="mw-collapsible mw-collapsed wikitable"  | |||
! Programmatically pressing a button  | |||
|-  | |||
| You MUST DO TWO THINGS:  | |||
* Set the active class on the button/label  | |||
* Set the input to checked  | |||
 <label class="btn active">  | |||
   <input type="checkbox" autocomplete="off" checked>  | |||
   Click me  | |||
 </label>  | |||
|}  | |||
{| class="mw-collapsible mw-collapsed wikitable"  | |||
! Handling the UNCHECK event on a pushbutton  | |||
|-  | |||
| Again you MUST SET BOTH active and checked STATES PROPERLY when creating the button (see above).  Do not set either if the button is unpressed; set both if it is pressed.  | |||
Then you can use a single change event:  | |||
   $("input[type='checkbox'][class='run-hold-on-buy'     ]").change(function() { patchPick(this.value,'{ "action" : "'+(this.checked?'hold-on-buy-on'     :'hold-on-buy-off'     )+'"}');  });  | |||
|}  | |||
{| class="mw-collapsible mw-collapsed wikitable"  | |||
! Collapsible panel  | |||
|-  | |||
|   | |||
* Use a unique id on content div, data-target to connect panel header to content, mdm-panel-collapser so javascript can find icon, abt-scrollable-panel for margin.  | |||
* HTML for each panel (starts collapsed)  | |||
<pre>  | |||
    <div class="panel panel-default abt-scrollable-panel">  | |||
      <div class="panel-heading collapsed" data-toggle="collapse" data-target="#my-content-block-one">Software development skills<span class="mdm-panel-collapser text-muted glyphicon glyphicon-chevron-down pull-right"></span></div>  | |||
      <div class="collapse" id="my-content-block-one">  | |||
        <div class="mdm-panel-body">  | |||
         <!-- CONTENT, can include another nested panel, just add .mdm-nested-panel to class; example: -->  | |||
          <div class="panel panel-default mdm-scrollable-panel mdm-nested-panel">  | |||
            <div class="panel-heading collapsed mdm-job-panel-heading" data-toggle="collapse" data-target="#toshiba-job"><p><strong>Senior Developer and Offshore Manager</strong><i> - Toshiba Global Commerce Solutions, Inc.</i><span class="mdm-panel-collapser text-muted glyphicon glyphicon-chevron-up pull-right"></span></p><p><small>April 2014 – August 2015</small></p></div>  | |||
            <div class="collapse in" id="toshiba-job">  | |||
              <div class="mdm-panel-body">  | |||
                <!-- SUBCONT(IN)ENT im so funny -->  | |||
              </div>  | |||
            </div>  | |||
          </div>  | |||
        </div>  | |||
      </div>  | |||
    </div>  | |||
</pre>  | |||
* For an expanded panel, simply change icon from down to up, and add "in" to content div:  | |||
<pre>  | |||
    ... glyphicon-chevron-up ...  | |||
    <div class="collapse in mdm-panel-body" id="collapseOrderItems1">  | |||
</pre>  | |||
* Define Javascript collapser once on load  | |||
  $('.collapse').on('hide.bs.collapse show.bs.collapse',   | |||
    toggleCollapser  | |||
  );  | |||
* CSS  | |||
    .mdm-nested-panel {  | |||
      margin-top: 1em;  | |||
      margin-left: 1em;  | |||
    }  | |||
    collapse.mdm-panel-body collapsing.mdm-panel-body {  | |||
        margin: 1em;  | |||
    }  | |||
* Common reusable function:  | |||
  function toggleCollapser(e) {  | |||
      $(e.target)  | |||
          .prev('.panel-heading')  | |||
          .find('.mdm-panel-collapser')  | |||
          .toggleClass('glyphicon-chevron-down glyphicon-chevron-up');  | |||
    // Prevent bubble up to any parent collapsers.  | |||
    // This allows nested collapsers, whoop.  | |||
    e.stopPropagation();  | |||
  }  | |||
|}  | |||
|}  | |||
<!--   | |||
===========================================================================================================================================================================================================================================================================================  | |||
-->  | |||
{| class="mw-collapsible mw-collapsed wikitable"  | |||
! D3  | |||
|-  | |||
|  | |||
{| class="mw-collapsible mw-collapsed wikitable"  | |||
! ALWAYS initialize incoming data  | |||
|-  | |||
| Hard-earned data-import lessons:  | |||
* tsv() will do complete date formatting, so when you remove it to use JSON directly, you HAVE TO convert JSON timestamps of ANY kind to full Javascript date objects:  | |||
  var data = [{"date":"2017-04-01T04:00:00.000Z",...  | |||
  // MDM WE MUST MASSAGE DATA HERE  | |||
  // JSON VALUES ARE ALWAYS STRINGS, we need to change to Javascript DATE!  | |||
  // Incoming datasets need a bit of massaging.  | |||
  // We do that in a function so we can reuse it on incoming dataset updates.  | |||
  function initializeDataset(dataset) {  | |||
      // TIME ON X  | |||
      // Convert date strings to actual date values.  | |||
      // MDM MAKE SURE this matches the incoming format.  | |||
      // Adding date so we can run the chart across days without trouble.  | |||
      // var parseDate = d3.time.format("%H:%M:%S %m-%d-%Y").parse;  | |||
      // var parseDate = d3.timeParse("%Y %b %d");  | |||
      var parseDate = d3.utcParse("%Y-%m-%dT%H:%M:%S.%LZ");  | |||
      dataset.forEach(function(d) {  | |||
          // there is NO SKIPING THIS STEP, you have to get valid Javascript date objects out of JSON strings  | |||
          d.date = parseDate(d.date);  | |||
          // we WOULD have to divide all data by zero,  | |||
          // but we already grabbed post-data that was already converted  | |||
          // This WORKS but makes data / 10000 (very small numbers)  | |||
          //for (var i = 1, n = dataset.columns.length; i < n; ++i) d[dataset.columns[i]] = d[dataset.columns[i]] / 100;  | |||
      });  | |||
  }  | |||
  initializeDataset(data);  | |||
* tsv() will create an ARRAY but it also jams in a columns PROPERY; it takes two steps to duplicate that:  | |||
   var data = [  | |||
     {"date":"2015-06-15T04:00:00.000Z","Google Chrome":0.48090000000000005,...},  | |||
     {"date":"2015-06-22T04:00:00.000Z","Google Chrome":0.48979999999999996,...),  | |||
  ];  | |||
  data.columns = ["date","Google Chrome","Internet Explorer",...  ];  | |||
|}  | |||
{| class="mw-collapsible mw-collapsed wikitable"  | |||
! ALWAYS set range and domain properly  | |||
|-  | |||
| You have to know your display size (range) and the min and max of your data (domain), on each axis.  From [https://bost.ocks.org/mike/bar/ Mike's docs]:  | |||
D3’s scales specify a mapping from data space (domain) to display space (range).  | |||
        D3’s scales can also be used to interpolate many other   | |||
        types of display-space values, such as paths, color spaces   | |||
        and geometric transforms.  | |||
          var x = d3.scale.linear()  | |||
              .domain([0, d3.max(data)])  | |||
              .range([0, 420]);  | |||
        Although x here looks like an object, it is also a function   | |||
        that returns the scaled display value in the range   | |||
        for a given data value in the domain.   | |||
        For example, an input value of 4 returns 40, and an input value of 16   | |||
        returns 160. To use the new scale, simply replace the   | |||
        hard-coded multiplication by calling the scale function:  | |||
        d3.select(".chart")  | |||
          .selectAll("div")  | |||
            .data(data)  | |||
          .enter().append("div")  | |||
            .style("width", function(d) { return x(d) + "px"; })  | |||
            .text(function(d) { return d; });  | |||
Watch out for Mike's examples where he (trickily) doesn't bother to set a domain because his data is in the [0..1] set, and that's the default domain, apparently.  | |||
|}  | |||
|}<!--   | |||
===========================================================================================================================================================================================================================================================================================  | |||
-->  | |||
{| class="wikitable"  | {| class="wikitable"  | ||
! [[Jquery]]  | ! [[Jquery]]  | ||
Revision as of 14:52, 3 March 2018
Basics
| Bootstrap | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
 
 
 
 
  | 
| D3 | ||||
|---|---|---|---|---|
 
  | 
| Jquery | 
|---|
| Vega-lite | 
|---|