Removing appended html code - javascript

I currently ran into a problem that i cannot remove the appended html with jQuery.
What works now is i can append the html that i want and it looks nice, but removing does not work. It works only on reload the first loaded html the others that i append are not working - I don't know why.
Here is my code for appending the html:
$("#adWasteStream").click(function(){
var newTxt = $('<div class="row-waste-container width-100"><div class="row"><div class="col-md-9"><p>Stream 1</p></div><div class="col-md-3"><button class="btn btn-add-waste deleteWasteStream"><i class="fa fa-minus-circle o-btn-add" aria-hidden="true"></i>Remove Waste Stream</button></div><div class="form-group col-md-7"><label for="business-mng-name" class="control-label">Waste Stream</label><input type="text" class="form-control form-input-field" name="business-mng-name" value="" required="" placeholder="Co-mingled recycling"><span class="help-block"></span></div></div><div class="row width-100"><div class="form-group col-md-4"><label for="business-mng-name" class="control-label">Volume (m <sup>3</sup>)</label><input type="text" class="form-control form-input-field" name="business-mng-name" value="" required="" placeholder="50"><span class="help-block"></span></div><div class="form-group col-md-4"><label for="business-mng-name" class="control-label">Weight (t)</label><input type="text" class="form-control form-input-field" name="business-mng-name" value="" required="" placeholder="20"><span class="help-block"></span></div><div class="form-group col-md-4"><label for="business-mng-name" class="control-label">Cost ($)</label><input type="text" class="form-control form-input-field" name="business-mng-name" value="" required="" placeholder="400"><span class="help-block"></span></div></div></div>');
$(".row-cont-main").append(newTxt);
});
My code for removing:
$(".deleteWasteStream").click(function(){
var curRow = $(this).parents('div.row-waste-container');
curRow.remove();
});
I don't need to use Id's as they need to be unique all elements (for back-end purposes).
The structure of the html looks like this:
<div class="row-waste-container width-100">
<div class="row">
<div class="col-md-9">
<p>Stream 1</p>
</div>
<div class="col-md-3">
<button class="btn btn-add-waste deleteWasteStream"><i class="fa fa-minus-circle o-btn-add" aria-hidden="true"></i>Remove Waste Stream</button>
</div>
<div class="form-group col-md-7">
<label for="business-mng-name" class="control-label">Waste Stream</label>
<input type="text" class="form-control form-input-field" name="business-mng-name" value="" required="" placeholder="Co-mingled recycling">
<span class="help-block"></span>
</div>
</div><!-- end row -->
<div class="row width-100">
<div class="form-group col-md-4">
<label for="business-mng-name" class="control-label">Volume (m <sup>3</sup>)</label>
<input type="text" class="form-control form-input-field" name="business-mng-name" value="" required="" placeholder="50">
<span class="help-block"></span>
</div>
<div class="form-group col-md-4">
<label for="business-mng-name" class="control-label">Weight (t)</label>
<input type="text" class="form-control form-input-field" name="business-mng-name" value="" required="" placeholder="20">
<span class="help-block"></span>
</div>
<div class="form-group col-md-4">
<label for="business-mng-name" class="control-label">Cost ($)</label>
<input type="text" class="form-control form-input-field" name="business-mng-name" value="" required="" placeholder="400">
<span class="help-block"></span>
</div>
</div><!-- end row -->
</div><!-- end row-waste container -->

You need to change your click event handler to handle also dynamically appended html.
Update your remove click handler with the code below
$("body").on('click' , '.deleteWasteStream' , function(){
var curRow = $(this).parents('div.row-waste-container');
curRow.remove();
});

You cant use .click() on dynamic objects/html. You can use .on()
$("body").on('click', '.deleteWasteStream', function( event ) {
var curRow = $(this).parents('div.row-waste-container');
curRow.remove();
});
Documentation: http://api.jquery.com/on/

Since the elements were created dynamically, they are not registered in DOM like pre-rendered elements (those rendered when your webpage is loaded in the browser). The best solution is binding the dynamically created element to the prerendered ones using the on event binder
$('.row-cont-main').on('click','.deleteWasteStream',function(){
var curRow = $(this).parents('div.row-waste-container');
curRow.remove();
});

Related

Add new row (html form) after click 'Add row' button

