Can I stop the page from 'scrolling' back to the top when a user clicks on a tab (with Rails not Javascript)? - ruby-on-rails

Ive built a webpage with 'tabs' using rails. When a user clicks a tab, a new page loads. I want to format it so the tabs are always in the same place on the page as a user clicks them. This happens as long as the user has not scrolled down on the page. If a user has scrolled down, clicking on the tab will refresh the page and it is no longer scrolled down - which make clicking the tabs look bad. Is there a way to keep the spot on the page where the user has scrolled down, without using Javascript? If it must be done with Javascript, any suggestions?
T
alt text http://img.skitch.com/20100526-xtrn2ncbetj6bs1a2s4xwywfjh.png

Without Javascript, nope. If they were at an exact location, you would be good to go, using an anchor (example.html#anchor), but since you don't know the exact location, you're pretty much out of luck.
So sorry!

You can do it but you will need a small amount of Javascript and some CSS hiding.
Suppose these are your tabs:
<ul id="nav">
<li class="tab">Content 1</li>
<li class="tab">Content 2</li>
</ul>
And suppose this is your content:
<div id="content" class="content1">
<div id="content1">
<h1>Some content</h1>
<p>This is my content.</p>
</div>
<div id="content2">
<h1>More content</h1>
<p>This is my other content.</p>
</div>
</div>
What you would need to do then, and I am demonstrating using the Ext.Core library, is:
<script type="text/javascript">
Ext.onReady(function() {
Ext.select('.tab a').on('click', function(ev, el) {
ev.stopEvent();
var content_id = el.href.replace('#', '');
Ext.get('content').removeClass(['content1', 'content2', ...]).addClass(content_id);
});
});
</script>
You also need a little CSS like so:
#content.content2 #content1,
#content.content1 #content2 {
display:none;
}
This hides the other content we are not looking at. We set a class on the content container called contentN which is the href of the link for that tab. So if we have a tab with href="#content1" then we add a class to the content container called content1 and now that content is visible and other content is not.
The Ext.Core samples page has another way of doing it, and they have an example up showing it working. Their way is more involved than this.

Related

Two similarly syntaxed menus - the one in footer works; the one in the header does not

I am learning to make menus. In a tutorial I learned to make a mobile-friendly menu (http://designshack.net/articles/css/responsive-slide-down-navigation). The page I created is at http://nspowers.org/ask/why-menu and uses lists for the links.
The links in the footer work. However, links with identical syntax in the top menu do not link.
Here is the structure of the working footer navigation:
<footer id="hfooter">
<div class="footer_nav">
<nav>
<ul>
<li> Home </li>
<li> Work </li>
<li> About </li>
<li> Contact </li>
</ul>
</nav>
</div>
<div class="copyright">&copy</div>
</footer>
This is the structure of the top navigation that is not working:
<header id="topnav">
<nav>
<ul>
<li> WORK </li>
<li> ABOUT </li>
<li> CONTACT </li>
</ul>
</nav>
Nav Menu
<h1>This is the 'home' page</h1>
</header><!-- #end #topnav -->
The css is here: http://nspowers.org/ask/why-menu/styles.css.
I would like to learn what other variables may affect successful linking other than the syntax of the links I've looked at in tutorials.
Solved it.
1) First, the menu.js from file has the following in the third section:
$('#topnav nav a,#topnav h1 a,#btmnav nav a').on('click', function(e){
e.preventDefault(); // stop all hash(#) anchor links from loading
});
Thank you to http://disqus.com/ashearlam, this doesn't need to be there. Delete it. It was supposed to stop the menu from linking away within a mobile view. However, it works fine without it. The working menu.js is as follows:
$(function(){
var nb = $('#navbtn');
var n = $('#topnav nav');
$(window).on('resize', function(){
if($(this).width() < 570 && n.hasClass('keep-nav-closed')) {
// if the nav menu and nav button are both visible,
// then the responsive nav transitioned from open to non-responsive, then back again.
// re-hide the nav menu and remove the hidden class
$('#topnav nav').hide().removeAttr('class');
}
if(nb.is(':hidden') && n.is(':hidden') && $(window).width() > 569) {
// if the navigation menu and nav button are both hidden,
// then the responsive nav is closed and the window resized larger than 560px.
// just display the nav menu which will auto-hide at <560px width.
$('#topnav nav').show().addClass('keep-nav-closed');
}
});
$('#navbtn').on('click', function(e){
e.preventDefault();
$("#topnav nav").slideToggle(350);
});
});
2) The webpage was missing a mobile meta viewport, so the website was not being scaled down to a mobile view when viewed on a mobile device. Adding the meta,
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
resolves this issue.
A working version can be found here: http://nspowers.org/ask/menu-solved

