Uncaught TypeError: Cannot read properties of undefined (reading 'unobtrusive') caused by $.validator.unobtrusive.parse('form');

Jose Daniel Navarro Brito 61 Reputation points
2023-04-18T08:19:51.06+00:00

Good morning all: I have some miniquestions that the answers hopefully will help me to understand how the Jquery libraries works ( I'm just a code enthusiastic) I have a Asp.net core web application with the following _Layout.cshtml shareable view



First question: are Jquery and bootstrap properly set up in my project? By default these libraries are installed in the latest versions of ASP.NET Core I heard. I have a jscript which pulls out a pop up dialog from my jquery datatable. Things get messy in the code below because I'm trying to implement an example I saw online but I'm not sure if I'm duplicating the Jquery references that are in the _Layout.cshtml shareable view . this is the jscrip code



Second question; Are all these references correct and necessary ? I don't know which ones are required considering that I'm using the layout of the _Layout.cshtml The jquery pop up dialog comes out with the data but the following error pops up:


Uncaught TypeError: Cannot read properties of undefined (reading 'unobtrusive')
    at HTMLDivElement.<anonymous> (Plots:165:37)
    at HTMLDivElement.<anonymous> (jquery-3.5.1.js:10402:14)
    at Function.each (jquery-3.5.1.js:381:19)
    at jQuery.fn.init.each (jquery-3.5.1.js:203:17)
    at Object.<anonymous> (jquery-3.5.1.js:10401:9)
    at fire (jquery-3.5.1.js:3496:31)
    at Object.fireWith [as resolveWith] (jquery-3.5.1.js:3626:7)
    at done (jquery-3.5.1.js:9786:14)
    at XMLHttpRequest.<anonymous> (jquery-3.5.1.js:10047:9)

The culprit is

$.validator.unobtrusive.parse('form');

that appears in the script ( an extract below).



Developer technologies | ASP.NET | ASP.NET Core
Microsoft 365 and Office | Development | Office JavaScript API
{count} votes

1 answer

Sort by: Most helpful
  1. Anonymous
    2023-04-19T06:02:23.71+00:00

    Hi @Jose Daniel Navarro Brito

    First question: are Jquery and bootstrap properly set up in my project?

    For this question, the _Layout.cshtml page is the master/Layout page, it typically includes common user interface elements such as the app header, navigation or menu elements, footer, stylesheets and scripts. When the content page using this layout page, it will also use the shared elements in the layout page. More detail information about layout, see Layout in ASP.NET Core.

    @{
        
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    

    So, in your scenario, since the content page already using the _Layout.cshtml page via the Layout property, there is no need to add the <html>, <header> and <body> elements and the 'jquery-3.5.1.js' script reference. The modified content page should like this:

    @{
        
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
     
    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>Index</title>
        
        <link rel="stylesheet" href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css" />
        <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/themes/smoothness/jquery-ui.css">
        <style>
            span.field-validation-error {
                color: red;
            }
        </style>
    
    <body>
        <div style="width:90%; margin:0 auto" class="tablecontainer">
            <a class="popup btn btn-primary" href="/home/save/0" style="margin-bottom:20px; margin-top:20px;">Add Plot</a>
            <table class="table table-bordered table-striped" id="myDatatable">
                <thead>
                    <tr>
                       
                        <th scope="col">Plot</th>
                        <th scope="col">Status</th>
                        <th scope="col">Contractor</th>
                        <th scope="col">Inspector</th>
                        <th>Edit</th>
                        <th>Delete</th>
                    </tr>
                </thead>
            </table>
        </div>
    </div>
    
    @section scripts{
        
        <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
        
            <script src="~/lib/jquery-validation/dist/jquery.validate.min.js" type="text/javascript"></script>
            <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
        <script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
        <script src="https://cdn.datatables.net/1.13.4/js/dataTables.bootstrap5.min.js"></script>
            <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>
            
        <script>
            $(document).ready(function () {
                bindDatatable();
            });
    
            function bindDatatable() {
                    datatable = $('#myDatatable')
                    .DataTable({
                        "ajax": {
                         "url":"Plots/Postdata",
                        "type": "POST",
                         "datatype": "json"
                        },
                        "serverSide": true,
                        "procesing":true,
                        "searching":true,
                        "order": [[1, 'asc']],
                        "language": {
                            "emptyTable": "No record found.",
                            "processing":
                                '<i class="fa fa-spinner fa-spin fa-3x fa-fw" style="color:#2a2b2b;"></i><span class="sr-only">Loading...</span> '
                        },
                        "columns": [
                           
                            {
                                "data": "plot", "autoWidth": true, "searchable": true
                            },  
                            {
                                "data": "status","autoWidth": true,"searchable": true                            
                            },
                            {
                                "data": "contractor","autoWidth": true,"searchable": true                            
                            },
                            {
                                "data": "inspector","autoWidth": true,"searchable": true                      
                            },
                            {
                                    "data": "idErven_Progress", "width": "50px", "render": function (data) {
                                        return '<a class="popup" href="/Erven_Progress_Status/save/' + data + '">Edit</a>';
                            }
                                },
                                {
                                    "data": "idErven_Progress", "width": "50px", "render": function (data) {
                                        return '<a class="popup" href="/home/delete/' + data + '">Delete</a>';
                                    }
                                }                   
                        ],
                        "error": function (xhr, error, thrown) 
                        {
                        alert("Error occurred while loading data. Please try again.");
                        }
                    }) 
                    $('.tablecontainer').on('click', 'a.popup', function (e) {
                            e.preventDefault();
                            OpenPopup($(this).attr('href'));
                    })
                    function OpenPopup(pageUrl) {
                        var $pageContent = $('<div/>');
                        $pageContent.load(pageUrl, function () {
                            $('#popupForm', $pageContent).removeData('validator');
                            $('#popupForm', $pageContent).removeData('unobtrusiveValidation');
                            $.validator.unobtrusive.parse('form');
    
                        });
    
                        $dialog = $('<div class="popupWindow" style="overflow:auto"></div>')
                            .html($pageContent)
                            .dialog({
                                draggable: false,
                                autoOpen: false,
                                resizable: false,
                                model: true,
                                title: 'Popup Dialog',
                                height: 550,
                                width: 600,
                                close: function () {
                                    $dialog.dialog('destroy').remove();
                                }
                            })
    
                        $('.popupWindow').on('submit', '#popupForm', function (e) {
                            var url = $('#popupForm')[0].action;
                            $.ajax({
                                type: "POST",
                                url: url,
                                data: $('#popupForm').serialize(),
                                success: function (data) {
                                    if (data.status) {
                                        $dialog.dialog('close');
                                        oTable.ajax.reload();
                                    }
                                }
                            })
    
                            e.preventDefault();
                        })
                        $dialog.dialog('open');
                    }
            }
        </script>
    }
    

    Second question; Are all these references correct and necessary ?

    After removing the duplicate JQuery reference, the others reference seems are correct.

    Uncaught TypeError: Cannot read properties of undefined (reading 'unobtrusive')

        <script src="~/lib/jquery-validation/dist/jquery.validate.min.js" type="text/javascript"></script>
            <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
    
    

    About this issue, please check the wwwroot\lib\ folder, make sure the above jquery validate files exist and the file path is correct, and then try to use F12 developer tool to check whether these files load success or not?

                        $pageContent.load(pageUrl, function () {
                            $('#popupForm', $pageContent).removeData('validator');
                            $('#popupForm', $pageContent).removeData('unobtrusiveValidation');
                            $.validator.unobtrusive.parse('form');
    
                        });
    

    From your code, it seems that you want to trigger the client-side validation and the form id is "popupForm", if that is the case, when enable form validation, you should also use the "popupForm", instead of "form". So, try to modify your code as below:

                        $pageContent.load(pageUrl, function () {
                            $('#popupForm', $pageContent).removeData('validator');
                            $('#popupForm', $pageContent).removeData('unobtrusiveValidation');
                            $.validator.unobtrusive.parse('#popupForm'); //enable form validation.
                            $('#popupForm').validate().form(); //check the validation result.
    
                        });
    

    You can also refer the following sample on my side: image1


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
    Best regards,
    Dillion


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.