0

I have a form that can be dynamically updated by using a js script based on this script. A select-list is dynamically generated to allow selection of an attribute for the dynamically generated field. However, the list contains hundreds of unique attributes and I therefore want to add a "search" box so selection is easier. I have been using the Jquery-ui autocomplete function and it works fine when the input box is outside the dynamically updated form, however, once I put it inside the form it does not work. The following div is dynamically inserted into the form:

<div id="readroot" style="display: none">
    <select name="_name">
        <option value="1">1</option>
        <option value="2">2</option>
        //many more options...
    </select>
    First text
    <input type="text" size="15" name="xyz" /> Second text
    <input type="text" size="15" name="xyz2" />
    <input type="button" value="Remove  trait" onclick="this.parentNode.parentNode.removeChild(this.parentNode);" />
</div>

The form:

<form method="post" name="disForm" target="_blank" id="disForm">
    <div id="writeroot"></div>
    <input type="button" value="Add trait" onclick="moreFields();" />
</form>

And here is the script that adds new fields (the "readroot"div) to the "writeroot"-div:

<script type="text/javascript">
    var counter = 0;

    function moreFields() {
        counter++;
        var newFields = document.getElementById('readroot').cloneNode(true);
        //newFields.id = '';
        newFields.style.display = 'block';
        var newField = newFields.childNodes;
        for (var i = 0; i < newField.length; i++) {
            var theName = newField[i].name
            if (theName)
                newField[i].name = theName + counter;
            newField[i].title = theName + counter;

        }
        var insertHere = document.getElementById('writeroot');
        insertHere.parentNode.insertBefore(newFields, insertHere);
    }
    window.onload = moreFields;
</script>

Here is the input and script for the autocomplete:

<input title="autocomplete" name="autocomplete">

<script>
    $("[title^='autocomplete']").autocomplete({
        source: ["...many values..."]
    });
</script>

I'm using jQuery UI Autocomplete 1.11.4 from jqueryui.com. Just to repeat myself, this script works when it is outside the "readroot" div but not when it is inside the "readroot"-div. Why doesn't it work inside the "readroot" div?

Update I have corrected the code as suggested by pablito.aven. Adding other types of searchable lists such as chosenjs also works outside the 'readroot' div but not inside. The autocomplete script works like this:

<div id="readroot" style="display: none">
    <select name="_name">
        <option value="1">1</option>
        <option value="2">2</option>
        //many more options...
    </select>
    First text
    <input type="text" size="15" name="xyz" /> Second text
    <input type="text" size="15" name="xyz2" />
    <input type="button" value="Remove  trait" onclick="this.parentNode.parentNode.removeChild(this.parentNode);" />
</div>

<input title="autocomplete" name="autocomplete">//input is outside readroot, Works!

<script>
    $("[title^='autocomplete']").autocomplete({
        source: ["...many values..."]
    });
</script>

But not like this:

<div id="readroot" style="display: none">
    <select name="_name">
        <option value="1">1</option>
        <option value="2">2</option>
        //many more options...
    </select>
    First text
    <input type="text" size="15" name="xyz" /> Second text
    <input type="text" size="15" name="xyz2" />
    <input type="button" value="Remove  trait" onclick="this.parentNode.parentNode.removeChild(this.parentNode);" />
 <input title="autocomplete" name="autocomplete"> //input is inside 'readroot' Does not work :(
</div>
<script>
    $("[title^='autocomplete']").autocomplete({
        source: ["...many values..."]
    });
</script>

3 Answers 3

1

I think I found your answer now. When you add a new select with the function moreFields(), you take the code inside readroot and copy it before writeroot. You are copying the code, generating new elements. But, the script that generates the autocomplete has already been ran.

<script>
    $("[title^='autocomplete']").autocomplete({
        source: ["...many values..."]
    });
</script>

So, the autocomplete will work only in the elements that were already there when the script is ran.

I might guess that if you remove the display:none from readroot, the autocomplete will work in it, but still won't work on the dynamically generated selects.

What you should have to do is to run that script again when you add more fields, so that it binds to the new generated fields. Something like this may probably work:

<script type="text/javascript">
  function initializeAutocomplete(){
    $("[title^='autocomplete']").autocomplete({
      source: ["...many values..."]
    });
  }

  var counter = 0;
  function moreFields() {
    counter++;
    var newFields = document.getElementById('readroot').cloneNode(true);
    //newFields.id = '';
    newFields.style.display = 'block';
    var newField = newFields.childNodes;
    for (var i = 0; i < newField.length; i++) {
      var theName = newField[i].name;
      if (theName){
        newField[i].name = theName + counter;
        newField[i].title = theName + counter;
      }
    }
    var insertHere = document.getElementById('writeroot');
    insertHere.parentNode.insertBefore(newFields, insertHere);
    initializeAutocomplete();
  }
  window.onload = moreFields;
</script>

I also added the {} to the if statement, and one or two semicolons that were missing.

If this works, I would be thankful if you upvote my answers. If it doesn't, we will have to keep trying.

Sign up to request clarification or add additional context in comments.

2 Comments

Awesome. Everything works perfectly! Thank you so much! See the final result here: mitodb.com
Lot of people have helped me out in this community, I am happy to be able to help others now! Best wishes
0

For having a search box inside your <select>, I use angularJS, which automatically creates the search box and is quite easy and friendly.

Something like this would be

<select ng-app="moduleName" ng-controller="controllerName" name="_name" id="unique_id" class="chosen-select" required>
    <option ng-repeat="x in options" value="{{x.val}}">{{x.name}}</option>
</select>

And you have to initialize it with javascript.

angular.module('moduleName', []).controller('controllerName', function($scope){
    $scope.options = [
        {val: 'value 1, 'name:'name 1'},
        {val: 'value 2', name:'name 2'},
        {val: 'value 3', name:'name 3'}
    ];
});

As your form loads dinamically, all you have to do is figure out how to fill the options inside the $scope variable in the controller from your js script

In order for this to work correctly, you have to include angularJS source code.

<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>

If you want to understand more about how angularJS works, i recommend you reading about it here, it shouldn't take you too much time

2 Comments

Thanks Pablito! Really appreciate your help. I could not get angularjs to work with the dynamically updated list. However, I did get chosenjs to work with the generated list but only outside the 'readroot'-div. Inside the 'readroot' div it still does not work. Any ideas? Help!
I just added a new answer with a few things i found. Still I am not 100% understanding your issue. Would you mind creating a JSFiddle to help me help you? Also, are there any errors in your console log?
0

There is a slight problem with your code <input type="button" id="moreFields" value="Add trait" onclick="init(this);" /> Here you call init function with a parameter. In it's definition it takes no parameters.

function init() {
    document.getElementById('moreFields').onclick = moreFields;
    moreFields();
}

And, I don't understand why on that init function you are binding a on click event to #moreFields if you already have the onclick attribute in your html. Isn't that function unnecesary? Maybe you could just do <input type="button" id="moreFields" value="Add trait" onclick="moreFields();" />

Also, you have a html comment line (<!--) inside your <script></script> tags. I think you should remove it, it may be causing some trouble. If you want to comment javascript code you should do it with //commented line or /*commented block*/

1 Comment

Thanks Pablito, Again really appreciate your feedback. I am not sure why I initially had that double function to run moreFields(). This is code I wrote a year ago. Anyway, I have corrected the functions as you suggested (code updated in example above). The dynamic generation of forms is based on this script. However, the drop down menu I want to make searchable such as with angularjs, jquery-ui autocomplete or with chosenjs. But I can't get those scripts to work inside the newly generated fields. I am trying to create a fiddle...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.