On click return data once

Viewed 33

I have this .each function that runs in an Ajax call.

On click, I would like it to run but on a second click, I don't want it to run as it just duplicates the data in the container.

Is there anything I can add to this to only run once?

$.each(result, function (i, extensionSubType) {
                $(extensionTypeDiv).append('<div class="button-styles extension-subtype ' + extensionSubType.Name + '"><input id="ExtensionSubtypeId" class="hidden-input sub-input" name="ExtensionSubtypeId" type="radio" value="' + extensionSubType.Id + '">' + ' <label for="" data-label="' + extensionSubType.Name + '" class="btn-label">' + extensionSubType.Name + '</label></div>');
            });

This is the full click event

$(document).on('click', '.extension-type', function () {

var extensionTypeId = $(this).find('input.extension-type-radio').val();
$(this).find('input.extension-type-radio').prop('checked', true);


$.ajax({
    url: '/umbraco/Surface/FixUpCashBackCalculator/_ExtensionSubTypes',
    type: 'GET',
    data: { extensionTypeId: extensionTypeId },
    success: function (result) {

            $.each(result, function (i, extensionSubType) {
                $(extensionTypeDiv).append('<div class="button-styles extension-subtype ' + extensionSubType.Name + '"><input id="ExtensionSubtypeId" class="hidden-input sub-input" name="ExtensionSubtypeId" type="radio" value="' + extensionSubType.Id + '">' + ' <label for="" data-label="' + extensionSubType.Name + '" class="btn-label">' + extensionSubType.Name + '</label></div>');
            });
    }
});

Any suggestions would be much appreciated.

Many thanks in advance.

2 Answers

There's two approaches you could take here depending on your use case.

The first is to use the one() event handler so that the event, and it's AJAX request, will only ever fire once. The data will never be updated on successive clicks:

$(document).one('click', '.extension-type', function() {
  // your code...
});

Alternatively you can make the AJAX call every time the element is clicked, but remove the old content so that it can be updated with the new data in the response. To do that use html() instead of append(). Also note the use of map() to make the HTML creation logic simpler.

$(document).one('click', '.extension-type', function() {
  let extensionTypeId = $(this).find('input.extension-type-radio').prop('checked', true).val();

  $.ajax({
    url: '/umbraco/Surface/FixUpCashBackCalculator/_ExtensionSubTypes',
    type: 'GET',
    data: { extensionTypeId: extensionTypeId },
    success: function(result) {
      let html = result.map(ext => `<div class="button-styles extension-subtype ${ext.Name}"><input id="ExtensionSubtypeId" class="hidden-input sub-input" name="ExtensionSubtypeId" type="radio" value="${ext.Id}"><label for="" data-label="${ext.Name}" class="btn-label">${ext.Name}</label></div>`);
      $(extensionTypeDiv).html(html);
    }
  });
});

Try dblclick() handler instead of click():

$('.extension-type').addEventListener('dblclick', function(e) {
  var extensionTypeId = $(this).find('input.extension-type-radio').val();
  $(this).find('input.extension-type-radio').prop('checked', true);

  $.ajax({
    url: '/umbraco/Surface/FixUpCashBackCalculator/_ExtensionSubTypes',
    type: 'GET',
    data: {
      extensionTypeId: extensionTypeId
    },
    success: function(result) {

      $.each(result, function(i, extensionSubType) {
        $(extensionTypeDiv).append('<div class="button-styles extension-subtype ' + extensionSubType.Name + '"><input id="ExtensionSubtypeId" class="hidden-input sub-input" name="ExtensionSubtypeId" type="radio" value="' + extensionSubType.Id + '">' + ' <label for="" data-label="' + extensionSubType.Name + '" class="btn-label">' + extensionSubType.Name + '</label></div>');
      });
    }
  });
});

reference: https://developer.mozilla.org/en-US/docs/Web/API/Element/dblclick_event

Related