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 }