How to edit NativeScript-Angular RadDataForm UIStepper on iOS? - ios

In a NativeScript-Angular app, I’m trying to style a RadDataForms TKPropertyEditor. For the Stepper Editor on iOS I want do increase the distance between the controls and the displayed value, but I can't find a way to access them.
I'm using nativescript-ui-dataform: 4.0.0.
<TKEntityProperty tkDataFormProperty name="grade"
displayName="Bewertung (1 – 10)" index="1">
<TKPropertyEditor tkEntityPropertyEditor type="Stepper">
<TKPropertyEditorParams tKEditorParams minimum="1" maximum="10"
step="1"></TKPropertyEditorParams>
<TKPropertyEditorStyle tkPropertyEditorStyle valuePosition="Left">
</TKPropertyEditorStyle>
</TKPropertyEditor>
</TKEntityProperty>

Refer the advanced styling examples here, you may directly modify the native object to style your element.
public editorSetupStepperIOS(editor) {
editor.valueLabel.textColor = colorDark.ios;
const coreEditor = <UIStepper>editor.editor;
coreEditor.tintColor = colorLight.ios;
for (let i = 0; i < coreEditor.subviews.count; i++) {
if (coreEditor.subviews[i] instanceof UIButton) {
(<UIButton>coreEditor.subviews[i]).imageView.tintColor = colorDark.ios;
}
}
const editorView = editor.editorCore;
editorView.labelAlignment = TKGridLayoutAlignment.Left;
}

Related

Printing using ngx-extended-pdf-viewer on iOS and Mobile Safari or Chrome

I have an Angular 7 app that is using ngx-extended-pdf-viewer to render a PDF that I get as a byte array from the web.api. I have no issues rendering the PDF or even printing it from any desktop application. ngx-extended-pdf-viewer as a print button built right in. However, when trying to print from Safari on an iPhone (iOS 12) it only prints a blank page with the url at the bottom. The actual PDF does not print. With Chrome on iOS it doesn't do anything that I can see. I am pretty new to Angular and actually to mobile web development, so perhaps lack of knowledge is getting me. The PDF viewer is in a mat-tab, so not sure if maybe that is causing some issues??
I have tried other packages, but they all seem to be based on the same pdf.js code from Mozilla. Also this is the only one I've found so far that has a print. I was thinking about perhaps trying pdf.js outside of an npm package, but so far have not found solid directions on getting this to work in Angular. I'm sure it will, but all directions I have found seem to omit details. Such as, put this code in your app. They just fail to say where in the app.
From the web.api:
[HttpPost("GetPdfBytes/{PdfId}")]
public ActionResult<byte[]> GetPdfBytesId([FromBody]int id)
{
string exactPath = string.Empty;
if (id == 1)
{
exactPath = Path.GetFullPath("pdf-test.pdf");
}
else if (id == 2)
{
exactPath = Path.GetFullPath("DPP.pdf");
}
else if (id == 3)
{
exactPath = Path.GetFullPath("Request.pdf");
}
else
{
exactPath = Path.GetFullPath("Emergency Issue.pdf");
}
byte[] bytes = System.IO.File.ReadAllBytes(exactPath);
return Ok(bytes);
}
The HTML:
<mat-tab label="PDF">
<ng-template matTabContent>
<ngx-extended-pdf-viewer *ngIf="visible[2]" id="pdf3" [src]="pdfSrc3" useBrowserLocale="true" delayFirstView="1000" showSidebarButton="false"
showOpenFileButton="false" >
</ngx-extended-pdf-viewer>
</ng-template>
</mat-tab>
TypeScript:
getPDFBytesId(id: string) {
this.getPDFFromServicePdfBytesId(Number(id)).subscribe(
(data: any) => {
this.pdfSrc3 = this.convertDataURIToBinary(data);
},
error => {
console.log(error);
}
);
}
// hits the web.api
getPDFFromServicePdfBytesId(id: number): Observable<any> {
const body = id;
return this.http.post<any>('http://localhost:5000/api/values/GetPdfBytes/' + id, body);
}
// converts what we got back to a Uint8Array which is used by the viewer
convertDataURIToBinary(dataURI: string) {
const raw = window.atob(dataURI);
const rawLength = raw.length;
const array = new Uint8Array(new ArrayBuffer(rawLength));
for (let i = 0; i < rawLength; i++) {
array[i] = raw.charCodeAt(i);
}
return array;
}

Xamarin UItest Android - Ids for images do not display in tree

