0

Delete requests should be POSTs (or DELETEs). But we can't create a POST/DELETE with an <a> tag.

Is it really necessary to wrap a single delete button in a giant <form> complete with hidden CSRF token for ~30 different items on a page, or is there a nicer way to approach this?

mpen
  • 237,624
  • 230
  • 766
  • 1,119
  • 1
    AJAX? (Let me ask that again, if only for the sake of the minimum character restriction on comments: AJAX?) – CBroe Aug 14 '15 at 18:05
  • `"But we can't create a POST/DELETE with an tag"` - why not? – Shomz Aug 14 '15 at 18:06
  • Ajax would definitely be a good way to go. You could set up an onclick event for buttons or links and contain the ID of the to-be-deleted item in the name of element and then run an AJAX function to send that data via post to a script that will delete it. – Tyler Collins Aug 14 '15 at 18:07
  • I do use Ajax, it works. – maytham-ɯɐɥʇʎɐɯ Aug 14 '15 at 18:08
  • One of you can submit an answer suggesting AJAX... I'm not opposed to it. I might just do a full page refresh after it completes because I don't want to jQuery-up the whole UI. – mpen Aug 14 '15 at 18:09
  • Any element can make any kind of request... I thought someone with 65k reputation should know that. – Shomz Aug 14 '15 at 18:11
  • this is the idea of Ajax, that it does not make page refresh your main page, but for example delete, insert or do another thing or what ever you like when you click on it transparently. – maytham-ɯɐɥʇʎɐɯ Aug 14 '15 at 18:11
  • 1
    @Mark I know how you feel about not wanting to jQuery up the whole UI. It becomes much more 'complicated' than just pushing out a layout. – Tyler Collins Aug 14 '15 at 18:17
  • @Shomz I'm well aware of that, but the "without overriding its default behaviour" bit was implied. You can't add a `method` attribute to an `` tag, for example. But yes, sure, you can do whatever you want with JS. – mpen Aug 14 '15 at 18:32
  • @maytham The delete will occur quietly in the background, yes, but how do I refresh all the page items after that? Delete the line item, update any counters, etc. Suddenly my nice static UI is got shat on by the jQuery. Easier to just do a `window.location.reload(true)`. – mpen Aug 14 '15 at 18:34
  • Sorry guys, I just wanted to know what other people are doing. I can do it either way, I just wanted to hear some pros and cons. – mpen Aug 14 '15 at 18:36
  • Ah, sorry, I didn't understand you wanted a HTML-only solution. I'd definitely go with a JS/AJAX call, overriding the default anchor behaviour. Btw. why do you think you'll have to have jQuery there... and even if you did, why do you think it will ruin your UI? – Shomz Aug 14 '15 at 18:36
  • And another thing: can you provide a bit more details about your UI? I'm trying to understand what are you trying to avoid. – Shomz Aug 14 '15 at 18:38
  • @Shomz I just explained. If I want to update the page elements to show that the delete actually occurred, I will have to update various UI elements. *Unless* I use JS to reload the page after the AJAX call completes. The UI is generated with PHP and Twig. It's mostly static. No fancy Angular or ReactJS libs going on here. – mpen Aug 14 '15 at 18:39
  • 1
    Got it now, I guess you could make a landing page with PHP that will handle the deletion and redirect you back - that way, you'll have no worries about the UI and you can even get away with a GET request from standard anchor tags. It might sound a bit weird, but if it works for you... just do it. The user flow will look more natural than doing AJAX + refresh on success. – Shomz Aug 14 '15 at 18:41
  • @Mark what you can do is after delete or any action, let jQuery update your page with out refreshing the page? is that some thing that helps? – maytham-ɯɐɥʇʎɐɯ Aug 14 '15 at 18:49
  • @maytham I think I addressed that a couple times already. jQuery gets hairy really fast. It's too brittle. If you update the HTML, your jQuery breaks. If you have other widgets updating the DOM on the same page and you don't account for every possible state, your jQuery breaks. It's doable, but it adds more long-term maintenance. – mpen Aug 14 '15 at 18:53

3 Answers3

1

You could do it in pure JavaScript by sending a POST request with XmlHttpRequest, as discussed here: Send POST data using XMLHttpRequest

Community
  • 1
  • 1
maxime.bochon
  • 542
  • 4
  • 13
1

A solution without JS:

Make a landing page with PHP that will handle the deletion and redirect you back - that way, you'll have no worries about the UI and you can even get away with a GET request from standard anchor tags. The user flow will look more natural than doing AJAX + refresh on success.

You can even use the existing page (let's call it page.php), for example:

  • click an anchor that will take you to page.php?action=delete&token=123&ids=1-2-3-4-5
  • the page will recognize the action parameter, validate the token and delete items with the submitted IDs
  • after it's done, it will redirect you back to page.php (so the URL looks nice again and you're safe with users clicking the refresh button)
Shomz
  • 36,161
  • 3
  • 52
  • 81
0

From what I've gathered from the comments, there's basically 3 approaches:

  1. Wrap each delete button in a <form> as originally stated in the question
  2. Issue an AJAX DELETE request and when it completes, either
    1. Refresh UI elements with jQuery (or other front-end framework)
    2. Reload the entire page
  3. Make the delete buttons link to an intermediate page with a single <form> element. This may also serve as a confirmation page.
    1. Have the form submit itself automatically with JS

The AJAX solution with full page reload (2.2) sounds like it would produce the least cruft to me.

mpen
  • 237,624
  • 230
  • 766
  • 1,119