views not showing when placed into ruby on rails app - ruby-on-rails

I dropped in my angular app into a new ruby on rails app. what i'm noticing is that no views are being rendered out. i only see the layout being rendered. also i'm not getting any errors. my 2 views (home.html and about.html) and list.json are located in the public folder. please let me know if you need any more code from the app.
i have my application layout as follows:
<!DOCTYPE html>
<html>
<head>
<title></title>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<button data-target=".nav-collapse" data-toggle="collapse" class="btn btn-navbar" type="button">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<img src="assets/tool-box.png" /> Dev Tool Chest
<div class="nav-collapse collapse">
<ul class="nav">
<li class="active">
Home
</li>
<li class="">
About
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="container">
<div id="view" ng-view></div>
</div>
</body>
</html>
i have my application controller as follows:
class ApplicationController < ActionController::Base
protect_from_forgery
def index
render :layout => 'application', :nothing => true
end
end
I've made my JS asset pipeline as follows:
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require angularmin.js
//= require angularstrap.min.js
//= require toolsapp.js
the toolsapp.js looks like this
var tools = angular.module("tools", ['$strap.directives'])
tools.config(function($routeProvider) {
$routeProvider.when('/home', {
templateUrl: 'home.html',
controller: 'HomeController'
});
$routeProvider.when('/about', {
templateUrl: 'about.html',
controller: 'AboutController'
});
$routeProvider.otherwise({ redirectTo: '/home' })
});
tools.controller("HomeController", function($scope, fetchData) {
fetchData.then(function(data){
$scope.record = data;
$scope.typeahead = function(){
var allNames = [];
for(var i=0;i<$scope.record.length;i++){
allNames.push($scope.record[i].name)
}
return allNames;
}
});
$scope.clearSearch = function(){
$scope.search = "";
$scope.name2 = "";
}
$scope.name2 = "";
$scope.search = "";
});
tools.controller("AboutController", function($scope) {
});
tools.factory('fetchData', ['$http', function($http){
var Url = "list.json";
var list = $http.get(Url).then(function(response){
return response.data;
});
return list;
}]);
tools.filter('unique', function () {
return function (items, filterOn) {
if (filterOn === false) {
return items;
}
if ((filterOn || angular.isUndefined(filterOn)) && angular.isArray(items)) {
var hashCheck = {}, newItems = [];
var extractValueToCompare = function (item) {
if (angular.isObject(item) && angular.isString(filterOn)) {
return item[filterOn];
} else {
return item;
}
};
angular.forEach(items, function (item) {
var valueToCheck, isDuplicate = false;
for (var i = 0; i < newItems.length; i++) {
if (angular.equals(extractValueToCompare(newItems[i]), extractValueToCompare(item))) {
isDuplicate = true;
break;
}
}
if (!isDuplicate) {
newItems.push(item);
}
});
items = newItems;
}
return items;
};
});

My suggestion for this is:
Create a home controller:
home_controller.rb
class HomeController < ApplicationController
def index
end
def about
end
end
Move your views to app/views/home folder.
Add following routes:
routes.rb
get 'about', to: "home#about"
root to: 'home#index'
Remove from application_controller:
def index
render :layout => 'application', :nothing => true
end
And add a yield in your layout:
<div class="container">
<div id="view" ng-view>
= yield
</div>
</div>
So, your home and about views are gonna be rendered inside your layout when you go to localhost:3000 and localhost:3000/about.

Related

Angularjs ReferenceError: post is not defined

