QuerySelector-无法读取NULL的属性。动态形式带有建议

发布于 2025-01-27 05:58:26 字数 5668 浏览 5 评论 0 原文

我正在尝试使用JavaScript创建一个动态表单,可以在其中添加更多字段。当用户开始在添加字段中键入时,则应根据列表显示建议。 基于书面输入的建议输入

添加的字段应像 1 。搜索功能通过使用QuerySelector来进行创建的新字段来起作用。但是,我收到一个类型错误,说: typeError:无法读取null 的属性。

该函数在没有 newsearch(i)的情况下起作用,但是我想在添加更多字段时出现此建议框。

源代码:

sites.html

<div class="sites-container">
    <form class="sites-form" method = "POST" id="myForm" name="myForm">
        <div class="wrapper">
          <div id="Site-options">
            <h1 class="sites-add-header"> Create a String </h1>
            <p class="sites-add-text"> Choose Modules at String </p>
            <div class="wrapper2">
              <div class="search-input2">
                <a href="" target="_blank" hidden></a>
                <input type="text" placeholder="Type to search.." name="PV-modules">
                <div class="autocom-box2">
                </div>
                <div class="icon2"><i class="fas fa-search"></i></div>
              </div>
            </div>
          </div>
        <div class="controls">
          <a href="#" id="add_more_fields"><i class="fa fa-plus"></i>Add Another String</a>
          <a href="#" id="remove_fields"><i class="fa fa-plus"></i>Remove Site</a>
        </div>
    </div>

    <button type="submit" class="sites-add-site button">Add Site</button>
  </form>
</div>

<script>
    let suggestions2 = {{ modules | safe}} ;
</script>
<script src="{{ url_for('static', filename='add-site.js') }}"></script>>

add-site.js


var site_options = document.getElementById('Site-options');
var add_more_fields = document.getElementById('add_more_fields');
var remove_fields = document.getElementById('remove_fields');
var count = 1;
add_more_fields.onclick = function(){
  var i = count++;
  var _div = document.createElement('div');
  _div.setAttribute('id','new-div'+i);
  _div.innerHTML =  '<p class="sites-add-text"> Choose Modules at Site </p>' + 
                    '<div class="wrapper2">' +
                      '<div class="search-input2" id="new-search-input' + i + ' ">' +
                        '<a href="" target="_blank" hidden></a>' +
                        '<input type="text" placeholder="Type to search.." name="PV-modules">' +
                        '<div class="autocom-box2 id="new-autocom-box' + i + '">' +
                        '</div>'+
                        '<div class="icon2" id="new-icon' + i + '><i class="fas fa-search"></i></div>'+
                      '</div>'+
                    '</div>';
  newSearch(i);
  site_options.appendChild(_div);
};
remove_fields.onclick = function(){
  var elem = document.getElementById("new-div");
  elem.parentNode.removeChild(elem);
}


function newSearch(i) {
  // getting all required elements
  var searchWrapper2 = document.querySelector("#new-search-input" + i);
  var inputBox2 = searchWrapper2.querySelector("input");  // <- Here i get TypeError
  var suggBox2 = searchWrapper2.querySelector(".autocom-box2");
  var icon2 = searchWrapper2.querySelector(".icon2");
  let linkTag2 = searchWrapper2.querySelector("a");
  let webLink2;
  // if user press any key and release
  inputBox2.onkeyup = (e2)=>{
      let userData2 = e2.target.value; //user enetered data
      let emptyArray2 = [];
      if(userData2){
          icon2.onclick = ()=>{
              webLink2 = `https://www.google.com/search?q=${userData2}`;
              linkTag2.setAttribute("href", webLink2);
              linkTag2.click();
          }
          emptyArray2 = suggestions2.filter((data2)=>{
              //filtering array value and user characters to lowercase and return only those words which are start with user enetered chars
              return data2.toLocaleLowerCase().startsWith(userData2.toLocaleLowerCase());
          });
          emptyArray2 = emptyArray2.map((data2)=>{
              // passing return data inside li tag
              return data2 = `<li>${data2}</li>`;
          });
          searchWrapper2.classList.add("active"); //show autocomplete box
          showSuggestions2(emptyArray2);
          let allList2 = suggBox2.querySelectorAll("li");
          for (let i = 0; i < allList2.length; i++) {
              //adding onclick attribute in all li tag
              allList2[i].setAttribute("onclick", "select2(this)");
          }
      }else{
          searchWrapper2.classList.remove("active"); //hide autocomplete box
      }
  }
  function select2(element){
      let selectData2 = element.textContent;
      inputBox2.value = selectData2;
      icon2.onclick = ()=>{
          webLink2 = `https://www.google.com/search?q=${selectData2}`;
          linkTag2.setAttribute("href", webLink2);
          linkTag2.click();
      }
      searchWrapper2.classList.remove("active");
  }
  function showSuggestions2(list){
      let listData2;
      if(!list.length){
          userValue2 = inputBox2.value;
          listData2 = `<li>${userValue2}</li>`;
      }else{
        listData2 = list.join('');
      }
      suggBox2.innerHTML = listData2;
  }
}

I am trying to create a dynamic form with Javascript, where it is possible to add more fields. And when the user starts typing in the added fields then suggestions should show based on a list. Suggested inputs based on written input

The added fields should look just like the one shown in 1. The Search function works by using querySelector to take the new field created. However, i receive a type error saying: TypeError: Cannot read properties of null.

The function works without newSearch(i), but i want to have this suggestion box appearing when adding more fields.

