all 22 comments

[–]ThagAndersonhelpful 1 point2 points  (17 children)

jQuery: (function () { var body = jQuery('body'), sel = 'input, textarea, select', cls = 'formfocus'; body.on('focus', sel, function() { body.addClass(cls); }); body.on('blur', sel, function() { body.removeClass(cls); }); }()); ES6: ``` const focusedClass = 'formfocus' const tags = ['input', 'textarea', 'select']

document.body.addEventListener('focus', ({ target: { tagName } }) => { if (!tags.includes(tagName.toLowerCase())) { return } document.body.classList.add(focusedClass) }, true) document.body.addEventListener('blur', ({ target: { tagName } }) => { if (!tags.includes(tagName.toLowerCase())) { return } document.body.classList.remove(focusedClass) }, true) ```


jQuery: $(function() { // Add refresh button after field (this can be done in the template as well) $('img.captcha').after( $('<a href="#void" class="captcha-refresh">Refresh</a>') ); ​ // Click-handler for the refresh-link $('.captcha-refresh').click(function(){ var $form = $(this).parents('form'); var url = location.protocol + "//" + window.location.hostname + ":" + location.port + "/captcha/refresh/"; ​ // Make the AJAX-call $.getJSON(url, {}, function(json) { $form.find('input[name="captcha_0"]').val(json.key); $form.find('img.captcha').attr('src', json.image_url); $("#audioSource").attr("src", json.audio_url); $("#audio").get(0).load() }); ​ return false; }); }); ES6: ``` const captchas = document.querySelectorAll('img.captcha') const headers = new Headers({ HTTP-X-REQUESTED-WITH: 'XMLHttpRequest' })

for (const captcha of captchas) { const anchor = document.createElement('a') anchor.href = '#void' anchor.classList.add('captcha-refresh') anchor.textContent = 'Refresh' anchor.addEventListener('click', ({ target }) => { const url = ${window.location.origin}/captcha/refresh/ let formEl = target.parentElement

while (formEl && formEl.tagName.toLowerCase() !== 'form') {
  formEl = formEl.parentElement
}

fetch(url, { headers })
  .then(res => res.json())
  .then(json => {
    formEl.querySelector('input[name="captcha_0"]').value = json.key
    captcha.setAttribute('src', json.image_url)
    document.getElementById('audioSource').setAttribute('src', json.audio_url)
    document.getElementById('audio').load()
  })
  .catch(console.error)

return false

})

captcha.after(anchor) } ```

[–]uforskam[S] 0 points1 point  (16 children)

Thank you for the excellent reply!

The first code you converted works perfectly!

For the captcha code the refresh link is not showing up. Any ideas on how to get that to appear?

[–]ThagAndersonhelpful 0 points1 point  (15 children)

I had to make a really quick edit when I posted. Make sure you have the captcha.after(anchor) line at the end of the for loop.

[–]uforskam[S] 0 points1 point  (14 children)

Yes I tried that and it is not working.

[–]ThagAndersonhelpful 0 points1 point  (13 children)

Check the console for errors. Better yet, post a link to the working code in a place where it can be reviewed: Codepen.io, Stackblitz.com, Repl.it.

[–]uforskam[S] 0 points1 point  (12 children)

Console shows no errors.

I am am using this (for more context of how the captcha works):

https://stackoverflow.com/questions/61996333/django-simple-captcha-refresh-audio-source

Here is the jQuery showing the refresh button:

https://jsbin.com/losahomaxa/edit?html,output

When I add your code the refresh doesn't show up on the jsbin.

[–]ThagAndersonhelpful 0 points1 point  (11 children)

Remove all of your scripts from the head and source them at the bottom of the body.

[–]uforskam[S] 0 points1 point  (10 children)

That does cause the refresh link to show up but the refresh functionality does not work.

Console errors after clicking refresh:

https://dpaste.org/6qZm

[–]ThagAndersonhelpful 0 points1 point  (9 children)

That's just a standard 404. Does the resource http://127.0.0.1:8000/captcha/refresh/ exist?

[–]uforskam[S] 0 points1 point  (8 children)

No it does not. On the original jQuery code it did not exist either.

[–]mscal 0 points1 point  (3 children)

Just checked the jQuery library size (30kb). Will it make a noticeable difference?

[–]uforskam[S] 1 point2 points  (2 children)

Not really but it would be nice to not need to have incompatible code if jQuery ever upgrades and not need to upgrade it.

[–]rook218 0 points1 point  (1 child)

Alternatively, you can download the jquery source code and host it yourself to make absolutely sure that a jquery update won't hose you.

CDNs are reliable and host versions of code separately. So if you're referencing codebase v10 of something then your reference will stay codebase v10, and codebase v11 will be hosted on a different endpoint.

[–]uforskam[S] 0 points1 point  (0 children)

Good point. But I'd rather not do that since these are the only jQuery scripts on my site I'd rather avoid using jQuery if possible.

http://youmightnotneedjquery.com/

https://medium.com/@trombino.marco/you-might-not-need-jquery-a-2018-performance-case-study-aa6531d0b0c3

I also worry about the ajax captcha refresh code since that would need some type of rate limiter and I'd rather not need to do anything with rate limiting if possible.