Click to delete dynamically created element in AngularJS - javascript

Currently whatever the user enters in the text box and clicks the button, is being displayed inside anchor tags dynamically (all in new lines).
Textbox and the button (HTML file)-
<input type="text" name="inputText"><br>
<tr>
<input type="button" value="ADD" ng-click="$ctrl.addtext()">
</tr>
<div id="outputDiv"></div>
JS function-
ctrl.addtext = function () {
var div = document.getElementById('outputDiv');
div.innerHTML += "<a href='' style='margin-left:10px'>"+newtext+"</a><br>";
}
Is there a way to add a close/remove button (like an X) at end of the dynamically created anchor tags, that On-click remove those particular rows of only?

Edit 3
Using a different component syntax:
function scanExceptionComponentCtrl ($scope, $compile) {
var ctrl = this;
ctrl.addtext = function (e) {
var newtext = document.listForm.inputText.value
var outputDiv = $('#outputDiv');
var newRow = $compile("<a href='' style='margin-left:10px'>"+newtext+" - <span ng-click='$ctrl.removeRow($event)'>X</span></a><br>")($scope);
newRow.appendTo(outputDiv)
};
ctrl.removeRow = function(e) {
e.preventDefault();
e.target.parentNode.remove();
};
};
// angular.module('consoleApp', [])
angular.module('consoleApp',[])
.component('scanException', {
templateUrl: 'templateId',
controller: scanExceptionComponentCtrl
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
<div ng-app="consoleApp">
<scan-exception></scan-exception>
<script type="text/ng-template" id="templateId">
<form name="listForm">
<table border="0" cellspacing="0">
<tr>
<input type="radio" style="margin-left:10px;" name="checkRadio" value="append" checked><span class="add-file-text" style="font-weight:bold;">Add File to Exception List</span><br>
<input type="text" style="width:250px;height:30px;margin-left:10px;margin-top:10px;" name="inputText"><br>
</tr>
<tr>
<input type="button" style="margin-left:10px;margin-top:10px;" value="ADD" ng-click="$ctrl.addtext($event)">
</tr>
<tr>
<td>
<div id="outputDiv"></div>
</td>
</tr>
</table>
</form>
</script>
</div>
Edit 2 - updates to use jQuery syntax and pass $scope into $compile
add an ng-click and use $compile (make sure to include in controller)
ctrl.addtext = function () {
var outputDiv = $('#outputDiv');
var newRow = $compile("<a href='' style='margin-left:10px'>" + 'newtext ' + " <span ng-click='removeRow($event)'>X</span></a><br>")($scope);
newRow.appendTo(outputDiv)
};
create function
I'm not sure exactly what element you wanted to remove.
ctrl.removeRow = function(e) {
e.preventDefault();
e.target.parentNode.remove();
};
Code Snippet
There may be differences in how you are writing your components/controllers.
angular.module('myApp', [])
.controller('myController', function ($scope, $compile) {
$scope.addText = function () {
var outputDiv = $('#outputDiv');
var newRow = $compile("<a href='' style='margin-left:10px'>" + 'newtext ' + " <span ng-click='removeRow($event)'>X</span></a><br>")($scope);
newRow.appendTo(outputDiv)
};
$scope.removeRow = function(e) {
e.preventDefault();
e.target.parentNode.remove();
};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
<button ng-click="addText($event)">add text</button>
<div id="outputDiv"></div>
</div>

You can use the $event property in angular or something like a html-5 data attribute to retrieve the info of the clicked element. Roughly your code would look like this:
HTML:
<input type="button" value="ADD" ng-click="$ctrl.addtext($event)">
and JS
ctrl.addtext = function (event) {
var clickedElem = document.getElementById(event.target.id);
// do whatever you want with the element.
var div = document.getElementById('outputDiv');
div.innerHTML += "<a href='' style='margin-left:10px'>"+newtext+"</a><br>";
}

Related

how to display the array of values for the single field using jquery?

Here I need to get all the values entered in the input field. But it echoes only the first value.
ie. When I press the + and give some values, I need to get that value too.
$(document).ready(function() {
$(document).on("click", ".add", function() {
var clone = '<div class="add1"><input type="text" name="selprice" /><input type = "submit" value = "+" class = "add" ><input type = "submit" value = "-" class = "remove" ></div>';
$(this).closest('.add1').after(clone);
});
$(document).on("click", ".remove", function() {
$(this).parent(".add1").remove();
});
});
$('#package').change(function() {
var arr = [];
$("input.packageclass").each(function() {
arr.push($(this).val());
alert(arr);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<div class="add1">
<h6>Sales Package </h6>
<div>
<input type="text" name="package" placeholder="Ex:34" id="package" class="packageclass">
<input type="submit" value="+" class="add"></div>
</div>
$('.package').change(function() {
You are using an ID in your input type="text". IDs are only used once. If you want to add the listener to all of your textfields use classes.
In addition to that the .change(function() is only once called, when the dom is ready. That will be a problem too. So the change listener is not added to the generated textfields. Maybe you use something like...
$('.package').on('change', 'input', function() {
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<div class="add1">
<h6>Sales Package </h6>
<div>
<input type="text" name="package" placeholder="Ex:34" id="package" class="packageclass">
<input type="submit" value="+" class="add">
</div>
</div>
<script type="text/javascript">
var addInput = function(e) {
var arr = [];
$("input.packageclass").each(function() {
arr.push($(this).val());
});
alert(arr);
};
$(document).ready(function() {
$(document).on("click", ".add", function() {
var clone = '<div class="add1"><input class="packageclass" type="text" name="selprice" /><input type = "submit" value = "+" class = "add" ><input type = "submit" value = "-" class = "remove" ></div>';
$(this).closest('.add1').after(clone);
$('.packageclass').unbind().bind('change', addInput);
});
$(document).on("click", ".remove", function() {
$(this).parent(".add1").remove();
});
});
$('.packageclass').unbind().bind('change', addInput);
</script>
Just using loop you can get the particular value from loop.
for (var i = arr.length - 1; i >= 0; i--) {
arr[i];
//work with arr[]
}
I have used event delegation to capture the events and take appropriate action.
In this, you can add a event listener to your parent element i.e., click to the .body in my case. When I click on the .add button, the event propagates and .body click handler gets invoked. By checking for event.target we can find out the origin of event and add or remove the divs.
Similary we can listen for the change event of the input boxes and take appropriate actions.
$('#body').click(function(e) {
if(e.target.className === 'add') {
$('#body').append(`
<div class="add1">
<input type="text" name="package" placeholder="Ex:34" id="package" class="packageclass">
<button class="add">+</button>
<button class="remove">-</button>
</div>
`);
}
if(e.target.className === 'remove') {
$(e.target).parent().empty();
}
});
$('#body').change(function(e) {
console.log(e.target.value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<div id="body">
<h6>Sales Package </h6>
<div class="add1">
<input type="text" name="package" placeholder="Ex:34" id="package" class="packageclass">
<button class="add">+</button>
</div>
</div>
Just add class="packageclass" to the input when creating your clone variable.
https://jsfiddle.net/289xvmu7/
var clone = '<div class="add1"><input type="text" name="selprice" class="packageclass"/> <input type = "submit" value = "+" class = "add" ><input type = "submit" value = "-" class = "remove" ></div>';

Input field validated only for first input field and not able to remove input field

I had created Ul which add the student input field with value and user can remove the field as well,Initially I am comparing student field value with each input field which are created to avoid duplication but it works only for first input field value not for others I used loop as well but its not working and not able to remove one input field at a time.
Here is my fiddle code
$('#addBtn').click(function () {
var studentArray = $(".students").text();
var i=" " ;
console.log(studentArray);
var studentSplitResult = studentArray.split('Remove');
console.log(studentSplitResult);
for (var i = 0; i < studentSplitResult.length; i++) {
if ($("#selectStd").val() !== $(".students").val()) {
$(".stdList").show();
var input_value = $('#selectStd').val();
$('ul').append('<input class="students" value="' + input_value + '">Remove</input>');
console.log($(".students").val());
// console.log(studentSplitResult[i]);
};
return false;
}
});
//prevent default action
$(document).on('click', 'a', function (e) {
e.preventDefault();
$(this).parent().remove();
});
You can simplify your code like below.
Just check any text input has the new value before adding using filter. It will also handle case insensitivity (remove if required).
Also while removing consider the removing the text input only.
Added e.preventDefault() to restrict the form posting. change or remove it as per requirement.
$('#addBtn').click(function(e) {
e.preventDefault();
var input_value = $("#selectStd").val();
var isValid = $('input.students').filter(function() {
return this.value.toLowerCase() == input_value.toLowerCase();
}).length <= 0;
if (isValid) {
$('ul').append('<input class="students" value="' + input_value + '">Remove</input>');
} else {
alert('Duplicate');
}
});
//prevent default action
$(document).on('click', 'a.deleteStd', function(e) {
e.preventDefault();
$(this).prev('.students').remove();
$(this).remove();
});
<body>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<div class="panel panel-body" style=" width:422px;border: 1px solid #00A4CC;">
<div id="errorLabel"></div>
<div id="parentType">
<form id="parentForm" name="parentForm">
<table style="margin-left: 8px;">
<tr>
<th>Select Student</th>
<td><input class="form-control" id="selectStd" placeholder="Please select students"></td>
<td><button id="addBtn" class="btn btn-default" style="margin-left: 17px;">Add</button></td>
</tr>
</table>
<ul class="stdList">
<label>Selected Students:</label><br>
<br>
</ul>
<table>
</table>
</form>
</div>
</div>
</div>
</body>
I have encountered two issues: input validation itself (your question) and the removal of the element when you click on the anchor element.
For input validation, I have rewritten it a bit. What I did is
1. Obtain new student value
2. Check if not empty by if(newStudent). If it's empty, nothing happens
3. obtain other inputs
4. match the new input against the values inside other inputs
4a. if match, don't add it.
4b. if no match, add it
For removing the element, You need to revise your HTML. It's not so correct. I have wrapped it around with a <section> element to have a save removal and corrected the HTML use.
A side note, you may also reconsider this
$(document).on('click', 'a', function(e) {
e.preventDefault();
$(this).parent().remove();
});
If your HTML page has multiple anchor (<a>) elements, this function is used too on another anchor elements. If you click on these, it will remove these from the page upon click. If you don't want it, please revise the above function.
$('#addBtn').click(function(e) {
// obtain new student value
var newStudent = $('#selectStd').val();
// check if it is not empty
if (newStudent) {
// obtain other names and check if there is no match
var studentArray = $(".students");
var hasMatch = false;
studentArray.each(function(i, el) {
if (el.value === newStudent) {
hasMatch = true;
return; // stopping loop
}
});
// if there is no match, add student
if (!hasMatch) {
$('ul.stdList').append('<section><input class="students" value="' + newStudent + '" />Remove</section>');
}
}
return false;
});
//prevent default action
$(document).on('click', 'a', function(e) {
e.preventDefault();
$(this).parent().remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panel panel-body" style=" width:422px;border: 1px solid #00A4CC;">
<div id="errorLabel"></div>
<div id="parentType">
<form id="parentForm" name="parentForm">
<table style="margin-left: 8px;">
<tr>
<th>Select Student</th>
<td>
<input class="form-control" id="selectStd" placeholder="Please select students">
</td>
<td>
<button id="addBtn" class="btn btn-default" style="margin-left: 17px;">Add</button>
</td>
</tr>
</table>
<ul class="stdList">
<label>Selected Students:</label>
<br>
<br>
</ul>
</form>
</div>
</div>
When adding you try this:
$('ul').append('<input class="students" value="' + input_value + '">Remove</input>');
Unfortunately this will not result in what you expect. The anchor will be adding by your browser next to the input not nested. Like this:
<input class="students" value="thevalue" />
<a href class="deleteStd">Remove</a>
So if you do this afterwards for removing $(this).parent().remove(); you will remove the entire container.
What you need to do is this:
$('ul').append('<div><input class="students" value="' + input_value + '" />Remove</div>');
This will work. I have updated your fiddle: https://jsfiddle.net/Lojdfyhn/1/
So based on your requirements, try this below code:
Student names can't be duplicate
And on removing, all names shouldn't removed.
While adding, code checks if the student name exists. If yes, it throws an error/alert.
$('#addBtn').click(function() {
var valueToCheck = $("#selectStd").val();
var flag = true;
$(".students").each(function() {
if ($(this).val() === valueToCheck) {
flag = false;
}
});
if (flag) {
$('ul').append('<span class="addedStudent"><input class="students" value="' + valueToCheck + '" />Remove</span>');
} else {
alert(valueToCheck + " already exists.");
}
return false;
});
//prevent default action
$(document).on('click', 'a.deleteStd', function(e) {
e.preventDefault();
$(this).parents(".addedStudent:first").remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panel panel-body" style=" width:422px;border: 1px solid #00A4CC;">
<div id="errorLabel"></div>
<div id="parentType">
<form id="parentForm" name="parentForm">
<table style="margin-left: 8px;">
<tr>
<th>Select Student</th>
<td><input class="form-control" id="selectStd" placeholder="Please select students"></td>
<td><button id="addBtn" class="btn btn-default" style="margin-left: 17px;">Add</button></td>
</tr>
</table>
<ul class="stdList">
<label>Selected Students:</label><br>
<br>
</ul>
<table>
</table>
</form>
</div>
</div>
You are trying to delete the parent element of anchor tag.
Just update your code like this
$('ul').append('<div><input class="students" value="' + input_value + '">Remove</input></div>');
then clicking on anchor will delete the parent of anchor element.
Hello first of all you need to get a good understanding of the DOM traversing, which can really help you to organise the students that you are adding to the list, and removing.
Here a simple solution can be implemented as follows.
First encapsulate all the students in a div tag with 'students' class name, and in that div, place the student text field with 'stdname' class and the anchor tag to help in removing the student details.
Now when traverse through all the students with 'stdname' class and check if there is a duplicate value.
Here is the code please check out.
and check on jsfiddle too.http://jsfiddle.net/naveen_namani/842bf5ke/1/
$('#addBtn').click(function () {
var student_list=document.querySelectorAll(".students .stdname");
var selectStd=document.getElementById("selectStd");
var duplicate=false;
for(var i=0;i<student_list.length;i++) {
if(student_list[i].value==selectStd.value) duplicate=true;
}
if(duplicate==false) {
$('ul').append('<div class="students"><input value="'+selectStd.value+'" class="stdname"/>Remove');
}
return false;
});
$(document).on('click', 'a', function (e) {
e.preventDefault();
$(this).parent().remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panel panel-body" style="width:422px;border:1px solid #00A4CC;">
<div id="errorLabel"></div>
<div id="parentType" >
<form id="parentForm" name="parentForm">
<table style="margin-left: 8px;">
<tr>
<th>Select Student</th>
<td>
<input class="form-control" id="selectStd" placeholder="Please select students">
</td>
<td>
<button id="addBtn" class="btn btn-default" style="margin-left: 17px;" >Add</button>
</td>
</tr>
</table>
<ul class="stdList">
<label>Selected Students:</label>
<br><br>
</ul>
<table ></table>
</form>
</div>
</div>

javascript removechild and remove not working

I'm trying to generate a row dynamically. It's generating but, I'm not able to remove the row....
<script type="text/javascript">
function Clonediv(divid) {
var application_id = $('#app_id').val();
//var rn = $('#rownum').val;
// var i = 0;
//alert(rn);
var rownum;
if (application_id != "") {
var cloned = $('#hdnClonedrows').val();
var num = parseInt(cloned);
num = num + 1;
i = i + 1;
$('#hdnClonedrows').val(num);
clonedelement = num;
rownum = "Requirement" + i;
// alert(rownum);
var newtr = document.createElement('tbody');
newtr.id = "Clonedrow_" + clonedelement;
$('#tableroles1').append(newtr);
$('#rowtoclone').css("display", "block");
var abc = $('#rowtoclone').clone();
$('#rowtoclone').css("display", "none");
abc.appendTo(newtr);
}
else {
alert("Please select an application to add a Requirement");
//$('#errordiv').html('Please select an application to add a Requirement<br/><br/>');
}
}
$("#remove").on("click", ".removebutton", function (e) {
//e.preventDefault();
//e.stopImmediatePropagation();
e.removeChild(tableroles1);
$(this).parents("newtr").remove();
});
</script>
<html>
<a id="Adddiv" class="clAddNewLeft" href="javascript:Clonediv();">Add Requirements</a><br />
#{
string rowid = "Clonedrow_" + #clonedelement;
int rownum = 1;
//rownum = rownum + 1;
<div id = '#rowid'>
<table id="tableroles1">
<tr id="rowtoclone" style="display: none">
<td>
<label id="rownum">Requirement #rownum </label>
</td>
<td class="editValue">
#Html.TextAreaFor(m => m.requirements, new { #class = "updatable", #style = "height : 150px; width : 653px" })
</td>
<td class="editValue">
#using (Html.BeginForm("FileUpload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" id="fileToUpload" />
<input type="submit" id="btnSubmit" value="upload" />
}
</td>
<td>
<img alt="delete" src="../../Images/deleteIcon4.gif" id="remove" style="cursor: pointer;" />
</td>
</tr>
</table>
</div>
}
</html>
It looks like you're using .removeChild() on something that is really a parent. If you're trying to remove the "tableroles1" table, try to use this for your delete function:
$("#remove").on("click", function (e) {
$("#tableroles1").remove();
});
This should do the following:
1) When the user clicks on the delete image it calls the function above
2) We then target 3 parent nodes above the image tag, which is <table id="tableroles1">
3) We then remove that parent which will remove all of the child elements as well.

How to Change each Appended text Angularjs

I'm not getting result properly using append event instead of using ng-repeat in adding each name. Can you please help me how can I change added each name from a single input field. Tell me without using ng-repeat in this because ng-repeat functionality is not working to me for my further running functionalities, you can solve this using jquery or javascript if it's possible without using ng-repeat. Thanks in advance..
Here is JSBin
var app = angular.module('myapp', ['ngSanitize']);
app.controller('AddCtrl', function ($scope, $compile) {
$scope.my = {name: 'untitled'};
$scope.add_Name = function (index) {
var namehtml = '<label ng-click="selectName($index)">{{my.name}} //click<br/></label>';
var name = $compile(namehtml)($scope);
angular.element(document.getElementById('add')).append(name);
};
$scope.selectName = function (index) {
$scope.showName = true;
};
});
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.2/angular.min.js"></script>
<script src="https://code.angularjs.org/1.5.0-rc.0/angular-sanitize.min.js"></script>
</head>
<body ng-controller="AddCtrl">
<button ng-click="add_Name($index)">Add Names</button>
<div id="add"></div><br/>
<form ng-show="showName">
<label>Name Change(?)</label><br/>
<input ng-model="my.name">
</form>
</body>
</html>
If I understand what you're looking for correctly this should work.
HTML:
<body ng-controller="AddCtrl">
<button ng-click="add_Name()">Add Names</button>
<div ng-repeat="item in names">
<label ng-click="selectName($index)">{{$index}}- {{item}} //click to change<br/></label>
</div>
<form ng-show="showName">
<label>Name Change at index {{nameIndex}}</label><br/>
<input ng-model="names[nameIndex]">
</form>
</body>
JS:
$scope.names = [];
$scope.add_Name = function(index){
$scope.names.push('untitled')
}
$scope.selectName = function (index) {
$scope.nameIndex = index;
$scope.showName = true;
};

Attribute directive in AngularJS

I am trying to create a attribute directive that will insert a label before the input field. Judging by the alert statement, the html looks correct. However I am not compiling or doing the angular element correctly. Any help would would be much appreciated.
The fiddle is http://jsfiddle.net/2suL9/
This is the JS code.
var myApp = angular.module('myApp', []);
myApp.directive('makeLabel', function ($compile) {
return {
restrict: 'A',
replace: false,
link: function (scope, inputFld, attrs) {
var ForInput = attrs['name'];
var LabelSize = attrs['labelSize'];
var LabelText = attrs['makeLabel'];
var htmlStart = '<label for="' + ForInput + '" class="label-control ' + LabelSize + '">';
var htmlStar = '';
if (attrs['required'] ) {
htmlStar = '<span style="color:red">*</span>';
}
var htmlEnd = LabelText + ":</label> ";
var htmlTotal = htmlStart + htmlStar + htmlEnd;
alert(htmlTotal);
// Now add it before the input
var newLabel = angular.element(htmlTotal);
inputFld.prepend(($compile(htmlTotal)));
}
};
});
This is the HTML
<!DOCTYPE html>
<html class="no-js" data-ng-app="myApp">
<head>
<title></title>
</head>
<body>
<div class="container">
<div class="row">
<form name="TestLabelForm" class="form-horizontal">
<div class="form-group">
<input type="text" name="Simple" required="" make-label="Test Label" label-size="col-md-7" />
</div>
</form>
</div>
<br />
Should look like
<br />
<div class="row">
<form name="ExampleForm" class="form-horizontal">
<div class="form-group">
<label for="Simple2" class="col-md-7"><span style="color:red">*</span>Test Label:</label>
<input type="text" name="Simple2" required="" />
</div>
</form>
</div>
</div>
<!-- Get Javascript -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js">
</script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js"> </script>
<script src="js/TestLabelAttr.js"> </script>
</body>
</html>
Did you see the DOM Exception, which was thrown? It could not find the elements, which you created. You have to use document.createElement() and introduce the newly created element to the scope via $compile(scope)(newElement). Here is a working fiddle of this: http://jsfiddle.net/2suL9/26/ Please note that I didn't implement the if condition of your example, you have to add it!
The javascript part looks like this:
var myApp = angular.module('myApp', []);
myApp.directive('makeLabel', function ($compile) {
return function (scope, inputFld, attrs) {
var el = inputFld[0];
var newEl = document.createElement("label");
newEl.setAttribute("for", attrs['name']);
newEl.setAttribute("class", "label-control");
var subEl = document.createElement("span");
subEl.setAttribute("style", "color:red");
subEl.innerHTML = "*";
var endText = document.createTextNode("Test Label:");
$compile(scope)(newEl);
$compile(scope)(subEl);
$compile(scope)(endText);
newEl.appendChild(subEl);
newEl.appendChild(endText);
inputFld.parent().prepend(newEl);
}
});
Note: Changing the dom elements outside of the directive is not a good practice. Rather use another directive for the label, which should be shown in front of the input. You can centralise the logic in your controller and use broadcast to inform the directives, when they should change.

Categories