<style>
    .fields-container ul {
      overflow-y: auto;
      border: 1px solid #ccc;
      padding: 5px 0 0 0;
      list-style-type: none;
    }
    .fields-container label {
      color: #008571;
      font-weight: bold;
    }
    .fields-container li {
      margin: 0px 5px 5px 5px;
      padding: 5px;
      border: 1px solid #ccc;
      background-color: lightcyan;
      overflow: hidden;
      width: auto;
      min-width: 150px;
    }
    .fields-container .keys-fields > label:not(:first-child),
    .fields-container .values-fields > label:not(:first-child) {
      display: none;
    }
    .fields-container.field-drag .keys-fields:not(.field-drag-acceptable) > ul,
    .fields-container.field-drag .values-fields:not(.field-drag-acceptable) > ul {
      opacity: 0.35;
    }
    .fields-container.field-drag .keys-fields:not(.field-drag-acceptable) > label:first-child,
    .fields-container.field-drag .values-fields:not(.field-drag-acceptable) > label:first-child {
      display: none;
    }
    .fields-container.field-drag .keys-fields:not(.field-drag-acceptable):not(.field-drag-no) > label:nth-child(2),
    .fields-container.field-drag .values-fields:not(.field-drag-acceptable):not(.field-drag-no) > label:nth-child(2),
    .fields-container.field-drag .keys-fields.field-drag-no > label:nth-child(3),
    .fields-container.field-drag .values-fields.field-drag-no > label:nth-child(3) {
      color: #ff0000;
      font-weight: 400;
      display: inline-block;
    }
    .fieldslist-wrapper {
      height: 100%;
    }
    .fieldslist-wrapper label {
      color: #008571;
      font-weight: bold;
    }
    .fieldslist-showlink {
      color: #337ab7;
      cursor: pointer;
      display: inline-block;
      font-size: 0.95em;
      font-weight: 300;
      position: absolute;
      right: 20px;
      top: 3px;
    }
    .fieldslist-showlink:hover {
      color: #286090;
      text-decoration: underline;
    }
    .fieldslist-allfields {
      height: calc(100% - 65px);
    }
    .fieldslist-allfields.numeric-only > [data-field-type="string"] {
      display: none;
    }
    .fields-container .ui-draggable-dragging {
      background-color: paleturquoise;
      width: 75%;
    }
    .fields-container .ui-draggable-dragging a {
      display: none;
    }
    .fields-container .ui-draggable-dragging span {
      display: inline;
    }
    .field-drop-hover.ui-droppable {
      background-color: ghostwhite;
      border-color: gray;
    }
    .field-remove {
      color: #777;
      font-size: 14px;
      float: right;
      margin: 0px;
      cursor: pointer;
    }
    .field-remove:after {
      content: "x";
    }
    .field-name {
      font-weight: 600;
    }
    .field-type {
      float: right;
      font-style: italic;
    }
    .keys-fields > ul {
      height: 147px;
    }
    .keys-fields .field-type,
    .values-fields .field-type,
    .fieldslist-wrapper .field-remove {
      display: none;
    }
    .keys-fields {
      height: 177px;
      margin-bottom: 5px;
    }
    .values-fields {
      height: 365px;
    }
    .keys-fields + .values-fields {
      height: 177px;
    }
    .warnEmptyValueFields {
      font-size: smaller;
      display: inline-block;
      top: -10px;
      position: relative;
    }
</style>
<div class="fields-container row">
  <div class="col-sm-6" style="padding: 0px 5px 0px 0px; height: 365px;">
    <div class="fieldslist-wrapper" style="height:100%">
      <label>Fields:</label>
      <span class="fieldslist-showlink" role="button">Show only numeric columns</span>
      <input type="text" class="fieldslist-filter form-control input-sm" placeholder="Search/Filter Fields">
      <ul class="fieldslist-allfields all-fields-drop-{{prefix}}">
      {% for field in this.fieldNamesAndTypes %}
        {% if field[0] in this.fieldNames %}
        <li class="fieldslist-field-{{prefix}}" data-field="{{field.0}}" data-field-type="{{field.1}}">
          <span class="field-name">{{field.0}}</span>
          <span class="field-type">{{field.1}}</span>
          <a class="field-remove">
            <pd_script>
if '{{field.0}}' in self.keyFields:
  self.keyFields.remove('{{field.0}}')