This question is for Android. StyleIds have been set for images. Per the documentation, these StyleIds should appear as labels in Android. But they do not.
I have verified that the following exists -
Xamarin.Forms.Forms.ViewInitialized += (object sender, Xamarin.Forms.ViewInitializedEventArgs e) =>
{
if (!string.IsNullOrWhiteSpace(e.View.StyleId))
{
e.NativeView.ContentDescription = e.View.StyleId;
}
};
I am new to Xamarin UItests and have to solve this as the first thing. Has anyone encountered this before?
You could switch over to using AutomationId, it was introduced to Xamarin.Forms in version 2.2 (release notes)
The AutomationId property isn't used by Xamarin.Forms so it doesn't affect any functionality to use it as a unique identifier for testing.
Below is a sample using AutomationId on an image, along with a screenshot of a Repl Tree output. (Click here to read more about AutomationId)
public App()
{
// The root page of your application
var content = new ContentPage
{
Title = "XamarinUITest_Images",
Content = new StackLayout
{
VerticalOptions = LayoutOptions.Center,
Children = {
new Label {
HorizontalTextAlignment = TextAlignment.Center,
Text = "Welcome to Xamarin Forms!"
},
new Image {
Source = "circle1",
StyleId = "myStyleID",
AutomationId = "myAutomationID"
}
}
}
};
MainPage = new NavigationPage(content);
}

How to code CssRect borderEdge

