Scrolling down a page after rendering in Rails - ruby-on-rails

Is there a way to scroll or jump down a page after rendering it?
Specifically, in my controller action, there are some situations where I'll want to send the user to a particular place on the page. If it were just a link from another page, I'd probably use a URI fragment identifier - "http://blorg.com/page#id" - but this needs to be dynamically generated depending on some condition.
Maybe I need to use JavaScript (Prototype) somehow, but I don't know how to call the function once the page is done loading, especially from the controller.

You should really do this type of thing in your view. In your controller you should evaluate your condition to determine the part of the page you want to show, then pass the result into the view. You can then be able to use this information in your view to add a small piece of javascript at the bottom of the page that does something like the following. Of course this doesn't help you if the user has javascript turned off ;)
Controller code:
def index
# evaluate the condition
#section = (rand*10).to_i
end
View view code:
<div id="#section1">some stuff</div>
....
<div id="#section9">other stuff</div>
<% if #section>0 %>
<script type="text/javascript">
// <!--
document.location.hash="#section<%= #section %>";
// -->
</script>

If you are using jQuery, an an answer could be as follows:
$("body").scrollTop($("#my-element").position().top;
Or if you want to be really fancy (recommended), you can animate the scroll top like so:
$("body").animate({scrollTop: $("#my-element").position().top},1000);

you can have browser scroll to a position down the page by including a fragment part in the url that links to the page. e.g. http://example.com/index.html#section3 will scroll the page to the element with 'id' section3. you can use that id on a link, paragraph, etc. the browser will make sure the element is visible after the rendering.

Related

Fix Menu on Left Side and Right Side Content Change on Menu Option Click MVC

I am creating a MVC application in which on the Left Side Menu will load first time when the user Login into the application and on click of any of the Menu Option only Right side Content will display(Will Call the Action Method).
I have achieved it using Partial Views. Is it good to create whole application on Partial Views or is there any other way to achieve this?
Looks like you want to load the page for which the link is clicked, in an asynchronous way. You can do that using jQuery ajax methods.
So first, mark your links with a css class name so we can use that as the jQuery selector to wire up the ajaxfied load behavior. You should also has a content page to which we will load the result of the ajax call.
<div>
<div id="leftPane">
About
Contact
Index
<div>
<div id="rightPane">
</div>
</div>
Now you can listen to the click event on those link, use jQuery load method to get the content of those action method and update the rightPane's innerHtml
$(function(){
$("a.alink").click(function(e){
e.preventDefault();
$("#rightPane").load($(this).attr("href"));
});
});
With proper css, you can keep the leftPane to the left side of the container and rightPane to the right side of that.

Rendering Backbone view into multiple elements with different configurations

I have a html page with 3 jquery-mobile page widgets. Each page widget has the same header with a slightly different configuration for sub links. I want to create the Header as a BackboneView and render it for each page widget. Each page widget has it's own view as well. The page template looks like this:
<body>
<div id="news" data-role="page">
<header class="header"></header>
</div>
<div id="updates" data-role="page">
<header class="header"></header>
</div>
<div id="stuff" data-role="page">
<header class="header"></header>
</div>
</body>
The view for the first page, in this case being news view, gets rendered first. This page creates an instance of the header view. The problem arises when working with the header.
1) How do I target the header specifically for the first page, "#news header" while keeping it flexible enough for me to call it again with a different set of parameters when I am ready to load the updates page?
2) When I'm ready to load the updates page, it will have a different set of configurations that need to target "#updates header". Therefore I don't want to hardcode tagName on the view.
3) How do I pass the first instantiated header to the rest of the views? Or am I thinking about this all wrong and should I be extending a base Header view as a template for each of my pages which come baked in with a set of configs?
The only thing that is different between each header is a class name it will attach to an element in the rendered view and a few anchor links it makes for the page. For this, I am trying to reuse the view as much as possible to have a light footprint.
Note: Not sure if it matters but I'm using requirejs. Maybe there is a suggested way to create a View and always have it reused when necessary since requirejs handles modules as singletons?
Thanks!
Use an overview like appView.js. It will be in charge to render all the subviews.
In appView (you'd need to require your subviews in this super module, HeaderView):
initialize: function() {
this.$news = $('#news');
this.$updates = $('#updates');
this.$stuff = $('#stuff');
},
render:function() {
var newsView = new HeaderView(param1,param2);
this.$news.append(newsView.render().el);
// do the same for your other subviews
}
In your subviews (lets say NewsView)
initialize:function(param1,param2) {
this.viewclass= param1;
//set the other things you need here
},
render: function() {
this.$el.html("my content here..model/template/anything"));
this.$el.attr('class',this.vewClass);
}
Remember that the point is to have an overview creating new SubViews and calling the render(). I hope it helps.
Edit: If you are waiting for some data to load a specific subview, use a promise. If you are waiting for a collection to finish to fetch use something like that
collection.fetch(function() {
success:function(res,model) {
new subView(model);
}
}

Change partial view on link press

I have something like
#{ Html.RenderPartial(#"~/Views/Management/_Main.cshtml"); }
Can I change this view without page refreshing? I mean, I want to render few partials on one place. Like gallery, may be. I mean, I press the link - some section loaded, depending on argument.
First I think about - master page (Layout page). Any other ideas?
You can dynamically load a partial view into a div without a page reload by using the #Ajax.ActionLink() method.
Have a look at this post.

mvc3 httpResponse.write

I have some partial views that are rendered sequentially. I would like to create a log of what has rendered successfully on the top of the page, when the last partial view has completed. The only way I can think of, is to keep an array of log details and then display the log detail in a partial view on the top of the page, using a rendersection.
This to me seems cumbersome, I would prefer to be able to use HttpResponse.Write to display it to the page. However this way I don't seem to be able to control the ordering of where my log will appear on the screen. I would like them to be displayed in the same location on the page. Is there a more elegant solution?
Why not put div in the top of the page and every Partial View write to that div?
<div id=log > <label id="logs"> The Log: </label> </div>
$('#logs').after('what you want1'); // from partial 1
$('#logs').after('what you want2'); // from partial 2
$('#logs').after('what you want3'); // from partial 3
$('#logs').after('what you want4'); // from partial 4
Pass the partial view the data you want to "log" in the Model\ ViewBag and start logging!

How to to rout to another action and render the second one partially too?

I have partial view renders itself inside a JQuery popup.
<div id="enumsDialog" class="dialog">
#Html.Action("List", "Enumeration")
</div>
In this view, I have an action link to another view.
The question is there a way to let the second view renders in the same popup? I mean keep the rendering partially and without closing the popup.
I read about Ajax.BeginForm(), but it causes a redirecting to the second view.
You can render the first action inside an IFRAME.
Then you can render the new one with a simple #Html.Action and it will render in the same IFRAME.

Resources