Jump to content

Single Page "ScrollTo"


Speed
 Share

Recommended Posts

Hi guys,

With Single page in HTML, especially when they are so long I could create page jump with #foo inside nav anchor tag...

This is what I would type in HTML...

<nav>
  <ul>
    <li><a href="#sec-a">Section A</a></li>
    <li><a href="#sec-b">Section B</a></li>
    <li><a href="#sec-c">Section C</a></li>
    <li><a href="#sec-d">Section D</a></li>
  </ul>
</nav>
<section id="sec-a">
    <div class="title">
        <h1>Title</h1>
    </div>
    <div class="content">
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut, atque?</p>
    </div>
</section>
<section id="sec-b">
    <div class="title">
        <h1>Title</h1>
    </div>
    <div class="content">
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut, atque?</p>
    </div>
</section>
<section id="sec-c">
    <div class="title">
        <h1>Title</h1>
    </div>
    <div class="content">
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut, atque?</p>
    </div>
</section>
                                  

I only wonder how could I do page jump in PW with Markup SImple Navigation following these PW code below? Any modules or suggestions?

   <nav>
       <?php
          $nav = $modules->get("MarkupSimpleNavigation"); 
          $nav_options = array(
              'show_root' => true,
              'outer_tpl' => '<ul class="nav">||</ul>',
              'inner_tpl' => '<ul class="drop">||</ul>',
              );
              echo $nav->render($nav_options); // render the menu
        ?>
</nav>
<section id="sec-a">
    <h2><?php echo $page->title; ?></h2>
   <?php echo $page->body ?>
</section>
<section id="sec-b">
    <h2><?php echo $page->title; ?></h2>
   <?php echo $page->body ?>
</section>
<section id="sec-c">
    <h2><?php echo $page->title; ?></h2>
   <?php echo $page->body ?>
</section>

Thanks in advance

Link to comment
Share on other sites

Instead of putting your content in body field, create  fields for each section in your page template. Then render each section in its own HTML section. 

<section id="sec-a">
    <h2><?php echo $page->title; ?></h2>
   <?php echo $page->sectionA ?>
</section>
<section id="sec-b">
    <h2><?php echo $page->title; ?></h2>
   <?php echo $page->sectionB ?>
</section>
<section id="sec-c">
    <h2><?php echo $page->title; ?></h2>
   <?php echo $page->sectionB ?>
</section>
  • Like 1
Link to comment
Share on other sites

hi,

I would create the sections as sub-pages in the backend:

- onepager
  -- section a
  -- section b
  ...
  -- section n

For the onepager contents, you can query for the 'onepager' children and loop them out into the sections markup. For the id attribute you can use the childpage's id, like 'id="section-{$section->id}"':

$onepager = $pages->find('selectorfortheonepagerpage'); // i.e find('/name-of-the-onepager'), find('template=onepager_template')
$onepagerSections = $onepager->children;
if($onepagerSections->count){
  foreach($onepagerSections as $section) {
    echo '<section id="section-'.$section->id.'">(..........)</section>';
  }
}
...

In the same way you can build the navigation, using the section id for the anchor. no need to use the simple nav render, just loop over the onepager children once again and build your navigation markup with "a href="{$onepage-r>url}#section-{$section->id}"

...
if($onepagerSections->count){
  echo '<ul>';
  foreach($sectionNav as $item){
    echo '<li><a href="''.$onepager->url.'#section-'.$item->id.'">'.$item->title.'</a></li>';	
  }
  echo '</ul>';
}
...

 

This could be optimized to go in one loop, creating two output variables, one for the nav, one for the sections, and echoing them out later, but for illustration purposes I think this'll work.

cheers,
Tom

  • Like 3
Link to comment
Share on other sites

Regarding MarkupSimpleNavigation:
You have more options here: http://modules.processwire.com/modules/markup-simple-navigation/ (See Default Options)
Including the options to modify the markup of the links:

<?php
$options = array(
	...
    'item_tpl' => '<a href="{url}#section{id}">{title}</a>',
    'item_current_tpl' => '<a href="{url}#section{id}" class="current">{title}</a>',
	...
);
echo $treeMenu->render($options, [...], [...]);

