making a picture slider in elm, model updates triggered by loaded element - elm

I am making a website in elm that includes a dynamic element for browsing pictures. One can click a given thumb to see the full picture in a lightbox, navigate to the next or previous picture or let the picture change automatically every three second.
By default one sees only a small selection (4 thumbs) but it is possible to previews all the thumbs by clicking on "voir toute les photos"
running example here
Each user click or tick of the clock change the underlying model, which in turn makes the browser actualize the HTML accordingly.
I am mostly satisfied with the current level of functionality except for the fact than I can't find a way to display a transition screen (or picture) while the next picture is loading.
The lightbox displays the last displayed picture while loading the next one, and transitions abruptly.
Is there a way to trigger a change in the model only when the next picture is loaded?
Or a more idiomatic way to do this sort of thing? I am quite new to elm and web development in general.
the elm code for the gallery is visible at:
https://github.com/eniac314/mairieMurol/blob/master/src/Gallery.elm

It sounds like you just need a way to know when an image is finally loaded. You can tie into the img.onload DOM event, but first you'll need a Json Decoder to pull image src attribute out of an event.
Updated to elm-0.18
onLoadSrc : (String -> msg) -> Html.Attribute msg
onLoadSrc tagger =
on "load" (JD.map tagger targetSrc)
targetSrc : JD.Decoder String
targetSrc =
JD.at [ "target", "src" ] JD.string
Now you can use that decoder to call a new ImageLoaded String action, passing the image source as a string.
img
[ src imgsrc
, onLoadSrc ImageLoaded
]
[]
Look at demo and code (you may need to change the random number in the image url to combat the browser caching the image).

Related

Screen readers unable to read options of `vue-search-select`

I inherited a vuejs project. People using screen readers as assistive devices complain that their screen readers are unable to read the options in drop down menus that were made from vue-search-select. Here is how you can reproduce the issue:
Install a screen reader such as NVDA.
Turn on NVDA screen reader.
Go to https://vue-search-select.netlify.app/#/model
Tab to a search text field.
Confirm drop down of results appear.
Press the down arrow key to focus on any of the search result items.
Confirm the NVDA says the word "Blank" instead of actually reading out the contents of the selected item.
Here is a 10 second clip to that demonstrates steps 3 of 7.
https://www.youtube.com/watch?v=Nxx1k1oKETI
How do you modify vue-search-select such that in step 7, the screen reader will read out the contents of the selected item instead of reading out the word "Blank"?
Right now, as a temporary solution, I'm trying to write a setTimeout function that will automatically add the appropriate meta data to force screen readers to read out the content. But I'm not sure how successful this approach will be. I prefer an approach that is idiomatic to vue-search-select.
I tried adding a customAttr like so:
<model-select :custom-attr="ariaAttrs" />
function ariaAttrs() {
return function() { return '" aria-label="hello" tabindex="0'; }
}
Although the attributes do appear in my developer console's inspector, my screen reader still does not read out the options.
It seems custom-attr will not help you as it does not allow you to add any attr you want - anything the function returns is just placed as a value of data-vss-custom-attr attribute
Any decent Vue library with similar functionality would offer a slot to customize rendering of menu items, but this does not. Plus it doesn't seem to be maintained for a long time so maybe it is a time to look for an alternative....

Remove nodes from the graph without reloading the web page in cytoscape.js

