How to attach datatables options when using ui router - angular-ui

I am using angular-datatables to format my tables. I am also using ui-routing to handle routing.
It is possible to define the formatting of the dataTable by attaching a couple of objects to $scope in the controler (http://l-lin.github.io/angular-datatables/#/withOptions), like:
angular.module('datatablesSampleApp', ['datatables']).controller('withOptionsCtrl', function($scope, DTOptionsBuilder, DTColumnDefBuilder) {
$scope.dtOptions = DTOptionsBuilder.newOptions()
.withPaginationType('full_numbers')
.withDisplayLength(2)
.withDOM('pitrfl');
$scope.dtColumnDefs = [
DTColumnDefBuilder.newColumnDef(0).notSortable(),
DTColumnDefBuilder.newColumnDef(1).notVisible(),
DTColumnDefBuilder.newColumnDef(2)
];
});
The dataTable is rendered like:
<table datatable="ng" class="table table-striped table-bordered table-hover">
My route is defineded as:
.state('unclassified', {
url: "/unclassified",
templateUrl: "/app/documentsUnclassified/documentsunclassified.html",
controller: 'documentUnclassifiedCtrl',
controllerAs: 'documentsUnclassified'
}
My question is how I can do this in the most efficient way since I don't have access to $scope in the controller when I am using ui router.

Since you are using the controllerAs syntax, you need to use the variable documentsUnclassified you set in your router in the HTML:
<table datatable="ng"
dt-options="documentsUnclassified.dtOptions"
dt-column-defs="documentsUnclassified.dtColumnDefs"
class="table table-striped table-bordered table-hover">
</table>

Related

Symfony 4, Twig & VueJS - Redirecting to Symfony routes in Vue component

I am getting started with Symfony 4 using Twig templating and VueJS for UI components.
I have a very basic component in a .vue file for listing tasks, which currently renders a basic table.
// task-list.vue
<template>
<div>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>
Task
</th>
<th>
Description
</th>
<th>
Completed?
</th>
</tr>
</thead>
<tbody>
<tr v-for="task in parsedTasks">
<td>
{{ task.title }}
</td>
<td>
{{ task.description }}
</td>
<td>
{{ task.completed ? 'Yes' : 'No' }}
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
name: 'task-list',
props: {
tasks: {required: true}
},
computed: {
parsedTasks() {
return JSON.parse(this.tasks);
}
},
};
</script>
This component is registered in the root JS file;
// assets/js/app.js
Vue.component('task-list', TaskList);
new Vue({
el: '#app-root'
});
This is then used in a Twig template;
// tasks/list.html.twig
...
<task-list tasks="{{ tasks | json_encode }}"></task-list>
...
I want to be able to use the path() Twig function so that, when a row in the task list is clicked, the user is redirected to the generated route/path. Is this possible given that the Vue component is not in a Twig file?
As a side question, is there a better way to pass a Twig variable to a Vue component than json encoding then parsing the data as above?
There is two main approaches:
Generate the URL in the backend and use it in javascript:
var route = "{{ path('blog_show', {'slug': 'my-blog-post'})|escape('js') }}";
https://symfony.com/doc/current/routing/generate_url_javascript.html
Or using a javascript routing library that integrates with symfony routes like FOSJsRouting:
var url = Routing.generate('blog_show', {
'slug': 'my-blog-post'
});
https://github.com/FriendsOfSymfony/FOSJsRoutingBundle

How to display a data table values in html table using angular js

I have a DataTable in OrderDetails.aspx.vb
Public Outlets As New DataTable
Outlets = objOrdersData.GetOnlineConfigCall()
In my OrderDetails.aspx
<script>
var Outlets = '<%=Outlets%>';
</script>
I want to display outlets details in a html table using AngularJS
I defined my html table as
<table class="table">
<thead>
<tr> <th>Outlets</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="outlet in Outlets">
<td><a >{{outlet.PartnerName}}</a></td>
</tr>
</tbody>
</table>
but it's not working.
Provided that Outlets is a valid js array, you just need to assign it to scope variable in your controller like:
OrderApp.controller("OrderCntrl", ['$scope', function ($scope) {
$scope.outlets = Outlets;
}]);
and then bind your data in the template like:
<tr ng-repeat="outlet in outlets">
<td><a >{{outlet.PartnerName}}</a></td>
</tr>

Changing CSS classes within Ember and SortMixin

I have a table which I have applied sorting to but to complete this task I would like the classes to change to show carets going up or down based on the sorting.
As you can see I have used the standard SortableMixin within Ember to get the sorting functionality but I'm having trouble changing the class of the individual element which has been clicked.
App.CampaignsController = Ember.ArrayController.extend({
sortProperties: ["id"],
sortAscending: true,
actions: {
sortBy: function(property){
if (this.get("sortProperties")[0] === property){
this.toggleProperty("sortAscending");
} else {
this.set("sortProperties", [property]);
this.set("sortAscending", true)
}
}
}
});
The table I'm I've applied the actions to is below:
<table class="table table-striped table-hover">
<thead>
<tr>
<th {{action "sortBy" "name"}}><i {{bind-attr class=":fa sortAscending:fa-caret-up:fa-caret-down"}}></i>Campaign Name</th>
<th {{action "sortBy" "campaign_code"}}><i {{bind-attr class=":fa sortAscending:fa-caret-up:fa-caret-down"}}></i>Campaign Code</th>
</tr>
</thead>
<tbody>
<td>{{name}}</td>
<td>{{campaign_code}}</td>
</tbody>
</table>
I'm using the sortAscending boolean to dictate what CSS class will appear. My problem is if I click the first heading, the classes on the second heading also change.
How do I get the CSS to change only on the heading that I have clicked?
Your <th> now has state (whether it's sorted, and whether it's ascending or descending), so you should wrap it up in a component. Something like this
<table>
<thead>
<tr>
{{#sortable-th property='name' action='sortBy'}}
Campaign Name
{{/#sortable-th}}
</tr>
</thead>
</table>
The component's template
// templates/components/sortable-th.js
<th>
<i {{bind-attr class=":fa sortAscending:fa-caret-up:fa-caret-down"}}></i>
{{yield}}
</th>
and code
// components/sortable-th.js
export default Ember.Component.extend({
sortAscending: true,
click: function() {
this.toggleProperty('sortAscending');
this.sendAction('action', this.get('property'), this.get('sortAscending'));
}
}
That's just a rough outline, try the implementation yourself. But that's how I would start thinking about it.

Why is my statically typed partial view trying to render an unintended model type?

I have a partial view, in my ASP.NET MVC4 web app. It's just a partial view designed to display a table, given a collection of entities. It looks like this:
#model ICollection<Portal.Models.Matter>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>Name</th>
<th>Last Accessed</th>
<th>Client</th>
</tr>
</thead>
<tbody>
#if (Model.Count > 0)
{
#Html.DisplayForModel()
}
else
{
<tr>
<td colspan="3" class="text-muted text-centered">There are no Matters to display.</td>
</tr>
}
</tbody>
</table>
I have a DisplayTemplate for Matter that is statically typed to the single Matter entity, and it handles rendering of each table row.
For some reason, when this partial is rendered, instead of using the Matter DisplayTemplate it just shows the following:
System.Collections.Generic.List`1[Portal.Models.Account]System.Collections.Generic.List`1[Portal.Models.Account]
Now, this partial is not even bound to a collection of Account entities. It's bound to a collection of Matter entities. So, why is #Html.DisplayForModel() trying to display for a collection of Accounts? At run time, using a debugger, I can see the Model is in fact a collection of Matter entities, not Account.
I render this partial using the following code:
#Html.Partial("~/Views/Matter/_Table.cshtml", Model.Client.Matters, new ViewDataDictionary())
I found a work around, or maybe a solution, not sure. Anyway, instead of using DisplayForModel on an ICollection, I iterate over the collection and use DisplayFor on each element.
For example ...
#model ICollection<Foo>
for (var item in Model)
{
#Html.DisplayFor(m => item)
}
I guess nothing is forcing you to use a property off of m in DisplayFor.

Get column index in onresizecolumn of declarative dojox.grid.datagrid

In a declarative dojox.grid.datagrid, am using onresizecolumn in table tag.
onresizecolumn="columnResize(this.id,this.cellIdx)"
onresizecolumn calls a function. on resizing particular column i want to get the cellIdx.
<div class="claro" id="eterte" name="dataGrid" onclick="getConnect('inner__eterte');setWidgetproperty(this.id,'xy','inner__eterte');" ondblclick="editCustomGrid(this.id)" onmouseup="setDocStyle(this.id)" style="height:200px; left:39px; position:absolute; top:251px; width:950px;">
<table class="claro" dojotype="dojox.grid.DataGrid" id="inner__eterte" onresizecolumn="columnResize(this.id,this.cellIdx)" rowselector="10px" style="height: 180px; width: 400px;">
<thead>
<tr>
<th field="Column1" id="Column1_6" width="159px">
Column1
</th>
</tr>
</thead>
</table>
<input id="hidden__eterte" name="dataGrid" style="display:none;" type="hidden">
</div>
function columnResize(id,index){
alert();
alert(id);
alert(index);
}
By reading the API documentation I come to the conclusion that Dojo automatically sends the Cell index to the event handler. So the solution is by simply providing the following attribute onResizeColumn="myFunction" and then you define a function like this:
function myFunction(cellDx) {
alert(cellDx);
}
This should work, I even made a JSFiddle to test it. By the way, is there any reason why you would like to do all of it in a declarative way? As far as my experience goes, it's a lot easier to write most of this in JavaScript.
I can get it working this way, not sure if it's a best practice.
http://jsfiddle.net/gE8rH/6/
HTML (removed onresizecolumn attribute):
<div class="claro" id="eterte" name="dataGrid" onclick="getConnect('inner__eterte');setWidgetproperty(this.id,'xy','inner__eterte');" ondblclick="editCustomGrid(this.id)" onmouseup="setDocStyle(this.id)" style="height:200px; width:950px;">
<table dojotype="dojox.grid.DataGrid" id="inner__eterte" rowselector="10px" style="height: 180px; width: 400px;">
<thead>
<tr>
<th field="Column1" id="Column1_6" width="109px">Column1</th>
<th field="Column2" id="Column1_7" width="109px">Column2</th>
<th field="Column2" id="Column1_8" width="109px">Column3</th>
</tr>
</thead>
</table>
</div>
JS (using Dojo 1.7+ module names), assign to the widget's onResizeColumn property:
require(["dojo/parser", "dijit/registry", "dojox/grid/DataGrid"], function (parser, registry) {
parser.parse().then(afterParse);
function afterParse() {
var d = registry.byId("inner__eterte");
console.log(d);
d.onResizeColumn = function (colIdx) {
console.log("columnResize");
console.log("args", arguments);
console.log("this", this);
console.log("colIdx", colIdx);
};
}
});
Outputs this when resizing the first column:
columnResize
args [0]
this [Widget dojox.grid.DataGrid, inner__eterte] { _attachPoints=[4], _attachEvents=[1], _connects=[0], more...}
colIdx 0

Resources