elif '{{field.0}}' in self.valueFields:
  self.valueFields.remove('{{field.0}}')
            </pd_script>
          </a>
        </li>
        {% endif %}
        {% endfor %}
      </ul>
    </div>
  </div>
  <div class="col-sm-6" style="padding: 0px 0px 0px 5px;">
    {%if this.keyFieldsSupported %}
    <div class="keys-fields">
      <label>Keys: <i class="fa fa-question-circle" title="Controls the X-Axis of the chart. Rows will be grouped by Key columns. Columns may be {% for kf in this.keyFieldsType %}{% if this.keyFieldsType|length > 1%}{% if loop.last %}or {% endif %}{% endif %}{{kf}}{% if not loop.last %}, {% endif %}{% endfor %}."></i></label>
      <label>Keys: Only {% for kf in this.keyFieldsType %}{% if this.keyFieldsType|length > 1%}{% if loop.last %}or {% endif %}{% endif %}{{kf}}{% if not loop.last %}, {% endif %}{% endfor %} columns are supported <i class="fa fa-warning"></i></label>
      <label>Keys: Adding the same Field to Keys and Values is not supported. <i class="fa fa-warning"></i></label>
      <ul id="keys-fields-{{prefix}}" class="field-drop key-field-drop-{{prefix}}" style="height:calc(100% - 30px);" pd_script="self.options_callback('keyFields', '$val(updateSelectedKeysFields)')">
      {% for field in this.fieldNamesAndTypes %}
        {% if field[0] in this.keyFields and field[0] in this.fieldNames %}
        <li class="fieldslist-field-{{prefix}}" data-field="{{field.0}}" data-field-type="{{field.1}}">
          <span class="field-name">{{field.0}}</span>
          <span class="field-type">{{field.1}}</span>
          <a class="field-remove">
            <pd_script>
if '{{field.0}}' in self.keyFields:
  self.keyFields.remove('{{field.0}}')
elif '{{field.0}}' in self.valueFields:
  self.valueFields.remove('{{field.0}}')
            </pd_script>
          </a>
        </li>
        {% endif %}
      {% endfor %}
      </ul>
    </div>
    {%endif%}
    <div class="values-fields">
      <label>Values: <i class="fa fa-question-circle" title="Controls the Y-Axis of the chart. Values must be {% for vf in this.valueFieldsType %}{% if this.valueFieldsType|length > 1%}{% if loop.last %}or {% endif %}{% endif %}{{vf}}{% if not loop.last %}, {% endif %}{% endfor %} columns."></i></label>
      <label>Values: Only {% for vf in this.valueFieldsType %}{% if this.valueFieldsType|length > 1%}{% if loop.last %}or {% endif %}{% endif %}{{vf}}{% if not loop.last %}, {% endif %}{% endfor %} columns are supported <i class="fa fa-warning"></i></label>
      <label>Values: Adding the same Field to Keys and Values is not supported. <i class="fa fa-warning"></i></label>
      <ul id="values-fields-{{prefix}}" class="field-drop value-field-drop-{{prefix}}" style="height:calc(100% - 30px);" pd_script="self.options_callback('valueFields', '$val(updateSelectedValuesFields)')">
      {% for field in this.fieldNamesAndTypes %}
        {% if field[0] in this.valueFields and field[0] in this.fieldNames %}
        <li class="fieldslist-field-{{prefix}}" data-field="{{field.0}}" data-field-type="{{field.1}}">
          <span class="field-name">{{field.0}}</span>
          <span class="field-type">{{field.1}}</span>
          <a class="field-remove">
            <pd_script>
if '{{field.0}}' in self.keyFields:
  self.keyFields.remove('{{field.0}}')
elif '{{field.0}}' in self.valueFields:
  self.valueFields.remove('{{field.0}}')
            </pd_script>
          </a>
        </li>
        {% endif %}
      {% endfor %}
      </ul>
      {%if this.keyFieldsSupported %}
      <span id="warnEmptyValueFields{{prefix}}" class="warnEmptyValueFields">PixieDust will automatically use count aggregation for each key</span>
      {%endif%}
    </div>
  </div>