Hi , I would to ask how to add new row after we click on the 'Add row' button. I found some Javascript code and try to edit it but it doesn't work. Thank you in advance :) Here is the code that I have been using. Would you guys tell what to do or share with me any sources regarding this matter since I haven't found one. There are some similar questions in Stackoverflow but there's no answers there.
The html code :
<h1 class="h3 mb-4 text-gray-800">Requirement Validation Principles</h1>
<div class="jumbotron jumbotron-fluid">
<div class="container">
<form>
<div class="form-row">
<div class="form-group col-md-7">
<label for="inputName1"></label>
<input type="Name" class="form-control" id="inputName1" placeholder="Name">
</div>
<div class="form-group col">
<label for="inputPassword1"></label>
<input type="name" class="form-control" id="inputPassword1" placeholder="Position">
</div>
</div>
<div class="form-row">
<div class="form-group col-md-7">
<label for="inputName2"></label>
<input type="Name" class="form-control" id="inputName2" placeholder="Name">
</div>
<div class="form-group col">
<label for="inputPassword2"></label>
<input type="name" class="form-control" id="inputPassword2" placeholder="Position">
</div>
</div>
<div class="form-row">
<div class="form-group col-md-7">
<label for="inputName3"></label>
<input type="Name" class="form-control" id="inputName3" placeholder="Name">
</div>
<div class="form-group col">
<label for="inputPassword3"></label>
<input type="name" class="form-control" id="inputPassword3" placeholder="Position">
</div>
</div>
<div class="form-row">
<div class="form-group col-md-7">
<label for="inputName4"></label>
<input type="Name" class="form-control" id="inputName4" placeholder="Name">
</div>
<div class="form-group col">
<label for="inputPassword4"></label>
<input type="name" class="form-control" id="inputPassword4" placeholder="Position">
</div>
</div>
</div>
<button id="btn">Add row</button>
The javascript code :
var count=1;
$("#btn").click(function(){
$("#container").append(addNewRow(count));
count++;
});
function addNewRow(count){
var newrow='<div class="row">'+
'<div class="col-md-4">'+
'<div class="form-group label-floating">'+
'<label class="control-label">Name '+count+'</label>'+
'<input type="text" class="form-control" v-model="act" >'+
'</div>'+
'</div>'+
'<div class="col-md-4">'+
'<div class="form-group label-floating">'+
'<label class="control-label">Position '+count+'</label>'+
'<input type="text" class="form-control" v-model="section">'+
'</div>'+
'</div>'+
'</div>';
return newrow;
}
Here is the code that perfectly working.
<div class="jumbotron jumbotron-fluid" id="dataAdd">
<div class="container">
<div class="form-row">
<div class="form-group col-md-7">
<label for="inputName1"></label>
<input type="Name" class="form-control" id="inputName1" placeholder="Name" v-model="name">
</div>
<div class="form-group col">
<label for="inputPassword4"></label>
<input type="name" class="form-control" id="inputPassword1" placeholder="Position" v-model="position">
</div>
</div>
</div>
<button id="btn">Add row</button>
HTML Code input start with one.
$("#btn").click(function(){
var len=$('#dataAdd .container .form-row').length+1;
//if(len>1)
$("#dataAdd .container:last").append(' <div class="form-row">'+
'<div class="form-group col-md-7">'+
' <label for="inputName'+len+'"></label>'+
' <input type="Name" class="form-control" id="inputName'+len+'" placeholder="Name" v-model="name">'+
' </div>'+
' <div class="form-group col">'+
' <label for="inputPassword4"></label>'+
' <input type="name" class="form-control" id="inputPassword'+len+'" placeholder="Position" v-model="position">'+
' </div>'+
'</div>');
});
});
JavaScript Code added HTML in last form-control.
I have Created a working Example you can check here
Turns out there's a Javascript method called insertRow().
You'd just need to get a handle on your form by giving it and ID and then accessing that in Javascript:
var table = document.getElementById("[the ID I gave my form");
after that, use the insertRow() method on that table variable and give it a position. Then add cells to the row you just created using insertCell():
var row = table.insertRow(0);
var cell1 = row.insertCell(0);
Instead of using InsertRow() you can alternatively put the button outside your container (the div containing the "container" class) and then use javascript to create your elements.
After all elements are created, you can simply append them to follow your desired structure.
const button = document.getElementById(#btn);
button.addEventListener('click', addRow);
function addRow(event) {
const container = document.querySelector('.container');
const row = document.createElement('div');
row.classList.add('form-row');
const group = document.createElement('div');
group.classList.add('form-group');
group.classList.add('col-md-7'); // Adjust after need.
const label = document.createElement('label');
label.setAttribute('for', 'myNewInputName');
const input = document.createElement('input');
input.setAttribute('type', 'text');
input.classList.add('form-control');
input.setAttribute('placeholder', 'My new placeholder');
// Assemble our structure.
group.appendChild(label);
group.appendChild(input);
row.appendChild(group);
container.appendChild(row);
}
Here you got a working sandbox of this example: https://codesandbox.io/s/busy-lovelace-9jw2b?file=/src/index.js.
Useful links:
appendChild
createElement
querySeleector
the more simple is to use a DOMParser
const DomParser = new DOMParser()
, myForm = document.getElementById('my-form')
, bt_Add = document.getElementById('btn-add')
;
function newRow(numRow)
{
let row_N = `
<div class="form-row">
<div class="form-group col-md-7">
<label for="inputName${numRow}"></label>
<input type="Name" class="form-control" id="inputName${numRow}" placeholder="Name ${numRow}">
</div>
<div class="form-group col">
<label for="inputPassword${numRow}"></label>
<input type="name" class="form-control" id="inputPassword${numRow}" placeholder="Position ${numRow}">
</div>
</div>`
return (DomParser.parseFromString(row_N, 'text/html')).body.firstChild
}
bt_Add.onclick =()=>
{
let rowCount = myForm.querySelectorAll('div.form-row').length
myForm.appendChild(newRow(++rowCount))
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<h1 class="h3 mb-4 text-gray-800">Requirement Validation Principles</h1>
<div class="jumbotron jumbotron-fluid">
<div class="container">
<form action="xx" id="my-form">
<div class="form-row">
<div class="form-group col-md-7">
<label for="inputName1"></label>
<input type="Name" class="form-control" id="inputName1" placeholder="Name 1">
</div>
<div class="form-group col">
<label for="inputPassword1"></label>
<input type="name" class="form-control" id="inputPassword1" placeholder="Position 1">
</div>
</div>
</form>
</div>
<button id="btn-add">Add row</button>
<!-- /.container-fluid -->
</div>
Useful links:
appendChild
querySeleectorAll
see also : What does ${} (dollar sign and curly braces) mean in a string in Javascript?

Clean way to generate HTML

First of All I can't put all my elements in ONE ROW ONLY (all inline) I'm trying to generate one row of elements inside envVariablesDiv. I did all the html using javascript in my attempt and it's a huge mess and confusing.
Is there a simpler way to add rows of my elements everytime I click the button? I also need to be able to delete the row when I click delete.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="top20 content-form">
<label class="col-sm-2 control-label" for="addEnv"><button class="btn btn-primary">add</button></label>
<div class="col-sm-10">
<label id="addEnv" class="label label-secondary pointer-label"><span class="fa fa-plus-circle"></span> Add environment variable</label>
<div id="envVariablesDiv">
<div class="input-group">
<span class="input-group-addon">Text</span>
<input id="msg" type="text" class="form-control" name="msg" placeholder="Additional Info">
</div>
<div class="input-group">
<span class="input-group-addon">Text</span>
<input id="msg" type="text" class="form-control" name="msg" placeholder="Additional Info">
</div>
<button class="btn btn-danger">Delete</button>
</div>
</div>
</div>
JS I done: The styling is different now. I want to use input group.
$('#addEnv').click(function () {
$('#envVariablesDiv').append('<div class="col-sm-5 top10"><label for="envName" class="control-label">Name</label><input id="envName" class="form-control" name="envName" type="text" placeholder="e.g. name1" /></div>' +
'<div class="col-sm-5 top10"><label for=envVar class="control-label">Variable</label><input class="form-control" id="envVar" type="text" name="envVar" placeholder="e.g. var1" /></div><div class="col-sm-2 top10"><button class="btn btn-danger"><span class="fa fa-trash"></span></button></div>');
});

How can I add some dynamic fields and use them to get some math results?

I'm using spring MVC and I have a form with dynamic field.
I can create several rows inside my form and each row has 4 input, like you can see below.
When I insert a number inside the second and third input field I want to multiply them and write the result into the fourth field.
How can I do it? Maybe using jQuery?
This is my code:
var riga = 0;
function aggiungiRiga() {
riga++;
var objTo = document.getElementById('rigaOfferta')
var divtest = document.createElement("div");
divtest.setAttribute("class", "removeclass" + riga);
var rdiv = 'removeclass' + riga;
divtest.innerHTML = '<div class="col-xs-5 col-sm-5 col-md-5"><div class="form-group"> <input type="text" class="form-control" id="descrizione_"' + riga + '" name="descrizione[]" value="" placeholder="Descrizione"></div></div><div class="col-xs-2 col-sm-2 col-md-2 col-md-offset-1"><div class="form-group"><input type="number" min="0" step="0.01" class="form-control" id="prezzo_"' + riga + '" name="prezzo[]" value="" placeholder="Prezzo €"/></div></div><div class="col-xs-2 col-sm-2 col-md-2 "><div class="form-group"><input type="number" min="0" step="0.5" class="form-control" id="ore_"' + riga + '" name="ore[]" value="" placeholder="Numero Ore"/></div></div><div class="col-xs-2 col-sm-2 col-md-2 "><div class="form-group"><div class="input-group"> <input type="text" class="form-control" id="totale_"' + riga + '" name="Totale[]" value="" placeholder="0" readonly="readonly"/><div class="input-group-btn"> <button class="btn btn-danger" type="button" onclick="rimuoviRiga(' + riga + ');"> <span class="glyphicon glyphicon-minus" aria-hidden="true"></span> </button></div></div></div></div>';
objTo.appendChild(divtest)
}
function rimuoviRiga(rid) {
$('.removeclass' + rid).remove();
}
<div id="rigaOfferta">
<jsp:text/>
</div>
<div class="col-xs-5 col-sm-5 col-md-5">
<div class="form-group">
<input type="text" class="form-control" id="descrizione_0" name="descrizione[]" value="" placeholder="Descrizione" required="required" />
</div>
</div>
<div class="col-xs-2 col-sm-2 col-md-2 col-md-offset-1">
<div class="form-group">
<input type="number" min="0" step="0.01" class="form-control" id="prezzo_0" name="prezzo[]" value="" placeholder="Prezzo €" required="required" />
</div>
</div>
<div class="col-xs-2 col-sm-2 col-md-2 ">
<div class="form-group">
<input type="number" min="0" step="0.5" class="form-control" id="ore_0" name="ore[]" value="" placeholder="Numero Ore" required="required" />
</div>
</div>
<div class="col-xs-2 col-sm-2 col-md-2 ">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="totale_0" name="Totale[]" value="0" placeholder="0" readonly="readonly" />
<div class="input-group-btn">
<button class="btn btn-success" type="button" onclick="aggiungiRiga();"> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> </button>
</div>
</div>
</div>
</div>
Since you are going to have multiple input fields I suggest you add a class to them, something like input-listener and then a data attribute like data-row="n" where n stands for the row number. Then you add an event listener using jQuery (since it's easier) like so:
$('.input-listener').on('change', function(){
var row = $(this).data('row'); //this way you know which row you are working with
//now that you have the row you can get all the inputs you want
var prezzo = $('#prezzo_' + row).val() || 0;
var ore = $('#ore_' + row).val() || 0;
$('#totale_' + row).val(prezzo * ore);
});
As I didn't test the code I am not sure if it works 100% but it can be a place to start. If you find any errors in the code let me know and I'll try and correct them.
The only thing is that if you add a new row you will have to rebind this event handler, so you'll have to find a way around that. Maybe add it in your aggiungiRiga() function.
Edit: I removed the e and changed it to this then I added the # to the ID of the jQuery selectors as I previously forgot to.

input-group pushes next inputs to the next row

I have a row divided into two parts(col-md-5 and col-md-7). First part contains a question and the second part has 6 input fields(5 text inputs and 1 selectbox).
So, i divided the second part into 6 fields(col-sm-2). Everything works fine. Now i want to add input-group-addon to two of the text field. But when, i'm trying to add input-group to the parent div of that input box, the size of input box increases and it pushes all the input boxes(next to it) to the next row.
Here's the code
<div class="row">
<div class="col-md-5">
<p class="text-info">How many PRI"s? How much are you paying per month?</p>
</div>
<div class="col-md-7">
<div class="form-group">
<div class=" col-sm-2">
<input type="text" value="" name="pri_qty" class="form-control input-sm" placeholder="QTY">
</div>
<!-- i want to add input-group to the next input field -->
<div class=" col-sm-2">
<input type="text" value="" name="pri_mrate" class="form-control input-sm" placeholder="$/M">
</div>
<div class=" col-sm-2">
<select name="pri_competitor_id" class="form-control input-sm"><option selected="selected" value="">Provider</option><option value="1">ALLSTREAM</option><option value="2">BELL</option><option value="3">BV</option><option value="4">CONVERGIA</option><option value="5">DISTRIBUTEL</option><option value="6">ONE CONNECT</option><option value="7">TELSYNERGIE</option><option value="8">TELUS</option><option value="9">VIDEOTRON</option><option value="10">SELECTCOM</option><option value="11">OTHER</option></select>
</div>
<div class=" col-sm-2">
<input type="text" value="" name="pri_avaya" class="form-control input-sm" placeholder="Avaya">
</div>
<div class=" col-sm-2">
<input type="text" value="" name="pri_our_rate" class="form-control input-sm" placeholder="$/M">
</div>
<div class=" col-sm-2">
<input type="text" value="" name="pri_install" class="form-control input-sm" placeholder="Setup">
</div>
</div>
</div>
</div>
`
From the bootstrap docs on input-groups (http://getbootstrap.com/components/#input-groups):
Don't mix with other components
Do not mix form groups or grid column classes directly with input
groups.
Instead, nest the input group inside of the form group or grid-related element.
So, rather than adding .input-group-addon to your .col-sm-2, wrap the input in another div.input-group-addon.

Adding ng-autocomplete to input tag when dynamically creating the input tag via Javascript

"Sorry for my English as it is not my native language"
On to the problem. I have a trouble with ng-autocomplete when I dynamically create form fields.
The ng-autocomplete works fine when I create an input tag in the index file but when I try to add more tags via the javascript function the ng-autocomplete does not work in the new input tags created..
As you see in the picture the two input fields "Travel from" and "Travel to" have ng-autocomplete but the input field "travel via" which is created by the javascript function does not have ng-autocomplete..
The question is how can I add a working ng-autocomplete for every created input field via the function?
Down below is the script.js file with the code for creating the input tag
$(document).ready(function(){
var i=1;
$("#add_city").click(function(){
$('#end_city'+i).html('<input type="text" class="form-control input-lg ng-isolate-scope" name="via_city" ng-autocomplete="via_city" placeholder="Travel via" autocomplete="off" />');
$('#tab_logic').append('<div id="end_city'+(i+1)+'"></div>');
i++;
});
$("#delete_city").click(function(){
if(i>1){
$("#end_city"+(i-1)).html('');
i--;
}
});
});
And there is the index.php
<div class="page-header">
<h4>Create your trip</h4>
</div>
<form ng-submit="submitTrip()"> <!-- ng-submit will disable the default form action and use our function -->
<!-- START CITY -->
<div class="form-group col-md-6">
<input type="text" class="form-control input-lg" name="start_city" ng-autocomplete="tripData.start_city" placeholder="Travel from">
</div>
<!-- END CITY -->
<div class="form-group col-md-6" id="tab_logic">
<div id="end_city0">
<input type="text" class="form-control input-lg" name="end_city" ng-autocomplete="tripData.end_city" placeholder="Travel to">
</div>
<div id="end_city1"></div>
</div>
<!-- START DATE -->
<div class="form-group col-md-6">
<input type="date" class="form-control input-lg" name="start_date" ng-model="tripData.start_date" placeholder="Travel date">
</div>
<!-- END DATE -->
<div class="form-group col-md-6">
<input type="date" class="form-control input-lg" name="end_date" ng-model="tripData.end_date" placeholder="Return date">
</div>
<!-- COMMENT -->
<div class="form-group col-md-12">
<textarea class="form-control input-lg" name="comment" ng-model="tripData.comment"></textarea>
</div>
<!-- Img -->
<div class="form-group col-md-12">
<input type="text" class="form-control input-lg" name="img" ng-model="tripData.img" placeholder="Image source">
</div>
<!-- SUBMIT BUTTON -->
<div class="form-group text-right">
<button type="submit" class="btn btn-primary btn-lg">Submit</button>
<a id="add_city" class="btn btn-default pull-left">Add City</a><a id='delete_city' class="pull-right btn btn-default">Delete City</a>
</div>
</form>
I have looked at these two examples and I dont know why it does not work.. Please if anybody knows how to fix this problem it would help a lot :)
http://plnkr.co/edit/il2J8qOI2Dr7Ik1KHRm8?p=preview
http://bootsnipp.com/snippets/featured/dynamic-table-row-creation-and-deletion
Thanks!
/K.A.
You need to compile the element by using the $compile service:
...
$('#tab_logic').append('<div id="end_city' + (i + 1) + '"></div>');
var element = angular.element(document.querySelector('#end_city' + i));
var scope = element.scope();
var $compile = element.injector().get('$compile');
$compile(element)(scope);
...
Good short explanation of how to work with Angular from the 'outside' can be found here.

Categories