jquery mobile dynamically change content (not the whole page)

I have a normal jquery page with header, content and a panel
<div id="myPage" data-role="page">
<nav id="myPanel" data-role="panel">...menu...</nav>
<div id="myHeader" data-role="header">...button...text...</div>
<div id="myContent" data-role="content">...welcome text...</div>
</div>
The page is initially loaded with a menu in the panel (with a custom ajax call) and a welcome text as content. Besides text, the header also contains a button to open the menu panel.
When a user taps on a menu item I only want to replace the content, not the entire page.
I've been trying with
$.mobile.changePage('my/valid/url', {
pageContainer : $('#myPage')
});
I can see in my network log that I get the correct content from the JQM ajax call. But when I look at the DOM, the only thing that happened is that an empty div is appended to #myPage, i.e. the content from ajax is not inserted. And the old content is still there. See below:
<div id="myPage" data-role="page">
<nav id="myPanel" data-role="panel">...menu...</nav>
<div id="myHeader" data-role="header">...button...text...</div>
<div id="myContent" data-role="content">...welcome text...</div>
<div data-role="content" data-url="my/valid/url">EMPTY</div>
</div>
One other thing is that the whole page, #myPage, is hidden (display="none"). It seems that JQM wants to show an entire new page instead of just allowing me to change the content of one div inside #myPage.
Is it possible to change just a part of a JQM-page using JQM?
I've done it with a custom ajax call and then appended the markup to the DOM myself. But then I need to do a lot of other stuff manually, like enhancing , showing/hiding the load indicator etc.

Applying the theme outside the page

I'm trying to learn jquery mobile and have been playing around with it for the past few days and things are going alright, but I'm not so sure if I'm taking the proper approach.
I tried making a site with a similar UI as the facebook app. On the top right and left corners of the page's header are buttons that causes the page to slide out like a drawer.
The top left button will slide the page out to the right to reveal a menu, while the top right button will slide out to the left to reveal a form to fill out.
What I did was create divs outside the page and used javascript to slide out the active page, to reveal the menu or form depending on which button is pressed:
<body>
<div id="my-menu">
<ul>
<li>Menu Item 1</li>
</ul>
</div> <!-- end of my-menu -->
<div id="my-form">
<form method="post" action="form-action.php">
<!-- form elements -->
</form>
</div> <!-- end of my-form -->
<div data-role="page" id="home">
<div data-role="header">
</div>
<div data-role="content">
</div>
</div> <!-- end of home -->
</body>
I used my own CSS to style the menu, but I also noticed my theme wasn't applied to "my-form", but everything in the page "home" had all elements properly styled.
I can't put the form inside the page "home" because I will not be able to do sliding drawer effect that I've done with the menu.
Am I suppose to have my own styling applied to the form outside the page or is there a way to apply the jquery mobile theme to elements outside the page?
Would this be the best approach to implement this kind of user interface or is there a better way using what's available in jquery mobile?
Since this will be my UI for the application does that mean I will just copy the same code to all the pages? Or is there a better way to do this?
I'd like to use the best practice for this use case so please offer any advice!
Thanks in advance for the help!
BTW I did the slide menu based on this blog post:
http://blog.aldomatic.com/facebook-style-slide-out-menu-in-jquery-mobile/
Solution 1:
As I told you in comments, jQM style can not be applied outside of page container but that should not prevent you from using its css.
If you are using firefox, use firebug plugin and take a look at every jQM page element, copy its structure and css. Use it to create styling outside page container.
One more thing, new elements are going to be styled but they will not have functionality, you will need to redo it by yourself.
Solution2:
Have your content inside a data-role="page" div at page-load, let jQuery Mobile style the page, and then move your content div out of the data-role="page" div to be a child of the body tag.

