Marco Gasi
asked on
Problems getting a div scrolled to list item
Hi everybody.
I'm workin on an application with get a list of contacts from both Gmail and Outlook: the code works fine and for each account I get my beautyful list filled with contacts. Since the list is huge, I placed on top a navigation built on alphabet: the goal is to allow the user to click a letter and jump directly to the first item whose email starts with that letter.
This is the markup:
Here's the markup:
Then, I tried several solution to scroll to the selected item. As you can see, I tried to use anchors, but this, though it work, looks bad, even the whle body scrolls down and if I click in another part of the page the list scrolls up again.
So I created the ids and used this code:
or
Thank you for any help :-)
Cheers
I'm workin on an application with get a list of contacts from both Gmail and Outlook: the code works fine and for each account I get my beautyful list filled with contacts. Since the list is huge, I placed on top a navigation built on alphabet: the goal is to allow the user to click a letter and jump directly to the first item whose email starts with that letter.
This is the markup:
function fetch(token) {
var listOwner;
listOwner = 'Your contacts from Gmail';
jQuery('#list-owner').text(listOwner);
jQuery('#sharing-mail-contacts').slideDown();
jQuery.ajax({
url: "https://www.google.com/m8/feeds/contacts/default/full?access_token=" + token.access_token + "&max-results=1000&alt=json",
dataType: "jsonp",
success: function (contacts) {
console.log(contacts);
if ( contacts['feed']['entry'] !== '' ) {
var profileImageUrl, emailOwner, emailAddress;
var email_array = [];
for ( var i = 0;i < contacts['feed']['entry'].length;i++ ) {
if ( contacts['feed']['entry'][i]['gd$email'] != null ) {
emailAddress = contacts['feed']['entry'][i]['gd$email'][0]['address'];
if ( contacts['feed']['entry'][i]['title']['$t'] != null &&
contacts['feed']['entry'][i]['title']['$t'] != '' ) {
emailOwner = contacts['feed']['entry'][i]['title']['$t'];
} else {
emailOwner = '';
}
email_array.push(emailAddress + '#' + emailOwner);
}
}
email_array.sort();
var first_letter;
for ( var i = 0;i < email_array.length;i++ ) {
var els = email_array[i].split('#');
var new_first_letter = els[0].substring(0, 1).toLowerCase();
if ( new_first_letter != first_letter )
{
first_letter = new_first_letter;
var html = '<li class="contacts" id="' + first_letter + '"><a name="' + first_letter + '"><input name="checkboxG5" id="checkbox' + i + '" value="' + els[0] + '" class="css-checkbox" type="checkbox"><label for="checkbox' + i + '" class="css-label"><span class="contact-address">' + els[0] + '</span> <span class="contact-name">(' + els[1] + ')</span></label></a><li>';
if ( html !== '' ) {
jQuery('#mail-contacts').append(html);
}
} else {
var html = '<li class="contacts"><input name="checkboxG5" id="checkbox' + i + '" value="' + els[0] + '" class="css-checkbox" type="checkbox"><label for="checkbox' + i + '" class="css-label"><span class="contact-address">' + els[0] + '</span> <span class="contact-name">(' + els[1] + ')</span></label><li>';
if ( html !== '' ) {
jQuery('#mail-contacts').append(html);
}
}
}
jQuery('#mail-contacts li').each(function () {
if ( jQuery(this).html() === '' ) {
jQuery(this).remove();
}
});
jQuery('#contacts-wrapper').mCustomScrollbar();
}
}
});
}
At line 27 I check for the first letter of emaiol address: if the first letter appears for the first time I set for that ite an unique id.Here's the markup:
<div id="sharing-mail-contacts">
<div id="contacts-header">
<img class="img-responsive" src="assets/sat_images/user-logo.png" /><img class="img-responsive" src="assets/sat_images/logo.png" /><span id="list-owner"></span>
</div>
<p id="contacts-tip">Please, select the contacts you want share the card with and press 'Share this card' button to send them your card image.</p>
<p>
<a class="alpha" href="#a">A</a>
<a class="alpha" href="#b">B</a>
<a class="alpha" href="#c">C</a>
<a class="alpha" href="#d">D</a>
<a class="alpha" href="#e">E</a>
<a class="alpha" href="#f">F</a>
<a class="alpha" href="#g">G</a>
<a class="alpha" href="#h">H</a>
<a class="alpha" href="#i">I</a>
<a class="alpha" href="#j">J</a>
<a class="alpha" href="#l">L</a>
<a class="alpha" href="#m">M</a>
<a class="alpha" href="#n">N</a>
<a class="alpha" href="#o">O</a>
<a class="alpha" href="#p">P</a>
<a class="alpha" href="#q">Q</a>
<a class="alpha" href="#r">R</a>
<a class="alpha" href="#s">S</a>
<a class="alpha" href="#y">T</a>
<a class="alpha" href="#u">U</a>
<a class="alpha" href="#v">V</a>
<a class="alpha" href="#w">W</a>
<a class="alpha" href="#x">X</a>
<a class="alpha" href="#y">Y</a>
<a class="alpha" href="#z">Z</a>
</p>
<div id="contacts-wrapper">
<ul id="mail-contacts">
</ul>
</div>
</div>
When the contacts are fetched the ul #mail-contacts is filled with data.Then, I tried several solution to scroll to the selected item. As you can see, I tried to use anchors, but this, though it work, looks bad, even the whle body scrolls down and if I click in another part of the page the list scrolls up again.
So I created the ids and used this code:
jQuery('.alpha').on('click', function (e) {
e.preventDefault();
var letter = jQuery(this).text().toLowerCase();
var aTag = jQuery("li."+letter).first();
jQuery(aTag).get(0).scrollIntoView();
});
or
var letter = jQuery(this).text().toLowerCase();
var container = jQuery('#contacts-wrapper');
var scrollTo = jQuery("li#" + letter);
console.log('container top '+container.offset().top);
console.log('scroll top '+scrollTo.offset().top);
container.animate({scrollTop: scrollTo.offset().top - container.offset().top + container.scrollTop()});
});
and even this brutal, desperate code:jQuery('.alpha').on('click', function (e) {
e.preventDefault();
var container = jQuery('#contacts-wrapper');
container.scrollTop(960);
});
Where set up, in console I see values for offset().top, but the list remains fixed.Thank you for any help :-)
Cheers
I'm not sure any JavaScript is needed. IIRC, I did this once before with only HTML. Let me see if I can give you an example... Back in a little while :-)
ASKER
Hi Ray. Well, without javascript I used an anchor
<a name=['a']></a>
You can see it in the snippet when I use the variable first_letter (starting at line 27). That gave me a bad result, as I said, but I hopefully wait for your lighning example :-)
Don't worry about the PHP wrapper - it's not necessary for the demonstration, just my way of keeping track of the code snippets.
<?php // demo/temp_marqusg.php
/**
* https://www.experts-exchange.com/questions/28941631/Problems-getting-a-div-scrolled-to-list-item.html
*
*/
error_reporting(E_ALL);
$htm = <<<EOD
<div id="sharing-mail-contacts">
<div id="contacts-header">
<img class="img-responsive" src="assets/sat_images/user-logo.png" /><img class="img-responsive" src="assets/sat_images/logo.png" /><span id="list-owner"></span>
</div>
<p id="contacts-tip">Please, select the contacts you want share the card with and press 'Share this card' button to send them your card image.</p>
<p>
<a class="alpha" href="#a">A</a>
<a class="alpha" href="#b">B</a>
<a class="alpha" href="#c">C</a>
<a class="alpha" href="#d">D</a>
<a class="alpha" href="#e">E</a>
<a class="alpha" href="#f">F</a>
<a class="alpha" href="#g">G</a>
<a class="alpha" href="#h">H</a>
<a class="alpha" href="#i">I</a>
<a class="alpha" href="#j">J</a>
<a class="alpha" href="#l">L</a>
<a class="alpha" href="#m">M</a>
<a class="alpha" href="#n">N</a>
<a class="alpha" href="#o">O</a>
<a class="alpha" href="#p">P</a>
<a class="alpha" href="#q">Q</a>
<a class="alpha" href="#r">R</a>
<a class="alpha" href="#s">S</a>
<a class="alpha" href="#y">T</a>
<a class="alpha" href="#u">U</a>
<a class="alpha" href="#v">V</a>
<a class="alpha" href="#w">W</a>
<a class="alpha" href="#x">X</a>
<a class="alpha" href="#y">Y</a>
<a class="alpha" href="#z">Z</a>
</p>
<div id="contacts-wrapper">
<ul id="mail-contacts">
<li id="a">A</a><br>Content<br>Content<br>Content<br><br></li>
<li id="b">B</a><br>Content<br>Content<br>Content<br><br></li>
<li id="c">C</a><br>Content<br>Content<br>Content<br><br></li>
<li id="d">D</a><br>Content<br>Content<br>Content<br><br></li>
<li id="e">E</a><br>Content<br>Content<br>Content<br><br></li>
<li id="f">F</a><br>Content<br>Content<br>Content<br><br></li>
<li id="g">G</a><br>Content<br>Content<br>Content<br><br></li>
<li id="h">H</a><br>Content<br>Content<br>Content<br><br></li>
<li id="i">I</a><br>Content<br>Content<br>Content<br><br></li>
<li id="j">J</a><br>Content<br>Content<br>Content<br><br></li>
<li id="l">L</a><br>Content<br>Content<br>Content<br><br></li>
<li id="m">M</a><br>Content<br>Content<br>Content<br><br></li>
<li id="n">N</a><br>Content<br>Content<br>Content<br><br></li>
<li id="o">O</a><br>Content<br>Content<br>Content<br><br></li>
<li id="p">P</a><br>Content<br>Content<br>Content<br><br></li>
<li id="q">Q</a><br>Content<br>Content<br>Content<br><br></li>
<li id="r">R</a><br>Content<br>Content<br>Content<br><br></li>
<li id="s">S</a><br>Content<br>Content<br>Content<br><br></li>
<li id="y">T</a><br>Content<br>Content<br>Content<br><br></li>
<li id="u">U</a><br>Content<br>Content<br>Content<br><br></li>
<li id="v">V</a><br>Content<br>Content<br>Content<br><br></li>
<li id="w">W</a><br>Content<br>Content<br>Content<br><br></li>
<li id="x">X</a><br>Content<br>Content<br>Content<br><br></li>
<li id="y">Y</a><br>Content<br>Content<br>Content<br><br></li>
<li id="z">Z</a><br>Content<br>Content<br>Content<br><br></li>
</ul>
</div>
</div>
EOD;
echo $htm;
ASKER
Yes I did it me too that way, but I find two issue:
1) - entire body scrolls down whereas I would like only the scrolling container div scroll: take a look at my markup
2) - If user moves the mouse wheel, the list suddenly scrolls to the top
1) - entire body scrolls down whereas I would like only the scrolling container div scroll: take a look at my markup
<div id="sharing-mail-contacts">
<div id="contacts-header">
<img class="img-responsive" src="assets/sat_images/user-logo.png" /><img class="img-responsive" src="assets/sat_images/logo.png" /><span id="list-owner"></span>
</div>
<p id="contacts-tip">Please, select the contacts you want share the card with and press 'Share this card' button to send them your card image.</p>
<p>
<a class="alpha" href="#a">A</a>
...
</p>
<div id="contacts-wrapper"> <-- this has overflow auto -->
<ul id="mail-contacts">
<-- here the list -->
</ul>
</div>
</div>
Shpould I set overflow: auto for the <ul> element itself instead of for the container?2) - If user moves the mouse wheel, the list suddenly scrolls to the top
Ahh, I see. Didn't know you only wanted the div to scroll. I'll think about this a little more (or maybe someone else will come along with a good answer).
Couple of remarks:
* you remove empty li's, this is probably not necessary, look at what you add: <li>...<li> at the end should be </li> (both times)
* you use a custom scrollbar? that seems related to your issue!
* I tested with a bunch of generated li's and the second click code works fine (the first one just has "." instead of "#") test page here: http://schutt.nl/ee/Q_28941631
* you remove empty li's, this is probably not necessary, look at what you add: <li>...<li> at the end should be </li> (both times)
* you use a custom scrollbar? that seems related to your issue!
* I tested with a bunch of generated li's and the second click code works fine (the first one just has "." instead of "#") test page here: http://schutt.nl/ee/Q_28941631
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi Robert.
I'm going to check everything. Unfortunately, I'm not sure I can replace the custom scroll bar plugin, I have to check that.
I'll come back asap with the response :-)
I'm going to check everything. Unfortunately, I'm not sure I can replace the custom scroll bar plugin, I have to check that.
I'll come back asap with the response :-)
I've made a simple test version including that scrollbar, note that the "link-letters" are now generated (into p#letters) and the click version is a stripped down version of the one on their website. New test page here: http://schutt.nl/ee/Q_28941631/index2.htm
ASKER
Bingo! Robert, great solution.
First, good eye for having noticed the opening li tag replacing the closing one.
Second, I had tried to drop out the custom scrollbar but in the pletora of tests, evidently I didn't test the right code without the plugin: the second code works fine without plugin as you said.
Third, yes the plugin is the one you linked above and yes, I should read plugin documentation, sometime :-)
Thank you!
First, good eye for having noticed the opening li tag replacing the closing one.
Second, I had tried to drop out the custom scrollbar but in the pletora of tests, evidently I didn't test the right code without the plugin: the second code works fine without plugin as you said.
Third, yes the plugin is the one you linked above and yes, I should read plugin documentation, sometime :-)
Thank you!
ASKER
Thank you
ASKER
I take advatage of your knowledge :-) Can you take a look at this question too? https://www.experts-exchange.com/questions/28941628/Google-contacts-API-returns-empty-names.html
ASKER
Lol, hope that green is just Photoshop!
I'll have a look at that one after dinner but not sure I will be able to help.
LOL indeed, no it's not Photoshop, that is how I looked a couple of years ago for St Patrick's day going to the Irish pub.
LOL indeed, no it's not Photoshop, that is how I looked a couple of years ago for St Patrick's day going to the Irish pub.