How to automatically clone <tr> when user finish fill up text input? - javascript

I have simple form with 2 textfield Name and Phone and can add new field when click Add new button. You can refer here jsfiddle .
My problem is how to add new textfield without press Add New button? When user fill up Text Input name and Text Input Phone new row <tr class="person"> will automatically added.
My second problem is I'm not sure how to write code for delete.
UPDATE : I also want to set maximum clone, can this be done?

If by "fill up" you mean "when the user enters as many characters as the Phone field allows" then you can add a maxlength="10" attribute to the input (setting the value as appropriate):
<input type="text" name="phone[]" id="phone" maxlength="10"/>
...and add a handler to the keyup event that checks whether the current value has reached the maxlength:
$('input[name="phone\[\]"]').keyup(function() {
if (this===$('input[name="phone\[\]"]').last()[0]
&& this.value.length===+$(this).attr("maxlength")) {
$("#add").click();
}
});
Note that you probably only want to do this test if the user is typing in the last row, hence the first part of the if test above.
Also you probably want the newly cloned fields to be blank, so you can do this within your add function:
$('#mytable tbody>tr:last').clone(true).insertAfter('#mytable tbody>tr:last')
.find("input").val("");
To set a maximum number of rows you can put a test in your add function:
$("#add").click(function() {
var $lastRow = $('#mytable tbody>tr:last');
if ($lastRow.index() < 10) { // set maximum rows here
$lastRow.clone(true).insertAfter($lastRow).find("input").val("");
}
return false;
});
Note also that you don't need to give those inputs an id attribute, but if you do you shouldn't copy it when you clone because id should be unique.
For a delete function, add a delete button to each row:
<td><input type="button" class="deleteRow" value="Delete"/></td>
...and then:
$("#mytable").on("click","input.deleteRow", function(){
if ($("#mytable tr").length > 2) // don't delete the last row
$(this).closest("tr").remove();
});
Demo: http://jsfiddle.net/3J65U/15/

