ngTable with icon outside of table - angularjs

I would want the trash bin icon to appear outside of the table. Right now its inside the table and upon hovering, the trashbin icon would appear before pushing the content to the right. How do i make it such that the trash bin icon would appear outside of the table beside each content?
JS
$scope.tdemo = {};
// table dataset
$scope.myDataset = [
{
name: 'eeee',
lastname: 'dada',
},
{
name: 'abc',
lastname: 'kfc',
}
];
$scope.hoverIn = function () {
this.hoverEdit = true;
};
$scope.hoverOut = function () {
this.hoverEdit = false;
};
HTML
<table ng-table="twinTableParams" class="table hover">
<tbody>
<tr ng-repeat="trans in $data" ng-mouseover="hoverIn()"
ng-mouseleave="hoverOut()">
<td>
<span ng-show="hoverEdit" class="animate-show">
<a><i class="fi-trash"></i></a>
</span>
</td>
<td ng-model="name" title="'name'">{{trans.name}}</td>
<td ng-model="lastname" title="'lastname'">{{trans.lastname}}</td>
</tr>
</tbody>
</table>

In order to do that (I don't really understand what's the good UX for it). You can set this as a float element and move it outside the table.

Change this to $scope. You can use this if you are using controller As syntax
$scope.hoverEdit=[];
$scope.hoverIn = function (index) {
$scope.hoverEdit[index] = true;
};
$scope.hoverOut = function (index) {
$scope.hoverEdit[index] = false;
};
And change your HTML to the following
<table ng-table="twinTableParams" class="table hover">
<tbody>
<tr ng-repeat="trans in $data" ng-mouseover="hoverIn($index)" ng-mouseleave="hoverOut($index)">
<td ng-model="name" title="'name'">
{{trans.name}}
</td>
<td ng-model="lastname" title="'lastname'">
{{trans.lastname}}
</td>
</tr>
</tbody>
</table>
<div ng-repeat="trans in $data">
<span ng-show="hoverEdit[$index]" class="animate-show" >
<a>
<i class="fi-trash"></i>
</a>
</span>
</div>

Related

Angularjs rename items in an array

