2
votes

There are two models, let's say A and B with A hasMany B relationship. User can associate as many B rows as (s)he wants while creating A. The application allow users to dynamically add and remove B rows using JQuery, more specially by following this example - http://jsfiddle.net/mjaric/tfFLt/

Everything works great unless save (using saveAll) fails due to server side validation. In that case, page refreshes on submit and all dynamically added fields are lost and user has to recreate all the rows from start.

Is there any way, none of dynamically added fields using JQuery are lost and retain their old values (same as Cake's default behaviour)? May be making Ajax request is one option so page doesn't reload on server side validation failure but for me that's not an option since the form has one file upload as well and as far as I know Ajax requests do not support file trsnafer?

1
Uploading files via ajax call works like a charm, the approach is just a bit different. You need to upload the File before saving the form and store some values after a successful upload in an hidden field. - Julian Hollmann
@JulianHollmann Thanks for your input. I was thinking of using JsHelper for ajax form submit however the CakePHP doc says that JsHelper doesn't support file uploads via ajax so I guess I first need to upload the file using ajax (without helper) and then submit the form using helper? Another problem is that I am using CakePHP media helper for file uploads (attachment mode) which make it more difficult for a novice like me to make changes like you suggested. - eth.block
You can create all B rows again, since have all informations you need in $this->data. I have lot of applications in this same format. For upload file, just validate all fields before save/upload. - Paulo Rodrigues
@PauloRodrigues Thanks! Reusing $this->data array should work. - eth.block
@PauloRodrigues I am trying to reuse $this->data array however I am facing an issue. As explained above, I have A hasMany B relationship and in case of server side validation failure, I count the number of total B fields (including dynamically generated ones) and recreate that many fields. Now number of fields are shown correctly however when I provide field names like (B.0.fieldname, B.1.fieldname etc) it converts them to A.0, A.1 and so on. Essentially it assumes they are parent model (A) fields. I am unable to understand what I am doing wrong here. - eth.block

1 Answers

0
votes

As pointed out you can put up all the fields statically when rendering the view upon validation failure.

File upload is not possible via AJAX, because you can't read files from JS. Albeit, there is a well established workaround: you can put the form for a moment into an invisible iframe, submit it natively, and trigger callbacks as it would be an AJAX response.

jQuery form plugin is really awesome at submitting forms the AJAX way, and performs the latter transparently when it encounter a file field.