One-to-many file upload with additional checkbox
One-to-many file upload with additional checkbox
Link to test case:
Debugger code (debug.datatables.net):
Error messages shown:
Description of problem:
I have a one to many file upload setup following your example using a link table. My image model looks like the following
public class ImagesModel : EditorModel
{
public System.Guid ImageID { get; set; }
public byte[] Content { get; set; }
public string ContentType { get; set; }
public string Extension { get; set; }
public string FileName { get; set; }
public int FileSize { get; set; }
public string MimeType { get; set; }
public DateTime CreatedDate { get; set; }
public bool IsDefault { get; set; }
}
Basically, I have "Products" that can have many images. This is all setup and working fine with all images currently being uploaded as "IsDefault" false. However, I need a way to mark the "IsDefault". I want to have a checkbox next to the image and then a validator in my controller to only allow 1 image to be checked but I'm struggling on how to accomplish this. Any suggestions? Here's my editor
using (var db = new Database(dbType, dbConnection))
{
var response = new Editor(db, "Product.Product", "ProductID")
//.Model<ProductModel>()
.Field(new Field("ProductID"))
.Field(new Field("Product.ProductID").Set(false))
.Field(new Field("Product.Identifier").Set(false))
.Field(new Field("Product.Title").Set(false))
.MJoin(new MJoin("Product.Images")
.Link("Product.Product.ProductID", "Product.ImageRef.ProductID")
.Link("Product.Images.ImageID", "Product.ImageRef.ImageID")
.Model<ImagesModel>()
.Field(new Field("ImageID")
.Upload(new Upload()
.Db("Product.Images", "ImageID", new Dictionary<string, object>
{
//{"web_path", Path.DirectorySeparatorChar+Path.Combine("uploads", "__ID____EXTN__")},
{"ImageID", Upload.DbType.ReadOnly},
{"Content", Upload.DbType.ContentBinary},
{"ContentType", Upload.DbType.ContentType},
{"Extension", Upload.DbType.Extn},
{"FileName", Upload.DbType.FileName},
{"FileSize", Upload.DbType.FileSize},
{"MimeType", Upload.DbType.MimeType},
{"CreatedDate", Upload.DbType.ReadOnly},
{"IsDefault", Upload.DbType.ReadOnly}
})
.Validator(Validation.FileSize(500000, "Max file size is 500K."))
.Validator(Validation.FileExtensions(new[] { "jpg", "png", "jpeg" }, "Please upload an image."))
)
)
)
//.Debug(true).TryCatch(false)
.Process(Request)
.Data();
return Json(response);
}
Note: I have IsDefault setup as a bit in my database and defaults to 0.
Thanks for any help you can provide.
Answers
Hi,
With the values in the Dictionary for the third parameter to
Db()
, you don't just need to use theUpload.DbType
enum - you can also use values or even a delegate. So for example:would write
false
into the IsDefault database field.Allan
Sorry, just getting back to this
So when I try as you suggest with false,true,0, or 1 I get the error -
Once I get this error fixed how could I get the value of the checkbox. Please see my js below that shows how I display a checkbox by my image in the UploadMany (I have my own logic for displaying image by UID but the part I'm trying to get the value of is the checkbox). How could I get the value of this checkbox to be updated with my image?
Can you show me the schema for your table please?
Thanks,
Allan
I also have the Product.Product table but items are added to that separately. All I'm trying to do is add the ability to setup multiple images per product (Which works). And then mark one as the default image for the product.
Many thanks. What version of the DataTables dll is it you are using? What should be happening is that the
ReadOnly
flag hits here and there is no write to the database on that column.But it looks like it might be getting down to line 687 for some reason and trying to set the column to be a dash, causing the error you are seeing.
Allan
2.0.4 is the version I'm using.
It would make sense that it's hitting line 687 if I'm changing
to
right?
It's no longer a DbType. Should it be hitting completely separate logic for a value rather than a DbType?
You are spot on - it didn't quite click for me first thing this morning!
The most obvious change is to simply remove those two
q.Set
calls, but there might be some who are depended upon this behaviour (it would need adefault
value in SQL for the target column). I could try setting it tonull
, but equally the column would need to allow null values.My inclination is to remove those two calls with Editor 2.1 (although I don't have a time scale for that yet). You could build the dlls from source with those lines removed, or I can send you over built ones if you prefer?
Allan
Yeah, if you could send me the built files I could try it out.
But would I need to to use a delegate to get the value from my checkbox for IsDefault? Do you have an example of an upload that uses a delegate?
No you shouldn't need to use a delegate. The
try
/catch
should handle cases where a non-delagate is given. However, you could use{"IsDefault", () => false}
which is a simple lambda for it.The dll's are here.
Allan
Alright so I've tested it and I'm no longer getting an error but I don't think it's actually doing anything.
I have my table defaulting the IsDefault to false in SQL.
When I set
the column is still set false. When I check my checkbox nothing happens there either it always stays false.
When I set
I get the error "Cannot convert lambda expression to type 'object' because it is not a delegate type"
Could you possibly try:
please? That worked for me (using MySQL as the database with a
boolean
field).Sorry about the delegate - I'm to used to writing Javascript. It would need to be more along the lines of:
That isn't quite right though - there is a cast missing in the dll I sent you. Hopefully using the
{"IsDefault", 1}
will do the job for you though.Allan
That didn't work for me either. Here are my 3 tables being used if you would like to create your own tables to try it.
Hey Allan,
Thanks for your help so far. Do you have any other suggestions on how to get this to work? I'm so close I just need to mark one as the default image somehow. I could even create another table to link to and then update somehow if that makes sense. Do you have any suggestions? Thanks.
Could you comment back in the
.Debug(true)
and then from the response to the upload action, show me the JSON that the server is returning please? I'm surprised that{"IsDefault", 1}
isn't working.Allan
Here is the part that gets returned after I select the image. Looks like it uploads the image to the table when you select it and when you click update it does another call to update the ref table with the ID.
NOTE: I removed the actual image from content value to make the json smaller.
The one thing I notice is the first debug inserts the table without "CreatedDate" or "IsDefault"
I might have realised what the problem is - the DbType is an enum, which is causing to conflict with just passing in
1
for example.Let me get back to you on this tomorrow - I've got a plan...
Allan
Actually - I've just gone ahead and tried it out... .
Try:
with this dll.
That does the job for me locally with SqlServer.
We need to use the anonymous function after all since just using
1
would cause it to match against the DbType enum!Allan
I get an error when trying to add the dll to my project. Can you send me a link like before that has the debug folder and the different net folders and dll's inside of it? Thanks
Sorry - it is actually a zip file, but I used the wrong extension. Here it is with the correct .zip extension.
Allan
I've tested the change and it works so thank you for that!
I think I've almost got my process down but having one more issue.
I've added more fields that are nullable to the Product.Images table. I've then followed this blog https://datatables.net/blog/2019-01-11 to add a parent/child row that has a datatable for editing details. All loads fine but when clicking update in editor my database isn't updated although the call is successful. When I check the network tab in chrome I can see the form data in my request contains
and I can also see this if I debug my controller action in my Request.Form, however nothing gets updated. When I check the debug of the response it's only doing a select query. Any idea why nothing is being updated even though it's getting the edit action and details?
Here is the controller actions and the js is posted in another comment due to length
Here is the js
Thanks for all your help with this. I realize this is a very complex solution I'm trying to accomplish. Hopefully this will help someone in the future as well.
Could you show me the JSON response from the server when you trigger an edit on the child row please?
Thanks,
Allan
Here is the Json for Request.Form
and here is the Json response. I have removed the actual image from "Content" due to size
Thank you. The JSON return there doesn't indicate that any write was done to the database at all. Are you able to give me a link to the page you are working on so I can take a look and interact with it please? You can drop me a private message by clicking my forum user name above and then Send message if you can't make it public.
Allan
Sent you a link in a private message. Thanks.
Still waiting for an update on this. Have you got a chance to look at it yet?
I'm really sorry - I totally lost track of this one! I suspect it is to do with the schema name that is being used.
For the child table initialisation, could you try:
And if that doesn't resolve the issue, could you show me what
ImageViewModel
is and I'll try to recreate the issue.Thanks,
Allan
Hey Allan,
Thanks for that it's now trying to do an update. However, I'm now receiving the error "Incorrect syntax near 'Images'.". You can see in the update statement below that it's putting "Images" before the set causing the error. How can I fix this?
I've went back to what I had and then added a class called "Product" in my ImageViewModel to get everything mapped correctly. Thank you for pointing me in the right direction of it being a schema issue. Here is my ImageViewModel now for anyone who may find this thread.