I would expand on enclares - I would use .blur() for each textbox , and each time check and make sure each value is not "" - that would make sure both are filled
Then in jQuery:
$(document).ready(function() {
$(".phone").blur(function() {
var phonetxt = $('.phone'.val();
var nametxt = $('.name').val();
if ( phonetxt != "" && nametxt != "" ){
$(this).closest('tr').clone(true)
.insertAfter('#mytable tr:last')
.find('input').val('').first().focus();
});
}
$(".name").blur(function() {
var phonetxt = $('.phone'.val();
var nametxt = $('.name').val();
if ( phonetxt != "" && nametxt != "" ){
$(this).closest('tr').clone(true)
.insertAfter('#mytable tr:last')
.find('input').val('').first().focus();
});
}
});​

You could do it on blur as well as the add new button. Also be careful with duplicated id's, use classes instead:
<tr class="person">
<td><input type="text" name="name[]" class="name" /></td>
<td><input type="text" name="phone[]" class="phone" /></td>
</tr>
Then in jQuery:
$('.phone').blur(function() {
var ppl = $('.person').length;
if ( this.value && ppl < 5 ) { // Max 5 people
$(this).closest('tr').clone(true)
.insertAfter('#mytable tr:last')
.find('input').val('').first().focus();
$(this).off('blur');
}
});
Demo: http://jsfiddle.net/elclanrs/YEBQt/ (tab from input to input)

Related

Unique name for Add More input

I am trying to create an add more button which will create a new input field. However, I would like to have an unique name set for it.
I tried to search up for an answer, but this does not answer my question.
So, basically what I tried to make my namefield unique is to use the php method rand(). The concept is that - when the add more button is clicked, it will have a name attached to the number given to me by rand().
However, what happens is that it takes the value generated by rand() and applies it to all the names of all the inputs generated.
This is my code and what I tried:
HTML:
<div class="field_wrapper">
<div>
<input type="text" name="field_name[<?php echo rand(); ?>]" value=""/>
Add More
</div>
</div>
JQUERY / JAVASCRIPT:
<script type="text/javascript">
$(document).ready(function(){
var maxField = 100; //Input fields increment limitation
var addButton = $('.add_button'); //Add button selector
var wrapper = $('.field_wrapper'); //Input field wrapper
var fieldHTML = '<div><input type="text" name="field_name[<?php echo rand(); ?>]" value=""/>Remove</div>'; //New input field html
var x = 1; //Initial field counter is 1
//Once add button is clicked
$(addButton).click(function(){
//Check maximum number of input fields
if(x < maxField){
x++; //Increment field counter
$(wrapper).append(fieldHTML); //Add field html
}
});
//Once remove button is clicked
$(wrapper).on('click', '.remove_button', function(e){
e.preventDefault();
$(this).parent('div').remove(); //Remove field html
x--; //Decrement field counter
});
});
</script>
As you can see, the first field generates the number as intended. If you click on the add more, the second field does create an unique number. However, if you click add more once again, the third field copies the same name as the 2nd field.
How do I go about achieving what I want and why is rand() not generating a new code?
Also, does rand() guarantee me that it will be an unique ID or is there a chance for it to repeat the same number?
If it does repeat, then what would be the best approach to take to make it as unique as possible?
If you generate random name with PHP it is done once on the server. Your JS code then copies the same element. What you need is to generate unique names with js.
Avoid random if you can, theoretically, you can hit the same number and run into mysterious bugs.
var generateField = function(name)
{
return '<div><input type="text" name="'+name+'" value=""/>Remove</div>'; //New input field html
}
//Once add button is clicked
$(addButton).click(function(){
//Check maximum number of input fields
if(x < maxField){
x++; //Increment field counter
$(wrapper).append(generateField('field_name['+x+']' ) ); //Add field html
}
});
Random does not necessarily mean unique, even if collisions would be extremely rare. This solution simply increments a totalFieldsCreated variable to get the next unique number (up to the maximum value JavaScript can provide.)
The new fields are created dynamically instead of using a fixed string of HTML. (This technique is more flexible.)
$(document).ready(function() {
// Defines global identifiers
let
currentFieldCount = 1,
totalFieldsCreated = 1;
const
maxFieldCount = 100,
addButton = $('.add_button'),
wrapper = $('.field_wrapper');
// Calls `addField` when addButton is clicked
$(addButton).click(addField);
// Executes anonymous function when `Remove` is clicked, which removes
// the parent div, and decrements (and logs) `currentFieldCount`
$(wrapper).on('click', '.remove_button', function(e) {
e.preventDefault();
$(this).parent('div').remove();
currentFieldCount--;
console.log(`currentFieldCount: ${currentFieldCount}`);
});
// Defines the `addField` function
function addField(){
// Makes sure that `currentFieldCount` and `totalFieldsCreated`
// are not at maximum before proceeding
if(
currentFieldCount < maxFieldCount &&
totalFieldsCreated < Number.MAX_VALUE
){
// Creates an input element, increments `totalFieldsCreated`,
// and uses the incremented value in the input's `name` attribute
const input = document.createElement("input");
input.type = "text";
input.name = "field" + ++totalFieldsCreated;
input.value = "";
// Creates an anchor element with the `remove_button` class
const a = document.createElement("a");
a.href = "javascript:void(0);";
a.classList.add("remove_button");
a.title = "remove";
a.innerHTML = "Remove";
// Adds the new elements to the DOM, and increments `currentFieldCount`
const div = document.createElement("div");
div.appendChild(input);
div.appendChild(a);
$(wrapper).append(div);
currentFieldCount++;
// Logs the new values of both variables
console.log(
`currentFieldCount: ${currentFieldCount},`,
`totalFieldsCreated ${totalFieldsCreated}`
);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="field_wrapper">
<div>
<input type="text" name="field1" value="" />
Add More
</div>
</div>
Try Math.random() in js rather than rand() in php ,Math.floor(Math.random()*90000) + 10000 will generate a five digit random number , Hope this helps
$('.rand').attr('name',"fields["+Math.floor(Math.random()*90000) + 10000+"]")
$('.add_button').click(function(e){
$('.field_wrapper').append('<div><input type="text" name=fields['+Math.floor(Math.random()*90000) + 10000+'] value=""/>Remove</div>')
})
$(document).on('click','.remove_button',function(e){
$(this).parent().remove()
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class="field_wrapper">
<div>
<input type="text" class="rand" value=""/>
Add More
</div>
</div>

Submit function when the same form is on the page twice

I have the below JavaScript submit function for a form that works fine. But when the form is on the page twice it only works for the first form and not for the second. I presume I need to use something with this so it only works on the active form?
HTML:
<form action="resultsnew.php" method="get" style="margin-bottom: 0" class="store-search-form">
<input type="text" name="d" value="Enter Postcode..." onclick="this.value='';" onfocus="this.select()" onblur="this.value=!this.value?'Enter Postcode...':this.value;" class="find-form-input field store-search-postcode" />
<input type="submit" onclick="java" value="Search" class="button" />
</form>
JavaScript:
$('.store-search-form').submit(function() {
//get the input's value
var postcodeinput = $('.store-search-postcode').val();
//remove spaces
postcodeinput = postcodeinput.replace(/\s/g, '');
//if valid postcode length trim it down
if (postcodeinput.length >= 5 && postcodeinput.length <= 7) {
//set the input's value
$('.store-search-postcode').val(postcodeinput.substring(0,postcodeinput.length - 3));
}
});
Do your searching relative to $(this) via find, i.e., change this:
var postcodeinput = $('.store-search-postcode').val();
to this:
var $this = $(this);
// ...
var postcodeinput = $this.find('.store-search-postcode').val();
(And in the other places you use it.)
Remember, within an event handler, this refers to the element the handler was hooked up to. $(this) creates a jQuery instance for that element. And then find searches within that element's descendants.
You need to reference the input that is in each form using $(this).find('.store-search-postcode') and then use that reference:
$('.store-search-form').submit(function() {
//get the input
var postcodeinput = $(this).find('.store-search-postcode');
//get the input's value
var postcode = postcodeinput.val();
//remove spaces
postcode = postcode.replace(/\s/g, '');
//if valid postcode length trim it down
if (postcode.length >= 5 && postcode.length <= 7) {
//set the input's value
postcodeinput.val(postcode.substring(0, postcode.length - 3));
}
});

tetxtbox enable/disable on checkbox select/unselect using Javascript

I have a table with three columns and multiple rows. 2nd and third column consist of a textbox(first child of a container) and a checkbox respectively.
Textbox
<td class="SBS1 c4">
<input class="Medium InputText" type="text" name="QR~QID33#1~1~1~TEXT" id="QR~QID33#1~1~1~TEXT" value="" disabled="">
<label class="offScreen" for="QR~QID33#1~1~1~TEXT">&nbsp; - &nbsp; - hh</label>
</td>
Checkbox
<td class="SBS2 c7">
<input type="checkbox" id="QR~QID33#2~1~1" name="QR~QID33#2~1~1" value="Selected">
<label class="q-checkbox q-checked" for="QR~QID33#2~1~1"></label>
<label class="offScreen" for="QR~QID33#2~1~1">&nbsp; - 󠆺random text</label>
</td>
I have to disable and enable the textboxes in each row on checkbox check and uncheck respectively using javascript. but there seem to be some pagelifecycle issues with the script I am using. Here is the Javascript that I am using in my Qualtrics survey JS interface,
Qualtrics.SurveyEngine.addOnload(function()
{
/*Place Your JavaScript Here*/
var count=document.getElementsByClassName("q-checkbox").length;
for(var i=0;i<count;i++)
{
document.getElementsByClassName("q-checkbox")[i].parentNode.addEventListener("click",hideFunc);
}
function hideFunc()
{
console.log(this.className);
if(this.classList.contains("checkers"))
{
//this.classList.toggle("checkers");
this.previousSibling.previousSibling.previousSibling.firstChild.disabled="false";
this.classList.add("checkers");
return;
}
else
if(!(this.classList.contains("checkers")))
{
this.previousSibling.previousSibling.previousSibling.firstChild.disabled="true";
this.classList.remove("checkers");
return;
}
}
});
I am just trying to toggle or add/remove the class "checkers"and setting "disabled" property of the texboxes accordingly. The code above in HideFunc is one of the work-around I have tried but it is not working.
Is there another way to check for checkbox change?
As the first comment hinted, a better approach is to check the status of the checkbox rather than add/remove a class. Also, making use of prototypejs makes it easier. Try this:
Qualtrics.SurveyEngine.addOnload(function() {
var qid = this.questionId;
$(qid).select('tr.Choice').each(function(choice,idx) { //loop through each row
var cbox = choice.select('td.SBS2').first().down(); //cbox enables 1st question in row
var txtEl = choice.select('td.SBS1').first().down(); //text input to be enabled/disabled
if(cbox.checked == false) { //initialize text input disabled status
txtEl.value = null; //blank text input
txtEl.disabled = true; //disable text input
}
cbox.on('click', function(event, element) { //enable/disable text input on cbox click
if(cbox.checked == false) { //unchecked
txtEl.value = null; //blank text input
txtEl.disabled = true; //disable text input
}
else { //checked
txtEl.disabled = false; //enable text input
}
}); //end on function
}); //end row loop
});
This is another solution I could come up with ,apart from the correct solution by T. Gibbons
var $j= jQuery.noConflict();
$j("td.SBS2 ").click(function(){
$j(this).closest("tr").find(".InputText").prop("disabled",$j(this).children("input")[0].checked);
$j(this).closest("tr").find(".InputText").prop("value","");
var len=document.getElementsByClassName("InputText").length;
for(var i=0;i<=len;i++)
{
document.getElementsByClassName("InputText")[i].style.width="300px";
}
});

Trying to append the textfield value to another textfield

I am doing some basic javascript where i am choosing some value from the popup and that value is appearing in the textfield. Now there is a button on the side of the textfieldfield, which when clicked will transfer its value to the another textfield as comma separated.
I mean the new textfield will have values as comma separated and not replaced.
I am doing a code like this
<input type="text" class="inputs" style="width:70px;" name="color1" id="color1" value="" maxlength="7" size="7">
<img src="icon_add.gif" alt="Add to text Box above" title="Add to text Box above" border="0">
function addtoTextField(cFieldName) {
var objTxt = document.getElementById('sta');
objTxt.appendChild(cFieldName);
}
Another text field where i need to pass value
<input type="text" name="sta" id="sta" class="inputs" />
Textbox element can't have child nodes, it only got a value. So to append value of other textbox as comma delimeted string, have this:
function addtoTextField(cFieldName) {
var oField = document.getElementById(cFieldName);
var valueToAdd = oField.value;
if (valueToAdd.length === 0)
return; //don't add empty values
var objTxt = document.getElementById('sta');
var existingValues = (objTxt.value.length === 0) ? [] : objTxt.value.split(",");
existingValues.push(valueToAdd);
objTxt.value = existingValues.join(",");
oField.value = ""; //clear textbox
oField.focus(); //bring focus back
}
Live test case.
The above will also clear the sender textbox value and re-focus it for next input.

how to find the next td element type using jquery

<tr>
<td class="value" style="width:40%;">
<label class="label">Gender value</label>
</td>
<td class="value" style="width:40%;">
<input id="checkbox" type="checkbox" tabindex="0" name="chkCustom">
<label>M</label>
<input id="checkbox" type="checkbox" tabindex="0" name="chkCustom">
<label>F</label>
<input id="checkbox" type="checkbox" tabindex="0" name="chkCustom">
<label>U</label>
</td>
</tr>
I have the above HTML, I am reading all the controls from my webpage dynamically. In above I want to read the label value to its specified type and read the next value on the basis of its type:
Please look on my code:
// Read labels text
$("#tblCustomFields tr .label").each(function () {
var value = this.innerHTML;
console.log(this);
var type = $(this).closest('td').next().find('input').val();
alert(value);
alert(type);
//If next element type is *checkbox* then read checkbox values
if(type == "checkbox")
{
// Read checkbox values
$('tblCustomFields tr input:checked').each(function (s) {
var inputCheckBox = new Array();
inputCheckBox.push([this.id, 0]);
});
for (var i = 0; i < inputCheckBox.length; i++) {
alert(inputCheckBox[i]);
}
}
});
The above code will give me all the checkboxes on the webpage but I want the checkboxes only defined in the above HTML, and I also want to read the values of only those checkboxes which are checked. Please help.
GOAL: I am binding the dynamic HTML to the page its type might be checkbox or dropdown or text. Now I want to read the page labels and the values related to that labels. For ex my label(Gender value) has values of type checkbox so I just want to read the checked checkbox values related to that label.
UPDATE: At least tell me that how can I get the next element type
I am using the below code:
var type = $(this).closest('td').next().find('type').val();
ANY HELP
I think that all the markup has to be reviewed, but anyway, I think I know (please notice me if don't) what you want.
Try this:
// Read labels text
$("#tblCustomFields tr .label").each(function () {
var value = this.innerHTML;
console.log(this);
alert(value);
var inputCheckBox = new Array();
$(this).first().closest("td").next().find("input[type='checkbox']:checked").each(function(){
inputCheckBox.push($(this).next("label").text());
});
for (var i = 0; i < inputCheckBox.length; i++) {
alert(inputCheckBox[i]);
}
});
I'll make you a jsFiddle to test it.
Your question is confusing.
$("#tblCustomFields tr .label") - This will look for a child of TR with class label. Your HTML, shows that this resides inside td. If all the label elements have class label, you can refer each by -
$(".label).each(function(){
//do whatever you want
});
To get the element type next to the label with class label -
$(".label).each(function(){
var NextTd = $(this).parent().next(); // refers to the next td
$(NextTd).each(function(){
var type = $(this).find('input').prop('tagName');
//do whatever you want
});
});

Categories

Resources