I found just what I needed to determine the dimensions of a div in Dart here
In short, it says:
Experimental
CssRect get borderEdge
Access the dimensions and position of this element's content + padding + border box.
How do code this?
I'm trying to use it with this variable:
import 'dart:html' as dom;
dom.DivElement textSpan = new dom.DivElement()
I found this example:
CssRect get borderEdge => textSpan.borderEdge;
My IDE (PHPStorm) throws up on it. I'm a Dart noob so I may be missing something obvious. Here's a screen shot:
I also get a build error:
Compiling citation|web/main.dart...
[Error from Dart2JS on citation|web/main.dart]:
packages/citation/tooltip/tooltip.dart:68:5:
Expected ';' after this.
CssRect get borderEdge => textSpan.borderEdge;
^^^^^^^
[Info from Dart2JS]:
Took 0:00:04.330468 to compile citation|web/main.dart.
Build failed.
I installed the Dart Editor and open the program in it. It didn't like it either:
tooltip.dart
This started out as the tooltip component from the Angular Dart Chapter 4 Tutorial
library tooltip;
import 'dart:html' as dom;
import 'package:angular/angular.dart';
#Decorator(selector: '[tooltip]')
class Tooltip
{
final dom.Element element;
#NgOneWay('tooltip')
TooltipModel displayModel;
dom.Element tooltipElem;
dom.Element entry; // Bibliographic entry: div in the index.html
Tooltip(this.element)
{
element..onMouseEnter.listen((_) => _createTemplate())
..onMouseLeave.listen((_) => _destroyTemplate());
}
void _createTemplate()
{
assert(displayModel != null);
tooltipElem = new dom.DivElement();
// All entries have the id 'bex' where x is an integer
entry = dom.querySelector('#be${displayModel.entryRef.toString()}');
String htmlText = entry.innerHtml;
if (displayModel.entryRef != null)
{
dom.DivElement textSpan = new dom.DivElement()
..appendHtml('<hr>')
..appendHtml(htmlText)
..style.color = "black"
..style.fontSize = "smaller"
..style.paddingBottom = "5px";
tooltipElem.append(textSpan);
}
int entryWidth = 200;
tooltipElem.style
..padding = "5px"
..paddingBottom = "0px"
..backgroundColor = "#FFF5E0"
..borderRadius = "5px"
..width = "${entryWidth}px";
// position the tooltip.
int windowHeight = dom.window.innerHeight;
int windowWidth = dom.window.innerWidth;
var elTopRight = element.offset.topRight;
var elBottomLeft = element.offset.bottomLeft;
int height = 100;
int top = elTopRight.y;
int bottom = elBottomLeft.y;
int left = elBottomLeft.x;
int right = elTopRight.x;
CssRect get borderEdge => textSpan.borderEdge;
print('borderEdge:$borderEdge');
// See if it will fit above
int y = top - height - 10;
if (y < 0) y = bottom + 10; // If it doesn't fit, put it below
// Start with the left
int x = left;
tooltipElem.style
..position = "absolute"
..top = "${y}px"
..left = "${x}px";
// Add the tooltip to the document body. We add it here because we need to position it
// absolutely, without reference to its parent element.
dom.document.body.append(tooltipElem);
}
void _destroyTemplate()
{
tooltipElem.remove();
}
}
class TooltipModel
{
final int entryRef;
TooltipModel(this.entryRef);
}
Answer
This summarizes Günter Zöchbauer's answer in the comments and an answer of my own.
The first problem was that I was using the wrong syntax given the location of the code. The correct code for this location is:
CssRect borderEdge = tooltipElem.borderEdge;
The second problem unique to my situation was that my import statement was declared as:
import 'dart:html' as dom;
The 'as dom' requires me to prefix all html api references with dom. So in my case, I needed to code:
dom.CssRect borderEdge = tooltipElem.borderEdge;
I got this code from the Angular dart tutorial. My next step is to remove that prefix so it doesn't screw me up again. Also note the answer code uses tooltipElem instead of textSpan. That change has nothing to do with the fix to the problem.
I tried and it works just fine (I'm using Dart bleeding edge/nightly build)

How to fill series data in candle chart in xamarin (TeeChart and MonoTouch)

I am using a tee chart library in xamarin (Android). i am facing a problem to daynamic binding data in "Candle Chart"
The Sample Code Like this!
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
RequestWindowFeature(WindowFeatures.NoTitle);
SetContentView(Resource.Layout.CandleChart);
//InitializeComponent();
chart = new Steema.TeeChart.TChart(this.ApplicationContext);
chart.Zoom.Style = Steema.TeeChart.ZoomStyles.InChart;
Steema.TeeChart.Themes.BlackIsBackTheme myTheme = new Steema.TeeChart.Themes.BlackIsBackTheme(chart.Chart);
myTheme.Apply();
Type tmp = (Type)Steema.TeeChart.Utils.SeriesTypesOf[12];
Steema.TeeChart.Styles.Series series;
series = chart.Series.Add(tmp);
series.FillSampleValues(); /* Here i want to fill series with my data listed bellow */
chart.Aspect.View3D = Needs3D(chart[0]);
chart.Panel.Transparent = true;
SetContentView(chart);
}
now i want add series data manually
like :
currentItem.Data.Close
currentItem.Data.Open
currentItem.Data.High
currentItem.Data.Low
currentItem.Time
etc.. so, plz help me to achieve this ..
thanks, in advance
==================================================================================
My Code Like as Bellow
private void LoadChart(GraphOutput resGraph)
{
DataSet_Obj.Tables.Add("CandleTable");
DataSet_Obj.Tables["CandleTable"].Columns.Add(new DataColumn("Date", System.Type.GetType("System.DateTime")));
DataSet_Obj.Tables["CandleTable"].Columns.Add(new DataColumn("Open", System.Type.GetType("System.Double")));
DataSet_Obj.Tables["CandleTable"].Columns.Add(new DataColumn("Close", System.Type.GetType("System.Double")));
DataSet_Obj.Tables["CandleTable"].Columns.Add(new DataColumn("High", System.Type.GetType("System.Double")));
DataSet_Obj.Tables["CandleTable"].Columns.Add(new DataColumn("Low", System.Type.GetType("System.Double")));
for (int i = 0; i < resGraph.graphSymbol[0].CandleSticks.Length; i++)
{
DataRow_Obj = DataSet_Obj.Tables["CandleTable"].NewRow();
DataRow_Obj["Date"] = resGraph.graphSymbol[0].CandleSticks[i].CandleTime; //DateTime
DataRow_Obj["Low"] = resGraph.graphSymbol[0].CandleSticks[i].CandleData.Low; //Float
DataRow_Obj["Close"] = resGraph.graphSymbol[0].CandleSticks[i].CandleData.Close; //Float
DataRow_Obj["Open"] = resGraph.graphSymbol[0].CandleSticks[i].CandleData.Open; //Float
DataRow_Obj["High"] = resGraph.graphSymbol[0].CandleSticks[i].CandleData.High; //Float
DataSet_Obj.Tables["CandleTable"].Rows.Add(DataRow_Obj);
DataRow_Obj = null;
}
Tag_Serie_Candle = new Steema.TeeChart.Styles.Candle ();
chart.Series.Add(Tag_Serie_Candle);
chart.Aspect.View3D = Needs3D(chart[0]);
chart.Panel.Transparent = true;
try
{
Tag_Serie_Candle.DataSource = DataSet_Obj.Tables["CandleTable"]; /* here I got Error Like: "Cannot bind to non-supported datasource: CandleTable" */
Tag_Serie_Candle.OpenValues.DataMember = DataSet_Obj.Tables["CandleTable"].Columns["Open"].ToString();
Tag_Serie_Candle.CloseValues.DataMember = DataSet_Obj.Tables["CandleTable"].Columns["Close"].ToString();
Tag_Serie_Candle.DateValues.DataMember = DataSet_Obj.Tables["CandleTable"].Columns["Date"].ToString();
Tag_Serie_Candle.DateValues.DateTime = true;
Tag_Serie_Candle.HighValues.DataMember = DataSet_Obj.Tables["CandleTable"].Columns["High"].ToString();
Tag_Serie_Candle.LowValues.DataMember = DataSet_Obj.Tables["CandleTable"].Columns["Low"].ToString();
Tag_Serie_Candle.LabelMember = "Candle Chart";
Tag_Serie_Candle.CheckDataSource();
chartpie.AddView(chart, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent));
}
catch (Exception exe)
{
exe.Message.ToString();
}
}
You should do something as in the examples here:
http://www.teechart.net/support/viewtopic.php?f=4&t=2978&p=10547#p10547
http://www.teechart.net/support/viewtopic.php?f=4&t=3291&p=11691#p11691
http://www.teechart.net/support/viewtopic.php?f=4&t=2741&p=11681#p11681
I have found that, at the present moment, this is not working. I added the defect (ID566) list to be fixed as soon as possible (now fixed, see update at the bottom of the reply). If you register at Steema Software's Bugzilla system, you will be able to be in the CC List and be notified about status updates. In the meantime you can manually read values from the DataSet using this code:
Tag_Serie_Candle.DateValues.DateTime = true;
for (int i = 0; i < DataSet_Obj.Tables["CandleTable"].Rows.Count; i++)
{
DataRow row = DataSet_Obj.Tables["CandleTable"].Rows[i];
DateTime dt = Convert.ToDateTime(row["Date"]);
Double open = Convert.ToDouble(row["Open"]);
Double high = Convert.ToDouble(row["High"]);
Double low = Convert.ToDouble(row["Low"]);
Double close = Convert.ToDouble(row["Close"]);
Tag_Serie_Candle.Add(dt, open, high, low, close);
}
UPDATE: As of 11th February 2014, the defect has been fixed. Anyone interested in testing the solution please let me know.

