$("#get-data").on("click", function() { const btn = $(this) const btnHtml = btn.html() btn.html($('#spinner-html').html()) btn.prop('disabled', true) setTimeout(() => { // this is my ajax immitation // on ajax complete: btn.html(btnHtml) btn.prop('disabled', false) }, 2000) }) <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="spinner-html" style="display: none"> Loading... </div> <button id="get-data">Get Data</button>Quiero que cada botón que invoque una llamada ajax a alguna API se deshabilite y muestre el control giratorio hasta que se complete la llamada a la API.
La idea es que sea reutilizable. Es decir, la parte ajax (representada como setTimeout aquí no debería tener ninguna referencia al botón en el que se hizo clic.
Esto funciona perfectamente, pero siento que repetir esas 6 líneas de código para el botón HTML para cada botón con ajax es una duplicación de código que se puede evitar.
Así que me gustaría tenerlo genérico y reutilizable. Lo he intentado de esta manera (y algunas variaciones) pero no funcionó...
function spinnerClick(b, f) { const btn = $(b) const btnHtml = btn.html() btn.html($('#spinner-html').html()) btn.prop('disabled', true) f() btn.html(btnHtml) // this goes immediately btn.prop('disabled', false) } function getData() { // all ajax stuff here } $('#get-data').on('click', function () { spinnerClick(this, getData) })Apreciaré cualquier consejo al respecto. ¡Gracias!
UPD : violín JS agregado
gracias por agregar jsfiddle, ¡pruebe esto por favor!
function spinnerClick(b, f) { const btn = $(b) const btnHtml = btn.html() btn.html($('#spinner-html').html()) btn.prop('disabled', true) f().then(() => { btn.html(btnHtml) btn.prop('disabled', false) }); } function getData() { return new Promise((resolve) => {setTimeout(() => { console.log('hello'); resolve(true); }, 2000); }) } $('#get-data').on('click', function () { spinnerClick(this, getData) })Podría estar malinterpretándolo, pero ¿por qué no simplemente enviar la instancia a una función separada para que pueda acceder a ella cuando se resuelva?
$(function() { $('button').click(function() { doAjax($(this)); }) }) function doAjax(btn) { if (btn.find('span.spinner').length > 0) return console.log('wait, still running'); btn.removeClass('finished').append('<span class="spinner"> * </span>'); setTimeout(function() { btn.addClass('finished').find('span.spinner').remove() }, 2000) } .finished { background: green; color: white; } .spinner { color: blue; } <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <button>Click 1</button> <button>Click 2</button> <button>Click 3</button>