Adding a comment to choiceType in a symfony form - symfony

I would like to add an extra comment to my ChoiceType field in Symfony. So here is my method. It works but I am curious to know if there would be a better methodology.
In my controller, I have an array of comments and pass the array to my formType. Values of array can contain some HTML tags as well.
$comments[0] = 'Lorem ipsum dolor sit amet,consectetur adipiscing elit. Praesent nec pellentesque velit, ut porta erat. Etiam convallis rhoncus erat vitae sodales. Vivamus porta tellus erat, non congue urna blandit eget. Nam urna dolor, lacinia luctus ex sed, ornare luctus eros. Morbi varius est a nisi facilisis, bibendum dictum turpis maximus.';
$comments[1] = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent nec pellentesque velit, ut porta erat. Etiam convallis rhoncus erat vitae sodales. Vivamus porta tellus erat, non congue urna blandit eget. Nam urna dolor, lacinia luctus ex sed, ornare luctus eros. Morbi varius est a nisi facilisis, bibendum dictum turpis maximus.';
$comments[2] = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent nec pellentesque velit, ut porta erat. Etiam convallis rhoncus erat vitae sodales. Vivamus porta tellus erat, non congue urna blandit eget. Nam urna dolor, lacinia luctus ex sed, ornare luctus eros. Morbi varius est a nisi facilisis, bibendum dictum turpis maximus.';
$form = $this->createForm(UserSessionType::class, $userSession, ['choices' => $choices, 'comments' => $comments, 'amounts' => $amounts]);
And my formType Is the following. I catch the comments and put them in a data attribute
$this->comments = $options['comments'];
$builder
->add('funding', ChoiceType::class, [
'mapped' =>false,
'choices' => $this->choices,
'choice_attr' => function($choiceValue, $key, $index) {
return ['data-comment' => $this->comments[$index]];
},
'expanded' => true
])
Then with a js script, I get the content of data ttribute an displays it.
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll('[data-comment]').forEach(function(field) {
var comment = field.getAttribute('data-comment');
var span = document.createElement('div');
span.classList.add("comment");
span.innerHTML = comment;
field.parentNode.appendChild(span);
});
});
Thanks for any insight.

Yes you can do it directly in the formType without javascript
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
->add('funding', ChoiceType::class, [
'choices' => [
'choice 1' => 'aa',
'choice 2' => 'bb',
'choice 3' => 'cc',
],
])
public function finishView(FormView $view, FormInterface $form, array $options): void
{
$comments[0] = 'Comment 1';
$comments[1] = 'comment 2';
$comments[2] = 'comment 3';
$choices = $view->children['funding']->vars['choices'];
foreach ($choices as $index => $choice){
$choice->label .= " ".$comments[$index];
}
}
The result :
Solution 2 based on post owner comment:
// formType
->add('funding', ChoiceType::class, [
'mapped' =>false,
'choices' => [
'choice 1' => 'aa',
'choice 2' => 'bb',
'choice 3' => 'cc',
'choice 4' => 'dd',
],
'expanded' => true
])
// in controller
$comments[0] = 'Lorem ipsum dolor sit amet,consectetur adipiscing elit. Praesent nec pellentesque velit, ut porta erat. Etiam convallis rhoncus erat vitae sodales. Vivamus porta tellus erat, non congue urna blandit eget. Nam urna dolor, lacinia luctus ex sed, ornare luctus eros. Morbi varius est a nisi facilisis, bibendum dictum turpis maximus.';
$comments[1] = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent nec pellentesque velit, ut porta erat. Etiam convallis rhoncus erat vitae sodales. Vivamus porta tellus erat, non congue urna blandit eget. Nam urna dolor, lacinia luctus ex sed, ornare luctus eros. Morbi varius est a nisi facilisis, bibendum dictum turpis maximus.';
$comments[2] = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent nec pellentesque velit, ut porta erat. Etiam convallis rhoncus erat vitae sodales. Vivamus porta tellus erat, non congue urna blandit eget. Nam urna dolor, lacinia luctus ex sed, ornare luctus eros. Morbi varius est a nisi facilisis, bibendum dictum turpis maximus.';
return $this->render('template_name.html.twig', [
'form' => $form->createView(),
'comments'=> $comments
]);
}
// twig
<div style="margin: 50px">
{{ form_label(form.funding) }}
{% for key, fundingItem in form.funding.children %}
<div style="padding: 12px">
{{ form_widget(fundingItem) }}
{{ form_label(fundingItem) }}
{% if key in comments|keys %}
<div style="padding: 5px">
{{ comments[key]|raw }}
</div>
{% endif %}
</div>
{% endfor %}
</div>
The result:

