Xamarin Forms Tabbed Page to have overlapping Custom View - xamarin.forms

I need to have something like that with XF Tabbed Page:
I.e., I need some panel which would appear over the whole content (including any tabs) where I can add some custom content. (The reason why I am asking it here, as it wouldn't be an issue in case of common simple page, when I would just have some overlapping view placed on the page).
In functionality it should be something like Action Sheets, but be cross-platform (i.e., defined as common XF view) and include custom content.
But it must be not necessary custom renderers with actually Action Sheet implementation (and AlertDialog accordingly to this). It would be perfect to have some view placed somewhere (I don't know where) in the page layout structure to achieve this.
Or Action Sheet and AlertDialog (with custom renderers) are still the easiest way to have it these days in XF? Thanks!

You can use ACR User Dialogs, and you can specify the UseBottomSheet option to make the action sheet appear at the bottom. Its available as a NuGet package, so there is no need for any custom renderers.
Acr.UserDialogs.ActionSheetConfig = new Acr.UserDialogs.ActionSheetConfig();
config.UseBottomSheet = true;
config.Title = "My Options";
config.Add(
"Option 1",
() =>
{
Device.BeginInvokeOnMainThread(async () => {
await DisplayAlert("", "Clicked option 1", "OK");
});
},
null);
config.Cancel = new Acr.UserDialogs.ActionSheetOption("Cancel");
And to display it:
Acr.UserDialogs.UserDialogs.Instance.ActionSheet(config);

Related

Xamarin.Forms: How to navigate to TabbedPage's child page

I meet a scenario to navigate from MyTabbedPage/ChildTabPage1/Page1 to MyTabbedPage/ChildTabPage2/Page2 in Xamarin.Forms
Right now, I can only switch between MyTabbedPage/ChildTabPage1 and MyTabbedPage/ChildTabPage2. But I need to navigate directly from MyTabbedPage/ChildTabPage1/Page1 to MyTabbedPage/ChildTabPage2/Page2
How to achieve this?
Thank you very much in advance for your helps.
You can try something like this.
public App()
{
InitializeComponent();
var parentPage = new MasterDetailView(); // name of the master detail page
parentPage.IsPresented = false;
var tabbedPage = new MasterDetailTabbedPage(); // name of the tabbed page
tabbedPage.CurrentPage = tabbedPage.Children[2]; // specify the index of the tab
parentPage.Detail = new NavigationPage(tabbedPage); // assign the tabbed page to master detail page
MainPage = parentPage; // navigate to master detail page (3rd tab selected)
}
If you want to navigate MyTabbedPage/ChildTabPage1/Page1 to MyTabbedPage/ChildTabPage2/Page2 in Xamarin.Forms, I suggest you can consider to use Shell to do this.
Xamarin.Forms Shell includes a URI-based navigation experience that uses routes to navigate to any page in the application, without having to follow a set navigation hierarchy. In addition, it also provides the ability to navigate backwards without having to visit all of the pages on the navigation stack.
Here is the article about using Shell:https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/navigation

How to attach a callback to a custom confirmation dialog in Google App Maker?

I am creating a custom confirmation dialog in Google App Maker and would like the Confirm button to call a passed-in function. I don't see an "onclick" event in the button widget. Any suggestions on how to do this?
function confirmationDialog(msg, confirmFunction)
{
var desc = app.pageFragments.ConfirmationDialog.descendants;
var label = desc.Label;
var confirmButton = desc.Confirm;
label.text = msg;
confirmButton.onClick = confirmFunction; // does not work
app.showDialog(app.pageFragments.ConfirmationDialog);
}
Thanks
It'd be great if this was a bit easier, but the best bet is to use Custom Properties (https://developers.google.com/appmaker/ui/viewfragments).
You can set up a custom property of type "Dynamic" and call it anything, take "onConfirmCallback", for example. Then you can set the function on that custom property:
Code to invoke dialog:
app.pageFragments.ConfirmationDialog.properties.onConfirmCallback = function(param) {
alert(param);
};
app.showDialog(app.pageFragments.ConfirmationDialog);
And then in the onClick for the close button:
app.pageFragments.ConfirmationDialog.properties.onConfirmCallback("hi");
app.closeDialog();
Also note that there are slightly better ways to set up labels than in your example, also using custom properties.
Create custom properties for any widget properties you want to customize, and then bind those custom properties (#properties.propertyName) to the widget property. For example you might have a confirmText property, with the confirm buttons text property boudn to #properties.confirmText.
Then when you invoke your dialog, you can just set those custom properties. Quick modification of your example code using properties for everything:
function confirmationDialog(msg, confirmFunction)
{
var properties = app.pageFragments.ConfirmationDialog.properties;
properties.text = msg;
properties.confirmCallback = confirmFunction;
app.showDialog(app.pageFragments.ConfirmationDialog);
}
For my confirmation dialogs, I just set the onclick of the OK button before I show the dialog (everything is in one place, which is easier for the dummy (me) who will have to maintain it in six months:
var dialog=app.pages.ConfirmationDialog;
dialog.descendants.message.text='Are you sure...?'
dialog.descendants.btnOk.getElement().onclick=function(){
//do something here
app.closeDialog();
});
};
app.showDialog(dialog);
}

Display a widget using Durandal modal dialog

I recently started using the Durandal library for a SPA I am developing... kudos to the author, it is an excellent library.
I like the concept of widgets, vs using Views for stateless screens, but I was not able to display a widget in a modal dialog, without attaching it to a view. Does anyone know how to do this?
To elaborate, there is a widget.create function that allows for the creation of a widget in the JS but requires a DOM element to attach to. What I would prefer to do is create a widget, without attaching it to the DOM, then call something like:
app.showModal(theWidget);
As an alternative, I know I can create a "dialog" view that maps to swappable widgets, then use that view for dialogs, e.g. the view would have:
<div data-bind="widget: {kind:widgetId}">/div>
... and then:
app.showModal('viewmodels/dialog');
where 'viewmodels/dialog.js' is the view-model for the "Dialog" view.
References:
Modals: http://durandaljs.com/documentation/Showing-Message-Boxes-And-Modals/
Widgets: http://durandaljs.com/documentation/Creating-A-Widget/
Widgets are meant to be reusable controls on a web page, so that's why they require a DOM element. I'm not sure if I completely understand what you're trying to do, but you can define a view that returns its constructor function rather than a singleton object.
Here's a view that returns a singleton:
define([], function() {
var singleton = {
title: "I'm Mr. Singleton"
};
return singleton;
});
Here's the same view, but returns its constructor function:
define([], function() {
var notSingleton = function () {
this.title = "I'm NOT Mr. Singleton"
};
return notSingleton;
});
You can then use either of these within another viewmodel or module, as such:
define(['viewmodels/singleton', 'viewmodels/notSingleton'],
function(singleton, NotSingleton) {
...
app.showModal(singelton);
app.showModal(new NotSingleton());
...
});
In the latter case, you could create multiple dialogs of the same viewmodel across multiple other views, but each would be its own instance with its own properties. If you wanted to share data and/or behaviors across all instances of that viewmodel type, you could add them to the viewmodel's prototype.
Hope this helps.

Ext-JS Html Editor get selected text

I am trying to insert a button into HtmlEditor's ToolBar. Button should get selected text by mouse or keyboard and add '#' character at the start of that selected text for locating it as a url.
As i understand the best solution is creating a plugin for adding buttons into html editor toolbar. I found creation codes but the problem is; how can i get selected text? Ext-js version 2.2
And there is the code that provides to create a plugin for html editor toolbar button:
Ext.ns('Ext.ux.form.HtmlEditor');
Ext.ux.form.HtmlEditor.NewLine = Ext.extend(Ext.util.Observable, {
init:function (cmp) {
this.cmp = cmp;
this.cmp.on('render', this.onRender, this);
},
onRender:function () {
this.cmp.getToolbar().addButton([
{
iconCls:'newline', //your iconCls here
handler:function () {
this.cmp.insertAtCursor('<br> ');
},
scope:this
}
]);
}
});
You can get the selected text like this: window.getSelection()
That gives you a Selection object. If you want to get the text only: window.getSelection().toString()
but if you want to make stuff bold or something, you need to check if the selection is inside the editor. Everything you need for that is inside the selection object.
=> correction: the htmlEditor uses an iframe you can get the iframe window by the getWin function.
Note that this is only for modern browser (not < IE9) judging from the legacy Ext version you use, that might be an issue for you... but there are workarounds for IE.
more info

How to access properties of a Tridion component like schema name based on which it is created in aspx page?

I am customizing the ribbon tool bar by adding a button to it in TRIDION 2011 SP1 version.
When I click on the button it will open an aspx page.Inside that aspx page I need to access the name of the schema used to create that component before creating the component itself(I mean to say while creating the component itself).
Please provide me a way to solve this issue. Thanks in advance.
You should pass it to your popup. The URI of the Schema is available on the Component model object within the CME - so your button command can access it and pass it to the popup (in the URL, for example).
var schemaId = $display.getView().getItem().getSchemaId();
If you have the component (as an object), you can get it's schema id as Peter indicated. If you only have the component id, you can load the component and through that get to the schema.
When you need to load any item, you have to be aware that it's not a synchronous call in the UI API, so you should use delegate methods for that. For example something like this:
Example.prototype._loadItemInformation = function Example$_loadItemInformation(itemId, reload) {
var item = $models.getItem(itemId);
if (item) {
var self = this;
function Example$_loadItemInformation$_onItemLoaded() {
$evt.removeEventHandler(item, "load", Example$_loadItemInformation$_onItemLoaded);
// proceed with the actions on the loaded item here
};
if (item.isLoaded(true) && !reload) {
Example$_loadItemInformation$_onItemLoaded();
}
else {
$evt.addEventHandler(item, "load", Example$_loadItemInformation$_onItemLoaded);
//$evt.addEventHandler(item, "loadfailed", Example$_loadItemInformation$_onItemLoadFailed);
item.load(reload, $const.OpenMode.VIEW);
}
}
};
Also be aware the item could fail loading, you should actually also register an event handler for loadfailed (as my example code neglects to do).

Resources