add input fields dynamically with codeigniter - javascript

I'm trying to add dynamically input fields in Codeigniter when the user clicks the link but it doesn't seem to work. It will be really helpful if someone can figure it out.
My JS code is:
<script src="js/jquery.js" type="text/javascript">
var count = 1;
jQuery(document).ready(function() {
$('p#add_field').click(function(){
count += 1;
$('#language').append(
'<strong>Language #' + count + '</strong><br />'
+ '<input id="language' + count + '"name="languages[]' + '" type="text" /><br />' );\
});
});
</script>
And my form code is:
<div id="container">
some code
<div id="body">
some more code
<div id="language">
<p id="add_field">Προσθηκη Γλώσσας</p>
</div>
</div>
</div>

var count = 1;
$('p#add_field').click(function(){
count += 1;
var html='<strong>Language #'+ count +'</strong><br />'+'<input id="language'+ count +'"name="languages[]'+'" type="text" /><br />';
$('#language').prepend(html);
});
remove all the spaces in appending html . javascript gives Unterminated String literal errors
fiddle

Related

Loop error on <fieldset> tags - inserting closing tag before it should

As part of a web app I'm building in Google Apps Script, I'm trying to create a checkbox field that shows one checkbox for each learner/student, arranged in rows of 3. The learner data is being taken from a spreadsheet (this bit is working fine).
I want the checkboxes to look like this:
image of 6 checkboxes, in 2 rows of 3
The problem I am having is that my code is inserting the closing fieldset tag in the wrong place (too early) and so the checkboxes don't look right (I'm using the jquery mobile 1.4.5 framework).
I've been staring at the code and tinkering with it for hours, I'm hoping it's something simple I just can't see and hoping someone can help me fix it.
The code I am using is basically a nested loop - the outer loop should create the fieldset tags for each row, and the inner loop should create each checkbox. My code is as follows:
First the container div
<div id="learners">Loading...</div>
The javascript to grab the data and replace the container div above with it...
// The code in this function runs when the page is loaded.
$(function() {
google.script.run.withSuccessHandler(showLearners)
.getLearnerData();
});
function showLearners(learners) {
var learnerCheckboxes = $('#learners');
learnerCheckboxes.empty();
var cols=['a','b','c'];
for (var i = 0; i < learners.length; i++) {
learnerCheckboxes.append("<fieldset class=\"ui-grid-b\">");
for (var j = 0; j < 3; j++) {
learnerCheckboxes.append(
"<div class=\"ui-block-" + cols[j] + "\">" +
"<input type=\"checkbox\" name=\"learner\" id=\"learner" + i + "\" data-mini=\"true\">" +
"<label for=\"learner" + i + "\">" + learners[i][0] + "</label>" +
"</div>"
);
i++
}
learnerCheckboxes.append("</fieldset>");
}
}
The problem is, when the code runs, the closing </fieldset> is inserted too early... here's the output from this code:
<div id="learners">
<fieldset class="ui-grid-b">
</fieldset><!-- THIS IS THE PROBLEM - IT SHOULD BE AT THE BOTTOM OF THIS GROUP?-->
<div class="ui-block-a">
<input type="checkbox" name="learner" id="learner0" data-mini="true">
<label for="learner0">David</label>
</div>
<div class="ui-block-b">
<input type="checkbox" name="learner" id="learner1" data-mini="true">
<label for="learner1">Dominic</label>
</div>
<div class="ui-block-c">
<input type="checkbox" name="learner" id="learner2" data-mini="true">
<label for="learner2">Eliza</label>
</div>
<fieldset class="ui-grid-b">
</fieldset><!-- THIS SHOULD BE AT THE BOTTOM OF THIS GROUP-->
<div class="ui-block-a">
<input type="checkbox" name="learner" id="learner4" data-mini="true">
<label for="learner4">Francois</label>
</div>
<div class="ui-block-b">
<input type="checkbox" name="learner" id="learner5" data-mini="true">
<label for="learner5">James</label></div>
<div class="ui-block-c">
<input type="checkbox" name="learner" id="learner6" data-mini="true">
<label for="learner6">Louise</label>
</div>
</div>
It took a lot of trial and error because I don't use jquery. I do it the old fashion way. But I finally got it to work. You can play with the CSS to get it to look like you want.
HTML_Test.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<div id="learners">Loading...</div>
<script>
(function() {
google.script.run.withSuccessHandler(showLearners).getLearnerData();
})();
function showLearners(learners) {
var learnerCheckboxes = $('#learners');
learnerCheckboxes.empty();
var cols=['a','b','c'];
let i = 0;
while( i < learners.length ) {
let id = "fieldset"+i;
let fieldset = $('<fieldset class="ui-grid-b" id="'+id+'"></fieldset>')
learnerCheckboxes.append(fieldset);
for (var j = 0; j < 3; j++) {
let div = $('<div class="ui-block-' + cols[j] + '"></div>')
fieldset.append(div);
id = "learner"+i;
let input = $('<input type="checkbox" name="learner" id="' + id + '" data-mini="true">');
let label = $('<label for="' + id + '">' + learners[i][0] + '</label>' );
div.append(input);
div.append(label);
i++;
if( i === learners.length ) break;
}
}
}
</script>
</body>
</html>
Code.gs
function getLearnerData() {
try {
Logger.log("In getLearnerData");
return [["Dave"],["Tom"],["Larry"],["Mary"],["Joe"],["Sam"],["John"]];
}
catch(err) {
Logger.log("Error in getLearnerData: "+err);
}
}
Results
Thanks TheWizEd for the idea to dynamically name the fieldset tags - this is what lead to the solution. By dynamically creating the fieldset ID, I can use the inner loop to append the checkboxes BETWEEN the fieldset tags. Here's the code:
function showLearners(learners) {
var learnerCheckboxes = $('#learners');
learnerCheckboxes.empty();
var cols=['a','b','c'];
var rowCount = 1;
for (var i = 0; i < learners.length; i++) {
//in this next line, use rowCount to create a unique fieldset id
learnerCheckboxes.append("<fieldset class=\"ui-grid-b\" id=\"checkRow" + rowCount + "\"></fieldset>");
//then grab it
var checkRow = $("#checkRow" + rowCount)
for (var j = 0; j < cols.length; j++) {
//and append the checkboxes to the newly created fieldset
checkRow.append(
"<div class=\"ui-block-" + cols[j] + "\">" +
"<div class=\"ui-checkbox ui-mini\">" +
"<label for=\"learner" + i + "\" class=\"ui-btn ui-corner-all ui-btn-inherit ui-btn-icon-left ui-checkbox-off\">" +
learners[i][0] + "</label>" +
"<input type=\"checkbox\" name=\"learner\" id=\"learner" + i + "\" data-mini=\"true\">" +
"</div>" +
"</div>"
);
i++;//we're in the inner loop, so have to manually increment i
}
rowCount++;
}
}

