I have a grid that i need to set:
scrollable: {
virtual: true
},
When users edit a cell then updates (or onSave(e)) their changes. The grid resets back to the top of the page. I don't know why. Users lose their place every time they try to change a cells contents.
When i make
scrollable: false,
it stays put. I think this is a huge bug in Telerik Kendo. Has anyone figured out how to stay in place on the grid after saving changes?
UPDATE
This problem only occurs in IE 11. Unfortunately my client can only use IE11.
I think this works for you:
Use GridViewRowInfo to get row info of selected row and set scroll to your custom row and column.
if (this.radGridView1.SelectedCells.Count > 0)
{
GridViewRowInfo row = this.radGridView1.SelectedCells[0].RowInfo;
radGridView1.TableElement.ScrollTo(row.Index, 0);
}
The answer is to save your current location before you bind.
in
onGridBinding(){
_currentLeftPosition = $(".k-virtual-scrollable-wrap").scrollLeft();
}
in onGridBound(){
//Go Back to previous position
var vs = mainGrid.wrapper.find('.k-grid-content').data('kendoVirtualScrollable');
var scrollGridContentOffsetTop = mainGrid.wrapper.find('.k-grid-content').offset().top;
var selectContentOffsetTop = mainGrid.content.offset().top;
var distanceTop = selectContentOffsetTop - scrollGridContentOffsetTop;
var scrollTop = vs.verticalScrollbar.scrollTop();
$("#mainGrid div.k-virtual-scrollable-wrap").animate({scrollTop: distanceTop + scrollTop,scrollLeft: _currentLeftPosition}, 0);
$("#mainGrid div.k-scrollbar-vertical").animate({scrollTop: distanceTop + scrollTop}, 0);
}
Related
I'm using the similar code to retain cursor position for ckeditor.
var range = null;
editor.on( 'blur', function() {
range = editor.getSelection().getRanges()[ 0 ];
});
someElement.on('click',function() {
var editor = CKEDITOR.instances.editor1;
if(editor){
editor.focus();
range.select();
}
});
I'm able to retain cursor position but the scrollbar scrolls to the top.
How can i keep/retain the scrollbar at same position as of cursor's?
range.select().scrollIntoView() helped me out!!
I have several editors on a long page, and scrollIntoView() never did exaclty what I wanted: either it scrolled laso the container page, or it doesn't, or it puts the elemnt to show just one line after the viewport... so, since my need was simply to return to the previous position after a small change in the HTML with setData(), I could do the following:
let window = editor.document.getWindow().$ ;
let scrollX = window.scrollX ;
let scrollY = window.scrollY ;
[...]
editor.setData(contents, {
callback: function() {
editor.document.getWindow().$.scrollTo(scrollX, scrollY) ;
}
}) ;
I don't think that CKEditor (at least, not the 4.x series) has the proper APIs for this, so I had to go to the underlying DOM.
I have a datatables table with infinite scrolling and no paging. When the user clicks a row, I insert a child row with details, and scroll the clicked row to the top.
This is all working perfectly.
However, I have a button on the child row that shows a bootstrap modal.
When the user dismisses the modal, the offset() and scrolltop() values for the dataTables_scrollBody are set to zero.
This causes the datatable to scroll incorrectly.
So I saved the values before showing the modal. Then after the model is hidden, I attempted to set the offset and scrolltop to the saved values.
I get no error, but the values stay zero.
Here is the code I am using to scroll the grid:
var container = $('#MainContent_grdBrowse,div.dataTables_scrollBody');
var scrollTo = $('.shown');
container.animate({
scrollTop: scrollTo.offset().top - container.offset().top + container.scrollTop()
});
Here is the code to restore the values:
container.offset({ top: dt_OffSetTop, left: dt_OffSetLeft });
container.scrollTop(dt_Scrolltop);
I get the same results in Firefox & IE.
Edit:
Here is the code where I save, and restore the values.
I save the values to hidden fields in the datatables click event:
document.getElementById('MainContent_dt_OffSetTop').value = container.offset().top;
document.getElementById('MainContent_dt_OffSetLeft').value = container.offset().left;
document.getElementById('MainContent_dt_Scrolltop').value = container.scrollTop();
document.getElementById('MainContent_rw_OffSetTop').value = scrollTo.offset().top;
document.getElementById('MainContent_rw_OffSetleft').value = scrollTo.offset().left;
I restore the values in the hidden.bs.modal event:
$('#ModalDisplayNotes').on('hidden.bs.modal', function (e) {
var dt_OffSetTop = document.getElementById('MainContent_dt_OffSetTop').value;
var dt_OffSetLeft = document.getElementById('MainContent_dt_OffSetLeft').value;
var dt_Scrolltop = document.getElementById('MainContent_dt_Scrolltop').value;
var rw_OffSetTop = document.getElementById('MainContent_rw_OffSetTop').value;
var rw_OffSetleft = document.getElementById('MainContent_rw_OffSetleft').value;
var container = $('#MainContent_grdBrowse,div.dataTables_scrollBody');
var scrollTo = $('.shown');
container.offset({ top: dt_OffSetTop, left: dt_OffSetLeft });
container.scrollTop(dt_Scrolltop);
scrollTo.offset({ top: rw_OffSetTop, left: rw_OffSetleft });
})
I displayed the values when I saved them and they were correct. I displayed the values returned from the hidden fields in the hidden-bs-modal event, and they were correct. Then I set the values to the datatable body. Then when I query the values from the datatables body, they are zero.
I want a nav to highlight (or something similar) once a user clicks on it AND when a user scrolls to the corresponding section.
However, on my computer when one clicks on any of the nav events after3, only nav event 3 changes. I'm guessing this is because after one clicks on 4 or 5, the scroll bar is already at the bottom of the page, so 4 and 5 never reach the top. The only div at the top is post 3, so my code highlights nav event 3 and ignores the click.
Is there any way I can fix this? Ive tried if statements (only highlight nav event if it's at the top AND the scrollbar isn't at the bottom or the top isn't the last item).
Here is a more accurate fiddle, using a fix below showing what I am talking about. The fix now highlights on scroll, but if you click option 5, it will not highlight.
$('.option').children('a').click(function() {
$('.option').css('background-color', '#CCCCCC;');
$(this).css('background-color', 'red');
var postId = $($(this).attr('href'));
var postLocation = postId.offset().top;
$(window).scrollTop(postLocation);
});
$(window).scroll(function() {
var scrollBar = $(this).scrollTop();
var allPosts = [];
var post = $('.content').offset();
var lastPost = allPosts.legnth-1
var windowHeight = $(window).height();
var bottomScroll = windowHeight-scrollBar;
$(".content").each(function(){
allPosts.push($(this).attr('id'));
});
i = 0;
for(i in allPosts){
var currentPost = "#"+allPosts[i];
var postPosition = $(currentPost).offset().top;
if (scrollBar >= postPosition){
$('.option').css('background-color', '#CCCCCC');
$('#nav'+allPosts[i]).css('background-color', 'red');
};
};
});
I think you've overdone your scroll() handler, to keep it simple you just needs to check if the scrollbar/scrollTop reaches the '.contents' offset top value but should not be greater than its offset().top plus its height().
$(window).scroll(function () {
var scrollBar = $(this).scrollTop();
$(".content").each(function (index) {
var elTop = $(this).offset().top;
var elHeight = $(this).height();
if (scrollBar >= elTop - 5 && scrollBar < elTop + elHeight) {
/* $(this) '.content' is the active on the vewport,
get its index to target the corresponding navigation '.option',
like this - $('.Nav li').eq(index)
*/
}
});
});
And you actually don't need to set $(window).scrollTop(postLocation); because of the default <a> tag anchoring on click, you can omit that one and it will work fine. However if you are looking to animate you need first to prevent this default behavior:
$('.option').children('a').click(function (e) {
e.preventDefault();
var postId = $($(this).attr('href'));
var postLocation = postId.offset().top;
$('html, body').animate({scrollTop:postLocation},'slow');
});
See the demo.
What you are trying to implement from scratch, although commendable, has already been done by the nice folks at Bootstrap. It is called a Scrollspy and all you need to do to implement it is include Bootstrap js and css (you also need jquery but you already have that) and make some minor changes to your html.
Scrollspy implementation steps.
And here is a demonstration. Notice only one line of js. :D
$('body').scrollspy({ target: '.navbar-example' });
Reference is this page:
http://demo.mypreviewbetasite.com/laverona/menu.html
File in question: http://demo.mypreviewbetasite.com/laverona/scripts/menu.js
The page works as expected in Firefox and Chrome, where as the user scrolls, the position of the window is checked against the position of my sub-menu, so that before it gets scrolled out of view, its position is set to fixed.
However, in IE8, the window position never gets updated as the user scrolls. My testing has shown that IE gets through all the functions, but only updates the windowPos variable when the page loads.
What can be done so that this page behaves the same in IE as it does in FF and Chrome?
this is from jquery documentation:
"The .offset() method allows us to retrieve the current position of an element RELATIVE TO THE DOCUMENT."
I can't understand why FF or Chrome return $('html').offset().top relative to the client screen/ It seems that IE's approach is more predictable.
Try that (use .scrollTop property of the DOM element instead of .offset().top):
$(document).ready(function(e){
//alert("subPos: " + subPos);
//first find the position of the things to sticky
submenu = $("#sub");
//submenu.removeClass("no-js");
subPos = $("#sub").position();
subPos = subPos.top;
var preScrollHtml = document.getElementsByTagName('html').item(0).scrollTop;
var preScrollBody = document.getElementsByTagName('body').item(0).scrollTop;
var checkPos = function(){
var scrolledHtml = document.getElementsByTagName('html').item(0).scrollTop;
var scrolledBody = document.getElementsByTagName('body').item(0).scrollTop;
if (preScrollHtml !== scrolledHtml) {
windowPos = scrolledHtml;
}
else {
windowPos = scrolledBody;
}
preScrollHtml = scrolledHtml;
preScrollBody = scrolledBody;
calculate();
}
var calculate = function() {
subPos = 64;
if (windowPos >= subPos){
$("#sub").addClass("fixed");
$("#minestre").css("marginTop", "50px");
}
else if (windowPos < subPos){
$("#sub").removeClass("fixed");
$("#minestre").css("marginTop", "0px");
}
//Setting text fields to show the values of everything can help in debugging
$("#windowpos").val(windowPos);
$("#subp").val(subPos);
}
//every time the window scrolls, this function is run
if ($(window).scroll){
$(window).scroll(checkPos);
}
else if(window.onscroll){
window.onscroll = checkPos;
}
});
I know this is old, but for new people coming to this question, you may want to check out Andy's answer to a similar question (which also seems to solve this one): https://stackoverflow.com/a/11396681/1793128
My ASP.Net application generates an <asp:Table> from the codebehind. What I need is for the header row of that table to slide down the page as the user scrolls past it.
I've tried the following approach using JavaScript:
window.onscroll = function () {
//grab the current scroll position
var scrollY = document.body.scrollTop;
if (scrollY == 0) {
if (window.pageYOffset)
scrollY = window.pageYOffset;
else
scrollY = (document.body.parentElement) ? document.body.parentElement.scrollTop : 0;
}
//grab the position of the header row I want to slide
var head = $("tr[name='headerrow']").offset();
var headtop = head.top;
var headleft = head.left;
//if the user has scrolled past the top of the header row
if (scrollY > headtop) {
//code correctly reaches this point as alerts show
//alert('got here');
//position the header row to the same as the scroll position
$("tr[name='headerrow']").offset({ top: scrollY, left: headleft });
}
}
I can't get the row to move. There are no error message to be seen on the various browsers developer tools.
Any help would be appreciated.
EDIT: I tried calling the offset() function on the children of the row (i.e. all of the <th> elements) like this:
$("tr[name='headerrow']").children().offset({ top: scrollY, left: headleft });
This now works but of course, they're all pushed over to the left because I'm using the left value of the header row itself... I'll keep this updated with my progress but in the meantime any assistance is appreciated as always.
Solution:
Use the children() method on the table row to allow you to change the offset of each of the <th> elements. The left value can be omitted from the offset() method, i.e.
$("tr[name='headerrow']").children().offset({ top: scrollY });
You cannot set the offset to any element. You should use css method and set the top and left parameters.