Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Mark Sommer 15 posts 105 karma points
    Mar 21, 2022 @ 07:15
    Mark Sommer
    0

    Submit model to surfacecontroller through Ajax

    Hey every one.

    I'm currently working on a single page website with the purpose of submitting data through multiple forms set up in a step guide (jQuery Smart Wizard).

    When going to the next step in my step guide, I want to validate the information which the user provided in this step by using annotations. My idea was that I could send the model via Ajax to the surfacecontroller.

    I have no luck so far getting the Ajax to use the model and if I simply submit my form I'm not aware of how to only update the form content to show the annotations and it will instead replace my entire page (Using a partial for each step).

    I will provide some screenshots to make it clear what I have been trying so far.

    The view from where I'm trying to send the data enter image description here

    Ajax that I tried to use for sending model enter image description here

    2 different ways I tried to handle the the validation enter image description here

  • Mark Sommer 15 posts 105 karma points
    Mar 22, 2022 @ 06:11
    Mark Sommer
    0

    Any one who can help me out?

  • Huw Reddick 1929 posts 6717 karma points MVP 2x c-trib
    Mar 22, 2022 @ 08:55
    Huw Reddick
    0

    you can validate the form through each step without having to post it to the server.

    You haven't really explained what you are unable to do, what errors or issues are you getting?

    This is how I would normally post to controller using ajax (some code removed for brevity)

                serializedData = $("#myForm").serialize();;
            $.ajax({
                url: '/umbraco/surface/OFTECRegistration/Summary',
                type: 'POST',
                contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
                data: serializedData, 
                success: function (data) {
                    $("#loading").hide();
                    $('#step-summary').html(data);
                }, error: function (xhr) {
                    alert('Error: ' + xhr.status + ' (' + xhr.statusText + ')');
                    console.log(xhr);
                }
            });
    

    Surface controller Method

            public ActionResult Summary(CPSRegistrationViewModel vm)
            {
                if (!ModelState.IsValid)
                {
    
                    foreach (KeyValuePair<string, ModelState> kvp in ModelState)
                    {
                        var modelState = kvp.Value;
                        var property = kvp.Key;
                        foreach (ModelError error in modelState.Errors)
                        {
                            _logger.Error(typeof(OFTECRegistrationController), error.Exception,error.ErrorMessage);
                        }
                    }
                }
                else
                {
                      //form is valid
    
                }
                return PartialView("_Summary",model:vm);
    }
    
  • Mark Sommer 15 posts 105 karma points
    Mar 22, 2022 @ 12:33
    Mark Sommer
    0

    Hi Huw

    Thanks for the help.

    My current issue is that I'm not sure how to proceed. What I have been trying so far is to pass my descendant model via the form seen on image 1 and then I wanted to let the annotations in the class handle the validations for me and then return those errors to the form validation message fields.

    If I do a simple submit on my form it does what I want it to do except it returns my partial and replaces my website with that only. I need to only update the form content to show my errors. If that is the correct thing to do here.

    I did another attempt with trying to pass on the descendant model using ajax but here it seems like I can only pass on form data and them I'm lost on how to do the validations I mentioned above

    Image 3 was only for showing the method I have been trying for handling/returning my errors but I have yet to find the correct way to do this.

    I hope this gave some more insight to my issue. Its not that I get any errors, I'm simply at a loss on how to proceed with finding a solution.

  • Mark Sommer 15 posts 105 karma points
    Mar 23, 2022 @ 06:39
    Mark Sommer
    0

    I tried your solution and it got me some of the way. It will now return and update only the content in step/form but it gives me an error.

    I had to include the [FromBody] or the function would get the form data. But this is what I ended up with.

    [HttpPost]
    public IActionResult CreateClaimRequest([FromBody]PolicyAndContactInfoStep infoStep)
    {
        if (ModelState.IsValid)
        {
            return Ok("SUCCESS");
        }
        else 
        {
            return PartialView("~/Views/Partials/stepTemplates/PolicyAndContact.cshtml", model:infoStep);
        }
    }
    

    The error that is returned to the page is

    Umbraco.Cms.Web.Common.ModelBinders.ModelBindingException: Cannot bind source type UmbracoProject.Models.PolicyAndContactInfoStep to model type Umbraco.Cms.Core.Models.PublishedContent.IPublishedContent
    

    The model I'm trying to return is not the current model of my page but a descendant model used to contain just that one part of the form. Do I have to include something extra for it update properly?

  • Patrick de Mooij 73 posts 623 karma points MVP 3x c-trib
    Mar 23, 2022 @ 10:45
    Patrick de Mooij
    0

    I think this error is caused by your PartialView("~/Views/Partials/stepTemplates/PolicyAndContact.cshtml", model:infoStep).

    If I am correct, then your PolicyAndContact.cshtml view is expecting an IPublishedContent (due to model IPublishedContent or inherits UmbracoViewPage on top). But you are now passing a PolicyAndContactInfoStep that cannot be cast to an IPublishedContent.

  • Mark Sommer 15 posts 105 karma points
    Mar 23, 2022 @ 11:28
    Mark Sommer
    0

    Is it possible to pass my IPublishedContent to the controller through ajax or how do I manage to return data in the correct format?

  • Huw Reddick 1929 posts 6717 karma points MVP 2x c-trib
    Mar 23, 2022 @ 12:59
    Huw Reddick
    0

    your partial view PolicyAndContact.cshtml needs it's model to be PolicyAndContactInfoStep rather than inheriting umbracoviewpage models.

    Ajax is just posting a html form, it doesn't know about publishedcontent, just form values.

    Why do you need pass the IPublishedContent in the controller?

  • Mark Sommer 15 posts 105 karma points
    Mar 23, 2022 @ 13:05
    Mark Sommer
    0

    The thing is I don't know if it should. I have been trying to get the ajax to return something useful for me so I can update the form content to show my annotations/errors.

    From your last comment I believe this is wrong then:

    @inherits UmbracoViewPage
    
    @{
    
        PolicyAndContactInfo pacModel = Model.Descendant<PolicyAndContactInfo>();
    
    }
    

    Since its a partial view I thought it could only inherit from its 'parent' and not have a model of its own but I understand now that I might have misunderstood that?

  • Huw Reddick 1929 posts 6717 karma points MVP 2x c-trib
    Mar 23, 2022 @ 13:12
    Huw Reddick
    0

    no, it will have a model of it's own

    so use @model PolicyAndContactInfoStep (that is what your controller is using) instead of @inherits UmbracoViewPage

    If you need to upadte your I published content in the controller then you will probably want to include the publishedcontents id in a hidden field so that you can retreive it in your controller.

  • Mark Sommer 15 posts 105 karma points
    Mar 23, 2022 @ 13:14
    Mark Sommer
    0

    Thank you.

    I will give this a shot and see how it goes :)

  • Mark Sommer 15 posts 105 karma points
    Mar 31, 2022 @ 05:56
    Mark Sommer
    0

    Nothing has worked so far so decided to take another route entirely.

Please Sign in or register to post replies

Write your reply to:

Draft