Remove input field with span

I written this code for creating new input fields, and i need to somehow modify it so i can remove the fields. I tought about adding var counter to mySpan and then i make$(#removeBox).click(function() and there i can get an id of the input field i need to delete. But i cannot make span clickable, and when I try to do it with like this <a class="deleteBox' + counter'"><span class="glyphicon glyphicon-remove"></span></a> It says that I am missing ). I know there are some solutions on this problem here, but i wanted to make mine work.
var counter = 2;
$("#addTextField").click(function() {
var newTextBoxDiv = $(document.createElement('div')).attr("id", 'textboxdiv'+counter);
newTextBoxDiv.after().html('<input type="text" name="textbox' + counter + '" placeholder="Category" /><span id="mySpan" class="glyphicon glyphicon-remove"></span>');
newTextBoxDiv.appendTo("#textboxgroup");
counter++;
});
try like this: The trick is to remove the element you clicked on which you can get with $(this) inside the click
var counter = 0;
$("#addTextField").on('click', function() {
var newTextBoxDiv = $(document.createElement('div')).attr("id", 'textboxdiv'+counter);
newTextBoxDiv.after().html('<div class="wrapper">' + counter + '<input type="text" name="textbox' + counter + '" placeholder="Category" /><span class="glyphicon glyphicon-remove">remove</span></div>');
newTextBoxDiv.appendTo("#textboxgroup");
counter++;
});
$('body').on('click', '.glyphicon-remove', function(){
$(this).closest('.wrapper').remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="addTextField">click to add</div>
<div id="textboxgroup"></div>
In your code you added an ID <span id="mySpan" on every click which is bad cause an ID should always be unique. So if you add it more than once it is not unique anymore. Better use classes instead...
try this:
var counter = 0;
$('#add').click(function() {
$('#target').append('<span>New Input: <input type="text"><button id="remove' + counter + '">Remove</button><br></span>');
$('#remove' + counter).click(function() {
$(this).parent().html('');
counter--;
});
counter++;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<button id="add">Add</button>
<div id="target"></div>

Display one text field on click from a set number of text fields

I have a form where users have 10 text fields. But initially only 1 text field is shown. If the user needs to enter more data they can click on the add one button and then displays the next text field from the maximum of 10.
like so:
Im working with angular.js so I thought about using ng-show to hide & show fields.
<div class="form-group">
<input type="text" class="form-control" name="pointOne" ng-show="pointOne">
<input type="text" class="form-control" name="pointTwo" ng-show="pointTwo">
<input type="text" class="form-control" name="pointThree" ng-show="pointThree">
<span><button ng-click="addOne()">Add One</button></span>
</div>
I am unable to figure out the most effective way to doing this. Any hints, help or suggestions would be great.
Haven't tested it but this is how I would do it:
<div class="form-group" >
<input ng-repeat="i in getNumber(number)" type="text" class="form-control" name="point{{i}}" ng-show="$index<=counter">
<span><button ng-click="addOne()">Add One</button></span>
</div>
And in your controller just add something like this:
$scope.number = 10;
$scope.getNumber = function(num) {
return new Array(num);
}
$scope.counter=0;
$scope.addOne= function() {
$scope.counter++;
}
You could easily add elements to the DOM:
function createPetField() {
var input = document.createElement('input');
input.type = 'text';
input.name = 'pet[]';
return input;
}
var form = document.getElementById('myForm');
document.getElementById('addPet').addEventListener('click', function(e) {
form.appendChild(createPetField());
});
To go the Angular route, I'd suggest using ng-repeat. Here's a fiddle that might not be exactly what you're looking for, but it shows how to use ng-repeat and you can modify as needed:
Fiddle: https://jsfiddle.net/jvsnao97/5/
<body ng-app="myApp" ng-controller="myController">
<button ng-click="add_input()">Add Input</button>
<br/><br/>
<input type="text" class="form-control" ng-repeat="x in random_array" name="point{{$index}}">
</body>
var app = angular.module("myApp", []);
app.controller("myController", ["$scope", function($scope) {
$scope.random_array = [0]
$scope.add_input = function() {
var i = $scope.random_array.length
$scope.random_array.push(i)
}
}]);
When you want a new <input>, you simply push a new element to $scope.random_array.
Probably good way is to make array of input fields and then ng-repeat them. When user clicks on AddOne, then just push input field in array, and it will be there.
<html>
<head>
<title>jQuery add / remove textbox</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<style type="text/css">
div{
padding:8px;
}
</style>
</head>
<body>
<h1>jQuery add / remove textbox example</h1>
<script type="text/javascript">
$(document).ready(function(){
var counter = 2;
$("#addButton").click(function () {
if(counter>10){
alert("Only 10 textboxes allow");
return false;
}
var newTextBoxDiv = $(document.createElement('div'))
.attr("id", 'TextBoxDiv' + counter);
newTextBoxDiv.after().html('<label>Textbox #'+ counter + ' : </label>' +
'<input type="text" name="textbox' + counter +
'" id="textbox' + counter + '" value="" >');
newTextBoxDiv.appendTo("#TextBoxesGroup");
counter++;
});
$("#removeButton").click(function () {
if(counter==1){
alert("No more textbox to remove");
return false;
}
counter--;
$("#TextBoxDiv" + counter).remove();
});
$("#getButtonValue").click(function () {
var msg = '';
for(i=1; i<counter; i++){
msg += "\n Textbox #" + i + " : " + $('#textbox' + i).val();
}
alert(msg);
});
});
</script>
</head><body>
<div id='TextBoxesGroup'>
<div id="TextBoxDiv1">
<label>Textbox #1 : </label><input type='textbox' id='textbox1' >
</div>
</div>
<input type='button' value='Add Button' id='addButton'>
<input type='button' value='Remove Button' id='removeButton'>
<input type='button' value='Get TextBox Value' id='getButtonValue'>
</body>
</html>
JQuery can be used to add inputs in your addOne() method.
Like so:
var maxInputs = 10;
var currentInput = 0;
function addOne() {
currentInput++;
if (currentInput > maxInputs) {
currentInput = maxInputs;
return;
}
var name = "point" + currentInput;
var $input = $("<input type='text' class='form-control' name='" + name + "' ng-show='" + name + "'>");
$(".form-group").append($input);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-group">
<span><button onclick="addOne()">Add One</button></span>
</div>

How to add a new textfield on clicking a button?

I'm trying to insert certain sentences to MySQL database using PHP. But the design of the field is such a way that it shows only one field and a [add] button to insert a new textfield. So depending on the user needs, the number of textfields varies.
<div class="row">
<h5>LEARNING GOALS</h5>
<div style="display:table; width:100%;">
<div style="display:table-row;">
<div style="display:table-cell;">
<input class="text-field" name="goal" type="text" placeholder="Goals*" style="width:100%">
</div>
<div style="display:table-cell; vertical-align:middle;width:65px;">
<input class="add-field-btn" type="button" value="+" style="width:65px;"></div>
</div>
</div>
</div>
How can I add a new textfiled and assign name value and when I click on the submit button, to save all the textfield values into the database?
<html>
<head>
<title>jQuery add / remove</title>
<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>
<style type="text/css">
div{
padding:8px;
}
</style>
</head>
<body>
<h1>jQuery add / remove </h1>
<script type="text/javascript">
$(document).ready(function(){
var counter = 2;
$("#addButton").click(function () {
if(counter>10){
alert("Only 10 textboxes allow");
return false;
}
var newTextBoxDiv = $(document.createElement('div'))
.attr("id", 'TextBoxDiv' + counter);
newTextBoxDiv.after().html('<label>Textbox #'+ counter + ' : </label>' +
'<input type="text" name="textbox' + counter +
'" id="textbox' + counter + '" value="" >');
newTextBoxDiv.appendTo("#TextBoxesGroup");
counter++;
});
$("#removeButton").click(function () {
if(counter==1){
alert("No more textbox to remove");
return false;
}
counter--;
$("#TextBoxDiv" + counter).remove();
});
$("#getButtonValue").click(function () {
var msg = '';
for(i=1; i<counter; i++){
msg += "\n Textbox #" + i + " : " + $('#textbox' + i).val();
}
alert(msg);
});
});
</script>
</head><body>
<div id='TextBoxesGroup'>
<div id="TextBoxDiv1">
<label>Textbox #1 : </label><input type='textbox' id='textbox1' >
</div>
</div>
<input type='button' value='Add Button' id='addButton'>
<input type='button' value='Remove Button' id='removeButton'>
<input type='button' value='Get TextBox Value' id='getButtonValue'>
</body>
</html>
First of all use your text field name as a array so when user will add new text field you can get all of them in just one post variable and you can store them in different row or as you want.
Now on click on you button append text field with same name as
your first field code:<input class="text-field" name="goal[]" type="text" placeholder="Goals*" style="width:100%">
Javascript code: $('#yourselector').append('<input class="text-field" name="goal[]" type="text" placeholder="Goals*" style="width:100%">');
It the server end you can get all the posted values in $_POST['goal'] which will be a array;
Demo Check this fiddle.
document.getElementById('#whereToAppend').append('<input type="text" name="WhateverYouwant"/>');
document.getElementsByTagName('body')[0].appendChild('<input type="text"/>');
If you want dynamic names, set a class name or id to the input. And make use of setAttribute in javascript to set the name
One solution would be to try and serialize all the inputs and save them to the database. You just send them by submitting the form then in PHP do something like:
$inputs = serialize($_GET); // $inputs = serialize($_POST);
mysql_query('INSERT INTO `table` SET inputs = "'.$inputs.'"'); // try to validate the variable before
This would be nice given the fact that you have variable number of fields.
When you select them use deserialize to recreate the data:
$r = mysql_query('SELECT inputs FROM `table`');
...
$data = deserialize($row['inputs']);
Another option would be to get all the inputs with JavaScript or jQuery and pass them via AJAX.
var _data = [];
$('input.text-field').each(function(i, e) {
_data.push($(e).val());
});
$.post('file.php', { d : JSON.stringify(_data)}, function(e){
alert(e);
})
PHP:
$d = json_decode($_POST['d']);
foreach($d as $k => $v) {
// value of the input no. $k is $v
}
You can use #Nickunj's jQuery code for appending the new input.

Jquery - dynamically added input field doesn't send value to post

I have this particular jquery code to add/remove fields on a form and then send its values:
$(document).ready(function() {
$("#add").click(function() {
var intId = $("#reglas div").length + 1;
var fieldWrapper = $('<div class="fieldwrapper" id="field' + intId + '"/>');
var fName = $('<input align="left" type="text" placeholder="Path" class="reglas_wrapper" id="path" name="field1_' + intId + '" required /> ');
var fName2 = $('<input type="text" class="reglas_wrapper" placeholder="TTL" id="ttl" name="field2_' + intId + '" required />');
var removeButton = $('<input align="right" type="button" id="del" class="remove" value="-" /> <br><br>');
removeButton.click(function() {
$(this).parent().remove();
});
fieldWrapper.append(fName);
fieldWrapper.append(fName2);
fieldWrapper.append(removeButton);
$("#reglas").append(fieldWrapper);
});
$("#cache").each(function() {
$(this).qtip({
content: {
text: $(this).next('.tooltiptext')
}
});
});
});
$('#formsite').on('submit', function (e) {
//prevent the default submithandling
e.preventDefault();
//send the data of 'this' (the matched form) to yourURL
$.post('siteform.php', $(this).serialize());
});
In which you can add/remove fields on the Cache section but the form sends every value except those which were added dynamically.
How can I solve it? You can see the posted form data with Firebug.
Here is a JS Fiddle for you: http://jsfiddle.net/34rYv/121/
Also I realized that when I delete fields, its name doesn't rename.
Maybe you can help me with this too :)
Thanks in advance
Nicolas
Your Cache section stands outside the <form> tags as i see in the source code, so that could be why your fields are not submitted.
Put your form around the left/right div like this:
<div id="wrapper" align="center">
<div class="container" align="center">
<form id="formsite"> // your form starts here
<div id="left">
</div>
<div id="right">
</div>
</form>
</div>
</div>
Instead of this ( what you have right now ):
<div id="wrapper" align="center">
<div class="container" align="center">
<div id="left">
<form id="formsite"> // your form starts here
// the form will automatically be closed in this div
</div>
<div id="right">
</form> // this one will go away
</div>
</div>
</div>
Also, try to keep your code clean, For example:
var fieldWrapper = $('<div></div>',{
class: 'fieldwrapper',
id: 'field'+intId
});
This is way cleaner than:
var fieldWrapper = $('<div class="fieldwrapper" id="field' + intId + '"/>');

Categories