0

So I'm building a filter option for my website and its options are loaded from DB and because of this, I believe I can't use a normal v-model to do the job.

I have different filter parameters such as Categories and Companies and their options are loaded from DB so they can have 5 or 10 options.

Screenshot of the filter in the website (Better for visualization):

enter image description here

My code:

body {
    position: relative;
  }

  .save_filter{
    height: 40px;
  }

  .save_filter button {
    background: black;
    color: white;
    width: 100%;
    height: 100%;
    border: 0;
    border-radius: 5px;
    cursor: pointer;
  }

  .see_offer{
    position: absolute;
    bottom: 0;
    width: 100%;
    height: 50px;
    background-color: black;
    border-bottom-left-radius: 5px;
    border-bottom-right-radius: 5px;
  }

  .see_offer span{
    position: relative;
    left: calc(50% - 39.93px);
    top: calc(50% - 9.2px);
    color: white;
  }

  .main-body {
    max-width  : 1270px;
    font-family: "Ubuntu", sans-serif;
    margin     : 0 auto;
  }

  .page-content {
    padding-top: 70px;
    position   : relative;
    margin     : 0 auto;
  }

  .page-content .container {
    display        : flex;
    justify-content: space-evenly;
  }

  .page-content .first-section .category-title span {
    font-family   : "Segoe UI Regular";
    font-style    : normal;
    font-weight   : 600;
    font-size     : 23px;
    letter-spacing: 0.21em;
    color         : #1D1D25;
    position      : relative;
  }

  .page-content .first-section .category-title span::after {
    content      : "";
    display      : block;
    position     : absolute;
    border       : 2px solid #1D1D25;
    border-radius: 20px;
    width        : 96%;
    bottom       : -11px;
    left         : 0;

  }

  .page-content .second-section {
    padding-top: 44px;
    display    : flex;
  }

  .page-content .second-section .left {
    flex: 1;
  }

  .page-content .second-section .right {
    flex: 3;
  }

  .page-content .second-section .left .left-container {
    width    : 200px;
    min-width: 200px;
  }

  .second-section .left .left-container .filter {
    display       : flex;
  }

  .second-section .combo-group {
    position: relative;
    width   : 100%;
  }

  .second-section .combo-group select {
    font-family       : "Ubuntu", sans-serif;
    font-size         : 14px;
    color             : black;
    width             : 100%;
    box-sizing        : border-box;
    border-radius     : 7px;
    padding           : 0 20px;
    height            : 34px;
    -webkit-appearance: none;
    -moz-appearance   : none;
    border            : 1px solid #1D1D25;

    background-image: linear-gradient(45deg, transparent 50%, #010101 50%),
      linear-gradient(135deg, #010101 50%, transparent 50%);
    background-position: calc(100% - 20px) calc(1em + 1px),
      calc(100% - 15px) calc(1em + 1px), 100% 0px;
    background-size  : 5px 5px, 5px 5px, 2.5em 2.5em;
    background-repeat: no-repeat;
    background-color : white;
  }

  .second-section .combo-group select:focus {
    border-color: lightblue;
  }

  .second-section .left .left-container .companies {
    padding-bottom: 54px;
  }

  .second-section .left .left-container .companies p {
    margin-top: 0;
    font-size : 16px;
  }

  .chk-container {
    display            : block;
    position           : relative;
    padding-left       : 27px;
    margin-bottom      : 12px;
    cursor             : pointer;
    font-size          : 16px;
    -webkit-user-select: none;
    -moz-user-select   : none;
    -ms-user-select    : none;
    user-select        : none;
  }

  .chk-container input {
    position: absolute;
    opacity : 0;
    cursor  : pointer;
    height  : 0;
    width   : 0;
  }

  .chk-container input:checked~.checkmark {
    background-color: #1D1D25;
  }

  .chk-container input:checked~.checkmark {
    height: 20px;
    width : 20px;
    border: none;
  }

  .checkmark:after {
    content : "";
    position: absolute;
    display : none;
  }

  /* Show the checkmark when checked */
  .chk-container input:checked~.checkmark:after {
    display: block;
  }

  /* Style the checkmark/indicator */
  .chk-container .checkmark:after {
    left             : 7px;
    top              : 3px;
    width            : 4px;
    height           : 10px;
    border           : solid white;
    border-width     : 0 2px 2px 0;
    -webkit-transform: rotate(45deg);
    -ms-transform    : rotate(45deg);
    transform        : rotate(45deg);
  }

  .chk-container .checkmark {
    position        : absolute;
    top             : 0;
    left            : 0;
    height          : 20px;
    width           : 20px;
    background-color: #1D1D25;
  }

  .second-section .left .left-container .price {
    padding-bottom: 54px;
  }

  .second-section .left .left-container .price p {
    margin-top   : 0;
    margin-bottom: 6px;
    font-size    : 16px;
  }

  .slider {
    -webkit-appearance: none;
    width             : 100%;
    height            : 4px;
    background        : #C4C4C4;
    outline           : none;
    -webkit-transition: .2s;
    transition        : opacity .2s;
    border-radius     : 10px;
  }

  .slider:hover {
    opacity: 1;
  }

  .slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance        : none;
    width             : 12px;
    height            : 12px;
    background        : #1D1D25;
    cursor            : pointer;
    border-width      : 0;
    border-radius     : 50%;
  }

  .slider::-moz-range-thumb {
    width        : 12px;
    height       : 12px;
    background   : #1D1D25;
    cursor       : pointer;
    border-width : 0;
    border-radius: 50%;
  }

  .second-section .products {
    display        : flex;
    flex-wrap      : wrap;
    justify-content: space-around;
  }

  .second-section .products .box {
    position: relative;
    max-width       : 260px;
    width           : 260px;
    background-color: #F7F7F7;
    margin-bottom   : 62px;
  }

  .second-section .products .box .image {
    text-align     : center;
    padding-top    : 30px;
    padding-bottom : 25px;
    min-height     : 157px;
    display        : flex;
    align-items    : center;
    justify-content: center;
  }

  .second-section .products .box .image img {
    max-width: 200px;

  }

  .second-section .products .box .names {
    text-align    : center;
    font-size     : 18px;
    line-height   : 21px;
    margin-left: 10px;
    margin-right: 10px;
    padding-bottom: calc(45% + 10px);
  }

  .second-section .products .box .star {
    text-align    : center;
    padding-bottom: 17px;
  }

  .second-section .products .box .price {
    position: absolute;
    width: 100%;
    bottom: 50px;
    text-align: center;
    padding-bottom: 21px;
    color: #1d1d25;
    font-weight: 700;
  }

  .second-section .products .box .price span {
    font-size  : 24px;
    line-height: 28px;
  }

  .second-section .products .box .price span:first-child {
    font-size: 16px;
    line-height: 18px;
    vertical-align: super;
  }

  .second-section .pagination-container {
    display        : flex;
    justify-content: center;
    margin-top     : 15px;
  }

  .second-section .pagination-container span,
  .second-section .pagination-container a {
    color       : #1D1D25;
    background  : none;
    box-shadow  : none;
    border-width: 0;
    font-size   : 14px;
    margin-right: 0;
  }

  .second-section .pagination-container .active .current {
    border-radius: 0;
    border-bottom: 1px solid #1D1D25;

  }

  .second-section .pagination-container li .page-link {
    border-radius: 0;
    border-bottom: 1px solid #C4C4C4;
  }

  .second-section .pagination-container .current.prev,
  .second-section .pagination-container .current.next,
  .second-section .pagination-container .page-link.prev,
  .second-section .pagination-container .page-link.next {
    display     : flex;
    align-items : center;
    border-width: 0;
  }

  .second-section .pagination-container .prev-image {
    margin-right: 12px;
  }

  .second-section .pagination-container .next-image {
    margin-left: 12px;
  }

  @media screen and (max-width: 1100px) and (min-width: 769px) {
    .second-section .products .box {
      width           : 49%;
      /* margin-bottom: 50px; */
    }
  }

  @media screen and (max-width: 1023px) and (min-width: 769px) {

    .page-content {
      padding-top: 80px;
      width      : calc(100% - 5em);
    }
  }

  @media screen and (max-width: 768px) {
    .text-align {
      text-align: center;
    }

    .page-content {
      padding-top: 20px;
    }

    .page-content .second-section {
      padding-top: 30px;
      display    : block;
      width      : 90%;
      margin     : 0 auto;
    }

    .page-content .second-section .left {
      padding-right: 0px;
      padding-top  : 45px;
      margin-left  : 0px;
    }

    .page-content .second-section .left .left-container {
      width: 100%;
    }

    .second-section .left .left-container .filter {
      padding-bottom: 35px;
    }

    .second-section .products {
      padding-top: 35px;
    }

    .second-section .products .box {
      width        : 48%;
      margin-bottom: 5px;
    }

    .page-content .second-section .title span {
      font-size: 25px;
    }

    .page-content .second-section .container {
      flex-direction: column;
    }

    .page-content .second-section .right {
      padding-right: 0px;
      font-size    : 14px;
    }

    .second-section .products .box .image {
      height        : 100px;
      padding-top   : 20px;
      padding-bottom: 10px;
    }

    .second-section .products .box .image img {
      max-width : 170px;
      max-height: 100px;
    }

    .second-section .products .box .names {
      font-size     : 13px;
      line-height   : 15px;
      padding-bottom: 13px;
    }

    .second-section .products .box .star {
      padding-bottom: 11px;
    }

    .second-section .products .box .price {
      padding-bottom: 18px;
    }

    .second-section .products .box .price span:nth-child(1) {
      font-size  : 14px;
      line-height: 18px;
    }

    .second-section .products .box .price span:nth-child(2) {
      font-size  : 18px;
      line-height: 21px;
    }
  }
<section class="second-section">
  <div class="left">
    <div class="left-container">
      <form @submit.prevent="processFilter">
        <div class="filter">
          <div class="combo-group mobile">
            <select>
              <option v-for="sub in subCategories" :key="sub.id">
                {{sub.value}}
              </option>
            </select>
          </div>
          <div class="combo-group mobile">
            <select>
              <option v-for="company in companies" :key="company.id">
                {{company.name}}
              </option>
            </select>
          </div>
        </div>
        <div class="companies desktop">
          <p>Categories</p>
          <label class="chk-container" v-for="sub in subCategories" :key="sub.id">
                    {{sub.value}}
                    <input type="checkbox" id="chk-account-standard" />
                    <span class="checkmark"></span>
                  </label>
        </div>
        <div class="companies desktop">
          <p>Companies</p>
          <label class="chk-container" v-for="company in companies" :key="company.id">
                    {{company.name}}
                    <input type="checkbox" id="chk-account-standard" />
                    <span class="checkmark"></span>
                  </label>
        </div>
        <div class="price">
          <p>Price</p>
          <span id="min-value">10</span><span> - </span><span>1.000</span>
          <div class="pt-10">
            <input type="range" min="10" max="1000" value="1" class="slider" id="priceRang">
          </div>
        </div>
        <div class="save_filter">
          <button type="submit">Filter</button>
        </div>
      </form>
    </div>
  </div>
</section>

So my question is how can I get the input values independently of the number of options loaded from the database?

1 Answer 1

1

You can use v-model for this, you just need a separate array to store the selected options. Here is an example in the Vue docs.

For your case you'll need to set a value of the inputs element for the field you want to use, then can use v-model to store the selected inputs.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.