I have a graph of molecular interactions that takes nodes and edges from a query to my database. I also have two buttons as node labels: "Remove" and "Add" (where "remove" should remove the selected node, while "add" should expand to first neighbors).
I would like to add a function that removes the selected node (on click) without reloading the web page, but just reloading the graph (I want the selected node to disappear from the graph). So, the problem is not the function cy.remove but rather the graph reloading.
I am new to cytoscape.js (let's say to javascript), so I have no idea on how to reload a graph and where to put the remove and reload functions. To date I am only able to pass the ID of the node I want to remove and/or expand via GET method using php. This actually works, but it reloads the web page making a new query to my database, and it becomes tricky when one wants to add and remove a lot of nodes.
Could anyone provide me some simple example code that explains how to reload a graph after a button click, keeping all nodes except the removed one?
Sorry if it is a stupid question
Thanks
$('#button_deleteNode').click(function(){
cy.remove(nodeID);
});

Inconsitent decoding of image URL via 'URL.createObjectURL()'

I have a WinJS app where the user can choose via a dropdown menu, to view one of several images.
During the dropdown's onchange event, I'm using:
URL.createObjectURL(file, { oneTimeOnly: true })
To generate a URL which I set as a html <img> element's src property.
Whilst this works 'some' of of the time, the behaviour is very inconsistent a high proportion of the time, I get the error:
DOM7009: Unable to decode image at URL: 'blob:7743DB87-59F8-4750-B3A2-3505518CA7CB'.
Obviously the blob URL varies.
This doesn't seem related to the actual image, as during testing I'm only using 3 images (all of which will load at times) but all three of them won't load at other times.
Am I using the wrong approach here? or could something else be the problem? any thoughts greatly appreciated.

Programatically disable Lazy Loading or infinite scroll with jQuery in Pinterest?

NOTE: New to this forum (UX/User Experience), so please let me know if this would be better in a different category. I searched Stack Exchange for "pinterest" and this forum seemed to have the most results. Thanks!
Hi guys. I'm writing a jQuery gist to grab links of all the images pinned to a given board in Pinterest. However, I've been running into the problem of having to repeatedly keep scrolling because all the results are not displayed on the same page. With the trendy "infinite scroll" or "lazy load" feature, one has to keep scrolling to the bottom without actually knowing if they are anywhere close because it seems to depend on your zoom percentage in your browser window and your window size as well, as to how many items display on your screen. I've been searching this for hours to no avail.
Searches I've already done keep returning non-productive results
The results I get when searching for
"Pinterest how to disable lazy loading" and "Pinterest how to disable infinite scroll"
keep returning the opposite of what I am looking for -- incorrect results for my purposes are anything like:
"How to add infinite scroll to my website",
"20 Useful Pinterest Tools",
or anything to do with adding infinite scroll.
The Problem: Infinite Scroll/Lazy Loading makes it hard for me to use browser plugins like jquerify (Chrome) and FireQuery (Firefox)
The issue for me is that I want to be able to view all my pins on a given board at once. Then I can use jQuery to manipulate all images on the page. Currently, infinite scroll makes it hard to keep track of where I'm at. I've tried stuff already by it's late at night and hard to remember everything. The important find was that in page source, Pinterest is using a "lazy" function. Here is what I found:
P.lazy = {
onImageLoad: function(a) {
var b = LOADED_CLASS;
P.overlap.isOverlappingViewport(a) && (b += FADE_CLASS);
a.className += b
}
};
This is just starting to be a deeper rabbit hole. I've checked for plugins to "remove", "disable", or "bypass" lazy loading, but haven't found any ... only those for adding it in.
Thanks in advance for your kind assistance and Cheers.
Pinterest loads cards via Ajax. When you scroll to the bottom of a page, browser javascript fires an Ajax call to load the next page full of cards.
This means it's not really possible to "disable" the infinite scrolling feature.
A few possible approaches:
Depending on how you're instantiating the browser, you might try setting or spoofing the window dimensions to a very large height. Pinterest may detect that height and attempt to load a window's worth of images, which may be enough to cover the feed you're trying to scrape.
If #1 is not practical for you, you can use javascript/jquery to keep scrolling the browser down until it has finished loading all the images. There are several ways to do this, since you are injecting javascript into the browser session.
(a) You can do this the "dumb" way with a loop that sets a timeout (setTimeout), then scrolls to the bottom (scrollTo()), then keeps going until the window stops scrolling and that comprises a kludgey auto-detect for the bottom of the page load.
(b) a more sophisticated approach would be to implement a listener for pinterest's ajax load function, (see the code, but it's a GET request to URL https://www.pinterest.com/resource/UserHomefeedResource/get/). An ajaxComplete() jQuery handler may help you detect the completion of a page load request so you can scrape the new images loaded.
Hope that helps

Sencha Touch: How to read certain record from the store?

I have an application that has 3 level of data depth:
list of presentations
presentation detail
presentation slides
Right now when user came to the app he's presented with list loaded from JSONP store. He click on one item and the callback function receives the record. It pushes it into new view - the detail and displays it. User can disclose presentation slides from there - data record is passed from detail again.
Problem is when user refreshes the page or came from URL. If he came to url like /presentations/slides/1, he wants to see the slides for presentation id:1. Problem is that as long as he wasn't at the list, data was not loaded and because it was not loaded, it was not passed to the detail and the detail didn't pass it along to the slides view. So I have no data.
But I still have the ID! Comming from the PHP's Zend Framework, I would call something like: this.store.find(1), but I can't find any way to do this.
How do I load something from the store based on it's record.data.id?
To add more, store.load() seems to work asyncronously, so when I do:
store.load();
store.each(function(rec){console.log(rec);});
It wouldn't work with JSONP store, because the data is not loaded yet. But when I use Chrome Debuger and pause the execution to let the data load, it works :(
You are correct the load is asyncronously so all you have to do is use the callback function of the store. You can find an example here How to get data from extjs 4 store