CraueFormFlowBundle icon indicating copy to clipboard operation
CraueFormFlowBundle copied to clipboard

populate stepData for existing entities

Open aarsla opened this issue 12 years ago • 27 comments

Dynamic navigation should have all steps available for editing existing objects.

aarsla avatar May 21 '13 12:05 aarsla

Can you elaborate on this a bit? What are trying to accomplish?

havvg avatar May 24 '13 17:05 havvg

User should have all steps available (all formFlow stepData populated) when editing existing entity. User would be able to choose directly step X of form flow instead of being forced to move from step 1 to the last step.

— Sent from Mailbox for iPhone

On Fri, May 24, 2013 at 7:52 PM, Toni Uebernickel [email protected] wrote:

Can you elaborate on this a bit? What are trying to accomplish?

Reply to this email directly or view it on GitHub: https://github.com/craue/CraueFormFlowBundle/issues/56#issuecomment-18419966

aarsla avatar May 24 '13 18:05 aarsla

I think this would be very useful.

If you are editing an entity versus creating a new one, all the steps should immediately navigable. You shouldn't have to save the first step, go to the second step, save it, go to the third step, etc.

I think all we would need is a way to take an entity object and convert it to the corresponding session that activates the dynamic step links.

Do you have any input Craue?

redstar504 avatar Jul 17 '13 20:07 redstar504

It depends on the use case what "editing" means. There could be conditions which need to be met by skipping steps or rendering subsequent steps differently depending on the data. E.g. in the demo, changing a location would be the same flow as creating one.

If such an "edit" form (in means of just showing all fields at once) would fit the use case, one could compose the types of all steps into one form (and not use a flow at all). But I truly doubt that it will be that easy in most cases.

craue avatar Jul 18 '13 07:07 craue

Hi, I have the same problem for editing a entity. I can't go directly to the wanted step. Example: I create a user: step 1: set an email and a password step 2: set an address and a birthday date step 3: set an avatar step 4: preview with the save button

I want to edit this new user and only change the avatar. I can't go directly to the step 3 without validate the step 1 + 2. url?step=3 doesn't work too.

I've try to tweak the flow class to load the steps in the session and accept to go directly to the 3rd step but this won't work well.

Have you an idea how to perform such thing?

Abhoryo avatar Sep 13 '13 21:09 Abhoryo

@Abhoryo: It seems to me that the behavior you're looking for is a form split into several tabs (maybe using JavaScript), which is not the intention of this bundle. I can't imagine how to handle arbitrarily switching tabs while still validating the input and properly render the (varying) fields for a part of the form depending on this input. It wouldn't be a controllable flow anymore, but rather just a mess. :smirk:

craue avatar Sep 14 '13 11:09 craue

The data is already valid, the data is load from the database so the flow is already controllable. This is the same case that @aarsla and @redstar504.

Abhoryo avatar Sep 14 '13 20:09 Abhoryo

I have the same problem, has someone found a solution? When I create any register, how can the bundle save the register in each step? because it just saves when the flow finished.

Jhenrry avatar Oct 11 '13 22:10 Jhenrry

@Jhenrry: Could you rephrase that? I don't get what you are talking about.

craue avatar Oct 12 '13 09:10 craue

I have created a very lengthy flow, one that could take users several sessions to complete. Currently, when a user times out and loses their session, they also lose their current step. When they return, the flow and form data is loaded from the database, but their current step number is lost. They must press next through the flow until they return to where they were.

I would be hugely in favor of a way to "prime" the session storage with the information from the database, so that users can resume what step they were on.

UFTimmy avatar Mar 25 '14 18:03 UFTimmy

@UFTimmy You are not required to use the session storage, see #21. Using your database directly should solve your issue. Binding the data should set the flow to the respective step.

havvg avatar Mar 26 '14 06:03 havvg

Do you find something to add this feature ?

Abhoryo avatar Mar 26 '14 08:03 Abhoryo

You could do something like this:

<?php

$flow->bind($data);
while ($flow->isStepDone($flow->getCurrentStepNumber()) and $flow->nextStep());

// .. 

havvg avatar Mar 26 '14 08:03 havvg

I'll try this. Thanks.

Abhoryo avatar Mar 26 '14 09:03 Abhoryo