I also go with @Webrockers method of having the sections of onepagers as childpages of the homepage. (Or they could sit anywhere basically).
It is nice because you can have different templates for each kind of section then: "onepager_text, onepager_carousel, onepager_contact". Find them with the selector ("template=onepager_text|onepager_carousel|onepager_contact")

  • Like 2
Link to comment
Share on other sites

Guys, Thank you for your replies... Your idea and suggestion helped me.

@deltavik -- instead of fields, I've used get page and render template method. You can see below here.

@Webrocker -- I must admit, I don't have strong knowledge in PHP, this is why I used mix php/html method for now. However, your method seem to be Interesting, I certainly, I would try that for next experiment project so I could gain more knowledge. For now, I'd stick with "mixed" html/php, Thank you for excellent tips. 

@blynx, Your code with MSN, this is what I did entire rainy weekend (see below). except for {id} part, that something I want to dig into. I believe this would help.

Here's what I did on single page using markup simple network....

/*Nav*/
<nav class="responsive">
	<?php
       $nav = $modules->get("MarkupSimpleNavigation"); 
       $nav_options = array(
       		'show_root' => true,
            'outer_tpl' => '<ul class="nav">||</ul>',
            'inner_tpl' => '<ul class="drop">||</ul>',
            'item_current_tpl' => '<a href="#{url}">{title}</a>'// for Home page(Current)
          	'item_tpl' => '<a href="#{url}">{title}</a>', //for Child page
             );
             echo $nav->render($nav_options); // render the menu
      ?>   
</nav>
/*Home Page*/
<section id="/">
<?php
$sec_a = $pages->get('/SectionA/'); 
$sec_Rendered = $sec_a->render('single/sec_a_tpl.php');
echo $sec_Rendered;
?>
</section>
<section id="sectionB">
<?php
$sec_b = $pages->get('/SectionB/'); 
$sec_Rendered = $sec_b->render('single/sec_b_tpl.php');
echo $sec_Rendered;
?>
</section>
<section id="sectionC">
<?php
$sec_c = $pages->get('/SectionC/'); 
$sec_Rendered = $sec_c->render('single/sec_c_tpl.php');
echo $sec_Rendered;
?>
</section>

this works flawless, I am able to get this to scroll up/down when pressing each menu list...  except for one thing... The drop down menu become "inactive".  Here's whats on my menu...

Home   About    Dropdown   Contact
                              Drop1
                              Drop2

I confirmed when viewing address bar /#/dropdown/drop1 and realized, since I've added this string in array'item_tpl' => '<a href="#{url}">{title}</a>' it  it affects entire main menu including Dropdown from going into another page but seeking for /#/dropdown somewhere. The main goal was get entire menu to scroll down using item_tpl except for dropdown. So, I wonder... are there any way to exclude only one menu (dropdown) from getting # using Markup Simple Navigation? Any suggestions? Thanks in advance. 

Link to comment
Share on other sites

Hm, this is weird:

Quote

href="#{url}"

The # (Anchor thingy) should definitely be after the url → href="{url}#....."
or if you don't want to jump anywhere there doesn't need to be a # at all - in that code you just posted you can simply remove it.

Maybe this is useful for understanding,
possible "href"s:

href="/link/to/some/page" — a link to another page
href="#sectionA" — a "jumplink" / anchor to an element with the id on the same page!
href="/other/page/#contact-form" — go to antother page and jump to that element with the id "contact-form"

Try this: href={url}#{name}

At first I was confused why your navigation worked apart from the dropdown. Because it shouldn't.
But then I realised that you are "accidentally" using the same word for the section id as there is for the page name ... and the url is based on the page name.

Instead of using the urls for as an id I would use the page name in combination with the id. So you get a unique identifier for the anchor.
#{name}-{id}

The problem is that you don't want urls for the sections on the homepage in your <a>, you want something like <a href="#sectionB">
... 'item_tpl' => '<a href="#{name}">{title}</a>'

But you want urls for the dropdown things - and maybe jump link? maybe not? So you would want something like <a href="/page/"> or <a href="/page/#anchor">
... 'item_tpl' => '<a href="{url}#">{title}</a>' or
... 'item_tpl' => '<a href="{url}#{name}">{title}</a>'

