Posting a collection to MVC3 from Plupload - asp.net-mvc-3

I've got a documents upload page in an MVC3 application that lets the user upload documents to be stored in a database and associated with a parent entity in the database. There are also some permissions that the user can customize to stipulate who can access the document.
I've implemented my document upload functionality with Plupload, The behavior that it's working with is that essentially it will take a queue of files, and upload them for me to a specific action dedicated to recieving this information, and when they are posted each file is given a unique name (something like p16kearti61rf31qb61fogjm2127i3.jpg for example.)
Once all of the files have been uploaded in plupload, the parent form is submitted with the information about the files plupload just uploaded as well as some other data for the documents like the Primary Key of the object they are to be associated with, and the groups that have been checked off for it's permissions aspect. Now this works fine except that I can't find a strongly typed object structure that MVC will bind my data to so that I can work with the posted back data. Here's an idea of what is in my Request.Form collection, what I'm looking for is some insight on how to best capture this information in my action. I have complete control over the naming of the controls for the document permissions, but the plupload controls are built in and I'd don't know if I can change them.
__RequestVerificationToken: "...XDsBA5oZA9Ku2oPPdyyi2J+DbvoKRY9HJ2...etc"
ownerId: "CCEE2ADF-633D-4D55-90EE-2829D352BEEB"
uploader_0_tmpname: "p16kearti61rf31qb61fogjm2127i3.jpg"
uploader_0_name: "picture1.jpg"
uploader_0_status: "done"
uploader_1_tmpname: "p16kearti61kqu8tsmja67911v44.jpg"
uploader_1_name: "picture2.jpg"
uploader_1_status: "done"
uploader_2_tmpname: "p16kebp785gci1e291i543cc1c8k4.jpg"
uploader_2_name: "picture3.jpg"
uploader_2_status: "done"
uploader_count: "3"
documentGroups[B8C97C5C-B1B8-43C2-89F1-B1DF353AF677]: "false"
documentGroups[A2C8331C-7068-4611-82BF-6F0C61C8BA7D]: "false"
documentGroups[6DCBF4A8-B863-49E6-AAE9-2A0E372FF622]: "true"
documentGroups[05C04E05-D7A8-45D6-8138-2FA36F0A5922]: "false"
documentGroups[3E2F2B1B-FAAA-420A-B9A1-F223ADF66AF0]: "true"
Any suggestions on how to write my action method? I was hoping for something like this but I can't get it to work.
public ActionResult Upload(Guid ownerId, IList<PluploadFile> uploader, IList<bool> documentGroups)

Just in case someone else was looking for an update on this (and since I got no response to my question what-so-ever), I ended up splitting my post into two; one handled by plUpload which I use to save the file(s) to a temp folder using the unique names pased in to the Action from plUpload (such as p16kearti61rf31qb61fogjm2127i3.jpg), and the other when I post the wrapping form which holds the information I need and the unique names plupload has as well as some fields indicating the status result of the original upload. The problem is that because it's two posts I now have to look at maintaining the contents of my temp folder in case the user uploads documents but doesn't submit the wrapping form. Not the solution I wanted but I can't an alternative working as expected.

Related

Kademi - allow front end user to delete a file they have uploaded

