MultiLineTextInput.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. if (this.canAddLine || this.lines.length === 0) {
  71. this.$emit('addClicked')
  72. }
  73. },
  74. emitRemove(index) {
  75. this.canDeleteLine && this.$emit('removeClicked', index)
  76. },
  77. emitUpdate(event, index){
  78. const {value} = event.target
  79. this.$emit('valueUpdated', {value, index})
  80. }
  81. }
  82. }
  83. </script>
  84. <style scoped lang="scss">
  85. .multi-input {
  86. float: left;
  87. width: 100%;
  88. }
  89. .multi-button {
  90. height: inherit;
  91. }
  92. .multi-input-container {
  93. display: flex;
  94. flex: 1;
  95. }
  96. .btn-container {
  97. display: flex;
  98. opacity: 0;
  99. }
  100. .multi-control {
  101. display: flex;
  102. &:hover > .btn-container {
  103. opacity: 1;
  104. }
  105. }
  106. </style>