Accessing correct preference value in onsyncfrompreference after preference.reset()

I want to have a "Restore defaults" button in my extension's preferences window:
<prefpane id="nextplease.phrases" label="&options.phrases.title;"
image="chrome://nextplease/skin/Document.png">
<preferences>
<preference id="nextphrases" name="nextplease.nextphrase.expr0"
type="unichar"/>
...
</preferences>
<hbox flex="1">
...
<listbox id="nextphrases_list" seltype="multiple" flex="1"
onkeypress="nextplease.removeSelectedOnDelete(event, this);"
onselect="nextplease.enableDisableRemoveButton(this);"
preference="nextphrases" preference-editable="true"
onsynctopreference="return nextplease.syncListbox(this);"
onsyncfrompreference="nextplease.loadListboxPreference(this);"/>
...
<button label="&options.restoreDefault;"
oncommand="nextplease.restoreDefaultListbox(this);" />
</hbox>
</vbox>
</hbox>
</prefpane>
This is the JavaScript code for the functions:
nextplease.restoreDefaultListbox = function (node) {
var listbox = node.parentNode.parentNode.firstChild.selectedPanel;
var preferenceId = listbox.getAttribute("preference");
var preference = document.getElementById(preferenceId);
preference.reset();
alert("preference.value="+preference.value+"; preference.valueFromPreferences="+preference.valueFromPreferences);
preference.setElementValue(listbox);
};
nextplease.loadListboxPreference = function (listbox) {
var i, phrase, values;
var preferenceId = listbox.getAttribute("preference");
var preference = document.getElementById(preferenceId);
var prefValue = ??? // neither preference.value nor preference.valueFromPreferences work, see below
// alert("Loading: "+prefValue);
// remove all items already in listbox
for (i = listbox.itemCount; i >= 0; i--) {
listbox.removeItemAt(i);
}
values = prefValue.split("|");
for (i = 0; i < values.length; i++) {
phrase = values[i].replace(/&pipe;/g, "|");
if (phrase !== "") {
listbox.appendItem(phrase, phrase);
// Scroll to the newly added item to workaround
// what I think is a Firefox bug. I was getting
// Javascript exceptions when trying to read the
// values at the bottom that are "hidden".
listbox.ensureIndexIsVisible(listbox.getRowCount() - 1);
}
}
listbox.ensureIndexIsVisible(0);
};
Now, when I click on the button, the alert I get (after preference.reset()) looks like this:
preference.value=undefined; preference.valueFromPreferences=old user-set preference value
So it seems like in onsyncfrompreference the correct preference value can't be accessed except in a really ugly way:
if (preference.value === undefined) {
prefValue = preference.preferences.defaultBranch.getIntValue(preference.name); // or other type instead of Int
} else {
prefValue = preference.value;
}
Is there a better alternative? Specifically, one which would work for any preference type?
If pref.value === undefined, you should use pref.defaultValue to get the value to display. I updated the reference page and the onsyncfrompreference documentation to say that.

Resources