I have a web page that asks user to enter number of networks. Based on number provided by user, it creates corresponding amount of text input fields. User than enters network addresses in those newly created boxes and when user clicks validate, it pings each networks.
Now, I managed to get the dynamically creation on input fields done but now I am having issue accessing their values. Please see below code and jsfiddle:
HTML:
<div ng-app>
<div ng-controller="Controller">
<div class="form-group" id = "numNetDiv" style="display:block">
<div class="col-sm-3">
<label for="numNetworks">Number of Networks</label>
<input id="numNetworks" ng-model="numNetworks"
ng-change="addNetworkFields()" type="text"
class="form-control" required />
<div class="col-sm-3" id="container" style="margin-left: 50px">
</div>
</div>
</div>
<div class="form-group" id = "checkNetsDiv" style="display:block">
<div>
<button id="checkNets" type="button" class="btn btn-nets"
style="margin-left: 100px"
ng-click="checkNets()">
Validate
</button>
</div>
</div>
<p id="demo"></p>
</div>
</div>
angularjs:
// Add input boxes based on # of networks
function Controller($scope){
$scope.count=0;
$scope.addNetworkFields = function() {
var number = document.getElementById("numNetworks").value;
console.log(number);
var container = document.getElementById("container");
while (container.hasChildNodes()) {
container.removeChild(container.lastChild);
}
for (i=0;i<number;i++){
container.appendChild(document.createTextNode("Network" + (i+1) + ": "));
var input = document.createElement("input");
input.type = "text";
container.appendChild(input);
container.appendChild(document.createElement("br"));
}
}
// Run ping on each subnet
$scope.checkNets = function() {
console.log('Click!')
var number = document.getElementById("numNetworks").value;
for (i=0;i<number;i++){
//Access each networks and run ping on each one after another
// Call below for each network to perform ping
var ping = $.param({network: $scope.network[i]}); // [i] to access each network? Just an idea
$http({
url: 'https://' + location.hostname + '/ping_network',
method: "POST",
data: ping
})
.then(function(response) {
$scope.pingResult = response.data;
})
}
}
}
https://jsfiddle.net/Lwy378ce/137/
I know POST works and the only issue I am having is access each networks one by one and calling that POST on it. For testing, we can get ride of the whole POST code and replace it with something like console.log(network[i]) and see if console can list all networks.
Thanks
Damon
It would be much simpler if you just used a form and the angular js models. You could create your field with ng-repeat, make the ng-model of these input fields the network address and then use those address for the ping. Addresses that would be easily updated when the form is submitted. Also by using ng-show you can hide that validate button until it's useful.
It's also a lot less code.
angular.module('myApp', [])
.controller('myAppCtrl', function($scope){
$scope.number = 0;
$scope.addNetworkFields = function(value) {
$scope.networks = [];
for(var i = 1; i <= parseInt(value); i++){
var network = {number : i, address: ""}
$scope.networks.push(network)
}
}
$scope.submit = function() {
for(var i = 0; i < $scope.networks.length; i++){
console.log($scope.networks[i].address)
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myAppCtrl as ctrl" ng-cloak layout="column" layout-fill>
<form ng-submit="submit()" class="form-group" id = "numNetDiv" style="display:block">
<div class="col-sm-3">
<label for="numNetworks">Number of Networks</label>
<input id="numNetworks" ng-model="number"
ng-change="addNetworkFields(number)" type="number"
class="form-control" required />
<div class="col-sm-3" id="container" style="margin-left: 50px">
<div ng-repeat="network in networks">
<label>Networks {{network.number}}
<input ng-model="network.address"
type="text" class="form-control" /></label>
</div>
<input ng-show="number > 0" type="submit" value="validate"/>
</div>
</div>
</form>
</body>
Here you go: set id to each input and get it by id later.
// Add input boxes based on # of networks
function Controller($scope) {
$scope.count = 0;
$scope.addNetworkFields = function() {
var number = document.getElementById("numNetworks").value;
console.log(number);
var container = document.getElementById("container");
while (container.hasChildNodes()) {
container.removeChild(container.lastChild);
}
for (i = 0; i < number; i++) {
container.appendChild(document.createTextNode("Network" + (i + 1) + ": "));
var input = document.createElement("input");
input.type = "text";
input.id = "network" + (i + 1);
container.appendChild(input);
container.appendChild(document.createElement("br"));
}
}
// Run ping on each subnet
$scope.checkNets = function() {
console.log('Click!')
var number = document.getElementById("numNetworks").value;
for (i = 0; i < number; i++) {
//Access each networks and run ping on each one after another
var network = document.getElementById("network" + (i + 1)).value
// Call below for each network to perform ping
var ping = $.param({
network: $scope.network
});
$http({
url: 'https://' + location.hostname + '/ping_network',
method: "POST",
data: ping
})
.then(function(response) {
$scope.pingResult = response.data;
})
}
}
}
Related
when i add new input box with javascript function, previous input boxes become empty. here is the code:
<div id="field">
<input type="text">
</div>
<div id="error"></div>
<button onclick="Add()">add</button>
<script>
let i=0;
const Add=()=>{
i++
if(i<5)
document.getElementById('field').innerHTML+=`<input type="text" id="value${i}">`
else
document.getElementById('error').innerHTML='Error: Field cant be more then 5'
}
</script>
what can I do to NOT change input values of input box on adding new input box with above codes.
You are overwriting the entire HTML content of ID field,
let i = 0;
const Add = () => {
i++
if (i < 5) {
const input = document.createElement('input');
document.getElementById('field').appendChild(input);
} else
document.getElementById('error').innerHTML = 'Error: Field cant be more then 5'
}
<div id="field">
<input type="text">
</div>
<div id="error"></div>
<button onclick="Add()">add</button>
One way of doing it, keeping in mind separation of concerns and avoiding the creation of unnecessary global variables could be:
#error {
display: none;
}
<div id="field">
<input type="text">
</div>
<div id="error"></div>
<button onclick="Add()">add</button>
<script>
const Add = () => {
const inputContainer = document.querySelector('#field'); // this variable is not strictly necessary but I think it makes the code more readable
const inputNotification = document.querySelector('#error'); // this variable is not strictly necessary but I think it makes the code more readable
const inputCount = inputContainer.querySelectorAll('input[type=text]').length // count how many input elements of type text are already inside the `field` div
if (inputCount < 5) {
const txtInput = document.createElement('input');
txtInput.setAttribute('type', 'text');
txtInput.setAttribute('id', `value${inputCount}`);
inputContainer.append(txtInput);
} else {
inputNotification.innerText = 'Error: Field can\'t be more than 5';
inputNotification.style.display = 'block'
event.target.setAttribute('disabled', true); // optionally, you can disable the add button if you reached the maximum number of input fields
}
}
</script>
You could use Document.createElement() and element.appendChild() so that you do not alter the HTML of the div#field :
<div id="field">
<input type="text">
</div>
<div id="error"></div>
<button onclick="Add()">add</button>
<script>
let i=0;
const Add=()=>{
i++
if(i<5) {
let input = document.createElement("input");
input.type = "text";
input.id = "value" + i;
let button = document.createElement("button");
button.innerText = "delete";
button.onclick = function(){
input.remove(); //remove text input
this.remove(); //remove this delete button
i--; //decrement i
};
document.getElementById('field').appendChild(input);
document.getElementById('field').appendChild(button);
} else {
document.getElementById('error').innerHTML='Error: Field cant be more then 5';
}
}
</script>
I asked a question earlier with answers which didn't help, I still haven't been able to figure out where my issue is. Originally I thought it was because I had two IDs named the same but this was not the issue.. The form submits and there are no errors but it does not update the values in localStorage?
Edit: After changing const idx to const i the value at position [2] (or final value) would update for every booking (regardless of index). I thought of maybe changing the i value to below but it gives error i is defined before it is initialised?
bookings.findIndex(booking => bookings[i].fname == fname && bookings[i].lname == lname);
Here's what I have (updated code):
// ~~~ add bookings to localStorage
var bookings = JSON.parse(localStorage.getItem("bookings")) || [];
window.onload = showBooking();
$("#submit").click(function() {
var newBookings = {
fname: $('#fname').val(),
lname: $('#lname').val()
}
bookings.push(newBookings);
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
showBooking();
});
// ~~~ edit bookings in localStorage
$(document).on('click','#edit',function (e) {
e.preventDefault();
var parent_form = $(this.form);
var fname = parent_form.find('.input:eq(0)').val();
var lname = parent_form.find('.input:eq(1)').val();
const i = bookings.findIndex(booking => bookings.fname == fname && bookings.lname == lname);
deleteBooking(i);
bookings.push({
fname,
lname
});
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
// showBooking();
});
// ~~~ display bookings in browser
function showBooking() {
var bookingResult = document.getElementById("result");
var ul = document.createElement("ul");
// var bookingItems = JSON.parse(localStorage.getItem("bookings")) || [];
bookingResult.innerHTML = "";
for (let i = 0; i < bookings.length; i++) {
bookingResult.innerHTML += `<div class="card card-body bg-light m-4">
<h3>${bookings[i].fname + " " + bookings[i].lname}
<button onclick="deleteBooking(${i})" class="btn btn-danger text-light ">Delete</button>
<button onclick="editBooking(${i})" class="btn btn-danger text-light ">Edit</button>
</h3>
</div>`;
}
}
// ~~~ edit bookings in browser
function editBooking(i) {
// $('#regForm').hide();
$('#result').hide();
var currentItem = document.getElementById("currentItem");
var editBooking = document.getElementById("editAppt");
currentItem.innerHTML += `<div class="card card-body bg-light m-4">
<h3>${bookings[i].fname + " " + bookings[i].lname} </h3>
</div>`;
editBooking.innerHTML = `<input type="text" class="input" id="fname_${i}" placeholder="${bookings[i].fname}" name="${bookings[i].fname}" value="${bookings[i].fname}" required>
<input type="text" class="input" id="lname_${i}" placeholder="${bookings[i].lname}" name="${bookings[i].lname}" value="${bookings[i].lname}" required>
<input id="edit" type="submit" value="Edit">`;
}
// ~~~ delete bookings from localStorage
function deleteBooking(i) {
bookings.splice(i, 1);
localStorage.setItem("bookings", JSON.stringify(bookings));
showBooking();
}
My HTML form:
<form id="regForm" name="regForm" action="" class="col-sm-6">
<div class="row">
<input type="text" class="input" id="fname" placeholder="First Name" name="fname" required>
<input type="text" class="input" id="lname"placeholder="Last Name" name="lname" required>
<input id="submit" type="submit" value="Submit">
</div>
</form>
<div id="result" class="row"></div>
<div id="currentItem" class="row"></div>
<div id="editAppt" class="row"></div>
There are several changes you need to consider
You have bookings AND bookingItems
You do some changes (I assume there will be some destination change) but do not save them
You parse the localStorage far too often. Not needed. Only read once and write when modified
You cannot have duplicate IDs so you need to delegate and use class names
Be consistent and use jQuery to create elements and to add events- for example the delete button should be d er legates and remove its closest form element
Here is how to find the booking based on names
const idx = bookings.findIndex(booking => bookings.fname == fname && bookings.lname == lname);
I was not able to get this to display the data entered into my table like I wanted. Keeps saying "Uncaught ReferenceError: createRequest is not defined
at HTMLButtonElement.onclick" however I did! or I thought I did... please help me to see what I did wrong! I tried fixing the error messages but it doesn't seem to help.
thank you
function myRequest(medium, subject, quantity) {
requestMedium = medium;
requestSubject = subject;
requestQuantity = quantity;
}
var requestButton = document.getElementById("createRequest");
if (requestButton.addEventListener) {
requestButton.addEventListener("click", Request, false);
} else if (requestButton.attachEvent) {
requestButton.attachEvent("onclick", Request);
}
function createRequest
{
var requestMedium = document.getElementById(medium).value;
var requestSubject = document.getElementById(subject).value;
var requestQuantity = document.getElementById(quantity).value;
//create new request request, store reference in myRequest
//myRequest= new request(requestMedium, requestSubject, requestQuantity);
var addRequest = new Request(requestMedium, requestSubject, requestQuantity);
//display usere's request on page
createRequestDisplay(addRequest);
}
//display gloval request object on page
function displayRequest() {
document.getElementById("requestDisplay").innerHTML = Request.requestMedium + "<br>" +
Request.requestSubject + "<br>" +
Request.requestQuantity;
}
//display any request object to new document node on page
function createDisplayRequest(request) {
// create new object div element
var fragment = document.createElement("div");
//add newObject class name to div element
var classAttrib = document.createAttribute("class");
classAttrib.value = "newObject";
//set class attibute to div fragment;
fragment.setAttributeNode(classAttrib);
//put request object info inside div
fragment.innerHTML = requestMedium + < "br" > +
requestStubject + < "br" > +
requestSubject;
document.body.appendChild(fragment);
}
<div class="main">
<h1>Order Form for comissions</h1>
<legend>Request Comission</legend>
<label for="medium">Medium</label>
<input id="medium" type="text"><br>
<label for="subject">Subjects</label>
<!-- Grader: HTML error needs fixing...missing a '>'' character -->
<!-- <input id="subject" type="subject"<br> -->
<input id="subject" type="text">
<label for="quantity">quantity</label>
<input id="quantity" type="number"><br>
<button id="requestButton" onclick="createRequest">Submit</button>
</div>
<div id="displayRequest">
</div>
Here is a fixed version
var submitRequestBtn = document.getElementById("submitRequestBtn");
submitRequestBtn.addEventListener("click", submitRequest, false);
function submitRequest() {
const medium = document.getElementById('medium').value;
const subject = document.getElementById('subject').value;
const quantity = document.getElementById('quantity').value;
const request = {medium, subject, quantity};
displayRequest(request);
}
function displayRequest(request){
document.getElementById("requestDisplay").innerHTML =
request.medium + "<br>"
+ request.subject + "<br>"
+ request.quantity
;
}
<div class="main">
<h1>Order Form for comissions</h1>
<legend>Request Comission</legend>
<label for="medium">Medium</label>
<input id="medium" type="text"><br>
<label for="subject">Subjects</label>
<input id="subject" type="text">
<label for="quantity">quantity</label>
<input id="quantity"type="number"><br>
<button id="submitRequestBtn" onclick="submitRequest()">Submit</button>
<br/>
<div id ="requestDisplay"></div>
</div>
I have to get 'n' - total number of names from the user and then create n number of fields for getting all the names. I've currently written this as:
HTML code:
<form action="/flight_ticket/book" name="myform" method="post">
.
.
.
Enter the number of tickets to be booked:
<input name="nooftickets" type="text"><br/><br/>
Enter names
<div id='container'/>
</div>
<br/><br/>
</form>
</body>
JS code:
function addFields(){
var number = parseInt(document.getElementById("nooftickets").value);
var container = document.getElementById("container");
while (container.hasChildNodes()) {
container.removeChild(container.lastChild);
}
for (i=0;i<number;i++){
container.appendChild(document.createTextNode("Name " + (i+1)));
var input = document.createElement("input");
input.type = "text";
input.name = "name" + i;
//input.required= true;
container.appendChild(input);
container.appendChild(document.createElement("br"));
}
}
But when I run it on browser, after clicking the "Enter names", I don't see any changes in the browser!
What have I got wrong?
What you are doing is trying to fetch the value of the noofticktes which is defined as a name in the HTML but in your code, you are using document.getElementById('noofticktes').value which is throwing an undefined error as there is no id defined as noofticktes.
So, just change your code on from:
var number = document.getElementById("nooftickets").value;
To this:
var number = document.getElementsByName("nooftickets")[0].value;
you will be able to make your code work.
One small update in your code would be if you are trying to clear/remove all the contents of the element container just use the container.innerHTML='' instead of looping and removing each element.
Here is the updated Snippet of your code.
function addFields() {
debugger;
var number = document.getElementsByName("nooftickets")[0].value;
var container = document.getElementById("container");
container.innerHTML = '';
for (i = 0; i < number; i++) {
container.appendChild(document.createTextNode("Name " + (i + 1)));
var input = document.createElement("input");
input.type = "text";
input.name = "name" + i;
//input.required= true;
container.appendChild(input);
container.appendChild(document.createElement("br"));
}
}
<form action="/flight_ticket/book" name="myform" method="post">
. . . Enter the number of tickets to be booked:
<input name="nooftickets" type="text"><br/><br/>
Enter names
<div id='container' />
</div>
<br/><br/>
</form>
function addFields() {
// body...
var input = '';
var number = document.getElementById('number').value;
for(var i=0;i<number;i++)
{
input +="<input id='number"+i+"' name='number"+i+"'><br>";
}
document.getElementById('container').innerHTML = input;
}
<form action="/flight_ticket/book" name="myform" method="post">
Enter the number of tickets to be booked:
<input name="nooftickets" id="number" type="text"><br/><br/>
Enter names
<div id='container'/>
</div>
<br/><br/>
</form>
I found this fiddle and I am trying to get it to work...I can not figure out why the names are not being added to the list, for some reason Add button is acting like a submit button and I can not tell why...It should add all the numbers to a list so when I click submit, then it should send the numbers in an array..
JavaScript:
function bindName() {
var inputNames = document.getElementById("names").getElementsByTagName("inputNames");
for (i = 0; i < inputNames.length; i++) {
inputNames[i].onkeydown = function() {
if (this.value == "") {
setTimeout(deletename(this), 1000);
}
}
}
}
document.getElementById("addName").onclick = function() {
var num1 = document.getElementById("name");
var myRegEx = /^[0-9]{10}$/;
var myRegEx = /^[0-9]{10}$/;
var itemsToTest = num1.value;
if (myRegEx.test(itemsToTest)) {
var form1 = document.getElementById("names");
var nameOfnames = form1.getElementsByTagName("inputNames").length;
var newGuy1 = document.createElement("inputNames");
newGuy1.setAttribute("id", nameOfnames);
newGuy1.setAttribute("type", "text");
newGuy1.setAttribute("value", num1.value);
form1.appendChild(newGuy1);
num1.value = "";
bindName();
}
else {
alert('error');
}
};
HTML:
<h1>Enter Name</h1>
<div id="mainName">
<h2>name</h2>
<label for="name">Add Names: </label>
<input id="name" type="text">
<button id="addName">Add</button>
<form>
<div id="names">
</div>
<input METHOD="POST" action="text.php" type="submit" value="Submit">
</form>
</div>
I've seen
document.createElement("inputNames");
Shouldn't be
document.createElement("input");
?
Because this /^[0-9]{10}$/; will accept only 10 numbers and only that, try entering 1234567890 and you will see no error.
I'm not sure why your "name" field is restricted to 10 digit numbers, but I've got the thing to work.
http://jsfiddle.net/y8Uju/4/
I think the problem was that you were trying to create an element with the tag name inputNames, but that's not a valid tag. Instead I changed it to create inputs, and set the class to inputNames.