How to add button click event inside AutoComplete itemTemplate

Hi Team,

I am working on requirement, where autocomplete list-item have button inside it. User can selected option by clicking on list-option or user can click on button for different functionality. Need to disable default event if user clicks on button and pass selected item to parent

I am adding screenshot of itemTemplate along with code.

Itemtemplate:

var productSearchTemplate = Vue.component('itemTemplate', {
  template: `<div class="single-item">
    <div class="product-img">
      <img src="@/assets/images/placeholder.png">
    </div>
    <div class="item-name">
      <div class="item-code p-0 text-limit" :title="data.ItemNumber">
      #{{ data.ItemNumber }}
      </div>
      <p class="text-limit" :title="data.ItemCode">{{ data.ItemCode }}</p>
    </div>
    <input type="hidden" :value="data.ItemCode">
    <div class="item-price">100$</div>
    <div>
      <span class="badge badge-success">Stock</span>
    </div>
    <div class="item-add-btn badge badge-pill badge-secondary p-2">
<!-- ADD CLICK EVENT AND PASS DATA TO PARENT -->
      <span class="mr-1" @click="addItem">Add</span>
    </div>
  </div>`,
  data() {
    return {
      data: {}
    }
  },
  methods: {
    addItem(arg) {
      // Need to pass data to parent component
      console.log(arg'additem method')
    }
  }
})


Data() property:

productSearchTemplate: function() {
        return {
          template: productSearchTemplate
        }
      },
      productSearchFields: { text: 'ItemCode'value: 'ItemNumber' },


HTML

              <ejs-autocomplete
                :dataSource="productMaster"
                :placeholder="'Search Product'"
                :filtering="getProducts"
                :focus="getProducts"
                :value="itemAddObj.ItemCode"
                @change="changeSelectedProduct"
                :itemTemplate="productSearchTemplate"
                :fields="productSearchFields"
                ref="sideBarSearch"
              ></ejs-autocomplete>


Methods:

changeSelectedProduct(event) {
      console.log('this.changeSelectedProduct'event)
      if (!event.isInteracted) {
        return
      }
      if (event.itemData && event.itemData.ItemNumber) {
        console.log(event.itemData)
      }
    }







Thanks & Regards,
Sandeep G


6 Replies

GK Gunasekar Kuppusamy Syncfusion Team September 23, 2021 05:41 PM UTC

Hi Sandeep, 

We have validated your reported query "How to add button click event inside AutoComplete itemTemplate" from our end.

Initially the popup items are not showed in the DOM. So, we suggest you that bind the event listener in the open event of the AutoComplete.

We have prepared a sample for your reference.
Code snippets:
<template>
  <div>
    <div class="control-section">
      <div id="content"style="margin: 0px auto; width: 300px; padding-top: 40px" >
        <ejs-autocomplete id="employees" :dataSource="data" :fields="fields"
          :placeholder="watermark" :headerTemplate="hTemplate" :itemTemplate="iTemplate"
          :open="onOpen" popupHeight="450px" cssClass="autocomplete-template">
        </ejs-autocomplete>
      </div>
    </div>
  </div>
</template>
<style>
</style>
<script>
import Vue from "vue";
import { AutoCompletePlugin } from "@syncfusion/ej2-vue-dropdowns";
import * as data from "./dataSource.json";
//import { data } from "./datasource.js";
import { actionButton } from "./main";

Vue.use(AutoCompletePlugin);

