7

I am trying to bind backAfterSaveStatus value to hidden input and for some reason then form is submited backAfterSave value is null. After that I go back and submit form again - backAfterSave value is 1. Where is the problem? I tried same thing without prevent and submit() but it's not working still. Also I had dumped div with x-text and code makes hidden input 1 before form submit. What I am doing wrong?

<form action="<...>" method="post">
    <div x-data="{
        backAfterSaveStatus: '',
        backAfterSave () {
            this.backAfterSaveStatus = '1';
            document.querySelector('form.withBackAfterSave').submit();
        }
    }">
        <input name="backAfterSave" :value="backAfterSaveStatus">
        <div>
            <span>
                <button x-on:click.prevent="backAfterSave()" type="submit">
                    Save & back
                </button>
            </span>
            <span>
                <button type="submit">
                    Save
                </button>
            </span>
        </div>
    </div>
</form>

I want same result as below:

let buttonBackAfterSave = document.getElementById('button-back-after-save');

if (buttonBackAfterSave) {
    buttonBackAfterSave.addEventListener('click',  () => document.getElementById('input-back-after-save').value = 1);
}
4
  • Don't you need to reset the value of backAfterSaveStatus = 0 after the submit() call in the backAfterSave() method Commented Nov 22, 2020 at 13:09
  • I tried it also, but main problem is that first time after form submit value is null. Commented Nov 22, 2020 at 13:14
  • @keizah Is this issue specific to alpine/php or can it be solved using JS as well? So to resume, whe the form is submitted, and only after submission, you want to be able to click the button save and back and display 1 inside the input field, correct? Commented Dec 19, 2020 at 17:26
  • 1
    I reproduced the issue and solved it using the $nextTick magic property Commented Dec 19, 2020 at 18:36

3 Answers 3

1

The problem is the form being submitted "too fast" (the backAfterSaveStatus value isn't done binding to the input). Use $nextTick so Alpine waits until the value is properly changed.

<form method="post" class="withBackAfterSave">
    @csrf
    <div x-data="{
        backAfterSaveStatus: '',
        backAfterSave () {
            this.backAfterSaveStatus = '1';
            this.$nextTick(() => { document.querySelector('form.withBackAfterSave').submit() });
        }
    }">
        <input name="backAfterSave" x-bind:value="backAfterSaveStatus">
        <div>
            <span>
                <button x-on:click.prevent="backAfterSave()" type="submit">
                    Save & back
                </button>
            </span>
            <span>
                <button type="submit">
                    Save
                </button>
            </span>
        </div>
    </div>
</form>
Sign up to request clarification or add additional context in comments.

Comments

0

Thank you! I don't use x-ref because these buttons are in separate layouts file, so I can't move it outside x-data range. My final code:

<div class="pt-5">
    <div class="flex justify-end" x-data="{
        backAfterSave: 0
    }">
        <input type="hidden" name="backAfterSave" :value="backAfterSave">
        <button type="button"
                class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
            {{ __('Cancel') }}
        </button>
        <button type="submit"
                @click.prevent="backAfterSave=1; $nextTick(() => {
                    document.querySelector('form.with-back-after-save').submit()
                })"
                class="ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
            {{ __('Save & back') }}
        </button>
        <button type="submit"
                class="ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-teal-600 hover:bg-teal-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-teal-500">
            {{ __('Save') }}
        </button>
    </div>
</div>

Comments

0

Just released that I could use simple button with custom name and given value.. No javascript was needed :)

<button type="submit" name="back-after-submit" value="1">Save</button>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.