github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-supply-chain-master/fish_client/src/components/forms.js (about)

     1  /**
     2   * Copyright 2017 Intel Corporation
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   * ----------------------------------------------------------------------------
    16   */
    17  'use strict'
    18  
    19  const m = require('mithril')
    20  const _ = require('lodash')
    21  
    22  const layout = require('./layout')
    23  
    24  /**
    25   * Returns a labeled form group
    26   */
    27  const group = (label, ...contents) => {
    28    return m('.form-group', [
    29      m('label', label),
    30      contents
    31    ])
    32  }
    33  
    34  /**
    35   * Returns a bare input field suitable for use in a form group.
    36   * Passes its value to a callback, and defaults to required.
    37   */
    38  const field = (onValue, attrs = null) => {
    39    const defaults = {
    40      required: true,
    41      oninput: m.withAttr('value', onValue)
    42    }
    43  
    44    return m('input.form-control.mb-1', _.assign(defaults, attrs))
    45  }
    46  
    47  /**
    48   * Returns a labeled input field which passes its value to a callback
    49   */
    50  const input = (type, onValue, label, required) => {
    51    return group(label, field(onValue, { type, required }))
    52  }
    53  
    54  const textInput = _.partial(input, 'text')
    55  const passwordInput = _.partial(input, 'password')
    56  const numberInput = _.partial(input, 'number')
    57  const emailInput = _.partial(input, 'email')
    58  
    59  /**
    60   * Creates an icon with an onclick function
    61   */
    62  const clickIcon = (name, onclick) => {
    63    return m('span.mx-3', { onclick }, layout.icon(name))
    64  }
    65  
    66  /**
    67   * Convenience function for returning partial onValue functions
    68   */
    69  const stateSetter = state => key => value => { state[key] = value }
    70  
    71  /**
    72   * Event listener which will set HTML5 validation on the triggered element
    73   */
    74  const validator = (predicate, message, id = null) => e => {
    75    const element = id === null ? e.target : document.getElementById(id)
    76  
    77    if (predicate(element.value)) {
    78      element.setCustomValidity('')
    79    } else {
    80      element.setCustomValidity(message)
    81    }
    82  }
    83  
    84  /**
    85   * Triggers a download of a dynamically created text file
    86   */
    87  const triggerDownload = (name, ...contents) => {
    88    const file = new window.Blob(contents, {type: 'text/plain'})
    89    const href = window.URL.createObjectURL(file)
    90    const container = document.getElementById('download-container')
    91    m.render(container, m('a#downloader', { href, download: name }))
    92    document.getElementById('downloader').click()
    93    m.mount(container, null)
    94  }
    95  
    96  /**
    97   * A MultiSelect component.
    98   *
    99   * Given a set of options, and currently selected values, allows the user to
   100   * select all, deselect all, or select multiple.
   101   */
   102  const MultiSelect = {
   103    view (vnode) {
   104      let handleChange = vnode.attrs.onchange || (() => null)
   105      let selected = vnode.attrs.selected
   106      let color = vnode.attrs.color || 'light'
   107      return [
   108        m('.dropdown',
   109          m(`button.btn.btn-${color}.btn-block.dropdown-toggle.text-left`,
   110            {
   111              'data-toggle': 'dropdown',
   112              onclick: (e) => {
   113                e.preventDefault()
   114                vnode.state.show = !vnode.state.show
   115              },
   116              onblur: e => { vnode.state.show = false }
   117            }, vnode.attrs.label),
   118          m('.dropdown-menu.w-100', {className: vnode.state.show ? 'show' : ''},
   119            m("a.dropdown-item[href='#']", {
   120              onclick: (e) => {
   121                e.preventDefault()
   122                handleChange(vnode.attrs.options.map(([value, label]) => value))
   123              }
   124            }, 'Select All'),
   125            m("a.dropdown-item[href='#']", {
   126              onclick: (e) => {
   127                e.preventDefault()
   128                handleChange([])
   129              }
   130            }, 'Deselect All'),
   131            m('.dropdown-divider'),
   132            vnode.attrs.options.map(
   133              ([value, label]) =>
   134               m("a.dropdown-item[href='#']", {
   135                 onclick: (e) => {
   136                   e.preventDefault()
   137  
   138                   let setLocation = selected.indexOf(value)
   139                   if (setLocation >= 0) {
   140                     selected.splice(setLocation, 1)
   141                   } else {
   142                     selected.push(value)
   143                   }
   144  
   145                   handleChange(selected)
   146                 }
   147               }, label, (selected.indexOf(value) > -1 ? ' \u2714' : '')))))
   148      ]
   149    }
   150  }
   151  
   152  module.exports = {
   153    group,
   154    field,
   155    input,
   156    textInput,
   157    passwordInput,
   158    numberInput,
   159    emailInput,
   160    clickIcon,
   161    stateSetter,
   162    validator,
   163    triggerDownload,
   164    MultiSelect
   165  }