Source Code:

sites.html

<div class="sites-container">
    <form class="sites-form" method = "POST" id="myForm" name="myForm">
        <div class="wrapper">
          <div id="Site-options">
            <h1 class="sites-add-header"> Create a String </h1>
            <p class="sites-add-text"> Choose Modules at String </p>
            <div class="wrapper2">
              <div class="search-input2">
                <a href="" target="_blank" hidden></a>
                <input type="text" placeholder="Type to search.." name="PV-modules">
                <div class="autocom-box2">
                </div>
                <div class="icon2"><i class="fas fa-search"></i></div>
              </div>
            </div>
          </div>
        <div class="controls">
          <a href="#" id="add_more_fields"><i class="fa fa-plus"></i>Add Another String</a>
          <a href="#" id="remove_fields"><i class="fa fa-plus"></i>Remove Site</a>
        </div>
    </div>

    <button type="submit" class="sites-add-site button">Add Site</button>
  </form>
</div>

<script>
    let suggestions2 = {{ modules | safe}} ;
</script>
<script src="{{ url_for('static', filename='add-site.js') }}"></script>>

add-site.js


var site_options = document.getElementById('Site-options');
var add_more_fields = document.getElementById('add_more_fields');
var remove_fields = document.getElementById('remove_fields');
var count = 1;
add_more_fields.onclick = function(){
  var i = count++;
  var _div = document.createElement('div');
  _div.setAttribute('id','new-div'+i);
  _div.innerHTML =  '<p class="sites-add-text"> Choose Modules at Site </p>' + 
                    '<div class="wrapper2">' +
                      '<div class="search-input2" id="new-search-input' + i + ' ">' +
                        '<a href="" target="_blank" hidden></a>' +
                        '<input type="text" placeholder="Type to search.." name="PV-modules">' +
                        '<div class="autocom-box2 id="new-autocom-box' + i + '">' +
                        '</div>'+
                        '<div class="icon2" id="new-icon' + i + '><i class="fas fa-search"></i></div>'+
                      '</div>'+
                    '</div>';
  newSearch(i);
  site_options.appendChild(_div);
};
remove_fields.onclick = function(){
  var elem = document.getElementById("new-div");
  elem.parentNode.removeChild(elem);
}


function newSearch(i) {
  // getting all required elements
  var searchWrapper2 = document.querySelector("#new-search-input" + i);
  var inputBox2 = searchWrapper2.querySelector("input");  // <- Here i get TypeError
  var suggBox2 = searchWrapper2.querySelector(".autocom-box2");
  var icon2 = searchWrapper2.querySelector(".icon2");
  let linkTag2 = searchWrapper2.querySelector("a");
  let webLink2;
  // if user press any key and release
  inputBox2.onkeyup = (e2)=>{
      let userData2 = e2.target.value; //user enetered data
      let emptyArray2 = [];
      if(userData2){
          icon2.onclick = ()=>{
              webLink2 = `https://www.google.com/search?q=${userData2}`;
              linkTag2.setAttribute("href", webLink2);
              linkTag2.click();
          }
          emptyArray2 = suggestions2.filter((data2)=>{
              //filtering array value and user characters to lowercase and return only those words which are start with user enetered chars
              return data2.toLocaleLowerCase().startsWith(userData2.toLocaleLowerCase());
          });
          emptyArray2 = emptyArray2.map((data2)=>{
              // passing return data inside li tag
              return data2 = `<li>${data2}</li>`;
          });
          searchWrapper2.classList.add("active"); //show autocomplete box
          showSuggestions2(emptyArray2);
          let allList2 = suggBox2.querySelectorAll("li");
          for (let i = 0; i < allList2.length; i++) {
              //adding onclick attribute in all li tag
              allList2[i].setAttribute("onclick", "select2(this)");
          }
      }else{
          searchWrapper2.classList.remove("active"); //hide autocomplete box
      }
  }
  function select2(element){
      let selectData2 = element.textContent;
      inputBox2.value = selectData2;
      icon2.onclick = ()=>{
          webLink2 = `https://www.google.com/search?q=${selectData2}`;
          linkTag2.setAttribute("href", webLink2);
          linkTag2.click();
      }
      searchWrapper2.classList.remove("active");
  }
  function showSuggestions2(list){
      let listData2;
      if(!list.length){
          userValue2 = inputBox2.value;
          listData2 = `<li>${userValue2}</li>`;
      }else{
        listData2 = list.join('');
      }
      suggBox2.innerHTML = listData2;
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡笑忘祈一世凡恋 2025-02-03 05:58:26

您需要调用 newsearch 添加元素后

site_options.appendChild(_div);
newSearch(i);

,需要删除 innerhtml 中的额外空间,这就是为什么 id> ID 属性未获取的原因发现,打破了所有代码:

'<div class="search-input2" id="new-search-input' + i + '">' +

you need to call newSearch after adding the element

site_options.appendChild(_div);
newSearch(i);

and you need to remove extra space in the innerHTML, which is why id attribute doesn't get found, breaking all the code:

'<div class="search-input2" id="new-search-input' + i + '">' +
绝情姑娘 2025-02-03 05:58:26

交换这两条线应该可以正常工作。在您的情况下,searchWrapper2为无效。

newsearch(i); site_options.appendchild(_div);

site_options.appendchild(_div); newsearch(i);

swap these two lines it should work fine . searchWrapper2 is null in your case.

newSearch(i); site_options.appendChild(_div);

site_options.appendChild(_div); newSearch(i);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文