Generate tr on click of Image button jquery - javascript

I have a scenario where I want to duplicate the existing <tr> whenever I click on + button which is: <i class="fa fa-plus" aria-hidden="true"></i>
Below is my <tr>. how to generate this using jquery or javascript
<tr>
<td>
<div class="row noPadding vendorForm">
<div class="vendorDaterow">
<div class="vendorName">
<label>SP Vender Name</label><span>Shri Kamalkanth Co.</span>
</div>
<div class="vendorFromDate">
<label>From Date</label><span class="datepicker"><input type="text" id="spFromDate1" /><i class="fa fa-calendar" aria-hidden="true"></i></span>
</div>
<div class="vendorToDate">
<label>To Date</label><span class="datepicker"><input type="text" id="spToDate1" /><i class="fa fa-calendar" aria-hidden="true"></i></span>
</div>
</div>
<div class="add">
<i class="fa fa-plus" aria-hidden="true"></i>
</div>
<i class="max">(Maximum 5 Vendors)</i>
</div>
</td>
</tr>

You can use this
(function () {
var toAddCloneCount = 2;
$('.add').on('click', function() {
var $tr = $(this).closest('tr');
var $tr2 = $tr.clone(true, true);
$tr2.find(".vendorName").children('label').remove();
$tr2.find(".add").children().remove();
$tr2.find(".vendorFromDate").children('label').remove();
$tr2.find(".vendorToDate").children('label').remove();
$tr2.find('#txtVendorName').prop('id', 'txtVendorName' + toAddCloneCount);
$tr2.find('#spFromDate1').prop('id', 'spFromDate' + toAddCloneCount);
$tr2.find('#spToDate1').prop('id', 'spToDate' + toAddCloneCount++);
$tr2.insertAfter($tr);
});
})();
.vendorName,.vendorFromDate,.vendorToDate{
width:33%;float:left;}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>
<div class="row noPadding vendorForm">
<div class="vendorDaterow">
<div class="vendorName">
<label>SP Vender Name</label><span>#*Shri Kamalkanth Co.*#<input type="text" name="nmVendorData" id="txtVendorName" /></span>
</div>
<div class="vendorFromDate">
<label>From Date</label><span class="datepicker"><input type="text" id="spFromDate1" /><i class="fa fa-calendar" aria-hidden="true"></i></span>
</div>
<div class="vendorToDate">
<label>To Date</label><span class="datepicker"><input type="text" id="spToDate1" /><i class="fa fa-calendar" aria-hidden="true"></i></span>
</div>
</div>
<div class="add">
<i class="fa fa-plus" aria-hidden="true"></i>
</div>
<i class="max">(Maximum 5 Vendors)</i>
</div>
</td>
</tr>
</table>

You'd first clone() the parent <tr/> by finding it through closest() and insert it as a sibling via insertAfter(). Make sure to also pass true as arguments so that all descendants are passed along with their events and data.
$('.add').on('click', function() {
var $tr = $(this).closest('tr');
$tr.clone(true, true).insertAfter($tr)
});

