Kendo ScrollView - Refresh/redraw current page - kendo-ui

I'm using a Kendo ScrollView to display person images on a form.
Separate from the ScrollView, users can change the display order of the images. After they save their changes to the display order, the ScrollView is reloaded, scrolls to the first item, and should display the images in their new order.
However, I've noticed that when the ScrollView is currently on the first page, that page does not get refreshed/redrawn.
My ScrollView looks something like this:
#(Html.Kendo().ScrollView()
.Name("personImage")
.TemplateId("personImageTemplate")
.DataSource(d => d
.Custom()
.Type("aspnetmvc-ajax")
.Transport(t => t
.Read(r => r.Action("PersonImages_Read", "Person", new { personID = Model.ID } ))
)
.Schema(s => s.Data("Data").Total("Total"))
.ServerPaging(false)
.PageSize(1)
)
)
The template looks like this:
<script type="text/x-kendo-tmpl" id="personImageTemplate">
<img class="personImage"
src="#(Url.Action("ImageRender", "Person"))?imageID=#= data.ID #"
title="#= data.Filename #" />
</script>
And here is my refresh function:
function refreshPersonImageScrollView() {
var scrollView = $("#personImage").data("kendoScrollView");
if (scrollView) {
scrollView.dataSource.read();
// https://docs.telerik.com/kendo-ui/api/javascript/ui/scrollview/methods/refresh
// redraws, doesn't re-read from datasource
scrollView.refresh();
// scroll to first image
scrollView.scrollTo(0);
}
}
When I watch the requests being made when I call this function, I see this:
A. When a page other than the first page is selected:
PersonImages_Read (the ScrollView's dataSource read)
The ScrollView scrolls to the first image
3x ImageRender, as it renders the first 3 items in the ScrollView
B. When the first page is selected:
PersonImages_Read (the ScrollView's dataSource read)
Nothing else
I tried switching the order of scrollView.refresh() and scrollView.scrollTo(0), but the result does not change.
Is there any way to get Kendo to refresh/redraw the current page? I thought refresh would do it, based on the documentation, but it does not.
Edit
I've been able to replicate this issue in REPL. To see the behavior in action:
Note the "Rendered" time under the first image.
Scroll to the second image in the ScrollView.
Wait several seconds, then click the "Refresh" button.
The ScrollView should scroll back to the first image.
Observe that the "Rendered" time under the first image matches the "Last clicked" time reported below the "Refresh" button, and is no longer what it was in step #1. (This is the correct behavior.)
Remain on the first image for several seconds. Note the "Rendered" time listed before continuing.
Click the "Refresh" button.
Note that the "Last clicked" time has updated, and in the "Log" section, there is an entry that reads "dataSource read complete" at approx. the same time. However, the "Rendered" time under the image has not changed, and there is no log entry that says "image for product #X loaded".
I am using Kendo version 2021.3.1109 in my project. The Kendo version in the REPL above is 2022.3.913 and it still occurs in that version.

I have found a way to resolve the issue, but this may be worth opening a possible bug ticket with Telerik, because you would think that scrollView.refresh call would work.
What I changed in your refreshPersonImageScrollview function was to call setDataSource on the scrollview rather than calling the refresh method. Like so:
function refreshPersonImageScrollView() {
$("#refresh-last-clicked").text("Last clicked: " + getCurrentTime());
addToLog("refresh button clicked");
var scrollView = $("#personImage").data("kendoScrollView");
if (scrollView) {
scrollView.dataSource.read();
scrollView.setDataSource(scrollView.dataSource);
// scroll to first image
scrollView.scrollTo(0);
}
}
This appears to force the scrollView to re-evaluate its life choices and properly refresh :) However, it does seem to trigger additional dataSource reads, so it's not ideal.
One other thing I tried that didn't resolve the problem, but may be a good thing to change to anyway, would be to utilize the promise returned by the dataSource.read call. Meaning, do your scrollView setDataSource and scrollTo calls after the dataSource read promise is settled, like so:
scrollView.dataSource.read().then(function() {
scrollView.setDataSource(scrollView.dataSource);
// scroll to first image
scrollView.scrollTo(0);
});
REPL link here

Related

CKEditor 5 how to get the click, update and deleted events from any widget/Model/View

How can I get notified on a CKEditor 5 model, View and widget's click, update and delete events?
Let's assume that I have a custom plugin implementation similar to a link plugin or highlighter plugin. Now, how can I get the following events?
When user clicks on the link/highlighted element.
When user updates the inner content of the highlighted element.
When user removes the entire highlighted link or highlighter element from editor.
The element can be a model element/view element/or a widget.
Here is the code I use. It need to be in the init() method for a plugin. I don't know if this is the correct way to do it, but it works for me(tm).
const editor = this.editor;
const model=editor.model;
const editingView=editor.editing.view;
editingView.addObserver( ClickObserver );
const viewDocument = editor.editing.view.document;
this.listenTo( viewDocument, 'click', (event,data) => {
const target=data.target; // This is the view the user clicked on
const modelObj=editor.editing.mapper.toModelElement(target);
// modelObj is the model object for the element the user clicked on. Now you just need to test if clicking on this model is something you are interested in.
// console.log(modelObj);
} );
Note that this does seem to fail if you click on a AttributeElement (Such as bold text). In that case you can either call on the target.parent until you get a result.

how to make a phonegap selectable scrollable div list

As the title says. I want to make a list of div elements inside a div. I want to be able to scroll the list up and down, and when the list is not scrolling anymore, i want to be able to click the listed elements do to something. I cant figure out how to do this.
the touchmove event executes whenever the user touches the div, even if the div its scrolling. THen i cant figure out how to make let the program know that the div isnt scrolling anymore, so the next touch on the elements will trigger a non scrollable event.....
EDIT:
what i have so far is this... However this is a quick "fix" and its not working as intended. For example if you scroll quickly up and down, then the div will think you pressed on one of the elements..
exerciseWrapper is the elements inside the scrolling div. Each element is wrapped around exerciseWrapper.
$('.exerciseWrapper').on('touchstart',function(){
touchstart=true;
setTimeout(function(){
touchstart=false;
}, 100);
});
$('.exerciseWrapper').on('touchend',function(){
if(touchstart)
{
$('.exerciseWrapper').not(this).css('border-color','black');
$(this).css('border-color','orange');
}
});
Ok so i finally figured this one out.. Reason why i couldnt wrap my minds around the solution on this, was because i couldnt get other events then eventstart and event end to work... At the time of writing i still cant get the other events like eventcancel and eventleave to work. However eventmove works and i solved the problem using this event. eventmove keeps updating the element its linked when you move your finger. Then i had a variable of touchmove to constantly be true if i am scrolling my div (with touchmove event). WHen i stop moving i can clik on selected element again and use a normal eventstart event.. This is my working code:
var touchmove=false;
function AddExercisesEvents()
{
$('#exerciseMenu').on('touchmove',function(){
touchstart=true;
$('h1').text("move");
});
$('.exerciseWrapper').on('touchend mouseup',function(event){
event.stopPropagation();
event.preventDefault();
// $('.exerciseWrapper').off();
if(event.handled !== true)
{
touchstart=false;
//ENTERING editExercise Menu..!
if(!touchstart)
{
//insert magic here
alert($(this).attr('id'));
}
}
return false;
});
}

Scriptaculous Autocomplete list closes on scroll bar click

I have a really annoying issue with Autocomplete with Prototype 1.6. I set up and dialog-style div with a form, which contains an Autocomplete. Everything works fine until I click the scroll bar, or drag it; it closes the list of suggestions. I checked this solution but now I got an javascript error
event.srcElement is undefined
I was checking the controls.js and tried to catch the event object inside the onBlur event, but it travels empty. Printed the offsetX property and is undefined. Looks like the event doesn't exist anymore. either way, it prevents that the list closes but, If I click outside the area, the list now doesn't close. And that's kinda of issue too
Anyone with this same issue? Any idea?
Thanks in advance
I was having the exact issue yesterday, but after doing some r&d I got a pretty handy fix for this.
By default this script was hiding the result div (Suggestion List) on the blur event on the search text box so as soon as we click on result div's scroll bar focus gets lost from input element & result div closes. So I did a small edit in controls.js to change the behavior of script, so now result div close method doesn't invoke on blur (focus out) from input element but triggered on the click on the document except the text input element.
For your convenience I've put the edited controls.js here.
If you like to know what has changed in JS file, here it is;
Added a event listener to the document. Just below this line
"Event.observe(this.update, "keypress", this.onKeyPress.bindAsEventListener(this));"
Event.observe($(document), "mouseup", this.onMouseup.bindAsEventListener(this));
Added a new onMouseup method.
onMouseup: function(event) {
if(!this.hasFocus) {
this.hideTimeout = setTimeout(this.hide.bind(this), 250);
this.hasFocus = false;
this.active = false;
}
},
Modify the onBlur method (Comment out two line in block)
onBlur: function(event) {
//this.hideTimeout = setTimeout(this.hide.bind(this), 250);
//this.active = false;
this.hasFocus = false;
}
I hope this will solve your issue.
Thanks
Vinod Kumar

YUI DataTable Button events lost after filtering

I'm using a YUI2 DataTable.
Some of the rows of the tables have an icon button that when clicked on will popup additional details for the row.
I'm doing the following to define the panel which gets displayed with the additional information:
MyContainer.panel2 = new YAHOO.widget.Panel("popupPanel2",
{ width:"650px", visible:false, constraintoviewport:true, overflow:"auto" } );
MyContainer.panel2.render();
YAHOO.util.Event.addListener("showButton2", "click",
MyContainer.panel2.show, MyContainer.panel2, true);
So, everything works well with that. Then I added a button that when clicked on filters out some of the rows.
MyContainer.oPushButton1.onclick = function onButtonClickp(p_oEvent)
{
var filter_val = "xxx";
myDataTable.getDataSource().sendRequest(filter_val,
{success: myDataTable.onDataReturnInitializeTable},myDataTable);
}
This filters and redraws the table. But after doing that, the buttons on the remaining rows that should popup a panel no longer work.
Nothing happens when I click on the buttons.
I'm sure I've done something wrong, but I don't know what. The buttons and panels with the correct id's still seem to be available on the page.
Do I somehow have to re-enable the listener for the click event after the datatable redraw? I'm not sure where to look for trying to debug the failed listener.
I got this working by making a call to addListener again after resetting the data for the Datasource.
MyContainer.oPushButton1.onclick = function onButtonClickp(p_oEvent)
{
var filter_val = "xxx";
myDataTable.getDataSource().sendRequest(filter_val,
{success: myDataTable.onDataReturnInitializeTable},myDataTable);
YAHOO.util.Event.addListener("showButton2", "click",
MyContainer.panel2.show, MyContainer.panel2, true);
}

Safari - updating a link's title via XMLHTTPRequest on mouse hover?

I'm doing some Mac development in a WebView. I want to expand URLs that have been shortened by a url shortener, and display that expanded URL to the user. So, given a link whose src attribute is set to http://is.gd/xizMsr, when the user hovers over the link I want the title tooltip to display http://google.com
My link tag looks like this:
Here's a shortened link to google
And here's the relevant javascript, which will use XMLHttpRequest to fetch the expanded URL and then update the title
var myRequest;
var mousedOverElement;
var isLoading = false;
function myFunction(anObject) {
if (isLoading == false) {
isLoading = true;
mousedOverElement = anObject;
var link = anObject.getAttribute('href');
var encodedURL = encodeURI(link);
var url = 'http://is.gd/forward.php?format=simple&shorturl=' + encodedURL;
myRequest = new XMLHttpRequest();
myRequest.open("GET", url);
myRequest.onreadystatechange = onStateChange;
myRequest.send();
}
}
function onStateChange() {
if (myRequest.readyState==4) {
if (myRequest.status==200) {
mousedOverElement.setAttribute('title',myRequest.responseText);
}
isLoading = false;
}
}
The problem is, when I hover over the link, and then stop moving the cursor, the title attribute is set properly, but the tooltip is not shown. I have to move the mouse again to make the tooltip show up. I don't necessarily have to move the cursor off of the link and then back over it, but simply moving a few pixels while remaining hovered over the link will do the trick.
I know that the title is being set properly from a combination of using the Web Inspector and the Javascript debugger in Safari. In fact, pretty much as soon as I hover over the link, I see the Web Inspector's view of the DOM in the "elements" tab update with the new title. But, if I take my hand off of the mouse, the tooltip never shows.
My assumption here is that WebKit only shows a tooltip when the user is moving the mouse. Is there a way to sort of "wake up" webkit, even if the cursor is not moving? Or am I better off implementing this with some of my own DHTML-ish magic instead of relying on the title attribute?
What about an element (move it over the anchor) or a wrapper (positive z-index) with a transparent background which will (onmouseover):
first add the anchor's title (you will have to modify your function)
and then change its (negative for the covering element) z-index (effectively putting the anchor in the foreground)
This way the title will be readily available. If necessary you can add a setTimeout() between step 1 and 2.
Or you could simply use setAttributeNode to modify the title attribute value.
You said
"The problem is, when I hover over the
link, and then stop moving the cursor,
the title attribute is set properly,
but the tooltip is not shown."
Its likely that because the title did not exist when you started the mouse hover, it could not display any tooltip (there was nothing to display). So no tooltip will appear. When you move the mouse again, this time it does have a title attribute, so it can display a tooltip. Theres not much you can do about that, its just how the browser works.
Instead your could try using a jQuery tooltip: http://www.reynoldsftw.com/2009/03/10-excellent-tooltip-plugins-with-jquery/
With jQuery you should be able control it so that a tooltip appears as soon as the title is set.

Resources