Adding items from one array to a new array using:
$scope.listItems = [];
$scope.addToList = function(item) {
$scope.listItems.push(item);
console.log($scope.listItems);
};
<tr ng-repeat="x in data">
<td><{{ x.id }}</td>
<td><button type="button" ng-click="addToList(x.id)">Add to</button></td>
</tr>
Then printing the new array:
<tr ng-repeat="item in listItems">
<td>{{item.id}}</td>
</tr>
Would it be possible to change the attribute names of the new listItems array using user input?
Sure its possible. But not the way your code is written. You need to pass the object to the function, not the id.
<tr ng-repeat="x in data">
<td>{{ x.id }}</td>
<td><input type="text" ng-model="newVal"/></td> <!--this property can be changed by user-->
<td><button type="button" ng-click="addToList(x, newVal)">Add to</button></td>
</tr>
and in the controller function:
$scope.addToList = function(item, newVal) {
var newItem = item;
newItem.id = newVal;
$scope.listItems.push(item);
console.log($scope.listItems);
};
You could definitely do that, But for that you need to pass in the object in itself not x.id.
Here is a sample working solution.
var app = angular.module("sampleApp", []);
app.controller("sampleController", ["$scope",
function($scope) {
$scope.data = [{
id: "City-1"
}, {
id: "City-2"
}, {
id: "City-3"
}, {
id: "City-4"
}, {
id: "City-5"
}];
$scope.listItems = [];
$scope.addToList = function(item) {
$scope.listItems.push(item);
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="sampleApp">
<div ng-controller="sampleController">
<table>
<tr ng-repeat="x in data">
<td>
{{ x.id }}</td>
<td>
<button type="button" ng-click="addToList(x)">Add to</button>
</td>
</tr>
</table>
New List:
<table>
<tr ng-repeat="item in listItems track by $index">
<td>
{{ item.id }}</td>
<td>
<button type="button" ng-click="addToList(x)">Add to</button>
</td>
</tr>
</table>
</div>
</div>

My ui not getting updated after updating list in the js file

<td rowspan="5" colspan="2">
<div id="style-2" class="scrollit">
<table class="table-borderless table-condensed" style="height:100px; width:100%; overflow-y:scroll">
<tr>
<td colspan="2" class="verticleAlignMidle">
<h6><b>{{ctrl.commentsBox.length}} Comments:</b></h6>
</td>
</tr>
<tr ng-repeat="item in ctrl.commentsBox">
<td class="width8">
<div class="commentCol divStyle">{{item.name}}</div>
</td>
<td class="width11">
<span><b>{{item.FullName}}</b> {{item.date}}</span>
<br /> <span>{{item.comment}}</span>
</td>
</tr>
</table>
</div>
</td>
This is my list. That need to be updated on adding comment and pressing enter:
<td class="width33 verticleAlignMidle" colspan="2">
<textarea cols="80" rows="5" ng-keyup="$event.keyCode == 13 ? ctrl.saveAdGroup() : null"
ng-model="ctrl.textComment" ng-view="ctrl.textComment" placeholder="Write a comment"></textarea>
</td>
And the function is :
ctrl.saveAdGroup = function () {
var ctrl = this;
var c = ctrl.textComment;
ctrl.textComment = "";
var n = "DN";
var fullName = "Dummy Name";
var formatDate = ctrl.dates();
var objComment = { name: n, date: formatDate, comment: c, FullName: fullName };
ctrl.commentsBox.push(objComment);
alert(ctrl.commentsBox.length);
};
I m getting increased length in the alert but not reflecting in the ui.
You need to call angular watcher manually using:
$scope.$apply()

Edit row in angularjs table

I have the following angular table with an edit button
<table class="tableData" border="0" cellspacing="0" cellpadding="0">
<thead>
<tr>
<th></th>
<th>Budget Name</th>
<th>Year</th>
<th>Month</th>
<th></th>
</tr>
</thead>
<tbody ng-repeat="(ind,O) in budgetdetails">
<tr ng-class-even="'even'" ng-class-odd="'odd'">
<td class="CX"><span>+</span></td>
<td>{{O.budget.BudgetName}}</td>
<td>{{O.budget.Year}}</td>
<td>{{O.budget.Month}}</td>
<td><input type="button" value="Remove" class="btn btn-primary" data-ng-click='removeRow(O)' />
<input type="button" value="Edit" class="btn btn-primary" data-ng-click='EditRow(O)' /></td>
</tr>
<tr class="sub">
<td></td>
<td colspan="5">
<table class="tableData" border="0" cellspacing="0" cellpadding="0">
<tr>
<th>Category</th>
<th>SubCategory</th>
<th>Amount</th>
</tr>
<tr ng-repeat="(indx,a) in O.budgetdetails" ng-class-even="'even'" ng-class-odd="'odd'">
<td>{{a.Category}}</td>
<td>{{a.Subcategory}}</td>
<td>{{a.Amount| currency}}</td>
</tr>
#* <tr>
<td colspan="2">Total</td>
<td></td>
<td>{{Totals().Amount| currency}}</td>
</tr>*#
</table>
</td>
</tr>
</tbody>
</table>
I want to be able to edit the data when I click on the edit button so far I have been playing with the angular controller and I have this
$scope.EditRow = function (item) {
$scope.budget = item.budget;
$scope.idBudget = item.budget.idBudget;
$scope.BudgetName = item.budget.BudgetName;
$scope.Year = item.budget.Year;
$scope.Month = item.budget.Month;
resp=BDetail.FindBudgetById(item.budget.idBudget);
};
The last line call a json and returns a set of data which I want to send to the page were I create the budgets for editing. Now I am not sure how to send the json to another page and the page that receives it is the View were I create the budgets and it has an IEnumerable editor to repeat the budgets details. Code is as follows
#model BudgetPortalMVC4.Models.budget
#{
ViewBag.Title = "NewBudget";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#Scripts.Render("~/bundles/jquery")
<script src="../../Scripts/jquery.validate.js" type="text/javascript"> </script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
<h2>NewBudget</h2>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<div>
<table>
<tr>
<td>
<div class="editor-label">
#Html.LabelFor(model => model.BudgetName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.BudgetName)
#Html.ValidationMessageFor(model => model.BudgetName)
</div>
</td>
<td>
<div class="editor-label">
#Html.LabelFor(model => model.Year)
</div>
<div>
#Html.DropDownListFor(model => model.Year, BudgetPortalMVC4.Controllers.BudgetController.GetDropDownListForYears())
#Html.ValidationMessageFor(model => model.Year)
</div>
</td>
<td>
<div class="editor-label">
#Html.LabelFor(model => model.Month)
</div>
<div>
#Html.DropDownListFor(model => model.Month, BudgetPortalMVC4.Controllers.BudgetController.GetDropDownListForMonth())
#Html.ValidationMessageFor(model => model.Month)
</div>
</td>
</tr>
</table>
</div>
<div>
<h3>Budget Detail</h3>
<div> <input type="button" id="addbudgetdetail" value="Add row" /></div>
<div id="new-budgetdetail">
#Html.EditorForMany(x => x.budgetdetails)
</div>
<input type="submit" />
</div>
#section Scripts{
<script type="text/jscript">
var url = '#Url.Action("GetSubCategories", "Budget")'; // Do not hard code your url's
$(document).on('change', '.SelectedCategory', function () {
var subCategory = $(this).closest('.item').find('.SelectedSubCategory');
subCategory.empty();
$.getJSON(url, { id: $(this).val() }, function (data) {
if (!data) {
return;
}
subCategory.append($('<option></option>').val('').text('Please select')); // Do not give the option a value!
$.each(data, function (index, item) {
subCategory.append($('<option></option>').val(item.Value).text(item.Text));
});
});
});
$(function () {
$('#addbudgetdetail').on('click', function () {
jQuery.get('#Url.Action("AddBudgetDetail", "Budget")').done(function (html) {
$('#new-budgetdetail').append(html);
$('form').data('validator', null);
$.validator.unobtrusive.parse($('form'));
});
});
$(".deleteRow").on("click", '', function () {
$(this).parents("#budgetRow:first").remove();
return false;
});
});
</script>
}
}
How can I accomplish passing the json data to this view and turning the view into and updating form instead of a create form?

Creating dynamic invoice with angularjs

I try to create a dynamic invoice, i have quantity and price column, and then i get total Value Of Products, so when i change value of quantity, price and total value should be changed, i find a way to change price but total value does not work:
<div class="container" ng-controller="OrderController" ng-init="quantity=1">
<div id="order-detail-content" class=" row">
<table id="cart_summary">
<thead>
<tr>
<th>Total</th>
<th> </th>
<th>Qty</th>
<th>Unit price</th>
<th>Availability</th>
<th>Description</th>
<th>Product</th>
</tr>
</thead>
<tfoot>
<tr class="cart_total_price">
<td colspan="2" class="price" id="total_product">{{totalValueOfProducts}}</td>
<td colspan="3" class="text-right">Total</td>
<td rowspan="4" colspan="3" id="cart_voucher" class="cart_voucher"></td>
</tr>
</tfoot>
<tbody>
<tr ng-repeat="order in Orders track by $index" >
<td class="cart_total" data-title="Total">
<span class="price" id="total_product_price_3_13_0">
{{order.Price * quantity}}
</span>
</td>
<td >
<input size="2" ng-model="quantity" type="text" value="1" name="quantity_3_13_0_0">
</td>
<td>
<ul class="price text-right" id="product_price_3_13_0">
<li ng-model="order.Price" class="price"> {{order.Price}}</li>
</ul>
</td>
<td class="cart_description">
<p style="color:black" class="product-name">{{order.ProductName}}</p>
<hr />
<small style="color:black" class="cart_ref">{{order.ProductDescription}}</small>
</td>
<td class="cart_product">
<img ng-src="" alt="Printed Dress" width="98" height="98">
</td>
</tr>
</tbody>
</table>
</div> <!-- end order-detail-content -->
and in controller i define $watch on quantity :
<script>
app.controller('OrderController', function ($scope, $http) {
$scope.Orders = {};
$scope.GetOrders = function () {
$http.get('/Order/GetAllOrders').success(function (response) {
$scope.Orders = response;
//debugger;
GetTotalValueOfProducts(response);
});
}
$scope.GetOrders();
GetTotalValueOfProducts = function (response) {
//debugger;
$scope.totalValueOfProducts = 0;
for (var i = 0; i < response.length; i++) {
$scope.totalValueOfProducts += response[i].Price * $scope.quantity;
}
}
$scope.$watch('quantity', function () {
debugger;
$scope.GetOrders();
});
});
</script>
when i changed value of quantity, the value of totalValueOfProducts was not changed!why $watch did not work? what is the problem?
'quantity' needs to be in the $scope for the binding to take place
on a separate note, it would be better to move all data (orders, quantity etc) into a service, it would better adhere to angular's MVC paradigm

ng-repeat and accessing item elements

I'm using ng-repeat to generate a table (for example):
<table ng-repeat="item in items">
<tr>
<td>
<input ng-blur="changeMyItem($event)">{{item.Name}}</input>
<td>
<td>
<div>{{itemError}}</div>
</td>
</tr>
</table>
I am making a call that could potentially fail and I am having a hard time figuring out how to set itemError above to the error message after the page has been rendered when there is an error.
From my changeMyItem method (triggered by ng-blur) I've tried the expression syntax and it just becomes an empty div. I've also tried calling $scope.$apply in my success callback and it says $digest is already in progress and errors.
Without using a custom directive, how can I update itemError above with the related error?
Mike,
If you are trying to set an error message for each individual input, this should do.
<table ng-repeat="item in items">
<tr>
<td>
<input ng-blur="changeMyItem(item, $event)" ng-model="item.Name">
<td>
<td>
<div>{{item.ErrorMessage}}</div>
</td>
</tr>
</table>
In you controller, you can have something similar to:
$scope.changeMyItem = function(item, $event) {
if(!item.Name) {
item.ErrorMessage = "This has error";
}
}
Well, I think the easiest way would be to ng-init a new object for each repeated table, and pass that to the changeMyItem function:
<table ng-repeat="item in items" ng-init="itemError = { message : '' }" >
<tr>
<td>
<input ng-blur="changeMyItem($event, itemError)">{{item.Name}}</input>
</td>
<td>
<div>{{itemError.message}}</div>
</td>
</tr>
</table>
Use an object with a property so that you pass it by reference to the function.
Then you can do:
$scope.changeMyItem = function(event, error) {
//whatever
error.message = "It didn't work!";
}
You really should use a service:
<table ng-repeat="item in myForm.items track by $index">
<tr>
<td>
<label>{{item.Title}}</label>
<input ng-blur="myForm.changeMyItem($event, $index)" ng-model="item.Value">
<td>
<td>
<div>{{item.Error}}</div>
</td>
</tr>
</table>
Then
app.factory('myForm', function(){
var myform = {};
myForm.items = [{ ... }];
myForm.changeMyItem = function(event, index){
};
myForm.submit = function(){
};
myForm.setErrors = function(){
};
...
return myForm;
});

Resources