Issue with uploads after validation fails

Issue with uploads after validation fails

nuggetap3nuggetap3 Posts: 24Questions: 5Answers: 2

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

  • allanallan Posts: 63,455Questions: 1Answers: 10,465 Site admin

    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

  • nuggetap3nuggetap3 Posts: 24Questions: 5Answers: 2

    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.

  • allanallan Posts: 63,455Questions: 1Answers: 10,465 Site admin

    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

  • nuggetap3nuggetap3 Posts: 24Questions: 5Answers: 2




  • nuggetap3nuggetap3 Posts: 24Questions: 5Answers: 2

    Hello, Allan!
    Please find screenshots above, we still have issue with attachments. Thank you!

  • nuggetap3nuggetap3 Posts: 24Questions: 5Answers: 2

    When i used return false for DbClean, everything works fine.

    .DbClean(data =>
    {

                       File.Delete("Id");
    
                       return false;
    
    
                   }
                   ))
    

    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?

  • allanallan Posts: 63,455Questions: 1Answers: 10,465 Site admin
    edited February 2018

    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

  • nuggetap3nuggetap3 Posts: 24Questions: 5Answers: 2

    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".

  • allanallan Posts: 63,455Questions: 1Answers: 10,465 Site admin

    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 the Id column in the expenseAttachment a serial?

    Allan

  • nuggetap3nuggetap3 Posts: 24Questions: 5Answers: 2

    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 () {

                alert("Please fill out required fields and if you have the attached file reload this file again!");
                traveltable.ajax.reload();
    
    
        });
    
    
        traveleditor.on('close', function () {
            alert("success");
            traveltable.ajax.reload();
    
        });
    

    I don't know what else we can do here? Any advise? Thank you!

  • nuggetap3nuggetap3 Posts: 24Questions: 5Answers: 2

    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

  • allanallan Posts: 63,455Questions: 1Answers: 10,465 Site admin

    The code sequence should be:

    1. Upload file - inserted into database
    2. ID of new field returned (that doesn't appear to be happening with yours since it is returning id: null). That's why I was asking about the database schema for the expenseAttachment table
    3. Form submitted (with the new file id included in it)
    4. Data written to the database
    5. DbClean will run, checking to see if any files are not linked from the main table. If they aren't, they'll be given to the callback function can you can decide if you want to delete them or not.

    Because 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

  • nuggetap3nuggetap3 Posts: 24Questions: 5Answers: 2

    the column is set to auto incrementing

  • allanallan Posts: 63,455Questions: 1Answers: 10,465 Site admin

    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

  • nuggetap3nuggetap3 Posts: 24Questions: 5Answers: 2







    Allan, there are all screenshots with .Debug(true), every step show how call Editor on Controller.

  • nuggetap3nuggetap3 Posts: 24Questions: 5Answers: 2

    There are 2 more screenshots what json returned after file uploaded to editor then datatable has been updated.

  • nuggetap3nuggetap3 Posts: 24Questions: 5Answers: 2

    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!

  • allanallan Posts: 63,455Questions: 1Answers: 10,465 Site admin

    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

  • nuggetap3nuggetap3 Posts: 24Questions: 5Answers: 2

    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.

  • allanallan Posts: 63,455Questions: 1Answers: 10,465 Site admin
    edited March 2018

    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

This discussion has been closed.