Have a look again at MarkupSimpleNavigation Documentation:

<?php
    'xtemplates' => '',
    // specify one or more templates separated with a pipe | to use the xitem_tpl and xitem_current_tpl markup
    'xitem_tpl' => '<a href="{url}">{title}</a>',
    // same as 'item_tpl' but for xtemplates pages, can be used to define placeholders
    'xitem_current_tpl' => '<span>{title}</span>',
    // same as 'item_current_tpl' but for xtemplates pages

With the xtemplates option you can define another kind of link template for specific page templates.

Sorry, might be a bit confusing with the {name} and {id} - hope this helps anyway ;)

Link to comment
Share on other sites

 

@blynx -- Thank you for taking time to respond... Maybe I wasn't much clear on what I was looking for... Here let me explain it better. From demo menu as showed from earlier post...

Home   About    Dropdown   Contact
                              Drop1
                              Drop2

The goal for was to get Home, About, Dropdown and Contact to jump into section on same page except for Drop1 and Drop2.  Instead of #drop1 it need to have url link to another page. 

so... 

Home     - (jump into same page section)  'item_tpl' => '<a href=" #{name}">{title}</a>'  (address bar shown) → /#home/
About    - (jump into same page section) → 'item_tpl' => '<a href=" #{name}">{title}</a>'   (address bar shown) → /#about/
Dropdown - (jump into same page section) → 'item_tpl' => '<a href=" #{name}">{title}</a>'   (address bar shown) → /#dropdown/
   Drop1 - (jump into same page section) →  ?? 'item_tpl' => '<a href=" {url}">{title}</a>'   (address bar expected to show) → /#dropdown/drop1
   Drop2 - (jump into same page section) →  ?? 'item_tpl' => '<a href=" {url}">{title}</a>'   (address bar expected to show) → /#dropdown/drop2
Contact  - (jump into same page section) → 'item_tpl' => '<a href=" #{name}">{title}</a>'  (address bar shown) → /#contact/

The 'item_tpl' => '<a href="#{url}">{title}</a>' almost worked, except it did not get Drop1 or Drop2 from Dropdown into another page after click.

yet 'item_tpl' => '<a href=" #{name}">{title}</a>' it worked too, but it assign # to entire menu list including Drop1 and Drop2 which I did not want that. I wanted URL instead...  Your suggestion #{name}  instead of #{url} is lot better since it doesn't require page load and its jumps into section on same page quickly after pressing on menu. I'm going to stick #{name}, Thank you for your suggestion.

I tried your suggestion #{name}-{id}  to set up as unique identifier, it didn't work, jump into section on same page, Link shows changes inside address bar.  I am gonna guess this have something to do with section ID such as <section ID="<?php ... {name}--{id} ?>

I've tried  href={url}#{name}  same issues, it did not jump into another section or to next page with link, except showing change in address bar with page name and ID changes. 

I've tried this....

    'xtemplates' => '',
    // specify one or more templates separated with a pipe | to use the xitem_tpl and xitem_current_tpl markup
    'xitem_tpl' => '<a href="{url}">{title}</a>',
    // same as 'item_tpl' but for xtemplates pages, can be used to define placeholders
    'xitem_current_tpl' => '<span>{title}</span>',
    // same as 'item_current_tpl' but for xtemplates pages

Nothing works as expected. Still trying to figure out how to make a exception replacement of # to url on child of dropdown menu... Hope you can help 

Link to comment
Share on other sites

Hej,

Ah, I also just see that of course you also need the url in the first level ...

Maybe then, instead of using MarkupSimpleNavigation it will probably be easier to build the navigation by yourself -
If the navigation is not overly complex-dynamic and you only have those items and maybe one dropdown it might be just fine to hard-code the navigation.

Could you paste the code of resulting navigation and the whole MarkupSimpleNavigation setup code here?

Another approach could be to modify the MarkupSimpleNavigation afterwards with preg_replace() - to find the links in the first level and modify the href to add the proper #anchor.

 

  • Like 1
Link to comment
Share on other sites

