Issue with uploads after validation fails
Issue with uploads after validation fails
I am having an issue with file uploads. When a user tries to create a new record in the table and one if the required fields is not filled out properly I get the "field is required" message and everything looks fine. However when I correct the required field error and try to create the record, it goes through without an error, but the file upload is not inserted into the database and the new record is not added to the table. Any thoughts?
```
//travel table
var traveleditor = new $.fn.dataTable.Editor({
ajax: '/api/DataTable/TravelTable',
table: '#TravelTable',
fields: [
{
"label": "FormInstanceId:",
"name": "FormInstanceId",
"className": "formidnew"
},
{
"label": "Date:",
"name": "date",
"type": "datetime",
"format": "MM/DD/YY"
},
{
"label": "Category:",
"name": "expensecategory",
"def": "Travel",
"className": "category"
},
{
"label": "Type of Expense:",
"name": "expense_type",
"type": "select",
"options": [
"Air Fare",
" Milege",
" Gas",
"Taxi",
"Other"
]
},
{
"label": "Description:",
"name": "description",
"type": "textarea"
},
{
"label": "Cost Center:",
"name": "cost_center",
"type": "select",
"placeholder": "Select a Cost Center"
},
{
"label": "Account Number:",
"name": "account_number",
"type": "select",
"placeholder": "Select an Account Number"
},
{
"label": "W\/O:",
"name": "wo_number"
},
{
"label": "Project:",
"name": "project_number",
"type": "select",
"placeholder": "Select a Project Number"
},
{
"label": "Amount:",
"name": "amount",
},
{
"label": "Attachment:",
"name": "attachments",
"type": "upload",
"display": function (Id) {
var ext = traveleditor.file('expenseAttachment', Id).webPath.toLowerCase();
var ext1 = ext.split(".").pop();
if (Id !== null) {
var ext = traveleditor.file('expenseAttachment', Id).webPath.toLowerCase();
var ext1 = ext.split(".").pop();
if (ext1 == "pdf") {
return '<a href ="' + traveleditor.file('expenseAttachment', Id).webPath + '" target=_blank><i class =" glyphicon glyphicon-file" style="font-size: 1em; "</i>' + traveleditor.file('expenseAttachment', Id).filename + '</center></a>';
}
if ((ext1 == "png") || (ext1 == "jpg") || (ext1 == "gif")) {
return '<a href ="' + traveleditor.file('expenseAttachment', Id).webPath + '" target=_blank><img width="100px" src="' + traveleditor.file('expenseAttachment', Id).webPath + '"/></a>';
}
}
else {
return "No File";
}
},
clearText: "Remove file",
fieldInfo: "Upload file, then create."
}
]
});
$('label', traveleditor.field('date').node()).addClass('aster');
$('label', traveleditor.field('description').node()).addClass('aster');
$('label', traveleditor.field('account_number').node()).addClass('aster');
$('label', traveleditor.field('amount').node()).addClass('aster');
$('label', traveleditor.field('cost_center').node()).addClass('aster');
traveleditor.on('open', function () {
var id1 = $("#thisid").val();
var id2 = $("#thisid2").val();
var cc = $("#CostC").val();
if (id1 != "") {
var id = id1;
}
else {
var id = id2;
}
$("#DTE_Field_FormInstanceId").val(id);
$("#DTE_Field_cost_center").val(cc);
$(".formidnew").hide();
$(".category").hide();
});
traveleditor.on('close', function () {
traveltable.ajax.reload();
});
//API Controller
public IHttpActionResult TravelTable()
{
var request = HttpContext.Current.Request;
using (var db = new Database("sqlserver", dbCon))
{
var response = new Editor(db, "ExpenseTable", "id")
.Where(q => q.Where("FormInstanceId", request.Form["Value"], "=").Where("expensecategory", "Travel", "="))
.Model<ExpenseTableModel>()
.Field(new Field("date")
.Validator(Validation
.DateFormat("MM/dd/yy"))
.GetFormatter(Format.DateSqlToFormat("MM/dd/yy"))
.SetFormatter(Format.DateFormatToSql("MM/dd/yy"))
.Validator(Validation.NotEmpty(
new ValidationOpts
{
Message = "The field is required"
}
)))
.Field(new Field("description")
.Validator(Validation.NotEmpty(
new ValidationOpts
{
Message = "The field is required"
}
))
)
.Field(new Field("account_number")
.Options(new Options()
.Table("ExpenseAccountNumber")
.Value("AccountNumber")
.Label("AccountNumber"))
.Validator(Validation.NotEmpty(
new ValidationOpts
{
Message = "The field is required"
}
)
))
.Field(new Field("amount")
.Validator(Validation.NotEmpty(
new ValidationOpts
{
Message = "The field is required"
}
)))
.Field(new Field("cost_center")
.Options(new Options()
.Table("CostCenters")
.Value("CostCenterNumber")
.Label("CostCenterNumber"))
.Validator(Validation.NotEmpty(
new ValidationOpts
{
Message = "The field is required"
}
)))
.Field(new Field("project_number")
.Options(new Options()
.Table("ExpenseProjectNumber")
.Value("ProjectNumber")
.Label("ProjectNumber"))
)
.Field(new Field("attachments")
.Upload(new Upload(request.PhysicalApplicationPath + @"ExpenseAttachments\Travel\2018\__NAME____ID____EXTN__")
.Validator(file => {
if (file.ContentLength >= 5000000)
{
return "Files must be smaller than 500K";
}
return null;
})
.Validator(
Validation.FileExtensions(
new[] { "png", "jpg", "gif", "pdf"},
"Only image or pdf files can be uploaded (png, jpg, gif and pdf)"
)
)
.Db("expenseAttachment", "Id", new Dictionary<string, object>
{
{ "filename", Upload.DbType.FileName },
{"url", Upload.DbType.SystemPath },
{"webPath", Upload.DbType.WebPath}
})
.DbClean(data =>
{
File.Delete("Id");
return true;
}
))
.SetFormatter(Format.NullEmpty()))
.Process(request)
.Data();
return Json(response);
}
Answers
Editor's file upload is async to the rest of the form. It will be uploaded as soon as the image is selected, not when the rest of the form is submitted. In the case above it should add to the
expenseAttachment
table as soon as the file is selected.Allan
Allan,
Your are correct, it does upload the file as soon as I attach it to the form. However, when I hit the create button and I receive the "field is required" message. The record of the attachment is removed from my attachments table. The id number for the attachment is listed in the expense table, but there is no corresponding record (id) in the attachment table. For some reason, it thinks the file is orphaned but it is not.
Are you able to give me a link to the page so I can trace through what is happening please?
What does the server respond with when the file is uploaded for example?
Thanks,
Allan
Hello, Allan!
Please find screenshots above, we still have issue with attachments. Thank you!
When i used return false for DbClean, everything works fine.
.DbClean(data =>
{
There is diffidently in this problem. Can we probably create a message for user to ask them to upload file again or what else we can do here?
Uploads should be working now I think. Let me know if you are still having problems with them.
Could you get the response from the server - unfortunately that isn't shown above. This tech note shows how you can get it.
I suspect that it will not be valid JSON given the error message. edit - Ignore this part - I was thinking of a different thread. If you are able to give me a link to your page that would greatly increase my chance of being able to provide help.
Allan
Allan, id = null and it why datatable cannot upload the file and create the row because db.Clean delete id from expenseAttachment table when we hit the button "Create".
The clean should run only after the insert is complete, and would only clean up the newly inserted record if it wasn't reference.
The
id: null
is going to be a problem if that is the response from the file upload Ajax request - is it? Is theId
column in theexpenseAttachment
a serial?Allan
Yes, but it run before insert complete, before validations complete. From your documentation said "Editor performs a database clean (which is on create, edit and remove - not upload)." and then you click on create button the db will clean a file while validation stopped to create new row but file will be still on Editor. One thing we have to do is remove the file and upload again. The Id column in the expenseAttachment is a serial.
One thing we can do just notify user to remove file and upload again:
traveleditor.on('submitUnsuccessful', function () {
I don't know what else we can do here? Any advise? Thank you!
Allen,
I believe the id is = null. i have attached as much of the response information as I could pull together from one call and attached it below
The code sequence should be:
id: null
). That's why I was asking about the database schema for theexpenseAttachment
tableBecause the file id is being returned as null, it sounds like the whole thing is collapsing. There can be no reference to the file entry, since we don't know its id. So the question is, why does it not get an id.
Is the id column in the files table a serial / auto incrementing column?
Allan
the column is set to auto incrementing
Could you add
.Debug( true )
just before the.Process(...)
call please? Then in the JSON respond from the upload action there will be the SQL that Editor has executed. Can you show me that returned JSON so I can take a look at it please?Allan
Allan, there are all screenshots with .Debug(true), every step show how call Editor on Controller.
There are 2 more screenshots what json returned after file uploaded to editor then datatable has been updated.
Allan, good new!!! we figure out how to correct this erro. We started to use validations on client-side that prevent to submit form, using function 'preSubmit'.
What is good way to check a numeric character in field?
I tried:
if ( val.match( /[^\d]/ ) ) {
editor.field( 'myField' ).error( "Numbers only please!" );
return false;
}
but din't work for me.
Thank you!
I think the regex is fine there - the question is what is
val
? I ask because we need to keep in mind that Editor submits multi-row editing information, so I'm wondering if it might be an object.Allan
It has been fixed. Thank you, Allan!
How we can hide a column if there are a certain value? What kind function we can use?
For example:
column[ 'Type of Expense'].
If ["Type of Expense"]=="Mileage"{
column['Total of Miles']. hidden;
}
similar to that function but using it in .DataTable.
column().visible()
can be used to dynamically show and hide a column. You need to keep in mind that a column will contain multiple values through (i.e. one for each row).Allan