ng-table get data from rails api not working - ruby-on-rails

I'm trying to make a simple table with pagination by using Angularjs ng-table.
I included the js and css files to my rails 3 layout. When page first loaded, it displays a table then fires a http get to rails controller to get json(it works fine until this point).
What I'm trying to do is add pagination to my table.
I received error "angular is not defined" and there is no request from http get to rails controller. Please show me what I'm doing wrong here.
Thank you
(function(){
var app = angular.module("apTags", ["ngTable"])
// call back after table finished ng-repeat
.directive('onFinishRender', function ($timeout) {
return {
restrict: 'A',
link: function (scope, element, attr) {
if (scope.$last === true) {
$timeout(function () {
scope.$emit('ngRepeatFinished');
tableResponsiveAdjustHeight();
});
}
}
}
});
app.controller("apTagsController", [ "$http", function($scope, ngTableParams, $http){
// table has empty data when page first loaded
var apTags = this;
apTags.tags = [];
// Then it fires a http get to rails api to get data and append to table
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10 // count per page
}, {
total: data.length, // length of data
getData: function($defer, params) {
$http.get("ap_tags.json", {params: { api: true, page: params.page() } }).success(function(data){
apTags.tags = data;
$defer.resolve(data.slice((params.page() - 1) * params.count(), params.page() * params.count()));
});
}
});
}]);
})();
<div class="container" ng-app="apTags">
<div ng-controller="apTagsController as list">
<p><strong>Page:</strong> {{tableParams.page()}}</p>
<p><strong>Count per page:</strong> {{tableParams.count()}}</p>
<table ng-table="tableParams" id="table_tags" class="table table-condensed table-bordered table-hover">
<tr ng-repeat="tag in list.tags" on-finish-render="ngRepeatFinished">
<td data-title="'Tag'">{{tag.name}}</td>
<td data-title="'Share'">{{tag.share}}%</td>
<td data-title="'Direct Product Count'"></td>
</tr>
</table>
</div>
</div>

Related

Track user clicks from list populated of URL's using MVC framework

I have an MVC 5 application that displays a list of 100+ unique URL's. The user can sort, search, and eventually click the URL from the list launching the website in a new window. I want to be able to track every time someone clicks a URL from that list. The URL list is populating as expected. View code below:
<table class="table table-condensed table-hover table-responsive table-striped">
<tr>
<th class="col-md-1">
#Html.ActionLink(" Name", "Index", new { sortOrder = ViewBag.ReportNameSortParam, SelectedReportCategory = ViewBag.SelectedReportCategory, FindReportName = ViewBag.FindReportName}, new { #class = "glyphicon glyphicon-sort", #title = "sort by name" })
</th>
</tr>
#foreach (var item in Model)
{
if (ViewBag.counter == "")
{
ViewBag.rowType = "normalRow";
ViewBag.counter = "1";
}
else {
ViewBag.rowType = "alternateRow";
ViewBag.counter = "";
}
<tr class=#ViewBag.rowType>
<td class="col-md-1" title="#Html.DisplayFor(modelItem => item.Report_Description) : #Html.DisplayFor(modelItem => item.SLA)">
#Html.DisplayFor(modelItem => item.Report_Name)
</td>
</tr>
}
</table>
What would be the best approach to track a user click when they are doing this via the View? I have a column in my table called 'Hits' that I would like to increment by 1 whenever that URL gets clicked. Ideally, after a user clicks a URL, I would like for the list to stay where it is and not have to refresh by hitting another controller and then repopulating. How can I write to the database on via the View?
as mentioned... capture the click event of each link clicked and perform an Ajax post to the relevant controller and action.
$(document).ready(function () {
$(document).on('click', 'a', function () {
var linkID = $(this).attr("id");
$.ajax({
type: "POST",
url: "#Url.Action("YourAction", "YourController")",
data:
{
linkid: linkID
}
});
});
});
hope that helps.
Consider standing up an action method that receives the URL and redirects to the final destination:
#Html.DisplayFor(modelItem => item.Report_Name)
In the controller, add:
public ActionResult Redirect(int id, string url)
{
//Get record using ID, and update Hits column
//Redirect to the final URL
return Redirect(url);
}
Be aware that if your URL's use any special characters, some encoding may occur... that might mean you have to do some encoding on the client end potentially. It's just good to test that out to confirm.

ng-table filter after hitting submit