Hi I realize I got you confused again, probably... it have been overwhelming week for me... :) 

From the last post...
Drop1 - (jump into same page section) →  ?? 'item_tpl' => '<a href=" {url}">{title}</a>'   (address bar expected to show) → /#dropdown/drop1
Drop2 - (jump into same page section)  ?? 'item_tpl' => '<a href=" {url}">{title}</a>'   (address bar expected to show) → /#dropdown/drop2 

Correction....  (see orange bold)...                                                                                                                                                                                                                                        Drop1 - (jump into another PW page) →  ?? 'item_tpl' => '<a href=" {url}">{title}</a>'   (address bar expected to show) → /#dropdown/drop1
Drop2 - (jump into another PW page) →  ?? 'item_tpl' => '<a href=" {url}">{title}</a>'   (address bar expected to show) → /#dropdown/drop2

3 hours ago, blynx said:

Could you paste the code of resulting navigation and the whole MarkupSimpleNavigation setup code here?

Sure, here's what I have so far...

           <nav>
                <?php
                    $nav = $modules->get("MarkupSimpleNavigation"); 
                   
                    $nav_options = array(
                    'show_root' => true,
                    'outer_tpl' => '<ul class="nav">||</ul>',
                    'inner_tpl' => '<ul class="drop">||</ul>',
                    'item_current_tpl' => '<a href="#{name}">{title}</a>', //home
                    'item_tpl' => '<a href="#{name}">{title}</a>', // ...nav menu after current (home)
             
                    echo $nav->render($nav_options); 
                ?>
            </nav>

And the results in picture explains it all

example.jpg

Everything there is perfect with hash in anchors, I am able to get same page jump after clicking on Home, About and Contact. But with two dropdown menus (drop1 and drop2) I would need to get that hash in achors replaced with URL so Drop1 and Drop2 can go into next PW page as mentioned in picture (The greenbox part)

3 hours ago, blynx said:

Ah, I also just see that of course you also need the url in the first level ...

"First Level"??  I not sure I get that but am guessing you mean the visible in menu i.e. Home, About, Contact and Dropdown? 

3 hours ago, blynx said:

Maybe then, instead of using MarkupSimpleNavigation it will probably be easier to build the navigation by yourself -
If the navigation is not overly complex-dynamic and you only have those items and maybe one dropdown it might be just fine to hard-code the navigation.

Oh I could do hardcoding, I could write something like this <li><a href="/drop1/"><?php page->title ?></a></li> for my personal website perhaps. But, for my future clients, that know nothing about coding, I don't think hardcoding would be best option. Especially if client decided to add new page for dropdown menu (drop3).  MarkupSimpleNavigation would probably be best solution unless, there are other options, perhaps with PW's original navigation code?

 

4 hours ago, blynx said:

Another approach could be to modify the MarkupSimpleNavigation afterwards with preg_replace() - to find the links in the first level and modify the href to add the proper #anchor.

Could you demonstrate me example with code... or point out some document around? I couldn't find anything on preg_replace() in search.  I don't really have much knowledge in php and would love to learn more about it. 

Link to comment
Share on other sites

Hej, without having read the whole post, just a quick reply about preg_replace() and regular expressions - it is definately useful to learn that stuff!
Have a look at these sites:

http://www.phpliveregex.com regular expressions in php and the according php functions
http://www.regexr.com live editing of regular expressions - very nice to learn 

Regular expressions let you search for patterns in strings. E.g. you have a link <a href='url'></a>
And then you could write some code which identifies the 'url' part and replaces it with 'url#anchor' - for example. And in your case you could limit that to the first level - it might be a bit tricky - but that topic is good to know anyway.

Will get back to you later, have to go ;)

Edit:

Ah, and the "hard coding" needn't be that "hard coded". Sometimes I use a pagefield on the homepage to let the user add items to the menu (which is based on that pagefield). Subpages could be generated depending on themplate or so - but that depends on your whole site concept. ... But there are many possibilieties!

  • Like 1
Link to comment
Share on other sites

Oh yes I know about preg_replace(), I did this before when I built contact form with validation back then. But I never really got deep into it.  What I mean, I was wonder if there are some examples on preg_replace() and MarkupSimlpleNavigation all together? so I can get idea where to start, Hope you come back and can help me to get warm start.

