0

My question might not match to the problem that I am facing, So, I will explain it in detail here. This is code for SeparateTechnology.vue. I have removed a few methods to make code shorter.

<template>
  <div>
    <div v-for="mss in ms" :key="mss.name">
      <section class="container shadow-box techno-box" v-if="mss.name==selected">
        <p>Review the software criteria below and ensure that you complete each section</p>
        <h4>{{mss.name}}</h4>
        <div class="row shadow-box">
          <div class="col-sm-12 col-lg-6">
            <p>Select all that apply</p>
            <div class="dropdown">
              <input
                v-model.trim="inputValue"
                class="dropdown-input"
                type="text"
                placeholder="Search for your Solution"
              />

              <div class="dropdown-list" v-show="selected">
                <div
                  v-show="itemVisible(item)"
                  v-for="item in mss.subMenu"
                  :key="item"
                  class="dropdown-item"
                >
                  {{ item }}
                  <button
                    class="button button-mini button-dark button-rounded itemLabel"
                    @click="selectSolution(item,mss)"
                  >
                    <i class="icon-line-plus"></i>
                  </button>
                </div>
              </div>
            </div>
          </div>
          <div class="col-sm-12 col-lg-6 rightList">
            <div class="dropdown-list" v-show="selected" v-if="mss.selected_solutions!=''">
              <div v-for="item in mss.selected_solutions" :key="item" class="dropdown-item">
                {{ item }}
                <button
                  class="button button-mini button-dark button-rounded deleteLabel"
                  @click="deleteSelectedItem(item,mss)"
                >
                  <i class="icon-line-minus"></i>
                </button>
              </div>
            </div>
            <div v-else>
              <div class="style-msg errormsg">
                <div class="sb-msg">
                  <i class="icon-remove"></i>You have not selected any solutions.
                </div>
              </div>
            </div>
            <button
              class="button button-mini"
              @click="clearUserOptions(mss)"
              v-if="mss.selected_solutions.length > 1"
            >
              <i class="icon-line-cross"></i>Clear all selection
            </button>
          </div>
          <div style="padding:20px;"></div>
        </div>
        <div class="row">
          <div class="col-sm-12 col-md-3 inputTitle">
            <h5>Don't see it in the list above:</h5>
          </div>
          <input
            class="col-sm-12 col-md-6"
            type="text"
            v-model="value"
            @keydown.enter="getUserSolution(value,mss)"
            placeholder="Enter your solution here.. "
          />
        </div>
        <div style="padding:20px;"></div>
        <div class="row shadow-box">
          <h5
            class="col-sm-12"
          >Identify how the software solution is leveraged within your organization</h5>
          <div
            v-for="item in mss.selected_solutions"
            :key="item"
            class="clearfix col-sm-12 col-md-6"
            style="padding:20px"
          >
            <span v-if="mss.isDifferent=='campaign'">
              <div class="card">
                <h5 class="card-header">{{item}}</h5>
                <CheckBox
                  :groups="campaignMangment"
                  name="campaignMangment"
                  :value="item"
                  classProp="col-sm-12"
                  @clicked-show-detail="clickedShowDetailModal"
                />
                {{item}} and {{productSelected}}
              </div>
            </span>
          </div>
        </div>

        <button class="btn btn-primary" @click="postUserDetails(mss)">Submit</button>
      </section>
    </div>
  </div>
</template>
<script>
import CheckBox from "../../../components/checkbox/Checkbox";
export default {
  name: "technology",
  data() {
    return {
      usageValue: "",
      value: "",
      campainCheckedNames: [],
      checked: "",
      productSelected: [],
      checkedValues: "",
      exists: null,
      inputValue: "",
      campaignMangment: [
        "Business to Customer (B2C)",
        "Business to Business (B2B)",
        "Customer to Customer (C2C)",
        "Customer to Business (C2B)",
        "E-Government",
        "M-Commerce",
      ],
    };
  },
  props: ["ms", "selected"],
  //method to show all the solutions that contains the user
  methods: {
    clickedShowDetailModal: function (campainCheckedNames) {
      console.log(campainCheckedNames);
      this.productSelected.push(campainCheckedNames);
    },
  },
  components: {
    CheckBox,
  },
};
</script>

This is CheckBox.vue

<template>
  <div class="row col-mb-0">
    <div
      :class="classProp + ' checkbox-margin'"
      v-for="singleSelector in groups"
      :key="singleSelector"
    >
      <div>
        <input
          :id="singleSelector+groupId"
          :value="singleSelector"
          class="checkbox-style"
          type="checkbox"
          v-model="checkedValues"
          @change="showDetailModal"
        />
        <label :for="singleSelector +groupId" class="checkbox-style-3-label">{{singleSelector}}</label>
      </div>
    </div>
  </div>
</template>
<script>
let groupId = 0;
export default {
  props: {
    groups: Array,
    name: String,
    classProp: String,
    value: String,
  },
  data() {
    return {
      groupId: groupId++,
      checkedValues: [],
      inputs: {},
    };
  },
  methods: {
    showDetailModal: function (e) {
      this.$set(this.inputs, this.value, e.target.value);
      this.$emit("clicked-show-detail", this.inputs);
    },
  },
};
</script>
<style scoped>
.checkbox-margin {
  margin-bottom: 10px;
}
</style>

Right Now, the line {{item}} and {{productSelected}} prints output like below as shown in screenshot enter image description here .

Problem: On every click/unclick of checkbox it adds an item to an array and not in the format I want. and if I select the checkbox on left only, it adds that item on right as well as shown in the screenshot above. It is due to the same array declaration, but I couldn't think more than that.

Expected Output: For every selected item, I want to print the list of selected checkboxes in an array format like below.

"selected_solutions": [{
        "name": "Adobe Campaign",
        "usage": [ "Business to Customer",...]
    }, {
        "name": "Marin Software",
        "usage": ["M-Commerce",...]
    }]

Even small hints or tips would be more than appreciated. I don't mind posting code on gist if required. Thank you.

0

1 Answer 1

2

With checkbox-components you want to emit "event.target.checked" likeso:

this.$emit('input', event.target.checked)

That way it'll behave like a checkbox and you can use a v-model on the parent:

<CheckBox v-model="item.checked" ...>

I do not use v-model inside the component and instead just bind :checked="value", but that might be up to preference. But using both :value and v-model could (should?) cause problems because v-model is actually a :value + emitter under the hood (or so I heard).

Anyway, here is my minimal reusable checkbox-wrapper:

<template>
  <input type="checkbox" :checked="value" @change="handleChange" />
</template>

<script>
import Vue from 'vue'
export default Vue.extend({
  name: 'MyCheckbox',
  props: {
    value: { type: Boolean, default: false }
  },
  methods: {
    handleChange(event) {
      this.$emit('input', event.target.checked)
    }
  }
})
</script>

After that is done you can just filter on checked items:

computed: {
    checkedSolutions(){ 
        return this.ms[0].selected_solutions
            .filter( solution => solution.checked );
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Can I ask you what is item.checked in checkbox? what type of data does that hold? How can I print that ?

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.