I am trying to allow front end user to delete a file they have uploaded.
#docs() tells me that $page.lead.files has a method called .remove() that accepts either an Int or an Object.
I keep getting a response of "false" when using this method. I am trying to pass and ID or Object of a file within $page.lead.files object.
Debugging...
User: https://spinsurance.admin.kademi.com.au/manageUsers/116783806/#summary-tab
Page: https://crm.spinsurance.co.nz/leads/148615383/
Source: https://spinsurance.admin.kademi.com.au/repositories/spcrm/version1/theme/apps/leadman/components/texteditor?fileName=leadDetailTabContentComponent.html
Under section on page called: Uploaded Files.
Click big red Delete button. (I don't mind if this file gets deleted)
Thanks for your help in advance.
The Lead.files property is a persisted list. Its not a good idea to try to modify the database using that approach.
Note that lead files are exposed as http addressable resources, which support the http DELETE method
So the simplest approach is to delete from the browser using ajax
Eg
DELETE /leads/123/myfile.pdf

Adding custom data based attributes based on Response object

Halo ! I'm trying to implement dropzonejs in a very specific way. Actually I follow the standard implementation described on the official page. Everything works perfectly.
But I'm willing to attach the server's generated URI for each uploaded file directly when uploaded : when uploading it's creating a database entry with some stuff like a page uri with title etc. This mean that the server would return as a response the id of the database saved file in order to attach the href attribute with its value to the the element in front.
This is quite ok to do this when only one file is uploaded, but it becomes trickier when bulk uploading.
So maybe I didn't understand the documentation well (and I'm quite sure I didn't), but is there any way to add custom data-dz-like attributes based on my server's response ? I'd like something like data-dz-url where the url points to a database entity (not the file itself).
Or if not if there is an "easy way" to handle this.
Thanks a lot
Here is the answer :
myDropzone.on('success', (file, response) => {
file.previewElement.href = "/admin/media/"+response.id+"/show/"
})
file is reference to the current uploaded element. It's possible to extend it's html attributes through previewElement. Setting the data-type attribute in the template before, then assigning it the right value works aswell.
Hope this will help some.

Dynamically add form to formset in Django and submit with AJAX

I have read a lot of answers relating to how to dynamically add forms to an model formset in Django and can successfully implement that. However, I would now like to submit the formset with AJAX. This is mostly working now but I have an issue that I can't find a solution to in any other answer:
If you dynamically add a form to the formset, you give it a new form id number that is one larger than the maximum the form currently has and you also increment the management TOTAL_FORMS count by one. The newly added form then saves successfully as a new object.
I am trying to submit by AJAX so the user can continue editing without having the page refresh. The formset saves fine but any dynamically added forms are now existing objects. To account for this I need to increment the INITIAL_FORMS count on the management form when the save is successful. Easy enough. However, I've also realised I need to give the newly created objects an ID since they now exist in the database.
How can I get my view to tell me the ID of the new objects in its response to the AJAX call? Or is there a better way of looking at this?
Django forms and formsets are intended for classic browser-based posting of data. Though they can definitely be made to work with Javascript, the more you want to part from the normal behavior, the more complex it gets.
Depending on your requirements, you might start thinking about dropping it and switch to Javascript + REST endpoint. Of course, if you need progressive enhancements and you are required to have it work without javascript, that's not an option.
In any case, you want to have a customized view for posting from JS, so that you can get the result back and parse it easily in your AJAX handler. Probably some JSON.
There are several approaches you could take.
Have your AJAX send data to a different URL. This is pertinent if you have an API or are planning to build one at some point. So your form, when submitted normally, will do its old-style processing but your AJAX will talk to the API endpoint instead.
For instance, your form send to https://example.com/myform, but your Javascript code talks to REST api at https://example.com/api/v1/mymodel/ (sending PUT, POST and DELETE requests as appropriate).
Or if you don't have an API and building one seems overkill, you may just alter your view so it formats its output differently depending on whether the data is being submitted in the regular way or using AJAX.
You'd go about it like this:
class MyFormView(.....):
def render_to_response(self, context, **kwargs):
if self.request.is_ajax():
return self.render_to_json(context, **kwargs)
return super().render_to_response(context, **kwargs)
def render_to_json(context, **kwargs):
data = {
# see below!
}
return HttpResponse(
content=json.dumps(data).encode('ascii'),
content_type='application/json',
)
This is just an outline. You need to ensure is_ajax will detect it properly (see django doc). And you need to properly build data from context: extract the things you want to send back to your JS code and put them in the dict.
You will find it's manageable if you just do this for one, maybe two views in your project, but very quickly you'll want to have a small API instead, especially given how easy it is to build one with packages such as Django REST framework.
In your view, where you save the object, AFTER the save, the object.id will contain the new id for the object, which you can return via json or however you want in your ajax response, and then yes you will need to fill that into the formset row so that it will be submitted the next time.
One thing you have to watch out for is that django expects all existing rows to be at the top of the formset, and any new rows to be at the bottom. Otherwise, the formset save will complain about missing id's. So if you're doing any kind of sorting in your javascript, you can't do that.. unless you do quite a bit of fixing of all the field names etc in the formset. The formset code uses the numbers in the management form to determine which rows to insert and which rows to update, it does not do it on the basis of whether or not an id is present. Unfortunately...

Joomla component "attachments" allow html in input

this question might be a bit special. I am using this Joomla 2.5 extensions to give authors the abilty to add Attachments to articles: Joomla Attachments
The extension renders an input field called "description" in a backend form to insert an file description for the provided file. Unfortunately it´s not taking HTML tags which I need. By saving the form it seems a strip_tags() or preg_replace() or something similar cleans the input. I combed through the code of the attachments extension but couldn´t find a place where the input is cleaned or saved.
To hopefully stay in the Question + Answer rule of Stackoverflow:
Is there a class which extensions inherit from the Joomla Core to save form data to a DB-table ( which also could be responsible to clean and validate user input )?
thanks for any idea,
tony
You should see how the field is defined first:
1. Form definition
look into the
administrator/component/yourcomponent/models/forms/somename.xml
there you could find a form definition, if so it will also specify the field type: depending on the type there are several available filters; for example the default textarea will strip html, and you need to set
filter="raw"
in order to enable it. see http://docs.joomla.org/Standard_form_field_and_parameter_types for a list of fields, click and you can find the available format options.
2. model
If the model inherits from JModelAdmin or JModelForm or other JModel* it will automatically handle binding of the forms' data to the database, look for the Save function which should receive the form $data.
3. more
There are at least another dozen possibilities. If the above didn't help, try finding the form: possibly you could find it just by looking at the markup. Once you have the form, check the following fields:
option
task
view
This should help you find the php code that is invoked based on the form:
if view is set, maybe in ./views/someview/view.html.php you could find the saving logic.
if task is set, look for a function with the same name in ./controller.php
if task contains a ".", look for the controller in the ./controllers/ folder.
if option is not the name of your component, your component is sending the data to another component for saving, and most likely set a return-url

MVC 3 Remote Validation, problem with duplicate check in Edit view

I am using remote validation to make sure that the email and username fields in a user class stop a user from entering a username and/or email that already exists within the database.
This works fine on the create view, however the obvious problem I run into in the edit view is that when I try save some changes for a given user - I get the same validation messages on the username and email saying that they already exist in the database! Therefore stopping me from editing anyone because their emails and usernames already exist.
I have been looking around and was surprised that I could not find a similar problem to mine. I have seen many examples of dupliate name/email/value validation on create pages but nothing on the inevitable problem that will arise in the Edit view.
Any hints/tips on a way around this would be greatly appreciated. Maybe there is a way to make the validation only work in the create view? Though ideally, I want the validation in the edit view, just excluding the user's own name and email in the validation checks.
Thanks in advance for any answers!
You should use view models. Those are classes which are specifically designed to meet the requirements of a view. Controller actions should take/pass only view models to views and never your domain models. So you will have two controller actions, one for inserting and one for editing, and two corresponding view models with their respective validation rules.
The way I've gotten around the problem is having 2 different validation methods; one takes a single argument (the user name) and one takes 2 arguments (the new user name, the original user name). The Edit method validates against the 2 argument method, where it looks for the new user name unless it matches the original user name.

Resources