I try to make a dynamic input form group to add extra rows.
Adding rows in the input group works!
Now I would like to send a variable back with the number of rows.
I have a working for loop that counts the rows. But the variable stays the same.
$(document).ready(function(){
var max_fields = 16;
var add_input_button = $('.add_input_button');
var field_wrapper = $('.field_wrapper');
var input_count = 4;
var new_field_html = // html code with input_count(works but stays on 4)
// Add button dynamically
$(add_input_button).click(function(){
if(input_count < max_fields){
input_count++;
console.log(input_count);
$(field_wrapper).append(new_field_html);
}
});
I can see in my console log the correct loop!
How can I change the code to update the input_count on return value?
screenshot of the problem
You should move this line within the click event, as this line gets called only once on page load. So to use the input_count incremented value within the new field, it should also be formed every time the click is performed.
var new_field_html = // html code with input_count(works but stays on 4)
Here I have designed a rough page what you are trying to achieve, please read out the comments to understand.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>The HTML5 Herald</title>
</head>
<body>
<form>
<div class="field_wrapper">
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email">
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<button type="button" class="btn btn-primary add_input_button">Submit</button>
</div>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
var max_fields = 16;
var add_input_button = $('.add_input_button');
var field_wrapper = $('.field_wrapper');
var input_count = 4;
// html code with input_count(works but stays on 4)
console.log("Outside ======> " + input_count); // Executes only on page load
// Add button dynamically
$(add_input_button).click(function(){
if(input_count < max_fields){
input_count++;
var new_field_html = '<div class="form-group"><button type="button" class="btn btn-primary" class="add_input_button">Submit-' + input_count + '</button></div>';
$(field_wrapper).append(new_field_html);
console.log("Inside ======> " + input_count); // Executed everytime the button is clicked
}
});
console.log("Outside-2 ======> " + input_count); // Executed only on page load
});
</script>
</body>
</html>
Related
I created a sidebar for a Google Document that takes in user input. I'd like to use the collected data to update some fields on my document, but for now, I am just trying to display the data collected on screen via an alert to test if my code is working. Unfortunately, I am stuck and not sure what I am doing wrong.
There are two problems I am running into, but due to my limited knowledge of app script and coding as a whole, I just can't seem to resolve my issue. The problems I am having are, 1) my eventListener may not be be firing and 2) I can't seem to access the data collected from the input boxes.
Could someone assist me with this problem? I've been searching through the forum for an answer for a few days now, but again, my knowledge is very limited so it's possible I've come across the answer a few times, but just don't understand it. The code I am using is below and a link to my document is here.
App Script Code:
function onOpen() {
// Add a custom menu to the document.
var ui = DocumentApp.getUi(); // Or SpreadsheetApp or SlidesApp or FormApp.
ui.createMenu('Menu')
.addItem('Sidebar', 'showSidebar')
.addToUi();
}
function showSidebar() {
// Create HTML template from a file
var html = HtmlService.createHtmlOutputFromFile('userform')
.setTitle("TEST FORM")
.setWidth(300);
DocumentApp.getUi()
.showSidebar(html);
}
function appendData(data) {
DocumentApp.getUi().alert(data.f + ' ' + data.l);
}
HTML code
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<div class="container">
<div>
<input id="firstName" type="text" name="firstName" placeholder="Enter first name">
</div>
<div>
<input id="lastName" type="text" name="lastName" placeholder="Enter last name">
</div>
<div>
<input type="button" value="SUBMIT" onClick="submitData();"/>
</div>
</div> <!-- End of container div -->
<script>
function submitData() {
var fName = document.getElementById('firstName').value;
var lName = document.getElementById('lastName').value;
var data {
f: fName,
l: lName
};
google.script.run.appendData(data);
}
</script>
</body>
</html>
Try this:
function submitData() {
var first=document.getElementById('firstname').value;
var last=document.getElementById('lastname').value;
var data={f:first,l:last};
google.script.run.appendData(data);
}
for simplicity you could also change this <button id="btn">Submit</button>
to this <input type="button" value="Submit" onClick="submitData();" />
I'm not really sure the best way to go about this but I've laid the framework.
Basically, I would like to add the functionality so that when my #moreItems_add button is clicked and calls the moreItems function, I simply want to add a new Input field below it, and so on. I want to limit this to 10 fields though, so I show that in the function.
The only trick is, I will be submitting all fields via ajax to save to the database, so I need to try and keep track of an ID with each.
What's the best way to continue the javascript here so that I can append an input field on button press and keep track of IDs for each?
<div class="modal-body">
<form id="Items">
<label id="ItemLabel">Item 1:</label>
<input type="text" name="Items[]">
<button id="moreItems_add" onclick="moreItems()" id="moreItems">More Items</button>
</form>
</div>
<div class="modal-footer">
<input type="submit" name="saveItems" value="Save Items">
</div>
<!-- modal JS -->
<script type="text/javascript">
function moreItems(){
var MaxItems = 10;
//If less than 10, add another input field
}
</script>
You can use the jQuery .insertBefore() method to insert elements right before "more items" button. Below is the code representing this:
var maxItems = 1;
function moreItems() {
if (maxItems < 10) {
var label = document.createElement("label");
label.id="ItemLabel"+maxItems;
label.innerHTML = "Item "+(maxItems+1)+": ";
var input = document.createElement("input");
input.type='text';
input.name = 'item'+maxItems;
$('<br/>').insertBefore("#moreItems_add");
$(label).insertBefore("#moreItems_add");
$(input).insertBefore("#moreItems_add");
maxItems++;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="modal-body">
<form id="Items">
<label id="ItemLabel">Item 1:</label>
<input type="text" name="Items[]">
<button type="button" id="moreItems_add" onclick="moreItems()" id="moreItems">More Items</button>
</form>
</div>
<div class="modal-footer">
<input type="submit" name="saveItems" value="Save Items">
</div>
Something like this should do the trick:
<!-- modal JS -->
<script type="text/javascript">
var MAX_ITEMS = 10,
added = 0;
function moreItems(){
if (added >= MAX_ITEMS) return;
var newField = document.createElement('input');
newField.type = 'text';
// TODO: Any field setup.
document.getElementById('items').appendChild(newField);
added++;
}
</script>
In terms of tracking each field with an ID, that should always be done by the back-end for data integrity and safety reasons.
some years ago I've wrote an article about making a repeated section using jQuery.
The live example is available on jsFiddle.
In the example you can find that both "add" and "remove" button are available, however you can set just the "add" button for your purpose.
The idea to limit to specific number of repeated boxes is to watch the number of repeatable elements just created in the context. The part of code to change in the live example is rows 13-18:
// Cloning the container with events
var clonedSection = $(theContainer).clone(true);
// And appending it just after the current container
$(clonedSection).insertAfter(theContainer);
There you should check if the number of repeated elements is less than <your desired number> then you will allow the item to be created, else you can do something else (like notice the user about limit reached).
Try this:
const maxItens = 10,
let itensCount = 0;
function moreItems() {
if (itensCount++ >= maxItens) {
return false;
}
let newInput = document.createElement('input');
// use the iterator to make an unique id and name (to submit multiples)
newInput.id = `Items[${itensCount}]`;
newInput.name = `Items[${itensCount}]`;
document.getElementById('items').appendChild(newInput);
return false;
}
Add type "button" to stop submiting the page (also, your button have two ID):
<button id="moreItems_add" onclick="moreItems();" type="button">More Items</button>
The submit button must be inside the form to work:
<form>
<div class="modal-body">
<div id="Items">
<label id="ItemLabel">Item 1:</label>
<input type="text" name="Items[]">
</div>
<button id="moreItems_add" onclick="moreItems()" id="moreItems">More Items</button>
</div>
<div class="modal-footer">
<button type="submit">Save Items</button>
</div>
</form>
To append itens in sequence the button must be outside of div "itens".
i found this tutorial, where they explain very well how to add dynamic inputs, however, if the submit button is clicked, this does not filter the empty values from the inputs. The idea is to filter those empty values before sending them to the server, some idea?
http://www.codexworld.com/add-remove-input-fields-dynamically-using-jquery/
The code:
<?php
if(isset($_REQUEST['submit'])){
$field_values_array = $_REQUEST['field_name'];
print '<pre>';
print_r($field_values_array);
print '</pre>';
foreach($field_values_array as $value){
//your database query goes here
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Add more fields using jQuery</title>
<script src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var maxField = 10; //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[]" value=""/><img src="remove-icon.png"/></div>'; //New input field html
var x = 1; //Initial field counter is 1
$(addButton).click(function(){ //Once add button is clicked
if(x < maxField){ //Check maximum number of input fields
x++; //Increment field counter
$(wrapper).append(fieldHTML); // Add field html
}
});
$(wrapper).on('click', '.remove_button', function(e){ //Once remove button is clicked
e.preventDefault();
$(this).parent('div').remove(); //Remove field html
x--; //Decrement field counter
});
});
</script>
</head>
<body>
<form name="codexworld_frm" action="" method="post">
<div class="field_wrapper">
<div>
<input type="text" name="field_name[]" value=""/>
<img src="add-icon.png"/>
</div>
</div>
<input type="submit" name="submit" value="SUBMIT"/>
</form>
</body>
</html>
One way would be remove the empty inputs within a submit event handler
$('form[name=codexworld_frm']).submit(function(){
$(this).find('input').filter(function(){
return !this.value;
}).remove();
})
From reading your comments, you are trying to validate existing Dom elements and elements that you add dynamically and the problem is that the added elements aren't hitting your validation code?
If so, try attaching the validator using delegate instead of however you are currently doing it
http://api.jquery.com/delegate/
This allows for elements added to the Dom to behave how you expect.
I'm trying to add the rows dynamically plus auto-increment of a counter.I want to start with 1 then 2 then 3 and so on . I have added my code on plunker ,in which every time the max value is getting in first column like 4 then 1,1,2,3.Where am i going wrong ?i Want it to be 1,2,3,4.
Here is the plunker link http://plnkr.co/edit/GuDbJ3SHOPvWkHfNfd8E?p=preview
var _counter = 0;
function Add() {
_counter++;
var oClone = document.getElementById("template").cloneNode(true);
oClone.id += (_counter + "");
document.getElementById("placeholder1").appendChild(oClone);
document.getElementById("myVal").value=_counter;
}
<div id="placeholder1">
<div id="template">
<div>
Value:<input type="text" id="myVal" placeholder="1">
Quantity:<input type="text" placeholder="Qty">
<input type="button" onClick="Add()" value="Click! ">
</div>
</div>
I think it is because you have multiple divs with the id="myVal". The id attribute should be unique on the page. If not, your page will still load, but you may have unexpected behavior.
You are changing the id of the template div, but not the myVal div.
I assume you are looking for something like this:
var _counter = 0;
function Add() {
_counter++;
var oClone = document.getElementById("template").cloneNode(true);
oClone.id += (_counter + "");
document.getElementById("placeholder1").appendChild(oClone);
oClone.getElementsByClassName("myVal")[0].value = _counter;
}
<div id="placeholder1">
<div id="template">
<div>
Value:
<input type="text" class="myVal" placeholder="1">Quantity:
<input type="text" placeholder="Qty">
<input type="button" onClick="Add()" value="Click! ">
</div>
</div>
</div>
In your original you are cloning your template with the same id for the input. So when you do document.getElementById("myVal").value=_counter;, you only get the first input. I changed it to use class instead and get the input with the appropriate class that is a child of the cloned node.
Maybe I've been working on my site for to long, but I can't get the following to work. I am having my textarea fire an onkeyup() event called limiter which is supposed to check the textarea and limit the text in the box, while updated another readonly input field that shows the amount of characters left.
This is the javascript code:
<script type="text/javascript">
var count = "500";
function limiter(){
var comment = document.getElementById("comment");
var form = this.parent;
var tex = comment.value;
var len = tex.length;
if(len > count){
tex = tex.substring(0,count);
comment.value =tex;
return false;
}
form.limit.value = count-len;
}
</script>
The form looks like this:
<form id="add-course-rating" method="post" action="/course_ratings/add/8/3/5/3"
accept- charset="utf-8"><div style="display:none;"><input type="hidden"
name="_method" value="POST" />
//Other inputs here
<div id="comment-name" style="margin-top:10px">
<div id="comment-name-text">
<b>Comments</b><br />
Please leave any comments that you think will help anyone else.
</div>
<style type="text/css">
.rating-form-box textarea {
-moz-border-radius:5px 5px 5px 5px;
}
</style>
<div class="rating-form-box">
<textarea name="data[CourseRatings][comment]" id="comment"
onkeyup="limiter()" cols="115" rows="5" ></textarea>
<script type="text/javascript">
document.write("<input type=text name=limit size=4
readonly value="+count+">");
</script>
</div>
<input type="submit" value="Add Rating" style="float: right;">
</form>
If anyone can help that would be great.
You have:
onkeyup="limiter()"
Since you aren't calling limiter in the context of an object, you are calling window.limiter.
var form = this.parent;
So this is window and form is window.parent, which is the same as window (unless the document is loaded in a frame).
You want to make this the form control. Do this using event binding in unobtrusive JavaScript.
(And don't use an input as an element solely for displaying output, it does not make sense. You probably want to use a label associated with the textarea … and to use another label for <b>Comments</b><br />Please leave any comments that you think will help anyone else.)
Would this work for your? Example Link
EDIT:
You should pass the element instance with the function call onkeyup="limiter(this)" this way in your function you'll have a reference to the object that called this function, now your function will be something like:
function limiter(a) {
var comment = a;
var form = document.getElementById('add-course-rating');
var tex = comment.value;
var len = tex.length;
if (len > count) {
tex = tex.substring(0, count);
comment.value = tex;
return false;
}
form.limit.value = count - len;
}
Also no need to create element dynamically if you don't really need that! so just set the value of the readonly with Javascript:
<input type="text" name="limit" id="limit" size="4" readonly value="">
<script type="text/javascript">
var limit = document.getElementById('limit');
limit.value = count;
</script>
And you are good to go!