MultiLineTextInput.vue 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <template>
  2. <div>
  3. <!-- Send a label through props -->
  4. <label class="label">{{label}}</label>
  5. <!-- Iterate lines here -->
  6. <div class="multi-field field"
  7. v-for="(line, index) in lines"
  8. :key="line.index">
  9. <div class="control multi-control">
  10. <div class="multi-input-container">
  11. <input
  12. @input.prevent="emitUpdate($event, index)"
  13. :value="line.value"
  14. placeholder="Add Something Nice (:"
  15. class="input is-medium multi-input"
  16. type="text">
  17. </div>
  18. <div class="btn-container">
  19. <!-- Delete the line -->
  20. <button
  21. @click.prevent="emitRemove(index)"
  22. type="button"
  23. class="button is-danger multi-button">
  24. Delete
  25. </button>
  26. </div>
  27. </div>
  28. </div>
  29. <!-- Add the Line -->
  30. <button
  31. @click="emitAdd"
  32. type="button"
  33. class="m-b-sm button is-medium is-link is-outlined">
  34. Add an answer
  35. </button>
  36. </div>
  37. </template>
  38. <script>
  39. export default {
  40. props:{
  41. label : {
  42. type: String,
  43. required: true
  44. },
  45. lines: {
  46. type: Array,
  47. required: true
  48. }
  49. },
  50. computed: {
  51. lastLine() {
  52. return this.lines[this.lines.length - 1]
  53. },
  54. hasLines() {
  55. return this.lines.length > 0
  56. },
  57. hasLastLineValue() {
  58. return this.lastLine && this.lastLine.value !== ''
  59. },
  60. canDeleteLine() {
  61. return this.lines.length > 1
  62. },
  63. canAddLine() {
  64. return this.hasLines && this.hasLastLineValue
  65. }
  66. },
  67. methods: {
  68. emitAdd() {
  69. this.canAddLine && this.$emit('addClicked')
  70. },
  71. emitRemove(index) {
  72. this.canDeleteLine && this.$emit('removeClicked', index)
  73. },
  74. emitUpdate(event, index){
  75. const {value} = event.target
  76. this.$emit('valueUpdated', {value, index})
  77. }
  78. }
  79. }
  80. </script>
  81. <style scoped lang="scss">
  82. .multi-input {
  83. float: left;
  84. width: 100%;
  85. }
  86. .multi-button {
  87. height: inherit;
  88. }
  89. .multi-input-container {
  90. display: flex;
  91. flex: 1;
  92. }
  93. .btn-container {
  94. display: flex;
  95. opacity: 0;
  96. }
  97. .multi-control {
  98. display: flex;
  99. &:hover > .btn-container {
  100. opacity: 1;
  101. }
  102. }
  103. </style>