I'm working on a simple app that create posts and comments to learn how to create ROR apps implemented with Angularjs.
I'm finding a problem as I'm trying to make my addComment function work. Seems like the variable that holds the expected object is not defined. At least this is the message I got from network inspection
ReferenceError: post is not defined
at k.$scope.addComment (http://localhost:3000/javascripts/app.js:99:34)
at bb.functionCall (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:176:141)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:193:165
at k.$get.k.$eval (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:112:319)
at k.$get.k.$apply (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:113:48)
at HTMLFormElement.<anonymous> (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:193:147)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:31:225
at Array.forEach (native)
at q (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:7:280)
at HTMLFormElement.c (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:31:207)angular.js:9959 (anonymous function)angular.js:7298 $getangular.js:12695 $get.k.$applyangular.js:18941 (anonymous function)angular.js:2822 (anonymous function)angular.js:325 qangular.js:2821
If someone can se a problem in my code that points to this error please let me know.
follows my code
angular.module('flapperNews', ['ui.router'])
//Provider
.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'MainCtrl',
resolve: {
postPromise: ['posts', function(posts){
return posts.getAll();
}]
}
})
.state('posts', {
url: '/posts/{id}',
templateUrl: '/posts.html',
controller: 'PostsCtrl',
resolve: {
postPromise: ['posts', function(posts){
return posts.getAll();
}]
}
})
$urlRouterProvider.otherwise('home');
}])
//Posts service
.factory('posts', ['$http', function($http){
var o = {
posts: []
};
o.getAll = function() {
return $http.get('/posts.json').success(function(data){
angular.copy(data, o.posts);
});
};
o.create = function(post) {
return $http.post('/posts.json', post).success(function(data){
o.posts.push(data);
});
};
o.addComment = function(id, comment) {
return $http.post('/posts/' + id + '/comments.json', comment);
};
return o;
}])
//Main Controller
.controller('MainCtrl', [
'$scope',
'posts',
function($scope, posts){
$scope.posts = posts.posts;
$scope.addPost = function(){
if(!$scope.title || $scope.title == '') { return; }
posts.create({
title: $scope.title,
link: $scope.link
});
$scope.title = '';
$scope.link = '';
};
$scope.incrementUpvotes = function(post) {
post.upvotes += 1;
};
}])
//Posts Controller
.controller('PostsCtrl', [
//the $scope declares that it will have elements visible in the view
'$scope',
'$stateParams',
//the posts under is the service
'posts',
function($scope, $stateParams, posts){
$scope.post = posts.posts[$stateParams.id];
$scope.addComment = function(){
if($scope.body === '') { return; }
posts.addComment( post.id, {
body: $scope.body,
author: 'user'
}).success(function(comment){
$scope.post.comments.push(comment);
});
$scope.body = '';
};}]);
and the html
<!DOCTYPE html>
<html>
<head>
<title>FlapperNews</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="javascripts/app.js"></script>
<script src="javascripts/application.js"></script>
<%= csrf_meta_tags %>
</head>
<body ng-app="flapperNews">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
</div>
</div>
<script type="text/ng-template" id="/home.html">
<div class="page-header">
<h1>Flapper News</h1>
</div>
<div ng-repeat="post in posts | orderBy:'-upvotes'">
<span class="glyphicon glyphicon-thumbs-up"
ng-click="incrementUpvotes(post)"></span>
{{post.upvotes}}
<span style="font-size:20px; margin-left:10px;">
<a ng-show="post.link" href="{{post.link}}">
{{post.title}}
</a>
<span ng-hide="post.link">
{{post.title}}
</span>
</span>
<span>
Comments
</span>
</div>
<form ng-submit="addPost()"
style="margin-top:30px;">
<h3>Add a new post</h3>
<div class="form-group">
<input type="text"
class="form-control"
placeholder="Title"
ng-model="title">
</div>
<div class="form-group">
<input type="text"
class="form-control"
placeholder="Link"
ng-model="link">
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
</script>
<script type="text/ng-template" id="/posts.html">
<div class="page-header">
<h3>
<a ng-show="post.link" href="{{post.link}}">
{{post.title}}
</a>
<span ng-hide="post.link">
{{post.title}}
</span>
</h3>
</div>
<div ng-repeat="comment in post.comments | orderBy:'-upvotes'">
<span class="glyphicon glyphicon-thumbs-up"
ng-click="incrementUpvotes(comment)"></span>
{{comment.upvotes}} - by {{comment.author}}
<span style="font-size:20px; margin-left:10px;">
{{comment.body}}
</span>
</div>
<form ng-submit="addComment()"
style="margin-top:30px;">
<h3>Add a new comment</h3>
<div class="form-group">
<input type="text"
class="form-control"
placeholder="Comment"
ng-model="body">
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
</script>
</body>
</html>
I think the problem is here Comments. You missed {. Because of which it is unable to find the stateparam id, which you are using to create post object on controller's scope.

PagedListPager page always null

This used to work... but now the >> anchor tag of the PagedListPager always passes null to the controller for the page value required...
VS 2013 Web Express & MVC 4 with latest package updates for all.
Just like in Scot Allen's MVC 4 intro, I have a partial view with a PagedListPager
The Controller:
public ActionResult Catalog(string Id= "0", int page=1)
{
var CurrentItemsPage = (get-data-blaw-blaw-blaw).ToPagedList(page,18);
var model = new ShowRoomCatalogPackage(){ CurrentItems = CurrentItemsPage};
return View(model);
}
The catalog page
#model craftstore.Models.ShowRoomCatalogPackage
#{
ViewBag.Title = "Catalog";
Layout = "~/Views/Shared/_Details.cshtml";
}
#using (Ajax.BeginForm("Catalog", "Home", new { category = #Model.SelectedCategoryId, page = 1 },
new AjaxOptions
{
UpdateTargetId = "products",
InsertionMode = InsertionMode.Replace,
HttpMethod = "post"
}
)
)
{
<div class="container" >
<div class="row">
<div class="col-lg-10 col-md-5 col-sm-4 dropdown-menu">
#Html.LabelFor(m => m.SelectedCategoryId)
#Html.DropDownList("id", Model.CategoryItems, new { #id = "ddlCategories", onchange = "this.form.submit();" })
</div>
<div class="col-lg-2 col-md-2 col-sm-1">
#Html.ActionLink("Your Cart", "Index", "ShoppingCart", "", new { #class = "btn btn-green btn-lg" })
</div>
</div>
<div class="row">
#Html.Partial("_CatalogPartial", Model.CurrentItems)
</div><!-- row -->
</div><!-- container -->
}
<br />
<br />
#section Scripts
{
<script type="text/javascript">
new AnimOnScroll(document.getElementById('grid'), {
minDuration: 0.4,
maxDuration: 0.7,
viewportFactor: 0.2
});
</script>
}
The partial view:
#model IPagedList<ShowroomCatalog>
<div id="productList">
<div class="col-lg-12 col-md-12 col-sm-12">
<div class="pagedList" data-cs-target="#productList">
#Html.PagedListPager(Model, page => Url.Action("Index", new { category = ViewBag.SelectedCategoryId, page }), PagedListRenderOptions.MinimalWithItemCountText)
</div>
<ul class="grid effect-2" id="grid">
#foreach(var item in Model)
{
var path = String.Format("~/Content/Images/catalog/{0}/{1}", item.OfferType, item.ImagePath);
<li>
<div class="itembox">
<div class="imagebox">
<a href="#Url.Action("Detail", "Home", new { id = item.Id })" title="Detail for #item.CatalogName">
<img class="catalogimg" src="#Url.Content(path)" />
</a>
</div>
<p>#item.CatalogName</p>
</div>
</li>
}
</ul>
</div>
</div><!-- productlist -->
Now the rendered partialview in the browser doesn't have anything in the anchors which may or may not be normal...
<div class="pagedList" data-cs-target="#productList">
<div class="pagination-container"><ul class="pagination"><li class="disabled PagedList-skipToPrevious"><a rel="prev">«</a></li><li class="disabled PagedList-pageCountAndLocation"><a>Showing items 1 through 18 of 65.</a></li><li class="PagedList-skipToNext">»</li></ul></div>
</div>
And when you hover on the >> it doesn't show the page parameter in the URL:
Again, back in the Controller - I get the category (15) but no page parameter or Request.URL parameter is passed to the controller - it's not hiding because of some routing mistake...I think...
How do I get the paging control to work again...???
[EDIT: one more note - the url path on the pager is /controller/action/category/page rather than what shows up on Scot Allen's OdeToFood example where it's equivalent would be /controller/action/category?page=n (like /Home/Catalog/15?page=1 ]
I was missing the JS for the PagedList class anchor element.
var getPage = function () {
var $a = $(this);
var options = {
url: $a.attr("href"),
data: $("form").serialize(),
type: "get"
};
$.ajax(options).done(function (data) {
var target = $a.parents("div.pagedList").attr("data-otf-target");
$(target).replaceWith(data);
});
return false;
};
And this is fired off by :
$(".main-content").on("click", ".pagedList a", getPage);
BUT, this means you need to have your #RenderBody() call in your _Layout.cshtml file wrapped in something with a class of main-content. An example:
<section class="content-wrapper main-content clear-fix">
#RenderBody()
</section>

Rails why routing error? No route matches error with another controller

i dont understand
in routes.rb i have write
match 'promotions/search' => 'promotions#search',:as =>:search_promo ,:via=>:get
in the promotions_controller.rb i have add:
def search
#promotions = Promotion.all
respond_to do |format|
format.html # search.html.erb
format.json { render json: #promotion }
end
end
and have create in the view promotions a file search.erb.html
<!DOCTYPE html>
<html>
<head>
<script type=text/javascript>
var geocoder;
var map;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(-34.397, 150.644);
var mapOptions = {
zoom: 9,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
codeAddress();
}
function loadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://maps.googleapis.com/maps/api/js?key=AIzaSyAlDKLvBpApFUJJVjSXbZ-BV40B3xBVtYY&sensor=false&language=it&callback=initialize";
document.body.appendChild(script);
}
window.onload = loadScript;
function codeAddress() {
var address = "<%= #promotion.Address %>";
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body onload="codeAddress()">
<div data-role="header" id="ale" data-theme="a">
<h1> View all details </h1>
<%= link_to 'Home', promotions_url,'data-icon' =>'home','class'=>'ui-btn- left','data-transition'=>'fade','data-mini'=> 'true' %>
</div>
<div data-role="content" data-theme="b">
<p id="notice"><%= notice %></p>
<%= link_to 'Back', promotions_path,'data-role'=>'button','data-inline'=>'true' %>
<div class="field">
<strong><%=p.label :Show_in_google_maps%></strong>
<div id="map-canvas" style="width: 100%; height:400px"/>
</div>
</div>
</body>
</html>
and in a other page write
<li><%= link_to "Search Promo",search_promo_path,'data-icon'=>'search','data-theme'=>'a','data-mini'=>'true',"data-ajax"=>"false"%></li>
what is wrong?
i get this error
ActiveRecord::RecordNotFound in PromotionsController#show
Couldn't find Promotion with id=search
why tell me show controller i want the search controller! help
You didn't post the full routes file, but I suppose ressources :promotions precedes your search matcher? Switch them and it should work.

Binding backbone collection to view and underscore template on front end

I am using backbone + jquery mobile and couldn't get my array of models (collections) to output to the UI via underscore template.
My model is as follows:
var shortcake = Backbone.Model.extend({
defaults: function() {
return {
name: "No Slot",
butter: false,
time: "3pm",
icon: "plus",
deladd: "ADD"
};
},
initialize: function() {
this.bind("change:butter", function(){
if (this.model.butter == false) {
this.set({name: this.defaults.name});
};
}),
}
});
My collection is as follows:
var shortcakes = Backbone.Collection.extend ({
model: shortcake
});
var shortcake1 = new shortcake({ name: "How Bizarre", butter: "true", time: "1", icon:"plus", deladd:"ADD" });
var shortcake2 = new shortcake({ name: "Sexual Healing", butter: "true", time: "1", icon:"plus", deladd:"ADD" });
var shortcakeAlbum = new shortcakes([ shortcake1, shortcake2]);
And my view:
var shortcakeUI = Backbone.View.extend ({
tagName: "li",
template: _.template($('#shortcakeTemplate').html()),
initialize: function(){
this.render();
},
render: function() {
var variables = { namee: name };
if (this.model.butter == false) {
this.model.deladd = "ADD";
this.model.icon= "plus";
this.el.html( template );
}
else {
this.model.deladd = "DELETE";
this.model.icon= "minus";
this.el.html( template );
}
},
)};
var ShortcakeUI = new shortcakeUI({
collection : shortcakeAlbum,
el: $("#shortcakeinterface")[0]
});
ShortcakeUI.render();
And my html is:
<ul data-role="listview" data-split-icon="gear" data-split-theme="d">
<div id="shortcakeinterface"></div>
</ul>
<!---Templates--->
<script id="shortcakeTemplate" type="text/template">
<% for(var i = 0; i < shortcakeAlbum.length; i++){ %>
<% var shortcakez = shortcakeAlbum[i]; %>
<fieldset class="ui-grid-a">
<div class="ui-block-a">
<h3><%= shortcakez.time %></h3>
<p><%= shortcakez.name %></p>
</div>
<div class="ui-block-b">
<div id="8" data-role="controlgroup" data-type="horizontal" >
<%= shortcakez.deladd %>
Test
</div>
</div>
</fieldset>
<% } %>
</script>
So with these, my UI does not show the list of models on load.
Just starting out on backbone and js, am I doing things right here?
You need to pass the model to your template in render().
Instead of
this.el.html( template );
do this
$(this.el).html( this.template(this.model.toJSON()) );

link_to action is create or index, depending on where the code is

I want to cycle through each page of a paginated model's index. I'm using jquery to cycle through the pages. I find the link_to expression is calling the create action when called by jquery. The link_to expressions calls the index action under any other circumstances.
For instance:
<div id="links">
<% 1.upto(#total_pages) do |number|%>
<%= link_to 'Page',"#{clients_path}?page=#{number}" %>
<br />
<% end %>
</div>
Produces a link that calls the index action, like you would expect with default routing (i.e. map.resources :clients).
For cycling through the pages I have the following html:
<div id="show" style="display: none">
<% 1.upto(#total_pages) do |number|%>
<%= link_to 'Page#{number}',"#{clients_path}?page=#{number}" %>
<% end %>
</div>
<a id="stop" href="#" onclick="stop()">stop</a>
<a id="start" href="#" onclick="start()" style="display: none">start</a>
<div id="output"></div>
And here's the jquery:
var cur = 0;
var links = [];
var timeout;
function nextLink() {
if (cur + 1 >= links.length) {
cur = 0;
} else {
cur++;
}
return links[cur];
}
function nextPage() {
$.post(nextLink(), function(data) {
$("#output").fadeOut("slow", function(){
$("#output").html(data);
$("#output").fadeIn("slow");
});
});
}
function stop() {
clearTimeout(t);
$("#stop").hide();
$("#start").show();
}
function start() {
$("#start").hide();
$("#stop").show();
slideshow();
}
function slideshow() {
nextPage();
t = setTimeout("slideshow()", 5000);
}
$(document).ready(function() {
$("#show").children().each(function() {
links.push(this);
});
slideshow();
});
The resulting action from this is a call to create. What am I missing?
It's happening because you're Posting to the url, $.post(...). Rails sees the post and tries to handle it with it's mapped resource magic. Change that to $.get(...) and you should be fine.

Resources