normal count in loop into another loop AngularJS - angularjs-ng-repeat

my problem is I have a ngRepeat inside another and I need a count starting at 0 that follow 1, 2, 3, 4, etc ...
But I can not, I need help with this because I can not think of anything, here is the link in plunker.
Thank you.

What exactly do you need the index for? Why not just implement that functionality in your controller and attach it to the object? 1 more tip - use ng-class to dynamically set the style of your table row.

Spain someone helped me , I leave the solution:
angular.module('app', [])
.controller('groupColorsController', function groupColors($scope){
$scope.colors = [
{name : "rojos", color : [
["IndianRed", "CD5C5C"],
["LightCoral", "F08080"],
["Salmon", "FA8072"]
]},
{name : "rosados", color : [
["Pink", "FFC0CB"],
["LightPink", "FFB6C1"],
["HotPink", "FF69B4"]
]},
{name : "narajnas", color : [
["Coral", "FF7F50"],
["Tomato", "FF6347"],
["OrangeRed", "FF4500"]
]}
];
})
.controller('colorController', function($scope) {
// $scope -> scope de colorController
// $scope.$parent -> scope de ng-repeat interior
// $scope.$parent.$parent -> scope de ng-repeat exterior
// $scope.$parent.$parent.$parent -> scope de groupColorsController
$scope.id = 0
for(var i = 0; i < $scope.$parent.$parent.$index; ++i) {
console.log($scope.$parent.$parent.$parent.colors[i].color.length)
$scope.id += $scope.$parent.$parent.$parent.colors[i].color.length
}
console.log($scope.$index)
$scope.id += $scope.$index + 1;
});
<body ng-app="app">
<div class="container">
<div class="table-responsive" ng-controller="groupColorsController">
<table class="table table-condensed table-bordered">
<tbody ng-repeat="colors in colors">
<tr>
<th colspan="3"><h3><strong>Colores {{colors.name}}</strong></h3></th>
</tr>
<tr>
<th>Nombre</th>
<th>Código hexadecimal</th>
<th>ID</th>
</tr>
<tr ng-repeat="color in colors.color" ng-controller="colorController" style="background-color:{{color[0]}}">
<td>{{color[0]}}</td>
<td>{{color[1]}}</td>
<td>{{id}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
but I could not do AngularJS D:

Related

data not displaying in table in vuejs

i have created vue file to display data in frontend. but i'm unable to print 2 tables on same page at same time. only table 2 is displaying data , in first table it shows data for 2 seconds and than disappears. what i'm doing wrong? please help. i am super new in vuejs and have not much knowledge.
here is my index.vue file,
Table 1
<tbody>
<tr
v-show="items && items.length"
v-for="(data, i) in items"
:key="i">
<td></td>
<td></td>
</tr>
and this is function code,
async fetchData1() {
this.$store.state.operations.loading = true;
let currentPage = this.pagination ? this.pagination.current_page : 1;
await this.$store.dispatch("operations/fetchData", {
path: "/api/calldata?page=",
currentPage: currentPage + "&perPage=" + this.perPage,
});
table 2
<tbody>
<tr
v-show="items && items.length"
v-for="(data, i) in items"
:key="i">
<td></td>
<td></td>
</tr>
and here is the function for table 2
async fetchData2() {
this.Loading2 = true
let currentPage = this.Pagination2 ? this.Pagination2.current_page : 1;
await this.$store.dispatch("operations/fetchData", {
path: "/api/datacall/data2?page=",
currentPage: currentPage + "&perPage=" + this.perPage,
});
this.Loading2 = false;
and this are the controller functions
public function index(Request $request)
{
return DataResource::collection(Datamodl::with('user')->where('type',1)->latest()->paginate($request->perPage));
}
public function index2(Request $request)
{
return DataResource::collection(Datamodl::with('user')->where('type',0)->latest()->paginate($request->perPage));
}
And Route ,
Route::get('/calldata/data2', [DataController::class, 'index2']);
Route::apiResource('calldata', DataController::class);
Observation : You are updating same variable which is items for both the tables. Hence, it is overriding the latest items with the old items array.
Solution : Here is the implementation as per my comment.
new Vue({
el: '#app',
data: {
table1Items: null,
table2Items: null
},
mounted() {
this.fetchData1();
this.fetchData2();
},
methods: {
fetchData1() {
this.table1Items = [{
id: 1,
name: 'table 1 alpha'
}, {
id: 2,
name: 'table 1 beta'
}]
},
fetchData2() {
this.table2Items = [{
id: 1,
name: 'table 2 alpha'
}, {
id: 2,
name: 'table 2 beta'
}]
}
}
})
table, th, td {
border: 1px solid black;
margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<table>
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr v-show="table1Items" v-for="(data, i) in table1Items" :key="i">
<td>{{ data.id }}</td>
<td>{{ data.name }}</td>
</tr>
</tbody>
</table>
<table>
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr v-show="table2Items" v-for="(data, i) in table2Items" :key="i">
<td>{{ data.id }}</td>
<td>{{ data.name }}</td>
</tr>
</tbody>
</table>
</div>
you are using same property which is items for both. so second request will changed first items. so in both table same data will visible. you have to store in different state property for different data rendering.
solution :
make another action fetchData2.
call another mutation setItems2. add state propery item2: []. and setItems2 value from this mutation.
render second table like this.
<tr
v-show="items2.length"
v-for="(data, i) in items2"
:key="i">
<td></td>
<td></td>
</tr>
For code quailty:
give proper and related variable name . don't use items1 and items2 like that.
never used v-if/v-show and v-for in same element.for more info
use template first in this senerio.
use the item's unique id instead of the index in the key.
if you take the items default value as [], instead of null, then you only required to check items.length instead of items && items.length. so always use list default value []
if both requests are not dependent on each other then you should use Promise.all() for fetching data concurrently. which saved tremendous time and also in this case you don't require two loading property.

Bootstrap Datatables pagination and sorting

I'm using datatables and bootstrap for pagination but its not working.
The data is received via ajax ,as soon as i press any header to sort the table, the data dissappears.
The html for table itself
<table id="tablePersonnel"
class="table table-striped table-bordered table-sm" cellspacing="0"
width="100%">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>First Name</th>
<th>Phone number</th>
<th>Status</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tfoot>
<tr>
<th>#</th>
<th>Name</th>
<th>First Name</th>
<th>Phone number</th>
<th>Status</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</tfoot>
</table>
here is the javascript for the function responsible for getting the data
refreshTable = function() {
$
.ajax({
url : "listPersonnel",
dataType : 'json',
success : function(response) {
data = response;
var no = 1;
for (i = 0; i < data.length; i++) {
$("#tablePersonnel")
.append(
'<tr> <td>'
+ data[i].id
+ '</td> <td>'
+ data[i].firstname
+ '</td> <td>'
+ data[i].name
+ '</td> <td>'
+ data[i].phone
+ '</td> <td>'
+ data[i].status
+ '</td><td><input type="button" class="btn1" onclick="openEditPopup('
+ i
+ ')" value="Edit"></input></td> <td> <button type="submit" class="btn" onclick="openDeletePopup('
+ i
+ ');" value=""><i class="fa fa-trash"></i></button></td> </tr>');
no = no + 1;
}
}
});
}
Any help is greatly appreciated.
Your approach involves adding data to the HTML table (i.e. to the DOM). However, the DataTables object does not know about this data - which is why the data disappears whenever you perform any action which involves a DataTables refresh. DataTables is showing you its data - which is no data.
Instead, you can perform your ajax call from within DataTables itself - and then DataTables will handle the data for you.
I will assume the JSON returned by your ajax call has the following structure:
[
{
"id": 123,
"firstname": "Tom",
"name": "Smith",
"phone": "121-212-1212",
"status": "foo"
},
{
"id": 123,
"firstname": "Jane",
"name": "Jones",
"phone": "434-545=6767",
"status": "bar"
}
]
In that case, you can use the following table HTML:
<table id="example">
<thead>
<tr>
<th>ID</th>
<th>First Name</th>
<th>Name</th>
<th>Phone</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
</table>
And your DataTable configuration will be this:
<script type="text/javascript">
$(document).ready(function() {
$('#example').DataTable( {
"ajax": {
"url": "listPersonnel",
"dataSrc": ''
},
"columns": [
{ "data": "id" },
{ "data": "firstname" },
{ "data": "name" },
{ "data": "phone" },
{ "data": "status" },
{ "data": function ( row, type, val, meta ) {
var content = '<input type="button" class="btn1" onclick="openEditPopup('
+ row.id
+ ')" value="Edit"></input></td> <td> <button type="submit" class="btn" onclick="openDeletePopup('
+ row.id
+ ');" value=""><i class="fa fa-trash">trash</i></button>'
return content;
} }
]
} );
} );
</script>
The result looks like this (I don't have your trash icon):
Points to note:
There is no iteration logic here - it's handled for you by DataTables, as it consumes your JSON response.
If your JSON has a different structure, you will need to adjust the above. Examples of different approaches are shown here.
In your case, we use dataSrc = '' because your JSON is an array of objects - and it does not have a container object.
The data in the final column is generated via a function which builds the string you need.
You can define column headings directly in DataTable also, instead of in the HTML.
There are many variations on this approach - DataTables has a lot of flexibility.

Html2Canvas Iteration in HTML table

Good day! I have this dynamic table which data is coming from database.
<table class="ui table" style="margin-top: 1em;border:1" id = "tbl">
<thead>
<tr>
<th class="four wide">FirstName</th>
<th class="four wide">LastName</th>
</tr>
</thead>
<tbody>
#foreach ($data as $name)
<tr>
<td>{!! $name !!} </td>
</tr>
#endforeach
</tbody>
</table>
What i want to do is get every row of table and screenshot that row using HTML2Canvas then the image will save to JSPDF. I only have this code of html2canvas which is capturing the whole table.
var w = document.getElementById("tbl").offsetWidth;
var h = document.getElementById("tbl").offsetHeight;
html2canvas(document.getElementById("tbl"), {
dpi: 300, // Set to 300 DPI
scale: 3, // Adjusts your resolution
onrendered: function(canvas) {
var img = canvas.toDataURL("image/jpeg", 1);
var doc = new jsPDF('P', 'px', [w, h]);
doc.addImage(img, 'JPEG', 15, 40, w, h);
doc.save('sample-file.pdf');
}
});
How will I be able to do that? I have iteration from html table to javascript but keep getting error. here is the iteration code.
for (let row of tbl.rows) {
for(let cell of row.cells) {
console.log(cell.innerText)
}
}
Thankyou in Advance

Jquery Bootgrid table with caption attribute is removing caption attribute after data bind

I'm trying a very simple jquery bootgrid table with caption attribute to make the header sticky while scrolling.
<table id="grid" class="table table-condensed table-hover table-striped">
<thead>
<tr>
<th caption="ID" data-column-id="id" data-type="numeric"></th>
<th caption="Sender" data-column-id="sender"></th>
<th caption="Received" data-column-id="received" data-order="desc"></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
After the data binding the rendered table looks like below, and the data binding is fine.
<table id="grid" class="table table-condensed table-hover table-striped">
<thead>
<tr>
<th data-column-id="id" data-type="numeric"></th>
<th data-column-id="sender"></th>
<th data-column-id="received" data-order="desc"></th>
</tr>
</thead>
<tbody>data rows goes here.
</tbody>
</table>
Any suggestion, how I can tell jquery-bootgrid, to stop removing the caption attribute ?
Thanks a lot.
Finally I figured out this and it is fixed.
In jquery.bootgrid.js file, locate the loadColumns method and include the caption attribute as mentioned below.
Step 1: Change in loadColumns() method
function loadColumns()
{
var that = this,
firstHeadRow = this.element.find("thead > tr").first(),
sorted = false;
/*jshint -W018*/
firstHeadRow.children().each(function ()
{
var $this = $(this),
data = $this.data(),
column = {
caption: $this[0].attributes.caption.value,//Find better way
id: data.columnId,
....
...
}
Step 2 : Changes in renderTableHeader() method
function renderTableHeader()
{ ....
....
$.each(this.columns, function (index, column)
{
if (column.visible)
{
//console.log(column.caption);
var sortOrder = that.sortDictionary[column.id],
iconCss = ((sorting && sortOrder && sortOrder === "asc") ? css.iconUp :
(sorting && sortOrder && sortOrder === "desc") ? css.iconDown : ""),
icon = tpl.icon.resolve(getParams.call(that, { iconCss: iconCss })),
align = column.headerAlign,
cssClass = (column.headerCssClass.length > 0) ? " " + column.headerCssClass : "",
caption = column.caption; //caption passed to template
....
.... }
Step 3: Changes in the headercell template.
Locate this headercell variable and add the caption attribute in the template.
headerCell: "<th data-column-id=\"{{ctx.column.id}}\" caption=\"{{ctx.column.caption}}\" class=\"{{ctx.css}}\" style=\"{{ctx.style}}\"><span class=\"{{css.columnHeaderText}}\">{{ctx.column.text}}</span>{{ctx.icon}}</th>",
Hope this helps someone.

laravel vue send array to backend

I want to send array of id's to backend with one button from vuejs table but i get error 500.
Logic
Check the check boxes
Collect the id's
Send id's to back-end when click on button
update the view
Code
template
<table class="table table-dark table-hover table-bordered table-striped">
<thead>
<tr>
<th class="text-center" width="50">
//the button
<button class="btn btn-outline-danger" #click="withdraw(index)">Withdraw</button>
</th>
<th class="text-center" width="50">#</th>
<th class="text-center">Amount</th>
</tr>
</thead>
<tbody>
<tr v-for="(income,index) in incomes" v-bind:key="index">
<td class="text-center">
//check box input
<input v-if="income.withdraw == '0'" type="checkbox" :id="income.id" :value="income.amount" v-model="checkedNumbers">
</td>
<td class="text-center">{{index+1}}</td>
<td class="text-center">Rp. {{formatPrice(income.amount)}}</td>
</tr>
<tr>
<td colspan="2"></td>
<td>
<span>Withdraw for today, Sum: <br> Rp. {{ formatPrice(sum) }}</span>
</td>
</tr>
</tbody>
</table>
script
export default {
data() {
return {
incomes: [],
checkedNumbers: [],
}
},
computed: {
sum() {
return this.checkedNumbers.reduce(function (a, b) {
return parseInt(a) + parseInt(b);
}, 0);
}
},
methods: {
withdraw(index) {
let checkedids = this.incomes[index]
axios.post(`/api/withdrawbutton/`+checkedids).then(response => {
this.income[index].withdraw = '1'
this.$forceUpdate()
});
}
}
}
route
Route::post('withdrawbutton/{id}', 'IncomeController#withdrawbutton');
controller
public function withdrawbutton($id)
{
$dowithdraw = Income::where('id', $id)->get();
$dowithdraw->withdraw = '1';
$dowithdraw->save();
return response()->json($dowithdraw,200);
}
Any idea where is my mistake and how to fix it?
......................................................................................................................
Don't send the list as a GET parameter, send it as a POST:
let params = {}
params.ids = this.checkedNumbers
axios.post(`/api/withdrawbutton/`, params)
.then(response => {
this.income[index].withdraw = '1'
this.$forceUpdate()
});
Controller
public function withdrawbutton(Request $request)
{
$dowithdraws = Income::whereIn('id', $request->input('ids', []));
$dowithdraws->update(['withdraw' => '1']);
return response()->json($dowithdraws->get(), 200);
}
Route
Route::post('withdrawbutton/', 'IncomeController#withdrawbutton');
And I don't think you need to update anything in the front because you already have them checked (if you want to keep them checked)

Resources