AngularJS Filter in rails - ruby-on-rails

I'm trying to make a searchable list of posts on a ruby on rails application that I made. I have AngularJS working on the application. All of the posts are saved on rails in #posts. How would I make AngularJS filter over that?
Here is the relevant view:
<h1>Posts</h1>
<div ng-app>
<div ng-controller = "PostCtrl">
<input placeholder = "Search Post Titles", ng-model="searchText">
<div ng-repeat="post in posts | filter:searchText">
<h2>{{post.title}}</h2>
<p>{{post.text}}</p>
</div>
</div>
</div>
I'm not sure how to fill the angular array posts with the objects in #posts.

It appears that your code works as it is. Here is a plunker that seems to recreate your code.
If you would like to filter inside the post object, you can use this syntax:
ng-repeat="post in posts | filter:{ text: searchText }"
The above will only search the values of the text property of post.

Continuing the answer of Davin Tryon, you can try as this.
First use ng-init="init()" in your Controller:
<div ng-controller = "PostCtrl" ng-init="init( <%= #posts.to_json %> )">
Then in your controller you can do:
$scope.init = (posts) ->
$scope.posts = angular.fromJson(posts)
Then posts will be a JavaScript Object which can be accessed in your scope as if you have query it using angular resource.
If you want to include the associations of posts (lets say comments i.e) you can check rails docs for to_json (or "as_json") and the :include option

Related

How do I use some inputted text in a html form to query a SQLite database?

How do I use some inputted text in a html form to query a SQLite database?
Forgive me, I am very new to Ruby on Rails (couple of days).
I am getting a user to enter a number followed by enter, I then want to query my SQLite db and return results to a variable. I am working in a Ruby on Rails project. Here is the code in my home.html.erb file.
<form name="myform" action="" method="get">
<input type="text" name="CardNumber" onkeypress="if(event.keyCode==13) {javascript:form.submit();>
<input type="submit" onClick="javascript:form.submit();"/>
<br>
</form>
<br>
<br>
<script type="text/javascript" language="JavaScript">
document.forms['myform'].elements['CardNumber'].focus();
</script>
First I think you'll want to do a post instead of a get. Then you need to point action to the correct route.
Usually in rails you'll have a model object instantiated on the action that renders the view with the form. Like if it's a form for creating a new User, on the controller#new action you'll have something like:
def new
#user = User.new
end
then on the view you'll have <%= form_for(#user) ... %>
Since you instantiated #user, form_for will be able to render correctly the path and action when you give it that object as a parameter. It won't be able to figure out if it's a multipart or whatever else, but the basis of routing it will.
But you don't need it obviously. Going back to your sample.
Imagine you have a route
post "save_payment_info", to: "payments#save_cc", as: :cc_save
Then a controller:
payments_controller.rb
def save_cc
cc_number_from_form = params[:CardNumber]
end
So you'll be able to access your form fields (as long as they're named correctly) on the params hash inside the controller.
You can do the same with Ajax and return a JSON response, etc.

Rails - two forms in one (ShopifyAPI)

Part of the app i'm developing involves a form which has to create a product on the users shopify store and also create a row in my own database for an identical product (with a few extra bits of information).
Where i'm struggling is with the form itself, i can do this with a html based form, but i can't get a single ruby form to do both jobs. A shortened version of my controller create code is as follows;
def create
#item = Item.new
#item.item_title = params[:item_title]
#item.item_profit = params[:item_profit]
#new_product = ShopifyAPI::Product.new
#new_product.title = params[:item_title]
#new_product.save
#item.save
end
So as you can see i'm using the same params to set values for both the shopify product and the product in my own db. The HTML form looks like this:
<form action="/items/submit" >
<input type="text" name="item_title">
<br>
<input type="text" name="item_profit">
<br>
<br>
<input type="submit"/>
</form>
And it works fine, but how do i convert this into a ruby form that does the same job?
You can do like this:
form_tag('/items/submit')
text_field_tag 'item_title'
tag("br")
text_field_tag 'item_profit'
tag("br")
tag("br")
<%= submit_tag 'Save' %>
Instead of tag("br"), you can directly use < br />.

Nested form trouble using Rails and AngularJS