I'm using ng-table in AngularJS with a Ruby on Rails backend. I'm using ng-table to display 10 rows at a time and I'm doing the search/sort and pagination on the server side.
The problem I'm having is the filter is sending a request to the server after every keystroke, is it possible to make ng-table wait until I want to send my filter to the server via a submit button?
$scope.tableParams = new ngTableParams({
page: if page then page else 1,
count: 10,
sorting: { invoice_no: 'desc'}
}, {
total: 0,
getData: ($defer, params) ->
Invoice.query params.url(), (data) ->
params.total($scope.total)
# put params in url
$location.search(params.url())
# Paginate / update table with new data
$defer.resolve(data)
})
My current view
<table ng-table="tableParams" show-filter="true" class="table">
<tr class='listing' ng-repeat="invoice in $data">
<td data-title="'Invoice No.'" sortable="'invoice_no'" filter="{'invoice_no':'text'}">
{{invoice.invoice_no}}
</td>
</tr>
</table>
An inline filter will get called many times.
To call the filter once when the submit button is clicked, add a click handler:
<button type="submit" ng-click="onSubmit()" />
In your controller, invoke your filter inside your click handler:
app.controller('ctrl', function($scope, $filter) {
$scope.$data = [];
$scope.onSubmit = function() {
$scope.$data = $filter('filter')($scope.data, {'invoice_no':'text'});
}
});

Backbone routing loading data-role=page

I have a mobile app built using jquery mobile and backbone. I'm trying to work through the routing logic to render my views accordingly and am thus starting simple and adding complexity as I go along.
The html is as follows
<div id="main">
<li>Click Here to Test Me</li>
</div>
<div id="view-goes-here"></div>
<script type="text/template" id="actions-template">
<table cellspacing='0' cellpadding='0' border='1' >
<thead>
<tr>
<th>Id</th>
<th>Str</th>
</tr>
</thead>
<tbody>
<% _.each(action, function(c) { %>
<% var f = c.id, g = c.str; %>
<tr>
<td class="<%= f %>"><%= c.id %></td>
<td class="<%= g %>"><%= c.str %></td>
</tr>
<% }); %>
</tbody>
</table>
</script>
Here is a jsfiddle with functional code: http://jsfiddle.net/horcle_buzz/4JGhZ/
I would like it so that when I do a hashchange to "test_me" then the contents of the "main" div (specifically, the url with text "Click Here to Test Me") would disappear with only the output from my view being rendered in the output, specifically the table contents from my variable c in the function test:
var c = [
{ id: 1, str: 'This'},
{ id: 2, str: 'is'},
{ id: 3, str: 'a'},
{ id: 4, str: 'test!'}
];
My view is as follows:
var ActionView = Backbone.View.extend({
template: ActionTemplate,
events:{
"click":"makeInput"
},
render:function(){
alert("a" + JSON.stringify(this.collection));
alert("b" + this.collection.toJSON());
$(this.el).html(this.template({
action: this.collection.toJSON()
}));
$('#view-goes-here').append(this.el);
return this;
},
makeInput:function(){
alert("im in");
}
});
My guess is that I would have to use the data-role=page tag for my divs, but when I do this, the view does not render as expected. I am slightly confused about how to get the desired output, especially since most examples out there are rather basic.
I disable jQuery Mobile routing as follows and then start Backbone history:
$(document).ready(function(){
$.mobile.linkBindingEnabled = false;
$.mobile.hashListeningEnabled = false;
var router = new ActionsRoute();
Backbone.history.start();
});
Routing is done as follows:
var ActionsRoute = Backbone.Router.extend({
routes: {
'': 'main',
'test_me': 'loader'
},
main: function() {
$.mobile.changePage( "#main" , { reverse: false, changeHash: false } );
},
loader: function() {
test(function(c, Actions, ActionView){
alert("Data:" + JSON.stringify(c));
var actions = new Actions(c);
var actionView = new ActionView({collection:actions});
actionView.render();
});
}
});
Thanks in advance!
Doh! I did not have jquery.mobile-1.2.0.min.css defined as a resource. Added it, and all is behaving as desired.

Display accordion using Jquery Ajax

I have a table full of data, upon clicking on any of the record. A jquery ajax function called and get the detailed information for that record and display it in the div associated with the record.
Now i want to show it in a accordion.
Most of time a jquery accordion works like this
$(document).ready(function() {
$('#accordion').accordion();
});
But here i want that my div gets populated first with data then accordion method gets called. Because if accordion() called first then there is nothing for accordion to display as the request for data is still in processing.
My jquery ajax method is like this
$(function () {
$("span.Consignment").click(function () {
var position = 'div#' + this.innerHTML;
var url = "/Tracking/TrackingConsignment?consno=" + this.innerHTML;
$(position).load(url, function() {
$("a.Consignment").accordion();
return false;
});
});
});
This is my code
#foreach (var lst in item.Item2)
{
<a href="#" class="Consignment">
<table class="gridtable">
<a href="#">
<tr>
<td>
<span class="Consignment" href="#">#lst.ConsignmentNo</span>
</td>
<td>#lst.ConsignmentDate
</td>
</tr>
</a>
</table>
</a>
<div id="#lst.ConsignmentNo">
</div>
}
How should i make it work. First data then accordion.
Setup your accordion in the success of the .load.
.load(url,function(){
$("#accordion").accordion();
})