jquery accordion sections does not open

I've got a jquery accordion on site BUT it kinda doesn't work >> when browser loads page accordion looks good (with one first section opened) BUT when I press on some other section, first section closes and none of sections ar opening up, so it kinda stucks with all sections closed! When I reload the page this loop starts from the beginning. Here is the link to the site, click on "Pakalpojumi" to see that accordion.
Here is the html of accordion:
<div id="accord">
<h3><a id="gr" href="#">Griezšana</a></h3>
<div>
<p>
max griešanas garums: 2500mm </br>max loksnes biezums: 4mm
</p>
</div>
<h3><a id="ur" href="#">Urbšana</a></h3>
<div>
<p>
Mēs piedāvājam 3 dažādu veidu stacionārie urbji
</p>
</div>
<h3><a id="lo" href="#">Locīšna</a></h3>
<div>
<p>
max loksens garums: 2000mm, </br>max spiešanas spēks: 65 t
</p>
</div></div>
Adding accordion to accord:
$('#accord').accordion();
Does anyone have any idea of what could be wrong?
The code works fine by itself, see here. On closer inspection of your site, there is a style which is placed on the active div each time the header is clicked (I'm using chrome, it appears as element.style in its css properties) which sets the height, padding-top and padding-bottom to 0px. If I disable those styles, the selected div appears fine. Do you happen to be adding these styles on every click?
Edit
Ok, I found your problem... Does the second tab here look familiar? According to this post it's because when you initialise your accordion, its parent element is hidden (via your 'off' class). So you can get around this issue by defining a height for your divs after initialising your accordian like so:
$('#accordion').accordion();
$('#accordion >div').css('height', '300');
... or by by initialising your accordion once its parent is shown.

Sharing an element between jQuery UI tabs?

I'm using jQuery UI's tabs to divide content on my page. I have a 'link bar' I would like to have hang at the bottom of each tab. (The tab text will change but generally they will navigate the user left or right through tabs.)
Hosting the #linkBar div inside the first tab makes it 'look' right, inside Themeroller's border. Putting it just outside the 'parent tab' div places the links below the theme's border. I've tried creating a spacer div but it just pushes #linkBar down further.
Of course when the user switches to another tab, the link bar goes away. How is ownership of elements organized between tabs? Should I dynamically destroy the #linkBar div on the tab being navigated away from and rebuild it in the tab being navigated to? Or is there a better way to move it between them, or just manage visibility?
I would like to have the link bar follow the content on each tab as a footer, 'floating' one or two lines below the last content of each tab (rather than having it in a fixed position relative to the tab bar).
Ok ... It was simply adding the jQuery UI classes to the linkBar. Check out my working jsFiddle demo:
I moved the linkBar div out of the tabOne div and put it at the bottom of the tabs div:
<div id="container">
<div id="title">
<h1>title bar</h1>
</div>
<div id="tabs">
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
<div id="tabone">
content goes here
<br><br><br><br>more stuff<br><br><br>more stuff<br><br>
</div>
<div id="tabtwo">
content goes here...
</div>
<div id="tabthree">
content goes here...
</div>
<div id="linkBar">
<span id="leftLink"><< left link</span>
<span id="rightLink">right link >></span>
</div>
</div>
</div>
I slightly altered the linkBar style by giving it a top and bottom margin as well as hiding it by default:
#linkBar {
display: none;
margin: 10px auto;
}
Then I simply added the jQuery UI classes to the $linkBar. I slightly altered the jQuery to be more readable:
$("#accordion").accordion({ header: "h3" });
var $tabs = $("#tabs"),
$linkBar = $("#linkBar");
$linkBar.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");
$linkBar.show();
$tabs.tabs();
$('#title').click(function() {
$tabs.tabs('select', 0);
return false;
});
Note: You could just add class="ui-tabs-panel ui-widget-content ui-corner-bottom" to the linkBar div and be done with it. But, I think I like it better managed in the JS.

Resources