I am fairly new to js and angular but I was trying to get a Rails app working after watching Ryan Bates's railscast on Rails+AngularJS (http://railscasts.com/episodes/405-angularjs?autoplay=true).
I believe what I want to do is fairly simple: I have a Place model that has many Phones and I want to dynamically be able to add and save phones when creating a new Place. This type of nested form is fairly easy in Rails alone (with js only creating a new field element when a user adds a Phone), but I want to do this in Angular.
I suppose my question then breaks down into two:
1) What is the best practice of creating nested forms in Rails+AngularJS (or even forms in general)? Right now I am passing every model to Angular via JSON but is this the best way?
My second question refers to the following code.
I've attempted to do this and I am able to save a Place in angular:
places_controller.rb
respond_to :json
def create
respond_with Place.create(params[:place])
end
_form.html.erb
<div class="container-fluid" ng-controller="PlaceCtrl">
<form ng-submit="addPlace()">
<div class="row-fluid">
<div class="span2"><label>Name</label></div>
<div class="span8"><input type="text" class="input-xlarge" ng-model="newPlace.name"></div>
</div>
<input type="submit" class="btn" value="Add">
</form>
</div>
place.js.coffee
app = angular.module("test", ["ngResource"])
app.factory "Place", ($resource) ->
$resource("/places/:id", {id: "#id"}, {update: {method: "PUT"}})
app.factory "Phone", ($resource) ->
$resource("/phones/:id", {id: "#id"}, {update: {method: "PUT"}})
#PlaceCtrl = ($scope, Place, Phone) ->
$scope.addPlace = ->
place = Place.save($scope.newPlace)
console.log place
$scope.newPlace = {}
In place.js.coffee I am able to save Place to the DB in the line (place = Place.save($scope.newPlace)). I want the id of place so I can append it to all Phones that are dynamically built (because Phones has a FK of place_id that points to a Place). However if I type in place.id in console, I get an undefined message. place.name will return the place's name, but id won't work. If I look at console.log place, however, I see that the id field is returned and populated.
2) How do I get the id field of the place JSON object? I am almost positive this is possible since Chrome's console returns the id field but place.id won't give me anything.
Thank you in advance for your help. I greatly appreciate it.
I would try something like this:
$scope.addPlace = ->
place = Place.save($scope.newPlace) ->
$scope.newPlaceId = place.id
console.log place
$scope.newPlace = {}

Rails: Rendering Multiple index.html.erb on a Single Page

I am using tabs and want to load multiple index pages into tabs. For instance:
class AnimalsController < ApplicationController
def index
#dogs = Dog.all
#cats = Cat.all
end
end
Then in my views/animals/index.html.erb
<ul class="tabs">
<li>Dogs</li>
<li>Cats</li>
</ul>
<div id="#dogs">
<%= render #dogs %>
</div>
<div id="#cats">
<%= render #cats %>
</div>
Is refactoring out into a partial the only way to achieve this?
I'd like to have them loaded statically at once and not have to resort to doing an Ajax.load() when the tab is clicked.
You have your answer in the question itself. Why don't you just use javascript to hide the two partials and call them when their respective tab is clicked? You don't need ajax for this at all :)
Since you did not mention the javascript library that you use, I will give a generic solution using jquery:
Also you need not add a # to your respective div's ids. Change it to this:
<ul class="tabs">
<li id="dogs">Dogs</li>
<li id="cats">Cats</li>
</ul>
<div id="dogs" class="subTabs">
<%= render #dogs %><hr />
</div>
<div id="cats" class="subTabs">
<%= render #cats %><hr />
</div>
$(document).ready(function() {
$('.subTabs').hide(); //Hide the subTabs as soon as the DOM is loaded.
$('li').live('click', function(e) {
$('.subTabs').hide(); //Calling this again so as to remove an already loaded
tab, if any. You can refactor this part to make it
even simpler.
$('body').find('.subTabs').attr('id',$(this).attr('id')).show();
//This finds the ".subTabs" whose id is the same as the "li" id that
was clicked and shows it. Ofcourse, even this can be made even more
compact had i known your entire DOM structure.
});
});
Edit:
You also have to make sure that you style it using CSS to make it look more like tabs if you haven't already. :)
Hope this helps. :)
You typically only want to use a partial if you are using the same or almost the same code in more than one place.
When you say "index page", do you really want to use the same code that is used in an index of another controller? If so, then a partial is the best strategy.
Don't use JavaScript to solve a layout / code organization problem.

Ajax actionlink

I had user control in MVC ASP.NET which list the comments for particular image. I had given delete link with every comment. Now i want to delete that comment using Ajax link. Please tell me how can I use Ajax?
This is my user control and I am calling controller action on delete link:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="ListComment.ascx.cs" Inherits="gConnect.Views.Shared.ListComment" %>
<li>
<div class="question-info">
<div class="votes count"></span><span><% Response.Write("<img src=../../images/" + ViewData.Model.Logo_url.ToString() + " width=75 height=100 >");%> </div>
<div class="views "><span><%= ViewData.Model.Username.Substring(ViewData.Model.Username.IndexOf("-")+1) %></span></div>
<div class ="deletem" ><span><%= Ajax.ActionLink("Delete", "DeleteComment/" + ViewData.Model.Username.Substring(0, 2) + "." + ViewData.Model.Id, new AjaxOptions(UpdateTargetId = "comments"))%></span></div>
<div class="question">
<h3 class="title"><%= Html.Encode(ViewData.Model.Comment )%></h3>
</div>
</div>
</li>
Use jQuery:
<script type="text/javascript">
function deleteComment(id) {
$.post(
"/MyController/DeleteAction",
{ id : id }
function (data) {
// do some gui updates
});
}
</script>
And use in a link:
<a onclick="deleteComment(<%= CommentId %>); return false;" href="#">Delete</a>
Use an Update Panel. It will capture the post back from your delete link and asyncronously reload the content.
Take a look at http://www.asp.net/ajax/documentation/live/Tutorials/CreatingPageUpdatePanel.aspx for an example.
Hope that helps.
Gavin
First, make sure that your delete link posts a form. Your question is not clear about this, but since you say that you are using a delete link I am guessing that you are doing this with a GET. Actions that modify resources should be done via POST, not GET.
Once you've done that, you can use the jQuery AJAX form plug-in to do the post via AJAX. It's quite simple, and once you have a working form to do that delete, you will find converting its to use the AJAX plug-in to submit the form instead very straightforward. Just follow the examples on the site.

Resources