Thanks for the pointer, @havvg. I created a custom storage, but I am a little confused, and was wondering if you could help.

The StorageInterface, and the FormFlow, expect you to pass data around as arrays, which mimic the data structure from the Request. However, what I have is an Entity, from the database. When I create my flow, I grab the Entity from the database, and bind it to the flow. That sets all of the form values from the database, so when I get to the right step, the form data is there, which is great.

I created a DatabaseStorage, and all it does is find out what steps have been completed, and pass that back to the FormFlow as an array, with completed steps as keys an empty values. Since the form values are already set via the previously mentioned bind, I didn't worry about converting the Entity into the array form that the storage expects.

However, now I can't validate the previous steps, because I have no array of data to submit to the form for each step.

I feel like I am approaching this from the wrong angle. I could save each form step's data, in array form, to the database, as well. However, that seems unnecessary, and I can see problems when I move an element from one form step to another.

I would appreciate any guidance you could offer. My apologies if this is the wrong forum for the question.

UFTimmy avatar Mar 27 '14 16:03 UFTimmy

Hi,

I can't understand how I can achieve this: "Dynamic navigation should have all steps available for editing existing objects."

Thanks a lot for help

matteomoretti avatar Feb 16 '15 12:02 matteomoretti

@matteomoretti When you edit existing object navigation should have all steps accessible so you can jump to the step you wish to edit.

aarsla avatar Mar 05 '15 11:03 aarsla

havvg's code doesn't work plus it brokes the previous feature.

Abhoryo avatar Mar 11 '15 22:03 Abhoryo

What code doesn't work?

havvg avatar Mar 12 '15 09:03 havvg

while ($flow->isStepDone($flow->getCurrentStepNumber()) and $flow->nextStep()); after the bind.

Steps link aren't active too.

Abhoryo avatar Mar 12 '15 20:03 Abhoryo

Well, maybe with newer version of the bundle, it's not working anymore. Back then (v2.1.5) it was working perfectly fine (I got this line in production).

havvg avatar Mar 13 '15 09:03 havvg

any news?

matteomoretti avatar Sep 03 '15 21:09 matteomoretti

Hello. I'm having the same case now. I just want to jump to each available step at any time when editing an existing entity. The argument that there could be dependencies do not apply, because even if I change anything in the active tab it would not be stored. So please just make it possible to jump directly to any available step. Many of us seem to wish for that. Thanks.

tknuppe avatar Nov 05 '15 17:11 tknuppe

My solution for now is to modify the isStepDone Method in the FormFlow Class by overriding the whole Class.

Now it returns true whenever the formData of the flow step has an ID. This is the case, when the step was edited. I left the test for isStepSkipped intact.

When editing an existing dataset you can now jump from the starting step to every available step. From there you have to skip forward until you reach the last step to save the whole thing. This is necessary if there are dependencies at the upcoming steps.

Beware: The modification works in my case. Please don't blame me if it produces any disturbance in yours.

The Code:


    public function isStepDone($stepNumber) {
        if ($this->isStepSkipped($stepNumber) || $this->formData->getId()) {
            return true;
        }
        return array_key_exists($stepNumber, $this->retrieveStepData());
    }

Any comments appreciated.

Cheers!

tknuppe avatar Nov 20 '15 15:11 tknuppe

@tknuppe your solution seems to work good.

I only overrided the method in my FooFormFlow which extends from the bundle base FormFlow class and leave the parent logic.

The code:

    /**
     * {@inheritDoc}
     */
    public function isStepDone($stepNumber)
    {
        if ($this->getFormData() != null && $this->getFormData()->getId()) {
            return true;
        }

        return parent::isStepDone($stepNumber);
    }

cocciagialla avatar Feb 08 '16 11:02 cocciagialla

@tknuppe && @cocciagialla Thanks. That solution is simple and elegant.

sujayjaju avatar Jul 02 '16 09:07 sujayjaju

That works pretty well for me, but shouldnt it be possible to also submit the form when you navigate to another step? My Flow has 7 Steps -> I edit something in step 2 -> I click "next" -> I navigate to the last step -> I submit the flow -> The changes in step 2 are saved.

That obviously doesnt work if I do not click next... but couldn't you also submit the form while you navigate to the last step?

karatektus avatar Mar 14 '18 11:03 karatektus