Vuetify scrolling issue - asynchronous

I'm trying to add links in my navbar that go to a section of page using Vuetifys scrolling, here's my code:
pageClicked (page) {
this.goToPage(page.path)
this.goToTarget(page, this.options)
},
goToPage (path) {
this.$router.push(path)
},
goToTarget (target, options) {
if (target.topOfPage) {
this.$vuetify.goTo(0, options)
} else if (target.id) {
this.$vuetify.goTo(target.id, options)
}
}
Problem is the scroll fails if I'm not on the same page that where I'm scrolling to is on cause it can't find the target id because it hasn't loaded yet. How can I ensure the page has fully loaded before trying to scroll to the section?

Related

SwiftUI custom button and menu not having same size in navigation bar

In my app, I want to customize the appearance of buttons and menus in the navigation bar.
This is what I did:
For the button:
struct BarButtonStyle: ButtonStyle {
private let cornerRadiusWidth:CGFloat = 4.0
func makeBody(configuration: Configuration) -> some View {
configuration.label
.padding(4)
.foregroundColor(Color.barButtonForeground)
.background(
LinearGradient(gradient: Gradient(colors: [Color.barButtonBackground1, Color.barButtonBackground2]),
startPoint: .top,
endPoint: .bottom)
)
.cornerRadius(cornerRadiusWidth)
}
}
For the menu:
struct BarMenuStyle: MenuStyle {
private let cornerRadiusWidth:CGFloat = 4.0
func makeBody(configuration: Configuration) -> some View {
Menu(configuration)
.padding(4)
.foregroundColor(Color.barButtonForeground)
.background(
LinearGradient(gradient: Gradient(colors: [Color.barButtonBackground1, Color.barButtonBackground2]),
startPoint: .top,
endPoint: .bottom)
)
.cornerRadius(cornerRadiusWidth)
}
}
I used them like this:
// navigation bar trailing
ToolbarItemGroup(placement: .navigationBarTrailing) {
// the menu
Menu {
}
label: {
Image(systemName: displayType.info.image)
}
.menuStyle(BarMenuStyle())
// the button
Button(action: {
}) {
Image(systemName: "list.number")
//.resizable()
}
.buttonStyle(BarButtonStyle())
}
However, the display size is different in the navigation bar (menu at left, button at right):
I have no idea why.
The only workaround is to change the padding for the menu, but it's not perfect.
What did I miss ?
I would try using .frame(maxWidth: .infinity) method on each element (in your case the button and the menu). What that does is it makes each element take the most amount of space possible, when there's multiple elements like that, they are distributed evenly. You can further regulate the size by adding a .frame() to the parent container. Should work like magic.

Cascade QML TabPane - maintaining TabPane through multiple pages

I've been trying to research this all weekend, but can't find a similar example.
I'm trying to keep a TabPane consistent through out multiple pages. As of right now, once you go past 1 page, the TabPane will no longer be there.
For example:
TabbedPane {
id: root
showTabsOnActionBar: true
Tab {
title: qsTr("Search") + Retranslate.onLocaleOrLanguageChanged
Search {
}
}
}
// Search.qml
NavigationPane {
id: navigationPane
Page {
Button {
onClicked: {
navigationPush.push(pageSearchResults.createObject())
}
}
}
attachObjects: [
ComponentDefinition {
id: pageSearchResults
SearchResults {
}
}
]
}
So basically at this point when we're on the Search page, we have the TabPane.
As soon as I push that Button and navigate to the SearchResults page. The TabPane is gone...
// SearchResults.qml
// We're now 2 pages -IN- from the TabPane
Page {
Button {
onClicked: {
navigationPush.push(nextPage.createObject())
}
}
attachObjects: [
ComponentDefinition {
id: nextPage
NextPage {
}
}
]
}
Also once we're on SearchResults - it won't let me push the next page. When I click the Button on SearchResults, you can see the navigationPush(nextPage.createObject()). It gives the following error:
pushPage : mNavigationStack : ("211") NavigationPane:
NavigationPaneOnFwdTransitionDone: emitting push transition ended for
page: 211 client top: 211
What you need to do is add a navigationPane to the tab and push pages onto that.
A sheet should be opened for something seperate to the tab - e.g. a settings page. Sheets also require buttons or code to close them.
It's not clear from your code whether you are using a navigationPane or not, so here is an example of how it should be working:
TabbedPane {
id: root
showTabsOnActionBar: true
Tab {
title: qsTr("Search") + Retranslate.onLocaleOrLanguageChanged
NavigationPane {
id: navSearch
Page {
}
}
}
}
Now when you want to navigate to the next page in search you will add it to the navSearch navigationPane. This will give you the back button as well.
It would be beneficial to read through the documentation on navigation here: http://developer.blackberry.com/native/documentation/cascades/ui/navigation/index.html
It will explain many details of how the navigation works and how different elements such as tabbed panes and sheets interact.

Magnific Popup Iframe - How to show that the iframe is loading

