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>
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.
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
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*/
Related
I am using this function:
function selectionchange() {
var e = document.getElementById("mySelect");
var str = e.options[e.selectedIndex].value;
document.getElementById('txt').value = str;
}
to fill the hidden field when changing options:
<form>
<select id="mySelect" onchange="selectionchange();">
<option value="1">Sun</option>
<option value="2">Moon</option>
</select>
<input type="hidden" id="txt" value="">
<button type="submit">send</button>
</form>
but it does not work.
The closing tag of < /script> looks bad. Not sure if it is caused by editing. But I have tested the code after changing < /script> to </script> and it worked fine.
Curerntly working on jquery clone where I need to addrow and delete rows I have searched lot in stackoverflow and in google based on that i understand a bit on how jquery clone will work.
Any suggestion please
Here is the jquery code.
var count=0;
$(document).on("click", ".phn_btn_more", function () {
var $clone = $('.cloned-row:eq(0)').clone();
//alert("Clone number" + clone);
$clone.find('[id]').each(function(){this.id+='someotherpart'});
$clone.attr('id', "added"+(++count));
$('.cloned-row:eq(0)').after($clone);
});
$(document).on('click', ".btn_less1", function (){
var len = $('.cloned-row').length;
if(len>1){
$(this).closest(".btn_less1").parent().parent().parent().remove();
}
});
With the current code updated code I can able to increment id dynamically but it cloning two times.
with this code when i try to click add more button it was cloning the div but i am getting two div instead of one and Iam trying to add id and name incrementing dynamically
I know it may be a possible duplicate but still I am not getting why I am not able to incrementing id and name. For btn less for the first div btn_less class won't be available once user click add more from second add less button should appear
Here is the html code
<div class="em_pho cloned-row" id="phone_content">
<select id="sel_phntype" name="sel_phntype" class="sslt_Field">
<option selected='selected' value="">Phone Type</option>
<option value="BUSN">Business</option>
<option value="CAMP">Campus</option>
<option value="CELL" >Cellphone</option>
<option value="CEL2">Cellphone2</option>
<option value="FAX">FAX</option>
<option value="HOME">Home</option>
<option value="OTR">Other</option>
</select>
<span class = "ph-inline">
<input type="text" class="cc_field" placeholder="Country Code" id="txt_CC" maxlength="3" name="txt_CC" />
<input type="text" class="pn_field" placeholder="Phone Number" id="txt_Pno" name="txt_Pno" />
<input type="radio" name="preferred" id="rad_Prf" value="preferred">
<label class="radio-label">Preferred</label>
<!--<button class="btn_more" id="buttonvalue"></button>-->
<input type="button" class="phn_btn_more" id="buttonvalue"/>
</span>
</div>
Kindly help me
Thanks & regards
mahadevan
Not sure if this is what you wanted.
JSfiddle
Let me know if I missed out anything or if anything is wrong.
JQuery
var count=0;
$(document).on("click", ".phn_btn_more", function () {
var $clone = $('.cloned-row:eq(0)').clone();
//alert("Clone number" + clone);
$clone.find('[id]').each(function(){this.id+='someotherpart'});
$clone.find('.phn_btn_more').after("<input type='button' class='btn_less1' id='buttonless' value = 'remove'/>")
$clone.attr('id', "added"+(++count));
$(this).parents('.em_pho').after($clone);
});
$(document).on('click', ".btn_less1", function (){
var len = $('.cloned-row').length;
if(len>1){
$(this).parents('.em_pho').remove();
}
});
I am trying to create clones of a HTML div. The div has a label and two text boxes inside it. I need to change the label value of the newly created div. Here is my code.
<body>
<div id="PayDiv2">
<label id="PayLbl2">Payment No 2: </label>
<input type="text" />
<input type="text" />
</div>
<div id ="totPayForm" >
<label id="totPayLbl">Total Payment: </label>
<input type="text" />
<input type="text" />
<input type="submit" value="Add new one" onclick="addNewField();
return false;">
</div>
<input type="button" value="Clone box" id="btn" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
var i=3;
//When DOM loaded we attach click event to button
$(document).ready(function() {
$('#btn').click(function() {
var cloned = $('#PayDiv2').clone();
cloned.insertBefore("#totPayForm");
$('#PayLbl2').html("Payment No "+ i++ + ':');
});
});
</script>
</body>
The problem is the place the newly created clones placed. First clone get placed before everything(even though I need to place it after the original div which I used to create divs. )
divs generated after that also get placed at first and, early divs goes down. It is hard to describe here. If you can be kind enough to run my code you will see what the issue is.
I have an another requirement to generate unique ids to cloned divs. Since I am new in JQuery, I found it difficult to generate id's.
I am pleased if you can help me in this case. Thank you all.
The problem is $('#PayLbl2').html("Payment No "+ i++ + ':'); it always changes the first element's label instead of the clone(because of the duplicated ids)...
so use class instead of id
<div class="PayDiv2">
<label class="PayLbl2">Payment No 2:</label>
<input type="text" />
<input type="text" />
</div>
then
var i = 3;
//When DOM loaded we attach click event to button
$(document).ready(function () {
$('#btn').click(function () {
var cloned = $('.PayDiv2').first().clone();
cloned.insertBefore("#totPayForm");
cloned.find('.PayLbl2').html("Payment No " + i+++':');
});
});
Demo: Fiddle
Here it is.
Demo
Make your HTML like below
<div id="PayDiv0" class="PayDiv0">
<label id="PayLbl0" class="PayLbl2">Payment No 2:</label>
<input type="text" />
<input type="text" />
</div>
<div id="totPayForm">
<label id="totPayLbl">Total Payment:</label>
<input type="text" />
<input type="text" />
<input type="submit" value="Add new one" onclick="addNewField();
return false;">
</div>
<input type="button" value="Clone box" id="btn" />
And JS should be like this
var i = 3;
$(document).ready(function () {
$('#btn').click(function () {
var cloned = $('.PayDiv0').first().clone();
var noOfDivs = $('.PayDiv0').length;
cloned.insertBefore("#totPayForm");
cloned.attr('id', 'PayDiv' + noOfDivs);
cloned.find('label').attr('id', 'PayLbl' + noOfDivs);
cloned.find('.PayLbl2').html("Payment No " + i+++':');
});
});
As mentioned in the answer by #Arun P Johny, set the div id PayDiv0
$('#btn').click(function () {
var cloned = $('.PayDiv2').first().clone();
// find total divs with class PayDiv2
var noOfDivs = $('.PayDiv2').length;
cloned.insertBefore("#totPayForm");
// add new id to the cloned div
cloned.attr('id', 'PayDiv' + noOfDivs);
// find the label element inside new div and add the new id to it
cloned.find('label').attr('id', 'PayLbl' + noOfDivs);
cloned.find('.PayLbl2').html("Payment No " + i+++':');
});
this way you can add the dynamic ids to your elements.
I'm having a listBox, when selected it, it will be printed in the textArea and beside to it I have given a clear button, so when clicked the value of the textArea has to be cleared, it works fine, now the problem is, after clearing the value in textArea and again when i select the listBox, the value is not getting printed on the textArea. What might be the problem?
Here is the code,
HTML:
<select id="aggregationFunct" name="aggregationFunct" size="3" multiple="multiple">
<option value="Count">Count</option>
<option value="Sum">Sum</option>
<option value="Avg">Avg</option>
</select>
<input type="button" id="addToExp1Id" value="Add" onclick="addToExpText()" >
</br> </br>
<label for="expTextId" style="font-family: sans-serif; font-size: small;"> Expression : </label>
<textarea name="textArea" id="expTextId" readonly="readonly"> </textarea>
<input type="button" id="clearId" value="Clear" onclick="clearTextArea()">
JavaScript:
function addToExpText() {
alert("hello);
var aggreFunct = document.getElementById("aggregationFunct").value;
var obj = document.getElementById("expTextId");
var aggFun = document.createTextNode(aggreFunct);
obj.appendChild(aggFun);
obj.appendChild(openP);
}
function clearTextArea(){
document.form1.textArea.value='';
}
After clearing the value in the textArea, again if i click on the listBox value and add it, it is not getting added. Pls help... Here is the implementaiton which is not working properly, may be its becaus i'm using it for the first time and i might be wrong.
http://jsfiddle.net/8dHf5/5/
Not sure why it works like that, but here are few possible fixes:
Instead of using append (to add a new aggregation function), you can use value both to add and clear:
function addToExpText() {
alert("hello");
var aggreFunct = document.getElementById("aggregationFunct").value;
var obj = document.getElementById("expTextId").value += aggreFunct;
}
function clearTextArea(){
document.getElementById("expTextId").value='';
}
Demo: http://jsfiddle.net/8dHf5/17/
Or you can use remove child nodes to clear values of textarea:
function addToExpText() {
alert("hello");
var aggreFunct = document.getElementById("aggregationFunct").value;
var obj = document.getElementById("expTextId");
var aggFun = document.createTextNode(aggreFunct);
obj.appendChild(aggFun);
}
function clearTextArea(){
var myNode = document.getElementById("expTextId");
while (myNode.firstChild) {
myNode.removeChild(myNode.firstChild);
}
}
Demo: http://jsfiddle.net/8dHf5/14/
Besides, there is a line obj.appendChild(openP); in your code, but I do not see it being available in code, so I removed it.
Another moment: in your clearTextArea you are trying to access your textarea like document.textArea - if I'm not missing something, it is IE only feature and it works with ids instead of names. It is better to use document.getElementById which is cross browser.
There was some mistake in your code.
I have modified it...
Now you are able to clear data.
Please refer below code:
<html>
<body>
<script>
function addToExpText() {
alert("hello");
var aggreFunct = document.getElementById("aggregationFunct").value;
var obj = document.getElementById("expTextId");
var aggFun = document.createTextNode(aggreFunct);
obj.appendChild(aggFun);
}
function clearTextArea(){
var textArea = document.getElementById("expTextId");
while (textArea.firstChild) {
textArea.removeChild(textArea.firstChild);
}
}
</script>
<select id="aggregationFunct" name="aggregationFunct" size="3" multiple="multiple">
<option value="Count">Count</option>
<option value="Sum">Sum</option>
<option value="Avg">Avg</option>
</select>
<input type="button" id="addToExp1Id" value="Add" onclick="addToExpText()" >
</br> </br>
<label for="expTextId" style="font-family: sans-serif; font-size: small;"> Expression : </label>
<textarea name="textArea" id="expTextId" readonly="readonly"> </textarea>
<input type="button" id="clearId" value="Clear" onclick="clearTextArea()">
</body>
</html>
I've experienced some code of enable/disable multiple html element by javascript:
<script type="text/javascript">
function enableDisable(bEnable, text_no1, text_no2, opt_no1, opt_no2){
document.getElementById(text_no1).disabled = !bEnable
document.getElementById(text_no2).disabled = !bEnable
document.getElementById(opt_no1).disabled = !bEnable
document.getElementById(opt_no2).disabled = !bEnable
}
</script>
<label for="toggler"><input type="checkbox" id="toggler" autocomplete="off"
checked="false"
onclick="enableDisable(this.checked, 'text_no1','text_no2','opt_no1','opt_no2')";>
Toggler</label>
<br>
<input type="text" name="text_no1"><br>
<input type="text" name="text_no1"><br>
<select name="opt_no1">
<option>1</option>
</select>
<select name="opt_no2">
<option>1</option>
</select>
I made a simple script of what you are trying to achieve.
(Tested in Chrome 21, Firefox 14, Internet Explorer 9)
The JavaScript
function Switch() {
var checkbox = document.getElementById("Switch")
var val = checkbox.checked
document.getElementById("textbox").disabled = val
}
The HTML
<input type="checkbox" id="Switch" onChange="Switch()" />Disable/Enable
<br />
<input type="text" id="textbox"/>
Live Example: http://jsfiddle.net/jHVNE/1/
I'll guess that your issue is that "it doesn't work", that is, that the elements aren't disabled. That is partly because you are using getElementById to access elements that don't have an ID attribute (though likely it works in IE since it thinks IDs and names are the same thing).
You can either change the name attributes to ID attributes (since you aren't using a form that shouldn't be an issue), or keep the names and put the controls in a form, then access them as named properties of the form.
Edit
There are a couple of errors and omissions in your code:
The checked attribute does not have a value, it's a boolean attribute whose presence indicates "true" and absence is "false", so …checked="false"… is true and checks the checkbox.
There are two inputs with a name of *text_no1*
It seems checking the checkbox should enable the controls, the label should indicate that.
Using a form makes life easier to access form controls
Some working code:
<script type="text/javascript">
function enableDisable(el) {
var f = el.form;
var bEnable = el.checked;
if (!f) return; // Stop if form not found
for (var i=1, iLen=arguments.length; i<iLen; i++) {
f[arguments[i]].disabled = !bEnable;
}
}
</script>
<form>
<label for="toggler">
<input type="checkbox" id="tggler" name="toggler" autocomplete="off" checked
onclick="enableDisable(this, 'text_no1','text_no2','opt_no1','opt_no2')";>
Controls enabled</label>
<br>
<input name="text_no1"><br>
<input name="text_no2"><br>
<select name="opt_no1">
<option>1
</select><br>
<select name="opt_no2">
<option>2
</select>
</form>