While at it, I just played around with  JQuery ...

$("a[href='#drop1']").attr('href', '/dropdown/drop1');

This string worked! it did replace PW page url, got this page to load into another page. But again... This not going to be good solution for my future clients. if every time clients decide they want to add new sub pages especially with different names, I'd have hard code on jQuery.  I was looking for maybe an easy alternative, more of the MSN way, overriding/replace href like this code 'item_tpl' => '<a href="#{name}">{title}</a>' but for subpages, and it can be multiple based on specific name. Dreaming too much am I? or maybe I should make requisition to Soma. :)

 

Link to comment
Share on other sites

7 hours ago, Speed said:

I was looking for maybe an easy alternative, more of the MSN way, overriding/replace href like this code 'item_tpl' => '<a href="#{name}">{title}</a>' but for subpages, and it can be multiple based on specific name.

I gave an example of how to do this in your other thread. You use a hook on MarkupSimpleNavigation:

$nav = $modules->get('MarkupSimpleNavigation');
$nav->addHookAfter('getItemString', function($event) {
    $page = $event->arguments('page');
    if($page->parent->id == 1) { // you can perform any test you want on $page
        $event->return = "<a href='#{$page->name}'>{$page->title}</a>"; // you can return any markup you want here
    }
});

 

  • Like 2
Link to comment
Share on other sites

:o Wow...so simple, it worked! 

19 hours ago, Robin S said:

I gave an example of how to do this in your other thread. You use a hook on MarkupSimpleNavigation:

Oh yes I remembered that example,  But I thought that was for element like button only. After you added comment  '...return any markup' , Now, I am duly noted, Thank you.

After looking at this document , I believe am getting somewhere about hook functionality. But, I am struggling to understand what is 'getItemString' , what does it do? I changed it name into 'test' and it does not affect anything.

$nav->addHookAfter('getItemString', function($event)

this one, ('page') too...

$page = $event->arguments('page');

Lastly...  I understand $page->parent->id means home page, And the  == 1 ?? does it mean home page too? please help me understand.

if($page->parent->id == 1)

 

Link to comment
Share on other sites

@Speed, to start learning about hooks have a read of this documentation page. It's not a simple concept to grasp so don't worry if you don't understand all of it at first. You also need to know a bit about Object-oriented programming terms like class and method.

Regarding MarkupSimpleNavigation, first understand what it is doing: it takes all the pages in your website (or all the pages you give it) and loops over them, looking at each page (item) one at a time and outputting some markup for that page. It has some markup that it uses by default but we can override that using a hook.

46 minutes ago, Speed said:

But, I am struggling to understand what is 'getItemString' , what does it do?

getItemString() is a method in the MarkupSimpleNavigation class - you can get some idea what it does from it's name. It gets the string (markup) for the item (the page in the loop that MSN is currently looking at).

In the hook example I gave we are saying to MSN "if the item you are currently looking at is a direct child of the Home page, don't output the default markup but output this special markup instead".

 

46 minutes ago, Speed said:

this one, ('page') too...


$page = $event->arguments('page');

Methods can have arguments (variables) that are used inside the method. When you hook a method you can use those variables in your hook, which can be handy for what you want to achieve. To know what arguments/variables are available you need to look at the method code. If you look at the code for getItemString() you can see there are two arguments: $tpl and $page. For this hook we want to get $page (the item MSN is looking at) so we can test it to see if the page is a direct child of the Home page. 

 

46 minutes ago, Speed said:

Lastly...  I understand $page->parent->id means home page, And the  == 1 ?? does it mean home page too?

$page->parent->id doesn't mean the home page. What this says is "for the parent of this page, get the ID property". Each page has a unique ID - one way you can see the ID of a page is to hover the "Edit" link for a page in the tree and look at the link URL. You'll see something like ".../page/edit/?id=1234". The Home page always has an ID of 1 (there might be some very rare exceptions but we won't worry about that). So in the hook we say if the page's parent has an ID that equals 1 then the page is a direct child of the Home page so output this special markup.

  • Like 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...