var itemVue = Vue.component("itemTemplate", {
  template:
    '<div><img class="empImage" :src="data.Eimg" alt="employee"/>' +
    '<span class="ename"> {{data.Name}} </span><div class="job"> {{data.Designation}} </div></div>',
  data() {
    return {
      data: {},
    };
  },
});
export default Vue.extend({
  data: function () {
    return {
     . . .
  },
  methods: {
    onOpen: function (e) {
      var names = e.popup.element.querySelectorAll(".ename");
      for (var i = 0; i < names.length; i++) {
        names[i].addEventListener("click"this.clickHandler);
      }
    },
    clickHandler: function (e) {
      alert(e.target.innerHTML);
    },
  },
});
</script>

Samplehttps://codesandbox.io/s/syncufsion-v18-dropdown-forked-0yc5e

Please check the sample and let us know ,if the sample meets your requirement.

Regards,
Gunasekar 



SG Sandeep G September 24, 2021 06:13 AM UTC

Hi Gunasekar,

Thanks for your reply. In example provided by you, we are able to get innerHTML of span but I require complete object of the item and keep the list open for the user to select other items of the list, currently list is getting closed after clicking on span.


clickHandler: function (e) {
// I need to access complete object here and
// keep the suggestions list open (for user to click next item) only when clicked on this particular span
alert(e.target.innerHTML);
},


Regards,
Sandeep G



GK Gunasekar Kuppusamy Syncfusion Team September 27, 2021 12:53 PM UTC

Hi Sandeep,

Currently we are preparing a sample for your requirement. We will update the further details with in one business day on 28th September.

Regards,
Gunasekar



VJ Vinitha Jeyakumar Syncfusion Team September 30, 2021 02:05 PM UTC

Hi Sandeep, 
 
 
Sorry for the inconvenience caused. Still, we are validating your query due to its complexity. We will update you the further details in two business days on 4th October 2021. 
 
We appreciate your patience until then. 
 
Regards, 
Vinitha 



SG Sandeep G October 13, 2021 08:13 AM UTC

Hi Team,

I look forward to receiving response from you.


Regards,
Sandeep G



GK Gunasekar Kuppusamy Syncfusion Team October 14, 2021 05:21 PM UTC

Hi Sandeep,

We apologies for the delay.

We have validated your reported query from our end.

Querywe are able to get innerHTML of span but I require complete object of the item and keep the list open for the user to select other items of the list, currently list is getting closed after clicking on the span.

We have prepared a sample to meet the above requirement and attached it below.
In this sample, we have done the following things,
  • Initially, we have bound the mousedown event for the items span element. Using the target, we were able to access the data of the clicked object within the event callback method.
  • According to autocomplete behavior. when you prevent the popup closing when clicking an item, the close event is not triggered the next time you click the same element.
  • So for that, we have bound the mousedown event for the popup element and performed actions based on the clicked target element.
  • So the popup will not close if you click the button span element, but it will close if you click outside of the button element.
Code Snippets:
<template>
  <div>
    <div class="control-section">
      <div id="content" style="margin: 0px auto; width: 300px; padding-top: 40px">
        <ejs-autocomplete ref="autoCompleteRef" id="employees" :dataSource="data" :fields="fields"
          :placeholder="watermark" :headerTemplate="hTemplate" :itemTemplate="iTemplate"
          :close="onClose" :open="onOpen" popupHeight="450px" cssClass="autocomplete-template">
          </ejs-autocomplete>
      </div>
    </div>
  </div>
</template>
<style>
</style>
<script>
import Vue from "vue";
import { AutoCompletePlugin } from "@syncfusion/ej2-vue-dropdowns";
import * as data from "./dataSource.json";
Vue.use(AutoCompletePlugin);
. . .
var itemVue = Vue.component("itemTemplate", {
  template:
    '<div><img class="empImage" :src="data.Eimg" alt="employee"/>' +
    '<span class="ename" > {{data.Name}} </span><div class="job"> {{data.Designation}} <span v-on:mousedown="onButtonMouseDown($event)" class="customButton"> Click</span> </div></div>',
  data() {
    return {
      data: {},
    };
  },
  methods: {
    onButtonMouseDownfunction (e) {
      var target = e.target.offsetParent.id;
      var index = parseInt(target.split("-").pop(), 10);
      console.log(this.$parent.ej2Instances.dataSource[index]);
    },
  },
});
export default Vue.extend({
  data: function () {
    return {
      isButtonClick: false,
      fields: { value: "Name" },
      watermark: "e.g. Andrew Fuller",
      hTemplate: function (e) {
        return {
          template: headerVue,
        };
      },
      iTemplate: function (e) {
        return {
          template: itemVue,
        };
      },
      data: data["empList"],
    };
  },
  methods: {
    onOpen: function (args) {
      args.popup.element.addEventListener("mousedown"this.clickHandler);
    },
    clickHandler: function (e) {
      if (!e.target.classList.contains("customButton")) {
        var clickTarget = e.target.offsetParent.id;
        var itemIndex = parseInt(clickTarget.split("-").pop(), 10);
        console.log(
          this.$refs.autoCompleteRef.ej2Instances.dataSource[itemIndex]
        );
        this.isButtonClick = false;
        this.$refs.autoCompleteRef.ej2Instances.hidePopup();
        this.tempValue.hide();
      } else {
        this.isButtonClick = true;
      }
    },
    onClose: function (args) {
      this.tempValue = args.popup;
      if (this.isButtonClick) {
        args.cancel = true;
      }
    },
  },
});


Sample: https://codesandbox.io/s/syncufsion-v18-dropdown-forked-zo8s2

Please check the sample and let us know if you have any concerns,

Regards,
Gunasekar


Loader.
Up arrow icon