I have seen the example on w3schools that shows how to toggle the visibility on a text/password input.
I would like to have something very similar but it would be one checkbox that can toggle several text inputs that are added in dynamically.
Something like the following:
Note that the code below isn't going to work. It is here to give an example of my situation. I am wondering how to adapt the code seen on the link so I have used the same names as the example on w3schools
HTML
<div class="container_home">
<form id="inputFrm_h" class="inputFrm_home" method="post">
<input type="text" name="env_name[]" /> =
<input type="password" name="env_contents[]" id="myInput"/>
<button class="add_form_field_home">Add</button>
<input type="checkbox" onclick="myFunction()"/>
</form>
</div>
JavaScript
$(document).ready(function(){
var wrapper_home = $(".container_home");
var add_button_home = $(".add_form_field_home");
var y = 1;
$(add_button_home).click(function(e){
e.preventDefault();
console.log('we here');
y++;
$('.inputFrm_home').append('<div><input type="text" name="env_name[]"/> =
<input type="password" name="env_contents[]" class="myInput"/>
Delete<br></div>'); //add input box
});
$(wrapper_home).on("click",".delete", function(e){
e.preventDefault(); $(this).parent('div').remove(); y--;
})
});
I would use an array to store these input elements and when you click the add button it will create and add the new input on the page and in the array. Then when you click the checkbox it will execute a for loop, which will then run through your array and change the type from password to text (making it the letters visible).
http://jsbin.com/risayiquha/edit?html,js,output
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id="inputs">
</div>
<button onclick="createInput();">Add Input</button>
<input type="checkbox" onclick="changeValues(this);">
</body>
</html>
JavaScript
var inputList = [];
function createInput() {
var input = document.createElement('input');
input.setAttribute('type', 'password');
document.getElementById('inputs').appendChild(input);
inputList.push(input);
}
// This will essentially just create an input in whatever container you specify and also push the DOM element into an array.
function changeValues(checkbox) {
if (checkbox.checked) {
for (var i = 0; i < inputList.length; i++) {
inputList[i].type = 'text';
}
} else {
for (var i = 0; i < inputList.length; i++) {
inputList[i].type = 'password';
}
}
}
// This just changes the type from text to password for every element
// in the array based on if the checkbox is checked or not.
It looks like you are using jQuery, so you can use that to select elements you want to work with, whether it's one or many.
In your case, $('.inputFrm_home div') will select all div elements that have been appended within the .inputFrm_home element. Which means $('.inputFrm_home div').remove() will remove all matching elements.
Add your Remove All link to the html:
<div class="container_home">
<form id="inputFrm_h" class="inputFrm_home" method="post">
...
</form>
Remove new fields
</div>
Then a click handler for the new link:
$(document).ready(function(){
...
$('.container_home').on('click', '.remove-new-fields', function (e) {
e.preventDefault();
$('.inputFrm_home div').remove();
});
});
Or if you want to use a checkbox to toggle the new fields instead of the link, you can use something like
$('.my-toggle-checkbox').on('change', function (e) {
if($(this).prop('checked')) {
// checkbox is checked
}
else {
// checkbox is not checked
}
})
Related
I'm trying to create a script that keeps our main button disabled until specific field requriments are met.
jQuery(document).ready(function() {//check if all are filled else disable submit
var inputFields = jQuery('#list-item-cc input, #field_28_50 input,#field_28_18 input');
inputFields.keyup(function() {
var empty = false;
inputFields.each(function() {
if (jQuery(this).val().length == 0) {
empty = true;
}
});
if (empty) {
jQuery('#gform_submit_button_28').attr('disabled', 'disabled');
} else {
jQuery('#gform_submit_button_28').removeAttr('disabled');
}
I'm having trouble thinking of a way to ensure my inputFields variable can be passed to my inputFields.each(function() in a way that would allow the loop.
We're not worried about all input fields. Just the specific inputs in our inputFields variable.
Is this an effective way to ensure a button is disabled if certain fields are not filled out and can I create the selector in the way that i did and use that in an each statement?
Looks like you are using gravity forms? In that case I would add a css class to each field that you want to validate. That way you don't have to go searching for ID's and change the code for multiple forms.
https://docs.gravityforms.com/css-ready-classes/
Here is a fiddle in which I pretend that I added "ensure-filled" to each item in the gravity forms builder
https://jsfiddle.net/dokLz4hm/3/
Also note that I added a .trim() to the value so that blank spaces aren't counted as input and made the submit button generic so it would work with any field in a form that contains the ensure-filled class
Html
<div>
<div id="arbitraty_id_1">
<input type="text" class="ensure-filled" />
</div>
<div id="arbitraty_id_2">
<input type="text" class="ensure-filled" />
</div>
<div id="arbitraty_id_3">
<input type="text" class="ensure-filled" />
</div>
<input type="submit" value="submit" disabled>
</div>
JS
$(document).ready(function() {
var inputFields = $('.ensure-filled');
inputFields.keyup(function() {
var empty = false;
inputFields.each(function() {
if ($(this).val().trim().length == 0) {
empty = true;
}
});
$('input[type="submit"]').attr('disabled', empty);
})
})
I am working on a attendance module and this is the prototype of the code, but I have some errors.
As you can see there are dynamically generated buttons and they change colour on click event. I am also storing the value of the buttons in textboxes on click as I have to handle this data on backend with PhP, the error is that when I turn a button to green it's value goes into a textbox and when again i turn it red same value goes into another textbox also, which I don't want. So please help me in solving this problem by reducing the duplicacy of data or by providing a code of a different submit button which when clicked checks the color of all the buttons and stores the values in different textboxes respectively, one for red and one for green. Thanks in advance.
<html>
<head>
<title>Button click event</title>
</head>
<body>
<?php
for($i=0;$i<=10;$i++) {
?>
<button class="btnColorChange" id="<?php echo $i; ?>" style="background-color:#FF0000"><?php echo $i; ?></button>
<?php
}
?>
<div>
<input type="text" name="text1" id="textbox1" value=""/><br><br>
<input type="text" name="text2" id="textbox2" value=""/><br><br>
</div>
<script>
$(".btnColorChange").click(function(){
xyz = this.id
if(this.clicked){
$(this).css('background-color', '#FF0000');
const tb=document.querySelector("#textbox1");
tb.value=tb.value+","+xyz;
console.log(xyz)
this.clicked = false;
} else {
$(this).css('background-color', '#008000');
const tb2=document.querySelector("#textbox2");
tb2.value=tb2.value+","+xyz;
console.log(xyz)
this.clicked = true;
}
});
</script>
</body>
</html>
First, the below statement is wrong:
there are dynamically generated buttons...
When talking about "dynamic" elements, we talk about element that were not existing on page load. It's not the case here, since they were created before page load, on the server-side. Using a loop does not make them "dynamic".
To store clicked/unclicked ids, I suggest you to use some arrays for this.
As I understand it, you want all the "clicked" and "unclicked" ids separately.
The "never clicked" are ignored.
Using two arrays, you can store ids in the relevant group... And even sort them (optionnally).
And you can send those arrays straight to your backend... So the input elements would now be just for testing purposes.
See comments in code:
// Arrays to store ids
var clicked = [],
unclicked = [];
$(".btnColorChange").on("click",function(){
// useful for this demo
console.clear();
// Get the clicked element id
var this_id = this.id;
console.log("Clicked id: "+this_id);
// Toggle the classes (button colors)
$(this).toggleClass("clicked unclicked");
// Check if in array
var in_clicked = $.inArray(this_id,clicked);
var in_unclicked = $.inArray(this_id,unclicked);
//console.log(in_clicked+" "+in_unclicked)
// If clicked
if($(this).hasClass("clicked")){
if(in_clicked==-1){
clicked.push(this_id);
clicked.sort();
}
if(in_unclicked>-1){
unclicked.splice(in_unclicked,1);
}
}
// If unclicked
if($(this).hasClass("unclicked")){
if(in_unclicked==-1){
unclicked.push(this_id);
unclicked.sort();
}
if(in_clicked>-1){
clicked.splice(in_clicked,1);
}
}
// Show arrays content in console
console.log(clicked);
console.log(unclicked);
// Show the ids in inputs as a coma separated string
$("#textbox1").val(clicked.join(","));
$("#textbox2").val(unclicked.join(","));
});
.unclicked{
background-color: #FF0000;
}
.clicked{
background-color: #008000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="btnColorChange unclicked" id="1">1</button>
<button class="btnColorChange unclicked" id="2">2</button>
<button class="btnColorChange unclicked" id="3">3</button>
<button class="btnColorChange unclicked" id="4">4</button>
<button class="btnColorChange unclicked" id="5">5</button>
<br>
<br>
<div>
<input type="text" name="text1" id="textbox1" value=""/><br><br>
<input type="text" name="text2" id="textbox2" value=""/><br><br>
</div>
Please run the snippet in full page mode, because of the console logs.
For more reading, the below demo uses the following methods:
.on()
.toggleClass()
$.inArray()
.hasClass()
.push()
.sort()
.splice
.val()
.join()
You certainly noticed that I used two CSS rules for the button colors, instead of inline style attributes.
CodePen
If i understood you well, you want for example the Button to handle updates of textbox1 on first click and update textbox2 on second click. You could do this.
$(".btnColorChange").on("click", function(){
var btn = $(this);
var id = btn.attr("id");
if(btn.hasClass('clicked')){
var textboxselected = $("#textbox1");
var backgroundColor = "#FF0000";
btn.removeClass('clicked');
}else{
var textboxselected = $("#textbox2");
var backgroundColor = "#008000";
btn.addClass('clicked');
}
btn.css("background-color", backgroundColor);
textboxselected.val(textboxselected.val()+id);
});
Suppose you want to update same textbox
$(".btnColorChange").on("click", function(){
var btn = $(this);
var id = btn.attr("id");
var textvalue = $("#textbox1").val();
if(btn.hasClass('clicked')){
var backgroundColor = "#FF0000";
btn.removeClass('clicked');
}else{
var backgroundColor = "#008000";
btn.addClass('clicked');
}
btn.css("background-color", backgroundColor);
$("#textbox1").val(textvalue);
});
Its untested but hopes it works for you.
So, I was adding a delete all button and it works, the only problem is that it needs to be double clicked just to make it work.
may I ask what's wrong? thank you :)
I added the codes that were used to create the button here:
<body>
<!--for everything in the navigation part including the add favorite bar-->
<div class="topnav">
<div class="addFave">
<!--the text bar-->
<input type="text" name="enter" class="enter" value="" id="added" placeholder= "Add Favorites"/>
<!--the enter button-->
<input type="button" value="Enter" id = "addIt" OnClick="adding()" />
<!--for the script of the add favorite bar to add its functions-->
<script type="text/javascript">
var faves = [];
var y = document.getElementById("added");
function adding() {
faves.push(y.value);
document.getElementById("faveLists").innerHTML = faves;
}
var input = document.getElementById("added");
input.addEventListener("keyup", function(event) {
event.preventDefault();
if (event.keyCode === 13) {
document.getElementById("addIt").click();
}
});
</script>
</div>
</div>
<br />
<div class="buttons">
<button onclick="eradicateFaves()">Remove All Favorite</button>
<script>
-coding to remove all the favorites on the list-->
function eradicateFaves(){
document.getElementById("faveLists").innerHTML = faves;
while(faves.length > 0){
faves.shift();
}
}
</script>
</div>
<p id = "faveLists"></p>
while(faves.length > 0){
faves.shift();
}
Why not just faves = [] to empty it? And shouldn't you empty the list before assigning it? That's why you need two clicks; first time re-assigns current list then empties it, and second time assigns the empty list then does nothing more as it is already empty. So, try this:
function eradicateFaves(){
faves = [];
document.getElementById("faveLists").innerHTML = faves;
}
When you say "delete all" I assume you mean reset the faves array back to []. Well why not just do this:
function eradicateFaves() {
faces = [];
document.getElementById("faveLists").innerHTML = faves;
}
The reason it wasn't working earlier was because Array.prototype.shift() only removes the first element of the array. According to the MDN docs:
The shift() method removes the first element from an array and returns that removed element. This method changes the length of the array.
Im building a dynamic form. The idea is that you can press a button to add new input fields, fill them up with string data and when you click submit it creates a div with this data in the correct format.
I got most of this working already, though the problem Im having is that only the first input field is being recognized, and any new text fields that have been created by JS are not.
The problem is that Im looking for the input's value by ID, but Im not sure what the ID of the newly created inputs is, thus Im unable to fetch it.
I've setup a JSFiddle with my prototype, but it's not working there even though it works correctly if I save the file and open it in a browser.
And here's the code just in case:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<style>
.HiddenDiv{
color: red;
}
</style>
<script>
//-----CREATES NEW INPUT LINE-----
var counter1 = 1;
var limit1 = 5;
function addInput(divName){
if (counter1 == limit1) {
alert("You have reached the limit of adding " + counter1 + " inputs");
}
else {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<input type='text' name='myInputs[]'>";
document.getElementById(divName).appendChild(newdiv);
counter1++;
}
}
//-----TAKES VALUE AND PRINTS IT ON DIV-----
var counter2 = 0; //Prevents user from creating multiple nodes on submit
var limit2 = 1; //Amount of nodes that can be created per input field
function createNode(){
if (counter2 == limit2) {
//Do nothing
}
else {
var input = document.getElementById('textInput1').value; //Retrieves input
var newText = document.createElement("li"); //Creates the HTML node
newText.innerHTML = input; //Sets the node's value to whatever is in the input
document.getElementById("Form").appendChild(newText); //Adds the node to the div
counter2++;
}
}
</script>
</head>
<body>
<div id="dynamicInput">
Job Requirements<br>
<input type="text" name="myInputs[]" id="textInput1">
</div>
<form method="POST">
<input type="button" value="+" onClick="addInput('dynamicInput');">
<input type="button" value="Submit" onClick="return createNode()">
</form>
<div id="Form" class="HiddenDiv">
</div>
</body>
</html>
I think it will be easier to use document.querySelectorAll:
var inputs = document.querySelectorAll('input[name="myInputs[]"');
and then you can obtain content from inputs in loop.
I've read many blogs and posts on dynamically adding fieldsets, but they all give a very complicated answer. What I require is not that complicated.
My HTML Code:
<input type="text" name="member" value="">Number of members: (max. 10)<br />
Fill Details
So, a user will enter an integer value (I'm checking the validation using javascript) in the input field. And on clicking the Fill Details link, corresponding number of input fields will appear for him to enter. I want to achieve this using javascript.
I'm not a pro in javascript. I was thinking how can I retrieve the integer filled in by the user in input field through the link and displaying corresponding number of input fields.
You could use an onclick event handler in order to get the input value for the text field. Make sure you give the field an unique id attribute so you can refer to it safely through document.getElementById():
If you want to dynamically add elements, you should have a container where to place them. For instance, a <div id="container">. Create new elements by means of document.createElement(), and use appendChild() to append each of them to the container. You might be interested in outputting a meaningful name attribute (e.g. name="member"+i for each of the dynamically generated <input>s if they are to be submitted in a form.
Notice you could also create <br/> elements with document.createElement('br'). If you want to just output some text, you can use document.createTextNode() instead.
Also, if you want to clear the container every time it is about to be populated, you could use hasChildNodes() and removeChild() together.
<html>
<head>
<script type='text/javascript'>
function addFields(){
// Generate a dynamic number of inputs
var number = document.getElementById("member").value;
// Get the element where the inputs will be added to
var container = document.getElementById("container");
// Remove every children it had before
while (container.hasChildNodes()) {
container.removeChild(container.lastChild);
}
for (i=0;i<number;i++){
// Append a node with a random text
container.appendChild(document.createTextNode("Member " + (i+1)));
// Create an <input> element, set its type and name attributes
var input = document.createElement("input");
input.type = "text";
input.name = "member" + i;
container.appendChild(input);
// Append a line break
container.appendChild(document.createElement("br"));
}
}
</script>
</head>
<body>
<input type="text" id="member" name="member" value="">Number of members: (max. 10)<br />
Fill Details
<div id="container"/>
</body>
</html>
See a working sample in this JSFiddle.
Try this JQuery code to dynamically include form, field, and delete/remove behavior:
$(document).ready(function() {
var max_fields = 10;
var wrapper = $(".container1");
var add_button = $(".add_form_field");
var x = 1;
$(add_button).click(function(e) {
e.preventDefault();
if (x < max_fields) {
x++;
$(wrapper).append('<div><input type="text" name="mytext[]"/>Delete</div>'); //add input box
} else {
alert('You Reached the limits')
}
});
$(wrapper).on("click", ".delete", function(e) {
e.preventDefault();
$(this).parent('div').remove();
x--;
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container1">
<button class="add_form_field">Add New Field
<span style="font-size:16px; font-weight:bold;">+ </span>
</button>
<div><input type="text" name="mytext[]"></div>
</div>