Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamically change hx-post #882

Closed
finevine opened this issue Apr 16, 2022 · 3 comments
Closed

Dynamically change hx-post #882

finevine opened this issue Apr 16, 2022 · 3 comments

Comments

@finevine
Copy link

Hi,

I try to make a bulk action select input for a list of "rewards".
Here is my HTML :

<form hx-post="" hx-trigger="reward-bulk-action" id="rewardsActionsForm">
    <input type="hidden" name="csrfmiddlewaretoken" value="csrftoken">
    <select name="" class="select form-control custom-select" required="" id="rewardsActions">
        <option value="">----- Bulk actions ----</option>
        <option value="delete" data-url="URLforBulkDelete/">Bulk Delete</option>
    </select>
    <table>
        <tbody 
               hx-trigger="RewardListChanged from:body" 
               hx-get="urlforlistofrewards/" hx-target="this">
            <tr id="reward_46">
                <td>
                <input type="checkbox" value="46" name="reward">
                Blablabla
                </td>
            </tr>
        </tbody>
    </table>
</form>

My JS looks like that:

$(document).ready(function () {
    delete_objects('reward')
})

function delete_objects(object) {
    let actions_id = find_actions(object)[0].id  // --> rewardsActions
    let actions = document.querySelector(`#${actions_id}`)
    $(`#${actions_id}`).on("change", function () {
        let url = actions.options[actions.selectedIndex].getAttribute("data-url")
        let formID = `#${actions_id}Form`
        let data = new FormData(document.querySelector(formID))
        htmx.ajax('POST', url, {values:data})
        // htmx.trigger(parent, "reward-bulk-action")
    })
}

Here request.POST is an empty dic (I use Django)
I have also tried

function delete_objects(object) {
    let actions_id = find_actions(object)[0].id  // --> rewardsActions
    let actions = document.querySelector(`#${actions_id}`)
    $(`#${actions_id}`).on("change", function () {
        let url = actions.options[actions.selectedIndex].getAttribute("data-url")
        let parent = htmx.find(`#${actions_id}Form`)
        parent.setAttribute('hx-post', url)
        htmx.process(parent)
        htmx.trigger(parent, "reward-bulk-action")
    })
}

Here the POST request is sent to the current page despite the htmx.process

I can't understand what I do wrong on this page https://htmx.org/api/#ajax

@finevine
Copy link
Author

I've managed to make it work!

surprisingly, values does not work but setting the source as the form is OK!

Here is my new code:

    function delete_objects(object) {
        let actions_id = find_actions(object)[0].id
        let actions = document.querySelector(`#${actions_id}`)
        $(`#${actions_id}`).on("change", function () {
            let url = actions.options[actions.selectedIndex].getAttribute("data-url")
            let formID = `#${actions_id}Form`
            if(url){
                htmx.ajax('POST', url, {source: formID})
                actions.value = ""
            }
        })
    }

@David-Guillot
Copy link
Contributor

Hi there,

It seems to me that most of the complexity could be removed by having, on server side, sort of a proxy view for all bulk actions, that would just read POSTed value for the <select> field. That way, your HTML would just be:

<form hx-post="urlForBulkActionsProxy" hx-target="#rewards">
    <input type="hidden" name="csrfmiddlewaretoken" value="csrftoken">
    <select name="bulk-action-to-perform" class="select form-control custom-select" required="required">
        <option value="">----- Bulk actions ----</option>
        <option value="delete">Bulk Delete</option>
    </select>
    <table>
        <tbody id="rewards">
            <tr id="reward_46">
                <td>
                <input type="checkbox" value="46" name="reward">
                Blablabla
                </td>
            </tr>
        </tbody>
    </table>
</form>

And you would have no JS at all, am I right? The only thing left to do would be the Django proxy view that would trigger the actual and appropriate bulk action and return the HTML fragment of the updated list of Rewards. But that's piece of cake 😉

@finevine
Copy link
Author

Thank you! Good idea: I haven't thought about that. This is much more neat.
Lovely piece of cake actually.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants