Uncaught syntaxerror: неожиданный конец ввода - удаление элемента html в javascript / jquery

Я пытаюсь создать эту форму, где у меня может быть кнопка, которая добавит дубликат, и кнопка, которая удалит текущую «новую форму». Все функции работают, кроме удаления формы - я пытаюсь использовать функцию JQuery .remove, но эта ошибка начала проявляться, как только я ее добавил.

Я почти на 100% уверен, что все круглые скобки выровнены - я прогнал это через несколько сайтов линтинга, чтобы убедиться.

Есть идеи, глядя на часть кода javascript?

<!DOCTYPE html>
<html>
    <head>
        <title>Add a New Course</title>
        <style>
            body {
                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            }

            .buttonHolder {
                text-align: center;
            }
        </style>
    </head>
    <body onload="loadXMLDoc_makeCatArray()">
        <form action="" id="courseForm">
            <div class = "div1">
                <fieldset>
                    <legend>Enter course info:</legend>
                    Course title: <br>
                    <input type="text" id="displayName1" value=""><br>
                    Category: <br>
                    <select name="categoryDropdown" id="category1"></select><br>
                    Duration: <br>
                    <input type="time" id="duration1" value=""><br>
                    Subcategory: <br>
                    <input type="text" id="subcategory1" value=""><br>
                    Description: <br>
                    <textarea rows="4" cols="60" id="description1"></textarea><br>
                    URL: <br>
                    <input type="text" id="url1" value=""><br>
                    ID: <br>
                    <input type="text" id="id1" value=""><br>
                    Table ID: <br>
                    <input type="text" id="tableId1" value=""><br>
                    <div class="buttonHolder">
                        <input type="button" value="Submit All" onclick="javascript: loadXMLDoc();">
                        <input type="button" value="New Course" onclick="javascript: addCourseForm();">
                    </div>
                </fieldset>
            </div>
        </form>
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://splm.sharepoint.com/sites/OCB/Shared%20Documents/Testing/js/vkbeautify.js"></script>
    <script src="https://splm.sharepoint.com/sites/OCB/Shared%20Documents/Testing/js/MicrosoftAjaxCore.js"></script>
    <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/4.0/MicrosoftAjax.js"></script> 
    <script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script> 
    <script type="text/javascript" src="/_layouts/15/sp.js"></script>
    <script type="text/javascript" src="https://unpkg.com/sharepointplus@5.1.0/sharepointplus-5.1.js"></script>
    
    <script>
        //Initialize the number of forms being submitted as 1
        var count = 1;

        function addCourseForm()
        {
            //Get the course form element
            var course = document.getElementById("courseForm");

            //Error checking here, making sure we got courseForm
            if (course)
            {
                //Create a new <div> element which contains the form
                var newDiv = document.createElement("div");
                newDiv.className = "div" + (count + 1);
                var divName = "div" + (count + 1);
                newDiv.innerHTML = '<fieldset> <legend>Enter course info:</legend> Course title: <br> <input type="text" id="courseTitle' + (count + 1) + '"><br> Category: <br> <select name="categoryDropdown" id="category' + (count + 1) + '" value=""></select><br> Duration: <br> <input type="time" id="duration' + (count + 1) + '" value=""><br> Subcategory: <br> <input type="text" id="subcategory' + (count + 1) + '" value=""><br> Description: <br> <textarea rows="4" cols="60" id="description' + (count + 1) + '"></textarea><br> URL: <br><input type="text" id="url' + (count + 1) + '" value=""><br> <div class="buttonHolder"> <input type="button" value="Submit All" onclick="javascript: loadXMLDoc();"> <input type="button" value="New Course" onclick="javascript: addCourseForm();"> <input type="button" value="Remove Course" onclick="removeCourseForm(' + divName + ');"> </div> </fieldset>';

                //Appends the new <p> element to the other forms
                course.appendChild(newDiv);

                //Add one to the number of forms being submitted
                count++;

                loadXMLDoc_makeCatArray();
            }
        }

        function removeCourseForm(paragraph) {
            $("." + paragraph).remove();
            count--;
        }

        function loadXMLDoc_submitFormData() {
                var xmlhttp = new XMLHttpRequest();
                xmlhttp.onreadystatechange = function () {
                    if (this.readyState == 4 && this.status == 200) {
                        submitFormData(this);
                    }
                };
                xmlhttp.open("GET", "https://splm.sharepoint.com/sites/OCB/Shared%20Documents/Testing/curriculumdata.xml", true);
                xmlhttp.send();
            }

        function submitFormData(xml)
        {
            var xmlDoc = xml.responseXML;

            console.log(xmlDoc);

            for (var x = 1; x <= count; x ++) {
                var p = xmlDoc.getElementsByTagName("course")[1];
                var p_prime = p.cloneNode(false);
                xmlDoc.getElementsByTagName("curriculumdata")[0].appendChild(p_prime);
                var br = xmlDoc.createElement("br");

                var elements = ["category", "description", "displayName", "duration", "id", "subcategory", "tableId", "url"];
                for (var y = 0; y < elements.length; y++){
                    console.log(elements[y] + x);
                    newElement = xmlDoc.createElement(elements[y]);
                    if (y == 0) {
                        newText = xmlDoc.createTextNode(document.getElementById(elements[y] + x).text);
                    } else {
                        newText = xmlDoc.createTextNode(document.getElementById(elements[y] + x).value);
                    }
                    newElement.appendChild(newText);
                    console.log(newElement);
                    xmlDoc.getElementsByTagName("course")[xmlDoc.getElementsByTagName("course").length - 1].appendChild(newElement);
                }
            };

            var clientContext = new SP.ClientContext('https://splm.sharepoint.com/sites/OCB');
            var oList = clientContext.get_web().get_lists().getByTitle('Course List');

            var itemCreateInfo = new SP.ListItemCreationInformation();
            this.oListItem = oList.addItem(itemCreateInfo);
 
            var documents = new XMLSerializer().serializeToString(xmlDoc.documentElement);
            documents = vkbeautify.xml(documents);
            oListItem.set_item('xml_data', documents);

            oListItem.update();

            clientContext.load(oListItem);
            clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
        };
        function onQuerySucceeded() {
            alert('Course successfully added');
        }
        function onQueryFailed(sender, args) {
            alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
        }


        function loadXMLDoc_makeCatArray() {
                var xmlhttp = new XMLHttpRequest();
                xmlhttp.onreadystatechange = function () {
                    if (this.readyState == 4 && this.status == 200) {
                        catArray(this);
                    }
                };
                xmlhttp.open("GET", "https://splm.sharepoint.com/sites/OCB/Shared%20Documents/curriculumdata.xml", true);
                xmlhttp.send();
            }

        
        function catArray(xml){
            eleArray = [];

            var xmlDoc = xml.responseXML;

            ele = xmlDoc.getElementsByTagName("course");

            for (i = 0; i < ele.length; i++) {
            if(!(eleArray.includes(ele[i].getElementsByTagName("category")[0].childNodes[0].nodeValue))){

                eleArray.push(ele[i].getElementsByTagName("category")[0].childNodes[0].nodeValue);
                }
            }
            var sel = document.getElementsByName('categoryDropdown')[count - 1];
            for(var i = 0; i < eleArray.length; i++) {
                var opt = document.createElement('option');
                opt.innerHTML = eleArray[i];
                opt.value = eleArray[i];
                console.log(opt);
                sel.appendChild(opt);
            }
        };
    </script>
    </body>
</html>

К вашему сведению: со встроенными обработчиками событий, такими как onclick="javascript: loadXMLDoc();", вы должны удалить javascript; и просто иметь onclick="loadXMLDoc();". А еще лучше вообще не использовать встроенные обработчики и выполнять привязку всех событий в JavaScript.

Scott Marcus 13.09.2018 20:07
0
1
1 217
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Во-первых, ваш HTML недействителен, потому что после </body> у вас не может быть ничего, кроме </html>. Все эти сценарии следует переместить непосредственно перед закрывающим тегом body. Кроме того, нельзя вкладывать fieldset в p. Вы можете сделать этот pdiv.

Далее, count --; должен быть count--;.

Неожиданный ввод - это пробел после ссылки на переменную count.

И ваша вручную созданная строка HTML должна быть рассмотрена, потому что у вас есть вложенные двойные кавычки в двойные кавычки, и вы ничего не объединяете после count:

onclick="javascript: removeCourseForm("p' + count + '");">

Это также приведет к той же ошибке, потому что у вас есть завершающий +, но не с чем его связывать.

Сказав это .... Вы действительно не должны использовать этот подход в первую очередь.

Вместо того, чтобы создавать огромную строку конкатенированного HTML (в чем заключается ваша проблема), просто клонируйте первый набор полей. Теперь, поскольку мы собираемся клонировать, мы хотим отказаться от использования атрибутов id и вместо этого использовать .querySelector() и .querySelectorAll() для поиска элементов на основе селекторов CSS.

Вам также следует прекратить использование .getElementsByTagName(), потому что это влияет на производительность, и вы все равно не заинтересованы в коллекции, которую он возвращает, вы передаете индекс в коллекцию. Вместо этого используйте .querySelector().

Наконец, не используйте встроенные обработчики событий (onclick). У вас есть привязка событий в JavaScript.

См. Комментарии ниже.

Вот рабочий пример.

<!DOCTYPE html>
<html>

<head>
    <title>Add a New Course</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
        
        .buttonHolder {
            text-align: center;
        }
    </style>
</head>
<body>
    <form action="" id="courseForm">

        <fieldset>
            <legend>Enter course info:</legend>
            Course title:
            <br>
            <input type="text" class="displayName">
            <br> Category:
            <br>
            <select name="categoryDropdown" class="category"></select>
            <br> Duration:
            <br>
            <input type="time" class="duration">
            <br> Subcategory:
            <br>
            <input type="text" class="subcategory">
            <br> Description:
            <br>
            <textarea rows="4" cols="60" class="description"></textarea>
            <br> URL:
            <br>
            <input type="text" id="url1">
            <br> ID:
            <br>
            <input type="text" id="id1">
            <br> Table ID:
            <br>
            <input type="text" id="tableId1">
            <br>
            <div class="buttonHolder">
                <input type="button" value="Submit All" class="submitAll">
                <input type="button" value="New Course" class="newCourse">
            </div>
        </fieldset>

    </form>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://splm.sharepoint.com/sites/OCB/Shared%20Documents/Testing/js/vkbeautify.js"></script>
    <script src="https://splm.sharepoint.com/sites/OCB/Shared%20Documents/Testing/js/MicrosoftAjaxCore.js"></script>
    <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/4.0/MicrosoftAjax.js"></script>
    <script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>
    <script type="text/javascript" src="/_layouts/15/sp.js"></script>
    <script type="text/javascript" src="https://unpkg.com/sharepointplus@5.1.0/sharepointplus-5.1.js"></script>

    <script>
        //Get the course form element
        var course = document.getElementById("courseForm");
        
        document.querySelector(".submitAll").addEventListener("click", loadXMLDoc_submitFormData);
                document.querySelector(".newCourse").addEventListener("click", addCourseForm);

        function addCourseForm() {

            var firstFS = document.querySelector("fieldset");

            //Error checking here, making sure we got courseForm
            if (course) {
                // >>> **** Clone the current fieldset ***** <<<<
                var newFS = firstFS.cloneNode(true);

                // Create and configure remove button
                var removeBtn = document.createElement("button");
                removeBtn.textContent = "Remove Course";
                removeBtn.type = "button";
                removeBtn.addEventListener("click", function() {
                    // Call the remove function but pass the fieldset
                    // that this button is part of
                    removeCourseForm(this.closest("fieldset"));
                });

                // Append the new button to the new fieldset
                newFS.querySelector("div.buttonHolder").appendChild(removeBtn);

                //Appends the new <p> element to the other forms
                course.appendChild(newFS);
                // ***********************************************

                loadXMLDoc_makeCatArray();
            }
        }

        function removeCourseForm(fs) {
            fs.remove();
        }

        function loadXMLDoc_submitFormData() {
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.onreadystatechange = function() {
                if (this.readyState == 4 && this.status == 200) {
                    submitFormData(this);
                }
            };
            xmlhttp.open("GET", "https://splm.sharepoint.com/sites/OCB/Shared%20Documents/Testing/curriculumdata.xml", true);
            xmlhttp.send();
        }

        function submitFormData(xml) {
            var xmlDoc = xml.responseXML;

            console.log(xmlDoc);

            for (var x = 1; x <= count; x++) {
                var p = xmlDoc.getElementsByTagName("course")[1];
                var p_prime = p.cloneNode(false);
                xmlDoc.querySelector("curriculumdata").appendChild(p_prime);
                var br = xmlDoc.createElement("br");

                var elements = ["category", "description", "displayName", "duration", "id", "subcategory", "tableId", "url"];
                for (var y = 0; y < elements.length; y++) {
                    console.log(elements[y] + x);
                    newElement = xmlDoc.createElement(elements[y]);
                    if (y == 0) {
                        newText = xmlDoc.createTextNode(document.getElementById(elements[y] + x).text);
                    } else {
                        newText = xmlDoc.createTextNode(document.getElementById(elements[y] + x).value);
                    }
                    newElement.appendChild(newText);
                    console.log(newElement);
                    xmlDoc.querySelectorAll("course")[xmlDoc.getElementsByTagName("course").length - 1].appendChild(newElement);
                }
            };

            var clientContext = new SP.ClientContext('https://splm.sharepoint.com/sites/OCB');
            var oList = clientContext.get_web().get_lists().getByTitle('Course List');

            var itemCreateInfo = new SP.ListItemCreationInformation();
            this.oListItem = oList.addItem(itemCreateInfo);

            var documents = new XMLSerializer().serializeToString(xmlDoc.documentElement);
            documents = vkbeautify.xml(documents);
            oListItem.set_item('xml_data', documents);

            oListItem.update();

            clientContext.load(oListItem);
            clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
        };

        function onQuerySucceeded() {
            alert('Course successfully added');
        }

        function onQueryFailed(sender, args) {
            alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
        }

        function loadXMLDoc_makeCatArray() {
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.onreadystatechange = function() {
                if (this.readyState == 4 && this.status == 200) {
                    catArray(this);
                }
            };
            xmlhttp.open("GET", "https://splm.sharepoint.com/sites/OCB/Shared%20Documents/curriculumdata.xml", true);
            xmlhttp.send();
        }

        function catArray(xml) {
            eleArray = [];

            var xmlDoc = xml.responseXML;

            ele = xmlDoc.getElementsByTagName("course");

            for (i = 0; i < ele.length; i++) {
                if (!(eleArray.includes(ele[i].querySelector("category").childNodes[0].nodeValue))) {

                    eleArray.push(ele[i].querySelector("category").childNodes[0].nodeValue);
                }
            }
            var sel = document.querySelector('categoryDropdown')[count - 1];
            for (var i = 0; i < eleArray.length; i++) {
                var opt = document.createElement('option');
                opt.innerHTML = eleArray[i];
                opt.value = eleArray[i];
                console.log(opt);
                sel.appendChild(opt);
            }
        };
        
        loadXMLDoc_makeCatArray();
    </script>
</body>

</html>

Если это правда, не должны ли мы закрыть опечатку?

mplungjan 13.09.2018 20:01

Ах, хороший улов! Это, вероятно, способствовало возникновению ошибки, но я все еще получаю то же сообщение после исправления ... Я предполагаю, что это как-то связано с тем, как я вызываю removeCourseForm?

bean03 13.09.2018 20:01

@ bean03 См. мой обновленный ответ. У вас также есть проблемы с вашей строкой HTML.

Scott Marcus 13.09.2018 20:11

@ScottMarcus Я предполагаю, что моя проблема где-то в том звонке, да; У меня происходит странное вложение, потому что вся эта строка помещается как innerHTML, поэтому она внутри одинарных кавычек ... конкатенация там должна добавлять ");"> </div> </fieldset> в конец звонка. Эта строка, безусловно, немного беспорядочная.

bean03 13.09.2018 20:16

@ bean03 Взгляни еще раз. Я устранил предыдущую ошибку, и теперь она жалуется, что p1 не существует, но, не зная подробностей имен ваших тегов, я не уверен, что это должно быть.

Scott Marcus 13.09.2018 20:19

@ScottMarcus, это проблема, с которой я тоже сейчас сталкиваюсь. Это имя тега должно быть p2 (я исправил это, просто установив для этого счетчика значение count + 1) - по сути, код создает новый элемент p, за которым следует значение счетчика, чтобы обозначить, какая итерация формы это. Разве что я неправильно использую класс элемента? Могу ли я не передать это в качестве аргумента функции?

bean03 13.09.2018 20:24

Поскольку это не переменная, я думаю, она должна быть внутри этих двойных кавычек, что просто возвращает нас к ошибке `` неожиданный конец ввода ''.

bean03 13.09.2018 20:33

@ScottMarcus огромное спасибо за вашу помощь - я очень ценю это! Я обновил код во фрагменте, чтобы он соответствовал вашим рекомендациям. По-прежнему сталкивается с той же проблемой, что и раньше. На самом деле не уверен, что происходит с этой функцией!

bean03 13.09.2018 21:19

В итоге я решил эту проблему довольно просто:

Я вызвал функцию removeCourseForm () без каких-либо параметров, а затем сгенерировал имя div внутри этой функции.

function removeCourseForm() {
        var divName = "div" + count;
        $("." + divName).remove();
        count--;
    }

Кажется, это устранило всю проблему, и теперь она отлично работает :)

Другие вопросы по теме