</div>
<script>
  var valueFieldsType = []
  {% for vf in this.valueFieldsType %}
  valueFieldsType.push('{{vf}}')
  {% endfor %}

  var keyFieldsType = []
  {% for kf in this.keyFieldsType %}
  keyFieldsType.push('{{kf}}')
  {% endfor %}

  $('.fieldslist-showlink').click(function() {
    if ($('.fieldslist-allfields').hasClass('numeric-only')) {
      $('.fieldslist-allfields').removeClass('numeric-only')
      $(this).text('Show only numeric columns')
    }
    else {
      $('.fieldslist-allfields').addClass('numeric-only')
      $(this).text('Show all columns')
    }
  })

  var rows = $('.fieldslist-wrapper .fieldslist-field-{{prefix}}')
  $('.fieldslist-filter').keyup(function() {
    var val = '^(?=.*\\b' + $.trim($(this).val()).split(/\s+/).join('\\b)(?=.*\\b') + ').*$'
    var reg = RegExp(val, 'i')
    var index = 0
    rows.each(function(i, e) {
      if (!reg.test($(this).text().replace(/\s+/g, ' '))) {
        $(this).attr('class', 'hidden')
      }
      else {
        $(this).attr('class', (++index % 2 == 0 ? 'even' : 'odd'))
      }
    })
  })

  $('.key-field-drop-{{prefix}}, .value-field-drop-{{prefix}}, .all-fields-drop-{{prefix}}').droppable({
    tolerance: 'pointer',
    hoverClass: 'field-drop-hover',
    accept: function(d) {
      if ($(this).hasClass('all-fields-drop-{{prefix}}')) {
        return true
      } else {
        var selected = []
        var fieldtype = $(this).hasClass('key-field-drop-{{prefix}}') ? keyFieldsType : valueFieldsType
        if (d.parent().hasClass('fieldslist-allfields')) {
          selected = ($(this).hasClass('key-field-drop-{{prefix}}') ? selectedFieldsListStr('values-fields-{{prefix}}') : selectedFieldsListStr('keys-fields-{{prefix}}')).split(',')
        }
        return (fieldtype.indexOf(d.data('fieldType')) >= 0 || fieldtype.indexOf('any') >= 0)
          && (selected.indexOf(d.data('field')) === -1 || $(this).parent().addClass('field-drag-no').hasClass('return-false'))
      }
    },
    activate: function(event, ui) {
      $(this).parent().addClass('field-drag-acceptable')
    },
    deactivate: function(event, ui) {
      $(this).parent().removeClass('field-drag-acceptable')
    },
    drop:function(event, ui) {
      var fieldName = ui.draggable.attr('data-field')
      if ($(this).find('[data-field="' + fieldName + '"]').length === 0) {
        var el = ui.draggable.clone()
        if (!ui.draggable.parent().hasClass('fieldslist-allfields')) {
          ui.draggable.find('a').click()
        }
        makeRemoveable(el.find('a'))
        makeDraggable(el)
        $(this).append(el).click()
      } else if (!$(this).is(ui.draggable.parent())) {
        ui.draggable.find('a').click()
      }
    }
  })

  makeDraggable($('.fieldslist-field-{{prefix}}'))
  makeRemoveable($('.key-field-drop-{{prefix}} .field-remove'))
  makeRemoveable($('.value-field-drop-{{prefix}} .field-remove'))

  function makeRemoveable(nodes) {
    nodes.click(function(e) {
      e.preventDefault()
      var drop = $(this).closest('.field-drop')
      $(this).parent().remove()
      setTimeout(function () {
        drop.click()
      }, 300)
      return false
    })
  }
  function makeDraggable(nodes) {
    nodes.draggable({
      helper: 'clone',
      zIndex: 500,
      cursor: 'grab',
      containment: 'document',
      start: function(event, ui) {
        $('.fields-container').addClass('field-drag')
      },
      stop: function(event, ui) {
        $('.fields-container')
          .removeClass('field-drag')
          .find('.keys-fields, .values-fields')
          .removeClass('field-drag-acceptable')
          .removeClass('field-drag-no')
      }
    })
  }
  function selectedFieldsListStr(fieldid) {
    var selected = []
    $('#' + fieldid + ' li')
      .each(function () {
        selected.push($(this).data('field'))
      })
    return selected.join(',')
  }
  function updateSelectedKeysFields() {
    var selected = selectedFieldsListStr('keys-fields-{{prefix}}')
    if (!selected && hasSelectedKeyFields) {
      hasSelectedKeyFields = false
      chartOptionsOKStatus{{prefix}}(true)
    } else if (selected && !hasSelectedKeyFields) {
      hasSelectedKeyFields = true
      chartOptionsOKStatus{{prefix}}(false)
    }
    return selected
  }
  function updateSelectedValuesFields() {
    var selected = selectedFieldsListStr('values-fields-{{prefix}}')
    if (selected){
      $('#warnEmptyValueFields{{prefix}}').hide()
    } else {
      $('#warnEmptyValueFields{{prefix}}').show()
    }
    {% if not this.keyFieldsSupported %}
    if (!selected && hasSelectedKeyFields) {
      hasSelectedKeyFields = false
      chartOptionsOKStatus{{prefix}}(true)
    } else if (selected && !hasSelectedKeyFields) {
      hasSelectedKeyFields = true
      chartOptionsOKStatus{{prefix}}(false)
    }
    {% endif %}
    return selected
  }

  var hasSelectedKeyFields = {% if this.keyFieldsSupported %} !!selectedFieldsListStr('keys-fields-{{prefix}}') {% else %} !!selectedFieldsListStr('values-fields-{{prefix}}') {% endif %}
  updateSelectedValuesFields()
  chartOptionsOKStatus{{prefix}}(!hasSelectedKeyFields)
</script>