Related

amp-live-list must have an "update" slot

This might be duplicate question, I search lot on google not found any thread
Code is as pages/amp/amp/
export const config = {amp: true};
const posts = [
{
body: "Vivamus viverra augue libero, vitae dapibus lectus accumsan eget. Pellentesque eget ipsum purus. Maecenas leo odio, ornare nec ex id, suscipit porta ipsum. Ut fringilla semper cursus.",
id: "1",
time: "1498910001"
},
{
body: "Sed leo sapien, molestie sit amet lorem eu, suscipit imperdiet tortor. Mauris maximus magna quam, non sodales metus auctor nec. Aenean tristique massa enim, non dictum mauris eleifend tristique. Proin fermentum nulla a nulla bibendum ultricies. Nulla pulvinar, risus vel tristique aliquet, elit quam tincidunt nisi, non blandit leo nulla eu ipsum. Sed porta, felis vitae elementum pellentesque, mauris felis rhoncus quam, ac suscipit eros justo ac justo. Proin et elit vitae sem interdum posuere et vitae nibh. Ut sed orci aliquam, pulvinar felis ac, pretium massa. Nullam porta ipsum non euismod mollis. Quisque scelerisque nisi quis pharetra blandit.",
id: "2",
time: "1498910002"
},
{
body: "Vestibulum eu varius dolor. Praesent sagittis magna sem, non bibendum quam aliquam et. Sed et tristique mi. Quisque porta lorem et nulla lacinia gravida. Nullam semper lobortis sem, interdum tempus tellus. Proin accumsan imperdiet leo at vulputate. Nulla euismod placerat finibus. Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
id: "3",
time: "1498910003"
},
{
body: "Aenean ante erat, egestas a justo eu, sollicitudin convallis nulla. Fusce ex est, ornare in odio eu, venenatis dapibus purus. Etiam sit amet orci quam. Proin lobortis lobortis tellus, non elementum nunc consequat ac. Suspendisse eu purus sit amet dolor elementum mattis ut in odio.",
id: "4",
time: "1498910004"
}
]
function Amp({items}) {
return (
<amp-live-list layout="container"
data-poll-interval="1000"
data-max-items-per-page="15"
id="amp-live-list-insert-post">
<button update
on="tap:amp-live-list-insert-post.update"
className="ampstart-btn ml1 caps">
You have updates
</button>
<div items>
{
items.map((post, index) => (<p key={index} id={post.id} data-sort-time={post.time}>{post.body}</p>))
}
</div>
</amp-live-list>
)
}
export default Amp;
export async function getServerSideProps({req, res, locale, params}) {
if (req.method === 'POST') {
console.log(req.body);
posts.push({
body: "sd",
id: posts.length + 1,
time: '' + (Date.now())
})
}
return {
props: {
items: posts,
}
};
}
I'm very thankful if you can provide any thread,link
i tried google search not found any thread which regard with nextjs
i'm trying to get rid of error as in picture
update[button] and items[div] was remove during ssr so replace update="true" and items="true"

How to set elements xy-position relative to selected text in another element?

