[EXTENSION] multimodelform/jqrelcopy Solutions for clientside cloning
#1
Posted 07 June 2011 - 08:21 PM
#2
Posted 16 June 2011 - 05:07 PM
Thanks for putting together multimodelform. I got it set up and working and it is a huge help but confused about a simple aspect of it.
Using the example group::member that you have posted I have set up group.id as INT with Auto Increment and then formed a relation from member.groupid to group.id and changed my widget('ext.multimodelform.MultiModelForm',array( to match.
On my form I have Tile, Firstname, Lastname, Member Since as expected but there is also labels for ID and GroupId below them.
What do I need to modify to remove these labels from attributes where I am not collecting any data in the form? I understand how to handle all of this in a normal form but having problems making sense of the logic in your extension.
#3
Posted 17 June 2011 - 01:01 AM
I will upgrade soon to v2.2
You have to change the code in line 843 with this.
if ($this->isCopyTemplate)// new fieldset { $element->name = $elemName . '[]'; $elemOutput = ($element->type == 'hidden' || //bugfix: v2.2 $this->parentWidget->tableView) ? '' : $elemLabel; $elemOutput .= $element->render(); //bugfix: v2.1 - don't render hidden inputs in table cell $output .= $element->type == 'hidden' ? $elemOutput :$this->getWrappedRow($elemOutput); } ....
#4
Posted 17 June 2011 - 03:39 AM
#5
Posted 19 June 2011 - 03:19 PM
I was wondering if you had an example of using this with 3 or more forms?
Extending from your Group::Member example if there was a relationship Member::Profile how could I get the Profile form elements to also show up on the Group form? In my app (using my tables of course), I have used multimodelform to create forms for both Group::Member and Member::Profile but I am assuming I need to form some arrays with actionCreate and actionUpdate of the GroupController to make this happen to have Profile elements directly on the Group form, correct? I have tried a few different things and even tried pulling the logic from what qiang had written here. Anyways wondering if you have an example.
Thanks
#6
Posted 20 June 2011 - 10:03 AM
But it works.
In a project I use an array of multimodelforms to render into a form (database is mongoDB).
For the profile you have to place a second multimodelform widget with another id and own validatedItems.
In the controller you have to handle extra validate / validatedItems / deleteItems.
It's similar to the wike-doc from qiang.
Hope the helps.
#7
Posted 20 June 2011 - 02:00 PM
Joblo, on 20 June 2011 - 10:03 AM, said:
But it works.
In a project I use an array of multimodelforms to render into a form (database is mongoDB).
For the profile you have to place a second multimodelform widget with another id and own validatedItems.
In the controller you have to handle extra validate / validatedItems / deleteItems.
It's similar to the wike-doc from qiang.
Hope the helps.
Ok I worked through it now. I had a problem with my relationships. I now have multiple forms displaying but can't fully test create and update until I clear up some things in my db.
#8
Posted 22 June 2011 - 12:03 AM
Currently, you can only use 'type' => 'file' in your form config to add an upload field to your dynamic form.
I'll try with CMultiUpload widget later.

Number of downloads: 147
#9
Posted 22 June 2011 - 06:40 AM
I am not sure if the method run() is causing this?
#11
Posted 22 June 2011 - 10:20 AM
thanks for your code.
In the method 'renderFormElements()' I use
$elements = $this->getElements(); foreach($elements as $element) ....
I was surprised that Yii returns all model attributes, not only the elements from the form config.
But maybe it's not bad when other elements were rendered as hidden to ensure data integrity ....
@enfield
I always add an empty 'CopyTemplate', even in validatation mode. Maybe the user want to correct errors add more items ...
See method 'run()'
.... // add an empty fieldset as CopyTemplate $form = new MultiModelRenderForm($this->formConfig, $this->model); $form->index = $idx; $form->parentWidget = $this; $form->isCopyTemplate = true; ...
Is it that what you mean with copied and blanked out?
#12
Posted 22 June 2011 - 02:38 PM
Joblo, on 22 June 2011 - 10:20 AM, said:
Joblo, sometimes it is easier to explain through pictures...

Sure I want the user to be able to correct their information but not through the second copy of the model (Member). I want them to be able to correct directly in the place where the mistake occurred. In the case above in the red shaded box of Firstname.
I have been trying to modify you method run() even before posting my original question but can't seem to be getting anything working.
#13
Posted 23 June 2011 - 02:37 PM
#14
Posted 24 June 2011 - 11:11 AM
enfield, on 22 June 2011 - 06:40 AM, said:
I am not sure if the method run() is causing this?
As I understand, if the validation failed, you don't want the Multi model form to add another blank form after the last subform. You just like the form to appear like it is, before click the "Save" button, right?
Unfortunately, this is not possible. The extension automatically create a sub form with the config provided, as a source for jQuery Relcopy to create new ones when click the Add Item.
Using CForm 's showErrorSummary setting (read Yii api about this), you can make the subform display its own error. By default, the extension return the error to Member model, so when validation failed, there is only one error Summary display on top of the form.
#15
Posted 24 June 2011 - 03:22 PM
The form is in displaying errors mode if the validated items are not empty.
public function run() { $isErrorMode = !empty($this->validatedItems); ... // add an empty fieldset as CopyTemplate if (!$isErrorMode) //some invalid models exists { $form = new MultiModelRenderForm($this->formConfig, $this->model); $form->index = $idx; $form->parentWidget = $this; $form->isCopyTemplate = true; if (!$this->tableView) { if ($idx == 0) // no existing data rendered echo $form->renderAddLink(); } echo $form->render(); } ...
Then you have to render the addlink only if the CopyTemplate is shown.
if ($idx == 0 && !$isErrorMode) // no existing data rendered echo $form->renderAddLink();
Maybe I will add this feature configurable in the widget.
But in my opinion a user should be able to add more items also when other fields show errors.
And the AddItem link needs a empty CopyTemplate to clone...
#16
Posted 24 June 2011 - 08:18 PM
Thanks for the response. Maybe I didn't fully appreciate the purpose of this extension. In my app I have changed my user forms to a more basic approach but can still utilize the functionality of this app in my admin forms.
#17
Posted 28 June 2011 - 03:10 PM
I fixed it for myself by adding a custom validation rule that sets the field to 0 if it is null, but it would be better if the hidden field was copied. (It works right for each row generated server side, just not for extra rows added client side.)
#18
Posted 29 June 2011 - 01:23 AM
I create a new AR model to store files, and use Multimodel Form to handle the form.
Attached File(s)
-
mmf_file.tar.gz (7.16K)
Number of downloads: 155
#19
Posted 11 August 2011 - 10:33 AM
Hope it's the right place to ask questions about jqrelcopy extension. Couple of things i don't know how to do with this extension.
1) Is it possible to assign new id's to the fields everytime when we do the cloning ?
2) In update mode, how to add "remove" link for the cloned rows ?
Appreciate your help on this .Thanks in advance.
#20
Posted 11 August 2011 - 11:58 AM
See the code of 'jquery.relcopy.yii.1.0.js':
// Increment Clone Children IDs $(clone).find('[id]').each(function(){ var newid = $(this).attr('id') + (counter +1); funcBeforeNewId.call($(this)); $(this).attr('id', newid); funcAfterNewId.call($(this)); });
If you want to change this behavior (necessary when cloning dateTimePicker ...),
you can add a js-code as option for 'jsBeforeNewId' or 'jsAfterNewId' on cloning to alter the id in another way.
$this->widget('ext.jqrelcopy.JQRelcopy', array( 'id' => 'copylink', 'removeText' => 'Remove this item', 'jsBeforeNewId' => "alert(this.attr('id'));", 'jsAfterNewId' => "this.attr('id','myNewId'); alert(this.attr('id'));", ));
2. The remove link should be there if you add a 'removeText' option like above.