Use clone() and after():
$(document).ready(function(){
$("i.fa-plus").click(function(){
var val = $("tr:last").clone()
$("tr:last").after(val)
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>
<div class="row noPadding vendorForm">
<div class="vendorDaterow">
<div class="vendorName">
<label>SP Vender Name</label><span>Shri Kamalkanth Co.</span>
</div>
<div class="vendorFromDate">
<label>From Date</label><span class="datepicker"><input type="text" id="spFromDate1" /><i class="fa fa-calendar" aria-hidden="true"></i></span>
</div>
<div class="vendorToDate">
<label>To Date</label><span class="datepicker"><input type="text" id="spToDate1" /><i class="fa fa-calendar" aria-hidden="true"></i></span>
</div>
</div>
</div>
</td>
</tr>
</table>
<div class="add">
<i class="fa fa-plus" aria-hidden="true">+</i>
</div>
<i class="max">(Maximum 5 Vendors)</i>

You need the template of the <tr> somehow. Use some kind of templating engine or the lazy way: copy it on page load. (to not have existing input when copying the <tr>)
var $template = $('yourTrSelector').clone();
And then paste it on button click.
$('yourButtonSelector').on('click', function(){
$('yourTableSelector').append($template.copy());
});

Related

How use sorting in ngx-datatable / ngx-datatable-column in Angular?

I'm trying to use ngx-datatable's sort feature to perform the action like this link: https://swimlane.github.io/ngx-datatable/
However, it does not work.
I've tried without luck to use properties like:
sortable="true"
[sortType]="'multi'"
[sorts]="[{prop: 'id_pessoa', dir: 'asc'}]"
Below is the code and version of ngx-datatable:
"#swimlane/ngx-datatable": "^15.0.2"
<section class="basic-elements">
<!-- Breadcrumbs -->
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a routerLink="/">Home</a>
</li>
<li class="breadcrumb-item active">
Pessoas
</li>
</ol>
</nav>
<div id="mb-4" class="row mb-4">
<div class="col-md">
<h1 class="h2">Pessoas</h1>
</div>
<div class="col-md">
<button routerLink="novo" type="button" class="btn btn-raised btn-raised btn-success btn-no-margin float-right btn-heigh2">
+ Nova Pessoa
</button>
</div>
</div>
<div id="mb-4" class="row mb-4">
<div class="col-md-11">
<input type="text" class="form-control" id="email" >
</div>
<div class="col-md-1">
<button [disabled]="submittingForm " type="submit" class="btn btn-raised btn-raised btn-no-margin btn-primary float-right btn-heigh button-margin-top">
Buscar
</button>
</div>
</div>
<div class="row text-left">
<div class="col-md-12">
<div class="card">
<div class="card-content">
<ngx-datatable
class="bootstrap"
[rows]="rows"
[columns]="columns"
[columnMode]="'force'"
[headerHeight]="10"
[footerHeight]="35"
[rowHeight]="35"
[externalPaging]="true"
[externalSorting]="true"
[scrollbarH]="true"
[count]="page.count"
[offset]="page.offset"
[limit]="page.limit"
[sortType]="'multi'"
[sorts]="[{prop: 'id_pessoa', dir: 'asc'}]"
(page)="pageCallback($event)">
<ngx-datatable-column name="Ações" sortable="true" prop="id_pessoa" width=140>
<ng-template let-row="data" let-value="value" ngx-datatable-cell-template>
<a class="btn btn-outline-primary mr-1" [routerLink]="[value,'editar']" href="javascript:void(0)">
<i class="fa fa-edit" title="Editar"></i>
</a>
<a class="btn btn-outline-primary mr-1" [routerLink]="[value,'subst']" href="javascript:void(0)">
<i class="fa fa-exchange" title="Substituir"></i>
</a>
<a class="btn btn-outline-primary mr-1" (click)="deletePessoa(value)" href="javascript:void(0)">
<i class="fa fa-trash" title="Remover"></i>
</a>
</ng-template>
</ngx-datatable-column>
<!--<ngx-datatable-column name="Pré-cad." prop="pre_cadastro" width=75>
<ng-template ngx-datatable-cell-template let-value="value">
<span *ngIf="value">
<i class="fa fa-check fa-2x"></i>
</span>
<span *ngIf="!value">
-
</span>
</ng-template>
</ngx-datatable-column>-->
<ngx-datatable-column *ngFor="let col of columns" [sortable]="true" [name]="col.name" [prop]="col.prop" [width]="col.width" [headerClass]="col.headerClass" [cellClass]="col.cellClass">
</ngx-datatable-column>
<ngx-datatable-column name="Inativo" prop="inativo" width=70>
<ng-template ngx-datatable-cell-template let-value="value">
<span *ngIf="value">
<i class="fa fa-check fa-2x"></i>
</span>
<span *ngIf="!value">
-
</span>
</ng-template>
</ngx-datatable-column>
</ngx-datatable>
</div>
</div>
</div>
</div>
there's an output for sort called sort you can use it and make your callback function
(sort)="onSort($event)"
It looks like you have [externalSorting]="true".
Try changing this to false or removing externalSorting (It defaults to false).

knockout sortable update function afer moving item to different position

I have knockout sortable bookmark page where it is possible to group your bookmarks and change the position. I have all my functions working but i can't seem to get the "afterMove" to work. This is my view:
<div class="col-lg-12">
<div class="bookmarkIconsBox">
<div data-bind="droppable: newGroup, connectClass : 'lists'" class="lists col-lg-6 bookmarkIcons bookmarkActionsBackground"><i class="fa fa-5x fa-plus"></i>Nieuwe groep aanmaken</div>
<div data-bind="droppable: deleteItem, connectClass : 'lists'" class="lists col-lg-6 bookmarkIcons bookmarkActionsBackground"><i class="fa fa-5x fa-trash"></i>Bookmark verwijderen</div>
</div>
<div class="bookmarkBoxTitle" data-bind="visible: $root.visible()">
<input class="title" data-bind="textInput: $root.groupname()" />
<span data-bind="click: function() { $root.setVisible(), $root.changeGroupName($root.groupname())}"><i class="fa fa-2x fa-save"></i></span>
<span data-bind="click: $root.setVisible, visible: $root.visible()"><i class="fa fa-2x fa-close"></i></span>
</div>
<div class="bookmarkBoxTitle" data-bind="visible: $root.visibleBookmarkName()">
<input class="title" data-bind="textInput: $root.bookmarkname()" />
<span data-bind="click: function() { $root.setVisibleBookmarkName(), $root.changeName($root.bookmarkname())}"><i class="fa fa-2x fa-save"></i></span>
<span data-bind="click: $root.setVisibleBookmarkName, visible: $root.visibleBookmarkName()"><i class="fa fa-2x fa-close"></i></span>
</div>
</div>
<div data-bind="foreach: allBookmarks.bookmarkGroups" class="col-lg-12">
<div class="bookmarkBoxTitle">
<h3 class="title" data-bind="text: Description" />
<span data-bind="click: function(){$root.edit(Description)}" class="editName"><i class="fa fa-2x fa-edit"></i></span>
</div>
<div data-bind="sortable: { template: 'itemTmpl', data: bookmarks, connectClass : 'lists', afterMove: $root.update($parent.allBookmarks.bookmarkGroups)}" id="sortable" class="lists bookmarkBackground">
</div>
</div>
<script id="itemTmpl" type="text/html">
<div class="card col-lg-4">
<div>
<span class="moveItem"><i class="fa fa-2x fa-arrows"></i></span>
<span data-bind="click: function(){$root.editBookmarkName(Description)}" class="editName"><i class="fa fa-2x fa-edit" data-bind="visible: !$root.visibleBookmarkName()"></i></span>
</div>
<div class="card-block">
<div class="bookmarkBoxTitle">
<h4 class="card-title" data-bind="text: Description " />
<h4 class="card-title" data-bind="text: $index" />
</div>
<ul class="card-text">
<li data-bind="text: workspace"></li>
<li data-bind="text: role"></li>
</ul>
<a class="btn btn-primary" data-bind="attr : {'href': '/#page/' + link }">Ga naar</a>
</div>
</div>
When i move an item in in a group or to a different group i want it to execute the $root.update() but i can't seem to get it to work.

Iterate in jquery to get values of input text

I have three rows of which I want to get the values of all the text by looping them all, so I tried something like this.
var collection = $(".vendorDaterow");
collection.each(function() {});
But while debugging i didn't find the value in any of the property.
Below is my html
<tr>
<td>
<div class="row noPadding vendorForm">
<div class="vendorDaterow">
<div class="vendorName" id="dvVendorNameData">
<label>SP Vender Name</label><span><input type="text" name="nmVendorData" id="txtVendorName" /></span>
</div>
<div class="vendorFromDate">
<label>From Date</label><span class="datepicker"><input type="text" name="spFromDate" id="spFromDate" class="dateClass" /><i class="fa fa-calendar" aria-hidden="true"></i></span>
</div>
<div class="vendorToDate">
<label>To Date</label><span class="datepicker"><input type="text" name="spToDate" id="spToDate" class="dateClass1" /><i class="fa fa-calendar" aria-hidden="true"></i></span>
</div>
</div>
<div class="add">
<i class="fa fa-plus" aria-hidden="true"></i>
</div>
<i class="max"><label>(Maximum 5 Vendors)</label></i>
</div>
</td>
</tr>
What should I do to get the values of the input text of all the element
This is walking down the tree method. You can make it shorter but it is self-explanetory.
var collection = $(".vendorDaterow");
collection[0].childNodes.forEach((element)=>{
if (element.tagName == 'DIV'){
//console.log(element.childNodes)
element.childNodes.forEach((element) => {
if(element.tagName == 'SPAN') {
//console.log(element.childNodes);
element.childNodes.forEach((element) => {
if(element.tagName == 'INPUT'){
console.log(element.value)
}
})
}
});
}
})
It iterates and finds the proper elements, assuming that the structure will remain the same. You can remove comment tags to get the flow.
Attempt no2.
function recursiveEach($element){
$element.children().each(function () {
var $currentElement = $(this);
// This is our input so we do something with it
if($currentElement[0].tagName == 'INPUT') {
console.log(" the values are: " + $currentElement[0].value)
}
//////////// Loop her children
recursiveEach($currentElement);
});
}
//////////// Parent div
recursiveEach($(".vendorDaterow"));
The syntax is more bit jquery-esk, but it has nice recursive form of iteration.
The following snippet prints only the input value when it changes. We use the selector $(".vendorDaterow") and the delegation event on the input that have changed.
$(".vendorDaterow").on('change', 'input', function(){
var text = $(this).val();
console.log(text);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<td>
<div class="row noPadding vendorForm">
<div class="vendorDaterow">
<div class="vendorName" id="dvVendorNameData">
<label>SP Vender Name</label><span><input type="text" name="nmVendorData" id="txtVendorName" /></span>
</div>
<div class="vendorFromDate">
<label>From Date</label><span class="datepicker"><input type="text" name="spFromDate" id="spFromDate" class="dateClass" /><i class="fa fa-calendar" aria-hidden="true"></i></span>
</div>
<div class="vendorToDate">
<label>To Date</label><span class="datepicker"><input type="text" name="spToDate" id="spToDate" class="dateClass1" /><i class="fa fa-calendar" aria-hidden="true"></i></span>
</div>
</div>
<div class="add">
<i class="fa fa-plus" aria-hidden="true"></i>
</div>
<i class="max"><label>(Maximum 5 Vendors)</label></i>
</div>
</td>
</tr>
The snippet below prints all the input values after a change. After a change in an input, each() will loop over all the input elements inside the class vendorDaterow and get their values.
var save;
$(".vendorDaterow input").on("change",function(){
save = []
$(".vendorDaterow input").each(function(){
var text = $(this).val();
if(text){
save.push(text);
}
})
console.log(save);
})
//console.log($(".vendorDaterow").html())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<tr>
<td>
<div class="row noPadding vendorForm">
<div class="vendorDaterow">
<div class="vendorName" id="dvVendorNameData">
<label>SP Vender Name</label><span><input type="text" name="nmVendorData" id="txtVendorName" /></span>
</div>
<div class="vendorFromDate">
<label>From Date</label><span class="datepicker"><input type="text" name="spFromDate" id="spFromDate" class="dateClass" /><i class="fa fa-calendar" aria-hidden="true"></i></span>
</div>
<div class="vendorToDate">
<label>To Date</label><span class="datepicker"><input type="text" name="spToDate" id="spToDate" class="dateClass1" /><i class="fa fa-calendar" aria-hidden="true"></i></span>
</div>
</div>
<div class="add">
<i class="fa fa-plus" aria-hidden="true"></i>
</div>
<i class="max"><label>(Maximum 5 Vendors)</label></i>
</div>
</td>

How to write text below checked textbox?

Here is my HTML and jQuery code. The code is working good but the problem is when I click on one checkbox, the text "FINISHED" becomes visible below all the checkboxes instead of that one only.
My html code is:
$('.label__checkbox').click(function() {
if ($(".label__checkbox").is(':checked')) {
$(".finish").css("display", "block");
} else {
$(".finish").css("display", "none");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="center">
<label class="label">
<input class="label__checkbox" type="checkbox" />
<span class="label__text">
<span class="label__check">
<i class="fa fa-check icon"></i>
</span>
</span>
</label>
<span class="finish">FINISHED</span>
</div>
<div class="center">
<label class="label">
<input class="label__checkbox" type="checkbox" />
<span class="label__text">
<span class="label__check">
<i class="fa fa-check icon"></i>
</span>
</span>
</label>
<span class="finish">FINISHED</span>
</div>
<div class="center">
<label class="label">
<input class="label__checkbox" type="checkbox" />
<span class="label__text">
<span class="label__check">
<i class="fa fa-check icon"></i>
</span>
</span>
</label>
<span class="finish">FINISHED</span>
</div>
<div class="center">
<label class="label">
<input class="label__checkbox" type="checkbox" />
<span class="label__text">
<span class="label__check">
<i class="fa fa-check icon"></i>
</span>
</span>
</label>
<span class="finish">FINISHED</span>
</div>
You can use DOM traversal method to target them in the current element context i.e. this
.closest() can be use to traverse up to label then use .next() to target the <span>
$('.label__checkbox').change(function() {
var finish = $(this).closest('.label').next(".finish");
//var finish = $(this).closest('.center').find(".finish");
if ($(this).is(':checked')) {
finish.css("display", "block");
} else {
finish.css("display", "none");
}
}).trigger('change');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="center">
<label class="label">
<input class="label__checkbox" type="checkbox" />
<span class="label__text">
<span class="label__check">
<i class="fa fa-check icon"></i>
</span>
</span>
</label>
<span class="finish">FINISHED</span>
</div>
<div class="center">
<label class="label">
<input class="label__checkbox" type="checkbox" />
<span class="label__text">
<span class="label__check">
<i class="fa fa-check icon"></i>
</span>
</span>
</label>
<span class="finish">FINISHED</span>
</div>

Change background color ng-click

I am new to angular, and I have a codepen that I am working in. I want to change the background color of another div to the corresponding color of the button when the user clicks the nav buttons at the bottom. I am not sure of the best way to implement this. Here is the code I have below.
Link to the codepen editor http://codepen.io/modDesigns/pen/YyKwGj
HTML
<div class="wrapper" ng-app="mobile">
<div class="phone">
<div class="page" ng-controller="Screen">
<div class="top_background" ng-style="{'background-color': changeScreen()}">
<i class="fa fa-signal sigs"></i>
<i class="fa fa-wifi sigs"></i>
<i class="fa fa-battery-full bats"></i>
<span class="times">11:44am</span>
<div class="home">
<h5 class="text-center"><i class="fa fa-user"></i> Account</h5>
</div>
<div class="navigation">
<div class="col-sm-3 homes" ng-style="{'background-color': '#C0392B'}" ng-click="changeScreen('#C0392B')">
<h4><i class="fa fa-home"></i></h4>
</div>
<div class="col-sm-3 shop" ng-click="" ng-style="{'background-color': '#E74C3C'}">
<h4><i class="fa fa-shopping-cart"></i></h4>
</div>
<div class="col-sm-3 feeds" ng-click="" ng-style="{'background-color': '#E67E22'}">
<h4><i class="fa fa-comment"></i></h4>
</div>
<div class="col-sm-3 settings" ng-click="" ng-style="{'background-color': '#F39C12'}">
<h4><i class="fa fa-cog"></i></h4>
</div>
</div>
</div>
</div>
</div>
Javascript
var app = angular.module('mobile', []);
app.controller('Screen', function($scope) {
$scope.changeScreen = function(myClass) {
$scope.theClass = myClass;
return $scope.theClass;
};
});
You actually don't need to write a function to get this working (unless you want to do more than you specified). You can use ngClick to set a variable and also use that variable as your background color, all within the HTML.
http://codepen.io/anon/pen/JYPJBR
<div class="wrapper" ng-app="mobile">
<div class="phone">
<div class="page" ng-controller="Screen">
<div class="top_background" ng-style="{'background-color': screenColor}">
<i class="fa fa-signal sigs"></i>
<i class="fa fa-wifi sigs"></i>
<i class="fa fa-battery-full bats"></i>
<span class="times">11:44am</span>
<div class="home">
<h5 class="text-center"><i class="fa fa-user"></i> Account</h5>
</div>
<div class="navigation">
<div class="col-sm-3 homes" ng-style="{'background-color': '#C0392B'}" ng-click="screenColor='#C0392B'">
<h4><i class="fa fa-home"></i></h4>
</div>
<div class="col-sm-3 shop" ng-click="screenColor='#E74C3C'" ng-style="{'background-color': '#E74C3C'}">
<h4><i class="fa fa-shopping-cart"></i></h4>
</div>
<div class="col-sm-3 feeds" ng-click="screenColor='#E67E22'" ng-style="{'background-color': '#E67E22'}">
<h4><i class="fa fa-comment"></i></h4>
</div>
<div class="col-sm-3 settings" ng-click="screenColor='#F39C12'" ng-style="{'background-color': '#F39C12'}">
<h4><i class="fa fa-cog"></i></h4>
</div>
</div>
</div>
</div>
</div>
But, if you just want to know why your code isn't working, it's because you're trying to use changeScreen() as both a getter and a setter, but it's not set up to do that.
You could either reference the variable theClass like so:
<div class="top_background" ng-style="{'background-color': theClass}">
Or else modify the function to not set theClass to undefined when you run it without arguments:
$scope.changeScreen = function(myClass) {
if(angular.isDefined(myClass)){
$scope.theClass = myClass;
}
console.log('the class', $scope.theClass);
return $scope.theClass;
};
Here is a codepen with what you wanted:
http://codepen.io/anon/pen/rOBwZV
HTML only is changed:
<div class="wrapper" ng-app="mobile" ng-init="bgCol='#F39C12'">
<div class="phone">
<div class="page" ng-controller="Screen">
<div class="top_background" style="background-color: {{bgCol}}">
<i class="fa fa-signal sigs"></i>
<i class="fa fa-wifi sigs"></i>
<i class="fa fa-battery-full bats"></i>
<span class="times">11:44am</span>
<div class="home">
<h5 class="text-center"><i class="fa fa-user"></i> Account</h5>
</div>
<div class="navigation">
<div class="col-sm-3 homes" ng-style="{'background-color': '#C0392B'}" ng-click="bgCol='#C0392B'">
<h4><i class="fa fa-home"></i></h4>
</div>
<div class="col-sm-3 shop" ng-click="bgCol='#E74C3C'" ng-style="{'background-color': '#E74C3C'}">
<h4><i class="fa fa-shopping-cart"></i></h4>
</div>
<div class="col-sm-3 feeds" ng-click="bgCol='#E67E22'" ng-style="{'background-color': '#E67E22'}">
<h4><i class="fa fa-comment"></i></h4>
</div>
<div class="col-sm-3 settings" ng-click="bgCol='#F39C12'" ng-style="{'background-color': '#F39C12'}">
<h4><i class="fa fa-cog"></i></h4>
</div>
</div>
</div>
</div>
</div>
The issue in your code is very tiny. Check this example to see how it works.
The first issue is that you call the method in html via:
<div class="top_background" ng-style="{'background-color': changeScreen()}">
Pay attention - no parameter passed to method.
But in angularjs method is expecting a class name.
Second, it would be better to have the entire style in an object as per example I provided, because in case there will be some other style properties, they can be added there and not call another function inside ng-style.
Hope this helps.

Categories