Im trying to make a simple tooltip element in a textarea. The idea is, that the tooltip should show what is selected. My code so far is:
import React, { useRef, useState } from 'react';
const Contact = () => {
const myref = useRef();
const [tooltip, setTooltip] = useState('');
const handleMouseUp = (e) => {
if (window.getSelection().toString() !== '') {
myref.current.style.display = "inline-block";
myref.current.style.background = "black";
myref.current.style.color = "white";
setTooltip(window.getSelection().toString());
myref.current.style.top = e.clientY + "px";
myref.current.style.left = e.clientX + "px";
}
}
return (
<div className="contact">
<h2>Contact</h2>
<textarea
rows="10" cols="100"
onMouseUp={handleMouseUp}
value="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sit amet vestibulum odio. Morbi porttitor, ante fermentum condimentum porta, elit tellus blandit lorem, eu porttitor turpis lectus sed urna. Morbi semper, velit luctus finibus aliquam, orci orci commodo velit, ut ultrices ligula ex id nulla. Quisque enim leo, mollis a consectetur quis, vestibulum id eros. Integer non vehicula ligula. Nulla eu quam consectetur, elementum felis rutrum, lobortis dolor. Mauris laoreet egestas orci, at posuere odio sagittis sagittis. Sed consequat urna turpis, ut tincidunt nunc posuere sit amet. In dui leo, euismod et tempus sed, sodales vitae nisi. Nam faucibus aliquet condimentum. Curabitur scelerisque, quam in dignissim mattis, erat felis ultrices metus, et sagittis purus magna quis magna."
/>
<div ref={myref} style={{ display: 'none', position: 'absolute' }}>{tooltip}</div>
</div >
)
}
export default Contact;
But I cant make the tooltip position just under the selected text. Any ideas?
getBoundingClientRect seem to do the trick.
import React, { useRef, useState } from 'react';
const Contact = () => {
const myref = useRef();
const myref2 = useRef();
const [tooltip, setTooltip] = useState('');
const handleMouseUp = (e) => {
console.log(e.current);
if (window.getSelection().toString() !== '') {
myref.current.style.display = "inline-block";
myref.current.style.background = "black";
myref.current.style.color = "white";
setTooltip(window.getSelection().toString());
myref.current.style.left = (e.clientX - myref2.current.getBoundingClientRect().left) + "px";
myref.current.style.top = (e.clientY - myref2.current.getBoundingClientRect().top) + "px";
}
}
return (
<div className="contact" ref={myref2}>
<h2>Contact</h2>
<textarea
rows="10" cols="100"
// onMouseUp={handleMouseUp}
onChange={() => { }}
onMouseUp={handleMouseUp}
value="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sit amet vestibulum odio. Morbi porttitor, ante fermentum condimentum porta, elit tellus blandit lorem, eu porttitor turpis lectus sed urna. Morbi semper, velit luctus finibus aliquam, orci orci commodo velit, ut ultrices ligula ex id nulla. Quisque enim leo, mollis a consectetur quis, vestibulum id eros. Integer non vehicula ligula. Nulla eu quam consectetur, elementum felis rutrum, lobortis dolor. Mauris laoreet egestas orci, at posuere odio sagittis sagittis. Sed consequat urna turpis, ut tincidunt nunc posuere sit amet. In dui leo, euismod et tempus sed, sodales vitae nisi. Nam faucibus aliquet condimentum. Curabitur scelerisque, quam in dignissim mattis, erat felis ultrices metus, et sagittis purus magna quis magna."
/>
<div ref={myref} style={{ display: 'none', position: 'absolute' }}>{tooltip}</div>
</div >
)
}
export default Contact;

React scroll position jumps on state update

