I have a BlogPost resources, where in BlogPost 'show' screen, I want a "new comment" button to be displayed and only on clicking that button I want the new Comment template to be rendered into the same page. I would like to use ajax concept to do this. How do I do this?
NOTE: I have BlogPost and Comment as seperate resources(plural)
Resources I've defined in my routes looks like this:
map.resources :blog_posts, :has_many => :comments
EDIT: For a better idea, the 'add comment' link just below a question in stackoverflow
I think all you need to do is render the comment box (the HTML markup) on page load but give it a CSS rule to be hidden ( <div id='comment' style="display:none"> ... comment markup ... </div> ). Then add a link just above or below that div to show the div and hide the "add comment" link using js (like jquery).
Something like this:
<script type='text/javascript'>
function fade_some_stuff(){
$('#comment_link').click( function(){ $('#comment').fadeIn(); $('#comment_link').fadeOut(); });
}
</script>
<a href="#" id='comment_link'>add comment</a>
<div id='comment' style="display:none;">
...
</div>
I believe you need something like this... http://jqueryui.com/demos/dialog/#modal-form
Please go through the documentation provided at the bottom to implement this in your App.
Good Luck!
Related
I have a problematic to render my views in my rails app.
I try to create a home page who load each tools of my app (5 - 6 different) but I want to allow users to call them one by one and without reloading the page (like some saas apps).
I tried with a welcome/index.html.erb page that render each views with ajax:
<button class="button1"></button>
<button class="button2"></button>
<button class="button3"></button>
<%= render "tools1/index %>
<%= render "tools2/index %>
<%= render "tools3/index %>
...
How could I do to show only tools 1 if the user click on button1, and then hide tools1 and show tools2 when the user click on button2, etc. ?
Another question, is it an efficient way to do that ?
Edit:
My fault, it wasn't clear. The point is that I don't want to render each page at the beginning, the perfect stuff will be to load (not just show) them page by page, just when the user call them
Thanks
A quick AJAX loader example
Add some links/buttons to your HTML:
<a class="ajax-load" href="/url1">Page 1</a>
<a class="ajax-load" href="/url2">Page 2</a>
<a class="ajax-load" href="/url3">Page 3</a>
<div class="ajax-content"></div>
Add this jQuery code:
$(document).ready(function(){
$('.ajax-load').on('click', function(e){
e.preventDefault();
$('.ajax-content').load($(this).attr('href'));
});
});
Now, when users click on any link, the content will be AJAX loaded.
Previous answer
Since you are rendering your pages in your view, you don't need to ajax load them again. I would suggest using some jQuery plugins to do this for you.
For example: tabs or accordion.
I am attempting to place the sign in, sign up and edit forms (from devise) into Bootstrap modals using partials. I have successfully done this by creating partials for the forms (wrapped in the modal code) and rendering them in application.html.erb as follows:
<%= render 'articles/sign_up_modal' %>
<%= render 'articles/sign_in_modal' %>
<%= render 'articles/edit_profile_modal' %>
At the top of application.html.erb I have:
<script type="text/javascript"> $(function () { $("#sign_up").modal({show:false });</script>
<script type="text/javascript"> $(function () { $("#sign_in").modal({show:false });</script>
<script type="text/javascript"> $(function () { $("#edit_profile").modal({show:false });</script>
Where "sign_up", "sign_in" and "edit_profile" represent the id's of the modals from the partials. The modal is then displayed by clicking a button in the _header.html.erb partial:
<%= link_to '<button type="button" class="btn btn-primary">Edit Profile</button>'.html_safe, "#edit_profile", "data-toggle" => "modal" %>
Everything works great except the Edit Profile modal form does not prefill the form with the appropriate values unless I am also on the edit page when I click the button to display the modal. How can I get the Edit Profile modal form to prefill the users data no matter which page they are on in the background?
Does this make sense? Please tell me how I might clarify my question. Thanks!
The answer was provided to me by u/alec5216 on reddit.
He said:
Take a look at the devise source.
https://github.com/plataformatec/devise/blob/master/app/views/devise/registrations/edit.html.erb
You'll see the form is bound to the "resource" variable which is going to be an instance of a user model. I bet if you use current_user in the partial instead of resource you'll have the desired effect.
This worked. See HERE for the full conversation.
In this case you will probably have to make an AJAX call to fetch the required data.
The data itself can either be JSON (for client-side rendering) or the complete html form rendered with the layout: false option. I usually go for the former because it is faster and easier to implement, unless your project is a single-page js application.
You can find more information on bootstrap ajax modals here on StackOverflow.
I am trying to use Simplemodal as a pop up box on an index page and put a form to add a new user inside it. It's not working, says there is an undefined method. How do I make this work? Does it have to do with :remote?
EDIT - Here's some code to hopefully explain a little better - from index.html.erb
<div id='basic-modal'>
<input type='button' name='basic' value='Demo' class='basic'/>
</div>
<!-- modal content -->
<div id="basic-modal-content">
<%= render 'form' %>
</div>
My form is the standard scaffold form, my Client model has a place to add some basic information about a client. My controller is the standard controller that is generated with scaffold, and my application.html.erb adds the required .js files. When I take the
<%= render 'form' %>
out and put in just plain text, it works just fine. Does that help?
Although I haven't found the answer to using simplemodal for a modal box, I found this tutorial at Nettus which uses modalbox and facebox:
http://net.tutsplus.com/tutorials/ruby/how-to-build-an-unobtrusive-login-system-in-rails/
With a few changes for rails 3, this helped me put a form inside a modal box with no problems.
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.
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.