Jquery form post Issues

I am using asp.net MVC and I am having an issue posting a form using jquery.
It is not posting to the url I am telling it to.
If I use firebug, it shows the post happening but it is posting to the index of the controller everytime. I cannot figure out why. I have verified the url of the action I am trying to post but I can't figure out why it is always posting to the index of the controller....Note: the view in which the form is found IS the index view. so Basically it is posting to it's own action rather than the one in the url i am telling it to. Any help would be great. thanks!
here is my form
<form action='' id="descriptionForm">
<%=Html.Hidden("claimNumber", ViewData["claimNumber"])%>
<%=Html.Hidden("partNumber", ViewData["partNumber"])%>
<%=Html.Hidden("qty", ViewData["qty"])%>
<table>
<tr>
<td style="text-align: right">
Category:
</td>
<td>
<%=Html.DropDownList("problemCategory", (IEnumerable<SelectListItem>)ViewData["problemSelect"], "-Select-")%>
</td>
</tr>
<tr>
<td style="text-align: right">
Details:
</td>
<td>
<select id="problemDetails">
</select>
</td>
</tr>
<tr>
<td style="text-align: right">
Dealer Notes:
</td>
<td>
<%=Html.TextArea("dealerNotes", "", 3, 40, null)%>
</td>
</tr>
</table>
<div style="position: absolute; bottom: 8px; right: 8px">
<input type="button" id="itemDetailsCancel" value="Cancel" />
<input type="submit" id="itemDetailsSubmit" value="Save" />
</div>
</form>
<a href='<%=ResolveUrl("~/Warranty/WarrantyClaims/CompleteAddLineItemToClaim/") %>'
id="CompleteLineItemUrl"></a>
Here is my Javascript
$("#descriptionForm").submit(function () {
var completeurl = $("#CompleteLineItemUrl").attr('href');
var data = $(this).serialize();
$.post({
type:'POST',
url: completeurl,
data: data,
success: function (result) {
alert("done");
}
});
return false
});
and just for good measure here is the controller action I am trying to post to(though it doesn't do much yet)
[HttpPost]
public ActionResult CompleteAddLineItemToClaim(string claimNumber, string partNumber, string qty, string problemCategory, string problemDetails, string dealerNotes)
{
var result = new { result = "done" };
return Json(result, JsonRequestBehavior.AllowGet);
}
Update:
updated javascript
$(function(){
$('#descriptionForm').submit(function () {
var completeurl = $('#CompleteLineItemUrl').attr('href');
var data = $(this).serialize();
$.ajax({
type: 'POST',
url: completeurl,
data: data,
success: function (result) {
alert('done');
}
});
return false;
});
});
Is the form itself loaded by an ajax call?
If so you need to use the live() function of jquery.
Make sure you have wrapped your javascript in a document.ready before subscribing for any events. Also you have a missing ; when returning false at the end of your method.
But your real problem is that you want to use $.ajax instead of $.post. So what actually happens is that you are getting a javascript error because of wrongly using the $.post function and the .submit handler never has time to return false and cancel the default submission of the form and the browser happily proceeds into POSTing to the action of the form (which is empty and default to the action that rendered this form).
So to sum up:
$(function() {
$('#descriptionForm').submit(function () {
var completeurl = $('#CompleteLineItemUrl').attr('href');
var data = $(this).serialize();
$.ajax({
type: 'POST',
url: completeurl,
data: data,
success: function (result) {
alert('done');
}
});
return false;
});
});
Or if you wanted to use $.post:
$(function() {
$('#descriptionForm').submit(function () {
var completeurl = $('#CompleteLineItemUrl').attr('href');
var data = $(this).serialize();
$.post(completeurl, data, function (result) {
alert('done');
});
return false;
});
});
Also instead of generating links à la classic WebForms way:
In ASP.NET MVC you use HTML helpers in order to ensure that link urls are conform to your routes:
<%= Html.ActionLink(
"Link text",
"CompleteAddLineItemToClaim",
"WarrantyClaims",
new { area = "Warranty" },
new { id = "CompleteLineItemUrl" }
) %>

Resources