Trying to implement a simple show more button with react using useState hook. Everything is working fine except that when the content is toggled on the vertical scroll position jumps down the size of the div that was shown. In other words, the content that is shown is positioned above the "Show More" button instead of extending the text and keeping the scroll position at the beginning of the text. I have searched everything and everywhere but was unable to find an elegant solution without remembering and restoring scroll positions. Here is a sample code that shows my problem.
import {useState} from "react"
export default function Test() {
let text = (
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec aliquet porttitor vulputate. Morbi pellentesque blandit est vel
dictum. Fusce mattis dolor in diam tempor commodo. Integer eu consequat magna. Cras placerat magna vitae nunc auctor, quis
sodales ex hendrerit. Interdum et malesuada fames ac ante ipsum primis in faucibus. Duis dapibus condimentum elementum.
Phasellus ultrices quis quam vel dignissim. Suspendisse ac sapien iaculis, suscipit nunc vel, commodo lorem. Vestibulum a arcu
ut mi commodo ullamcorper. Vestibulum massa nunc, sodales a diam et, condimentum finibus quam. Nulla aliquet lacus id rhoncus
maximus. Phasellus sed vehicula erat, eget suscipit ipsum. Donec nulla arcu, luctus nec mattis eu, cursus sit amet libero.
Nullam at egestas orci. Sed tempus convallis enim vitae rutrum. Sed mattis vel dolor eu laoreet. Nam a aliquet massa, eu
vulputate lacus. Fusce condimentum, eros in scelerisque dictum, turpis nisl sagittis diam, auctor blandit massa nunc eget purus.
Praesent vitae ultrices risus. Vivamus sed leo ipsum. Maecenas rhoncus, urna sit amet interdum maximus, risus odio ullamcorper
aug
</p>
)
const [show, setShow] = useState(false)
return (
<>
<div style={{height: 1000, backgroundColor: "red"}}></div>
<button onClick={() => setShow(!show)}>THIS IS HOW I WANT IT TO WORK</button>
<div style={{width: "20%"}}>{show ? text : "Not showing anything"}</div>
<button onClick={() => setShow(!show)}>BUT ON THIS BUTTON THAT IS BELOW TEXT</button>
<div style={{height: 1000, backgroundColor: "blue"}}></div>
</>
)
}
Runnable code snippet:
function Test() {
let text = (
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec aliquet porttitor vulputate. Morbi pellentesque blandit est vel
dictum. Fusce mattis dolor in diam tempor commodo. Integer eu consequat magna. Cras placerat magna vitae nunc auctor, quis
sodales ex hendrerit. Interdum et malesuada fames ac ante ipsum primis in faucibus. Duis dapibus condimentum elementum.
Phasellus ultrices quis quam vel dignissim. Suspendisse ac sapien iaculis, suscipit nunc vel, commodo lorem. Vestibulum a arcu
ut mi commodo ullamcorper. Vestibulum massa nunc, sodales a diam et, condimentum finibus quam. Nulla aliquet lacus id rhoncus
maximus. Phasellus sed vehicula erat, eget suscipit ipsum. Donec nulla arcu, luctus nec mattis eu, cursus sit amet libero.
Nullam at egestas orci. Sed tempus convallis enim vitae rutrum. Sed mattis vel dolor eu laoreet. Nam a aliquet massa, eu
vulputate lacus. Fusce condimentum, eros in scelerisque dictum, turpis nisl sagittis diam, auctor blandit massa nunc eget purus.
Praesent vitae ultrices risus. Vivamus sed leo ipsum. Maecenas rhoncus, urna sit amet interdum maximus, risus odio ullamcorper
aug
</p>
)
const [show, setShow] = React.useState(false)
return (
<div>
<div style={{height: 1000, backgroundColor: "red"}}></div>
<button onClick={() => setShow(!show)}>THIS IS HOW I WANT IT TO WORK</button>
<div style={{width: "20%"}}>{show ? text : "Not showing anything"}</div>
<button onClick={() => setShow(!show)}>BUT ON THIS BUTTON THAT IS BELOW TEXT</button>
<div style={{height: 1000, backgroundColor: "blue"}}></div>
</div>
)
}
ReactDOM.render(<Test/>, document.getElementById("test"));
<body>
<div id="test"></div>
<!-- React.js CDN links -->
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<!-- Babel (essential for JSX syntax - https://babeljs.io/docs/en/#jsx-and-react) -->
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
</body>
I have solved it! In Chrome CSS property overflow-anchor is auto by default which in turn makes the clicked button a scroll anchor. So when the new content is loaded the window scrolls with the anchor.
In order to fix this behavior you can set overflow-anchor: none; globally or to the button itself.
function Test() {
let text = (
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec aliquet porttitor vulputate. Morbi pellentesque blandit est vel
dictum. Fusce mattis dolor in diam tempor commodo. Integer eu consequat magna. Cras placerat magna vitae nunc auctor, quis
sodales ex hendrerit. Interdum et malesuada fames ac ante ipsum primis in faucibus. Duis dapibus condimentum elementum.
Phasellus ultrices quis quam vel dignissim. Suspendisse ac sapien iaculis, suscipit nunc vel, commodo lorem. Vestibulum a arcu
ut mi commodo ullamcorper. Vestibulum massa nunc, sodales a diam et, condimentum finibus quam. Nulla aliquet lacus id rhoncus
maximus. Phasellus sed vehicula erat, eget suscipit ipsum. Donec nulla arcu, luctus nec mattis eu, cursus sit amet libero.
Nullam at egestas orci. Sed tempus convallis enim vitae rutrum. Sed mattis vel dolor eu laoreet. Nam a aliquet massa, eu
vulputate lacus. Fusce condimentum, eros in scelerisque dictum, turpis nisl sagittis diam, auctor blandit massa nunc eget purus.
Praesent vitae ultrices risus. Vivamus sed leo ipsum. Maecenas rhoncus, urna sit amet interdum maximus, risus odio ullamcorper
aug
</p>
)
const [show, setShow] = React.useState(false)
return (
<div>
<div style={{height: 1000, backgroundColor: "red"}}></div>
<button onClick={() => setShow(!show)}>THIS IS HOW I WANT IT TO WORK</button>
<div style={{width: "20%"}}>{show ? text : "Not showing anything"}</div>
<button onClick={() => setShow(!show)}>BUT ON THIS BUTTON THAT IS BELOW TEXT</button>
<div style={{height: 1000, backgroundColor: "blue"}}></div>
</div>
)
}
ReactDOM.render(<Test/>, document.getElementById("test"));
body {
overflow-anchor: none;
}
<body>
<div id="test"></div>
<!-- React.js CDN links -->
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<!-- Babel (essential for JSX syntax - https://babeljs.io/docs/en/#jsx-and-react) -->
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
</body>

find shortcode inside content of post

I've a post with a video, contained inside the content. So, the content of my post is like:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur aliquam quam sed imperdiet viverra. In ornare semper nisl, ac sodales metus facilisis ac. Morbi quis erat id magna dapibus consequat. Vestibulum sollicitudin hendrerit nisl sit amet lacinia. Mauris sed sodales quam. Mauris semper, ante quis imperdiet iaculis, neque eros pulvinar eros, id aliquet magna mauris at sapien. Sed sodales, diam venenatis aliquam ornare, nisl lorem accumsan eros, vitae suscipit dolor purus quis odio. Integer quis hendrerit sapien, at pretium neque. Nullam convallis auctor enim et malesuada. Suspendisse id fermentum risus..
[video width="100%" height="360" url="http://www.youtube.com/watch?v=sd1273xA"]"
Where the shortcode is displayed like text... I need to display the video...to use do_shortcode.
I'm trying without luck:
function your_prefix_detect_shortcode()
{
global $post;
$pattern = get_shortcode_regex();
if ( preg_match_all( '/'. $pattern .'/s', $post->post_content, $matches )
&& array_key_exists( 2, $matches )
&& in_array( 'video', $matches[2] ) )
{
echo do_shortcode("[$matches[0][0]]");
}
}
add_action( 'wp', 'your_prefix_detect_shortcode' );
EDIT:
The content is called from single.php like:
<p class="titulillos">DescripciĆ³n: <br><span><?php echo nl2br($post->post_content); ?></span></p>
EDIT2:
I'm having problems with encoding...because when processing the shortcode, for example, height isn't 360px, it's "360"
And the result is a fatal error doing calcs

Scrollspy and order of highlighting

I am trying to get a basic bootstrap scroll spy working on a simple page.
I have a plunk setup showing my code (and issue): http://plnkr.co/edit/qh4jJiCWY7nb7KFEE12R?p=preview
Basically I have this in my body tag.
<body data-spy="scroll" data-target="#sidebar">
<div class="container">
<div class="row">
<div class="col-xs-9">
<h2 id="section1-1">1.1</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse posuere est in imperdiet mattis. Integer porta libero sed diam vestibulum, quis rhoncus nisl iaculis. Donec ac libero vehicula, ultricies ante sit amet, ornare libero. Nunc laoreet feugiat vehicula. Donec tempus sapien vel libero varius congue. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut eget feugiat nisi, sit amet faucibus ex. Sed rhoncus, odio in ultricies hendrerit, dolor leo bibendum enim, id volutpat neque arcu sed lacus. Integer sit amet justo lectus. Vivamus id luctus ante. Vestibulum quis egestas dui. Praesent auctor leo id pharetra commodo. Donec id nisi nunc. Nulla vestibulum scelerisque velit id dapibus. Etiam imperdiet enim id mauris scelerisque, id egestas mi laoreet. Nunc porttitor dolor at suscipit consectetur.</p>
<h2 id="section1-2">1.2</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse posuere est in imperdiet mattis. Integer porta libero sed diam vestibulum, quis rhoncus nisl iaculis. Donec ac libero vehicula, ultricies ante sit amet, ornare libero. Nunc laoreet feugiat vehicula. Donec tempus sapien vel libero varius congue. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut eget feugiat nisi, sit amet faucibus ex. Sed rhoncus, odio in ultricies hendrerit, dolor leo bibendum enim, id volutpat neque arcu sed lacus. Integer sit amet justo lectus. Vivamus id luctus ante. Vestibulum quis egestas dui. Praesent auctor leo id pharetra commodo. Donec id nisi nunc. Nulla vestibulum scelerisque velit id dapibus. Etiam imperdiet enim id mauris scelerisque, id egestas mi laoreet. Nunc porttitor dolor at suscipit consectetur.</p>
<h2 id="section1-3">1.3</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse posuere est in imperdiet mattis. Integer porta libero sed diam vestibulum, quis rhoncus nisl iaculis. Donec ac libero vehicula, ultricies ante sit amet, ornare libero. Nunc laoreet feugiat vehicula. Donec tempus sapien vel libero varius congue. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut eget feugiat nisi, sit amet faucibus ex. Sed rhoncus, odio in ultricies hendrerit, dolor leo bibendum enim, id volutpat neque arcu sed lacus. Integer sit amet justo lectus. Vivamus id luctus ante. Vestibulum quis egestas dui. Praesent auctor leo id pharetra commodo. Donec id nisi nunc. Nulla vestibulum scelerisque velit id dapibus. Etiam imperdiet enim id mauris scelerisque, id egestas mi laoreet. Nunc porttitor dolor at suscipit consectetur.</p>
<h2 id="section2-1">2.1</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse posuere est in imperdiet mattis. Integer porta libero sed diam vestibulum, quis rhoncus nisl iaculis. Donec ac libero vehicula, ultricies ante sit amet, ornare libero. Nunc laoreet feugiat vehicula. Donec tempus sapien vel libero varius congue. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut eget feugiat nisi, sit amet faucibus ex. Sed rhoncus, odio in ultricies hendrerit, dolor leo bibendum enim, id volutpat neque arcu sed lacus. Integer sit amet justo lectus. Vivamus id luctus ante. Vestibulum quis egestas dui. Praesent auctor leo id pharetra commodo. Donec id nisi nunc. Nulla vestibulum scelerisque velit id dapibus. Etiam imperdiet enim id mauris scelerisque, id egestas mi laoreet. Nunc porttitor dolor at suscipit consectetur.</p>
<h2 id="section2-2">2.2</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse posuere est in imperdiet mattis. Integer porta libero sed diam vestibulum, quis rhoncus nisl iaculis. Donec ac libero vehicula, ultricies ante sit amet, ornare libero. Nunc laoreet feugiat vehicula. Donec tempus sapien vel libero varius congue. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut eget feugiat nisi, sit amet faucibus ex. Sed rhoncus, odio in ultricies hendrerit, dolor leo bibendum enim, id volutpat neque arcu sed lacus. Integer sit amet justo lectus. Vivamus id luctus ante. Vestibulum quis egestas dui. Praesent auctor leo id pharetra commodo. Donec id nisi nunc. Nulla vestibulum scelerisque velit id dapibus. Etiam imperdiet enim id mauris scelerisque, id egestas mi laoreet. Nunc porttitor dolor at suscipit consectetur.</p>
<h2 id="section2-3">2.3</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse posuere est in imperdiet mattis. Integer porta libero sed diam vestibulum, quis rhoncus nisl iaculis. Donec ac libero vehicula, ultricies ante sit amet, ornare libero. Nunc laoreet feugiat vehicula. Donec tempus sapien vel libero varius congue. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut eget feugiat nisi, sit amet faucibus ex. Sed rhoncus, odio in ultricies hendrerit, dolor leo bibendum enim, id volutpat neque arcu sed lacus. Integer sit amet justo lectus. Vivamus id luctus ante. Vestibulum quis egestas dui. Praesent auctor leo id pharetra commodo. Donec id nisi nunc. Nulla vestibulum scelerisque velit id dapibus. Etiam imperdiet enim id mauris scelerisque, id egestas mi laoreet. Nunc porttitor dolor at suscipit consectetur.</p>
</div>
<div class="col-xs-3" id="sidebar">
<ul class="nav nav-tabs nav-stacked affix-top" id="mynav0" data-spy="affix">
<li class="active">1.1</li>
<li>1.2</li>
<li>1.3</li>
<li>2.1</li>
<li>2.2</li>
<li>2.3</li>
</ul>
</div>
</div>
</div>
</body>
Things are working for the most part. However, the scrolling jumps from the current top bookmark to the last the second the last bookmark shows on the screen. It depends on the screen size, but on my monitor when I scroll from 1.3 to 2.1, the highlighted/active li in the nav jumps to 2.3. Even if I manually select 2.1 or 2.2 the class on the li is never changed to 'active', even if 2.3 is not viewable on the screen. If I add text to the paragraphs to make them longer then things work like expected.
How do I tell scrollspy to highlight the bookmark that is at the top of the page, rather than the bottom most bookmark? Also, why do 2.1 and 2.2 never get the 'active' class added?
I am sure its something simple but I cannot for the life of me figure out what is causing this. Any insight would be most helpful.

Resources