I am loading content in the magnific popup using the iframe method.
It works just fine, except that it take awhile to load the iframe content. Until the content is loaded the iframe is just a blank dark and empty popup and the user has no clue as to what is happening.
Is there a way to make the iframe show a loading message or animation until the content arrives?
The .mfp-preloader css class is of no help because it is hidden behind the iframe.
I'm thinking the best was is to somehow hide the iframe until it has content.
Thanks
Thanks to Dmitry who pointed me in the right direction, here is the answer that worked for me:
The callback:
callbacks: {
beforeAppend: showIframeLoading
}
The showIframeLoading function:
var showIframeLoading = function() {
var curLength = 0;
var interval = setInterval(function() {
if ($('iframe').length !== curLength) {
curLength = $('.column-header').length;
$('.mfp-content').hide();
$('.mfp-preloader').show();
}
}, 50);
this.content.find('iframe').on('load', function() {
clearInterval(interval);
$('.mfp-content').show();
$('.mfp-preloader').hide();
});
};
You may use popup events to create custom actions, e.g.:
callbacks: {
beforeAppend: function() {
console.log('before iframe is added to DOM');
this.content.find('iframe').on('load', function() {
console.log('iframe loaded');
});
}
}
Instead of polling, how about if we just detect iframe and toggle the mfp-s-ready class from the container.
In case of images, mfp-s-ready is added to the mfp-container div when image has loaded. We can simply toggle that ourself for video (iframe) + use some custom css to our advantage.
callbacks: {
beforeAppend: function () {
if (this.currItem.type === 'iframe') {
$('.mfp-container').removeClass('mfp-s-ready');
}
this.content.find('iframe').on('load', function () {
$('.mfp-container').addClass('mfp-s-ready');
});
}
}
and add this CSS:
.mfp-container .mfp-content {
display: none;
}
.mfp-s-ready.mfp-container .mfp-content {
display: inline-block;
}
This will also support mixmode galleries with videos and images.

Sencha Touch Panel Scrollability issue in Android tablets

I have a panel in Sencha touch which shows some htm file.
Ext.define('Project.view.eula.EulaPanel',{
extend:'Ext.Panel',
requires: ['Ext.Ajax','Ext.Panel'],
xtype:'eulaPanel',
id:'eulaPanel',
config:
{
scrollable:true,
padding:10,
listeners: {
activate: 'onActivate'
},
// Create a new configuration called `url` so we can specify the URL
url: 'resources/eula/EULA.htm',
items:[
{
xtype:'toolbar',
docked:'top',
items:[
{
xtype:'button',
text:'Accept',
action:'eulaAcceptBtn',
},
{
xtype:'button',
text:'Decline',
action:'eulaDeclineBtn',
},
]
}
]
},
onActivate: function(eulaPanel, container) {
Ext.Ajax.request({
url: this.getUrl(),
method: "GET",
success: function(response, request) {
eulaPanel.setHtml(response.responseText);
},
failure: function(response, request) {
eulaPanel.setHtml("failed -- response: " + response.responseText);
}
});
}
});
This panel is the first panel that gets displayed when the app is opened. But it cannot be scrolled. If you navigate to any other page or reopen the app again the panel becomes scrollable. Please let me know if anyone knows the fix.
Just try setting scrollable config in Panel as follows instead of true
scrollable : {
direction : 'vertical'
}

Ext JS 4 direct store how to *prevent* loading mask?

I have found many references on how to create a 'loading' message or mask when loading data in to a grid in Ext JS 4 via a data store / proxy (I am using direct type).
So I had added this in my controller at one point (because I was NOT getting a loading message previously) :
init: function() {
var store = this.getEncountersStore();
store.on({
beforeload: function(store,operation,eopts) {
Ext.getBody().mask('Loading...');
},
load: function(store,records,success,operation,eopts) {
Ext.getBody().unmask();
}
});
}
That seems to work for me in my MVC application, however, next I added a task manager timer to automatically refresh the grid data every 10 seconds:
this.runningTask = Ext.TaskManager.start ({
run: this.loadEncounterData,
interval: 10000,
scope: this
});
loadEncounterData: function() {
var store = this.getEncountersStore();
store.load({
params: {
},
callback: function(r,options,success) {
if(success == true)
...
} //callback
}); //store.load
I noticed that there were now TWO 'loading' mask messages on the screen!
So, I removed my 'store.on' code block above from my controller init, and now I have only one message.
So where does the other message come from?
Is it part of a Grid?:
Ext.define('ESDB.view.encounter.List', {
extend: 'Ext.grid.Panel',
...
I found a page that seems to asking the same question, though I was not able to figure out how to get it to work, or how to do it according to ExtJS 4 / MVC.
loadMask is not a config in Grid panel.
You can add as a config in gridpanel
viewConfig : {
loadMask: false
}
The loadMask is part of the gridView.
http://docs.sencha.com/ext-js/4-0/#!/api/Ext.grid.View-cfg-loadMask
GridPanel components all have a gridView component that defines various things to do with the table view in the panel.
To prevent a loadMask on a grid, you set config for loadMask to false, IE:
Ext.define('ESDB.view.encounter.List', {
extend: 'Ext.grid.Panel',
loadMask : false,
...
You could change your load function to just load the store:
loadEncounterData: function() {
var store = this.getEncountersStore();
store.load();
...
Then you could use the following approach to automatically handle the loadMask whenever the grid store loads.
Using Ext.util.DelayedTask is handy to prevent the loadMask from appearing if the load takes less than 500ms.
Ext.define('ESDB.view.encounter.List', {
extend: 'Ext.grid.Panel',
...
initComponent: function() {
var me = this;
me._mask = new Ext.LoadMask(me, {msg: 'Loading...'});
me._maskd = new Ext.util.DelayedTask(function() {
me._mask.show();
});
me.store = Ext.create('Ext.data.Store', {
...
listeners: {
beforeload: function() {
me._maskd.delay(500);
...
},
load: function() {
me._maskd.cancel();
me._mask.hide();
...
}
}
});
...

Resources