You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
6.0 KiB

2 years ago
2 years ago
2 years ago
2 years ago
  1. <template>
  2. <div class="group tw-mb-[20px]">
  3. <div class="tw-flex tw-justify-between tw-items-center tw-mb-[20px]">
  4. <h3 class="t14 tw-font-bold tw-mb-0 md:t16">
  5. {{ $t(label) }}<span class="required tw-font-normal t12 md:t14">*</span>
  6. <span v-if="validation.length==false" class="required md:tw-ml-[20px] tw-font-normal t12 md:t14">{{ $t("Required.") }}</span>
  7. </h3>
  8. <button class="'seeMore tw-transition tw-btn-md tw-body-4 tw-text-secondary-default tw-px-[16px] tw-py-[9px]"
  9. @click="clearAll()">
  10. {{ $t("Clear all") }}
  11. </button>
  12. </div>
  13. <div>
  14. <div class="optionGroup tw-border tw-border-solid tw-border-slate-200 tw-rounded-[12px] tw-bg-white tw-p-[20px]">
  15. <div v-for="(item, index) in quantitySelectList" :key="index">
  16. <quantitySelectOption :index="index" :item="item" :hasValue="hasValue"
  17. :seeMore="seeMore" @disabled="disabled($event)" @selected="selected($event)" @change="change($event)">
  18. </quantitySelectOption>
  19. </div>
  20. </div>
  21. <button v-show="length !== undefined && length > 3" :class="[
  22. 'seeMore tw-transition tw-btn-md tw-text-primary-1 tw-border tw-border-solid tw-border-primary-1 tw-px-[30px] tw-py-[8.5px] tw-mt-[20px] tw-w-full tw-rounded-xl hover:tw-bg-primary-3 xl:hover:tw-bg-transparent xl:tw-border-none',
  23. seeMore ? 'open' : '',
  24. ]" @click="seeMore = !seeMore">
  25. {{ $t(seeMoreText) }}
  26. </button>
  27. </div>
  28. </div>
  29. </template>
  30. <script>
  31. import quantitySelectOption from "@/components/service/content/quantitySelectOption";
  32. export default {
  33. components: {
  34. quantitySelectOption,
  35. },
  36. props: {
  37. label: {
  38. type: String,
  39. },
  40. quantitySelectList: {
  41. type: Array,
  42. },
  43. pickupServiceShow:{
  44. type: Boolean,
  45. }
  46. },
  47. data() {
  48. return {
  49. hasValue: null,
  50. seeMore: false,
  51. formData: {
  52. selectList: [],
  53. truckList: []
  54. },
  55. validation:{
  56. length: true
  57. },
  58. errors: null,
  59. };
  60. },
  61. computed: {
  62. seeMoreText() {
  63. if (this.seeMore == false) {
  64. return "See more";
  65. } else {
  66. return "See less";
  67. }
  68. },
  69. length() {
  70. if (this.quantitySelectList) {
  71. return this.quantitySelectList.length;
  72. } else {
  73. return 0;
  74. }
  75. },
  76. // clear() {
  77. // return this.pickupServiceShow;
  78. // },
  79. },
  80. watch: {
  81. // clear: {
  82. // handler: function (value) {
  83. // // if(value==false){
  84. // // this.hasValue = null;
  85. // // this.formData.selectList = [];
  86. // // this.formData.truckList = [];
  87. // // this.$emit("ChangeCosts",{type: 'truck',value: this.formData});
  88. // // }
  89. // }
  90. // }
  91. },
  92. methods: {
  93. disabled(i) {
  94. this.hasValue = i;
  95. },
  96. selected(data){
  97. if(this.formData.selectList.length>0){
  98. for(let i=0;i<this.formData.selectList.length;i++){
  99. if(this.formData.selectList[i].id == data.id){
  100. this.formData.selectList.splice(i, 1);
  101. break;
  102. }
  103. }
  104. }
  105. if(data.number>0){
  106. this.formData.selectList.push(data);
  107. }
  108. if(this.formData.selectList.length>0){
  109. this.validation.length = true;
  110. }else{
  111. this.validation.length = false;
  112. }
  113. this.$emit("ChangeCosts",{type: 'truck',value: this.formData});
  114. },
  115. change(data){
  116. if(this.formData.truckList.length>0){
  117. for(let i=0;i<this.formData.truckList.length;i++){
  118. if(this.formData.truckList[i].id == data.id){
  119. this.formData.truckList.splice(i, 1);
  120. break;
  121. }
  122. }
  123. }
  124. if(data.number!="" && data.number!=0){
  125. this.formData.truckList.push(data);
  126. }
  127. this.$emit("ChangeCosts",{type: 'truck',value: this.formData});
  128. },
  129. clearAll() {
  130. this.hasValue = 0;
  131. this.$nextTick(() => {
  132. this.hasValue = null;
  133. });
  134. this.formData.selectList = [];
  135. this.formData.truckList = [];
  136. this.$emit("ChangeCosts",{type: 'truck',value: this.formData});
  137. },
  138. validators() {
  139. if (this.formData.selectList.length <= 0) {
  140. this.validation.length = false;
  141. } else {
  142. this.validation.length = true;
  143. }
  144. this.errors = Object.entries(this.validation).filter(
  145. (e) => e[1] == false
  146. );
  147. if (this.errors.length > 0) {
  148. return false;
  149. } else {
  150. return true;
  151. }
  152. },
  153. },
  154. };
  155. </script>
  156. <style lang="scss" scoped>
  157. .custom-button {
  158. background-position: center;
  159. background-repeat: no-repeat;
  160. background-size: 12px;
  161. }
  162. .button {
  163. &-reduce {
  164. background-image: url("~/assets/svg/reduce.svg");
  165. background-color: #e5e5e5;
  166. }
  167. &-add {
  168. background-image: url("~/assets/svg/add.svg");
  169. background-color: #f48800;
  170. }
  171. }
  172. :deep() {
  173. .optionGroup {
  174. .optionItem:last-child {
  175. border: none !important;
  176. margin: 0 !important;
  177. padding: 0 !important;
  178. }
  179. }
  180. }
  181. .seeMore {
  182. &-hide {
  183. position: relative;
  184. max-height: 295px;
  185. overflow: hidden;
  186. &::after {
  187. content: "";
  188. display: block;
  189. position: absolute;
  190. background: url("~/assets/img/gradient_white.png") repeat-x left bottom;
  191. width: 100%;
  192. height: 130px;
  193. left: 0;
  194. bottom: 0;
  195. z-index: 1;
  196. transition: bottom 0.5s;
  197. }
  198. }
  199. &-show {
  200. position: relative;
  201. max-height: 100%;
  202. overflow: initial;
  203. &::after {
  204. display: none;
  205. }
  206. }
  207. @media screen and (min-width: 1366px) {
  208. position: relative;
  209. display: flex;
  210. align-items: center;
  211. justify-content: center;
  212. &::after {
  213. content: "";
  214. display: inline-block;
  215. position: relative;
  216. background-image: url("~/assets/svg/arrow-down-primary.svg");
  217. background-position: center center;
  218. background-repeat: no-repeat;
  219. background-size: 100%;
  220. width: 9px;
  221. height: 6px;
  222. margin-left: 16px;
  223. transition: all 0.2s linear;
  224. }
  225. &.open {
  226. &::after {
  227. transform: rotate(180deg);
  228. }
  229. }
  230. }
  231. }
  232. </style>