Xamarin Forms - IOS , Scripts and styles are not calling - xamarin

I am working on Xamarin forms IOS application calling HTML pages, styles and scripts by using Hybrid WebView. I am not able to render styles and scripts and my code is
HybridWebViewRenderer.cs
protected override void OnElementChanged (ElementChangedEventArgs<HybridWebView> e)
{
base.OnElementChanged (e);
if (Control == null) {
userController = new WKUserContentController ();
var script = new WKUserScript (new NSString (JavaScriptFunction), WKUserScriptInjectionTime.AtDocumentEnd, false);
userController.AddUserScript (script);
userController.AddScriptMessageHandler (this, "invokeAction");
var config = new WKWebViewConfiguration { UserContentController = userController };
var webView = new WKWebView (Frame, config);
SetNativeControl (webView);
}
if (e.OldElement != null) {
userController.RemoveAllUserScripts ();
userController.RemoveScriptMessageHandler ("invokeAction");
var hybridWebView = e.OldElement as HybridWebView;
hybridWebView.Cleanup ();
}
if (e.NewElement != null) {
string fileName = Path.Combine (NSBundle.MainBundle.BundlePath, string.Format ("Content/{0}", Element.Uri));
//fileName = "/var/containers/Bundle/Application/2DC89563-D118-4092-B7A5-4549AF07F3B2/StoneApplication.iOS.app/Content/index.html"
Control.LoadRequest (new NSUrlRequest (new NSUrl (fileName, false)));
}
}
public void DidReceiveScriptMessage (WKUserContentController userContentController, WKScriptMessage message)
{
Element.InvokeAction (message.Body.ToString ());
}
and my index.html, here I am calling scripts, Images and styles
<html>
<head>
<title>STONEAPP TEMPLATE</title>
<!--Scripts-->
<script src="/Scripts/angular.min.js"></script>
<script src="/Scripts/jquery.min.js"></script>
<script src="/Scripts/bootstrap.js"></script>
<script src="/Scripts/fileServer.js"></script>
<script src="/Scripts/fileupload.js"></script>
<script src="/Scripts/ng-cordova.js"></script>
<script src="/Scripts/app.js"></script>
<!--Styles-->
<link href="/Styles/bootstrap.css" rel="stylesheet"/>
<link href="/Styles/main.css" rel="stylesheet"/>
</head>
<body ng-app="stoneApp" style="background-color: #ffffff;">
<div ng-controller="templateCtrl">
<div id="Header" style="background-color:#293846;min-height:50px">
<table style="width:100%;padding-top:5px;padding-left:5px;padding-right:5px">
<tr>
<td align="center" width="5%" valign="middle" ng-if="jobView == true" ng-click="showActList()">
<img src="/Images/arrow-back.png" alt="" style="height:50px;width:50px"/>
</td>
<td align="center" width="5%" valign="middle">
<img src="/Images/wifi_on.png" alt="" style="height:50px;width:50px" ng-click="ShowWifiSettings()"/>
</td>
<td align="center" width="5%" valign="middle" ng-click="ShowTabSettings()">
<img src="/Images/settings.png" alt="" style="height:50px;width:50px" ng-if="loginView == false"/>
</td>
<td width="5%" valign="middle" ng-if="activityView == true"></td>
<td width="60%" valign="middle"></td>
<td width="20%" valign="middle" align="right">
<span style="color:white" ng-if="loginView == false">{{userName}} !</span>
</td>
<td width="5%" align="right" valign="middle" ng-click="logout()" >
<img src="/Images/power_button.png" style="height:50px;width:50px" ng-if="loginView == false"/>
</td>
</tr>
</table>
</div>
</div>
</body>
I gave build action as bundle resource for styles and scripts even though I am not able to call styles and scripts and program structure is as attached image.
I am using iOS 10.2 tablet. How can I investigate my issue and make call the scripts styles and images as the links given in the HTML page?

You can't do that with Control.LoadRequest
You're problem is that you can't define baseUrl for your webview with this method and no other method let you define it.
So when your index.html is loaded into the webview, the webview can't retrieve script or css because the baseUrl is not defined and it doesn't know where to load them.
A workaround is to use LoadHtmlString (String htmlContent, NSUrl baseUrl)
Where htmlContent is your index.html content loaded into a var and baseUrl NSUrl baseurl = new NSUrl(NSBundle.MainBundle.BundlePath, true);

Related

Problem When Loading Base65 Image From Table Field

Using the following code I am trying to resize a image and to save it into a table into a VARBINARY(MAX) type field.
When I try to display the saved image, I get nothing on my screen...
When I try to decode manually the saved image using an online decoder, I get the following error :
"The MIME of file was detected as “application/octet-stream”, but the decoder displays it as “image/octet-stream”"
Please help me to save the image into table !
Thank you very much !
The sample below is based on :
https://www.prowaretech.com/Computer/Blazor/Examples/WebApi/UploadImages
and the online Base64 decoder I used is :
https://base64.guru/converter/decode/image
This is the code I am using :
#page "/TestBase64"
#using ResizeUploadImages.Shared
#using System.IO
#using System.Text;
#using System.Threading;
#using System.Threading.Tasks;
#using Microsoft.AspNetCore;
#inject HttpClient Http
#inject IJSRuntime JsRuntime
<table border="1" cellspacing="1" cellpadding="1">
<tr>
<td>
#foreach (var item in filesBase64_V1)
{
<tr>
<td style="text-align: center">
<h6> File Name : </h6>
<h6> "#item.fileName" </h6>
</td>
</tr>
<tr>
<td style="text-align: center">
<img src="data:#item.contentType;base64,#item.base64data" />
</td>
</tr>
}
</td>
</tr>
<tr>
<td>
<div class="custom-file" id="img_V1_div">
<InputFile id="inputFile_V1" class="custom-file-input" multiple="false" OnChange="OnChange" accept="image/png, image/jpeg, image/gif, image/bmp" />
<label class="custom-file-label" for="inputFile_V1">Choose file</label>
</div>
</td>
</tr>
</table>
#code {
List<ImageFile>
filesBase64_V1 = new List<ImageFile>();
async Task OnChange(InputFileChangeEventArgs e)
{
filesBase64_V1 = new List<ImageFile>(); // clear the list of files
var files = e.GetMultipleFiles(); // get the files selected by the users
foreach (var file in files)
{
var preview_file = await file.RequestImageFileAsync(file.ContentType, 250, 250); // resize the image file
var buffer_preview_file = new byte[preview_file.Size]; // allocate a buffer to fill with the file's data
using (var stream = preview_file.OpenReadStream())
{
await stream.ReadAsync(buffer_preview_file); // copy the stream to the buffer
}
filesBase64_V1.Add(new ImageFile { FileData=buffer_preview_file, base64data = Convert.ToBase64String(buffer_preview_file), contentType = file.ContentType, fileName = file.Name, IMAGE_IS_DISPLAYED = false }); // convert to a base64 string!!
await JsRuntime.InvokeVoidAsync("alert", $"{buffer_preview_file}");
//I am saving the two variables
// buffer_preview_file
// and
// base64data
// into a table into two VARBINARY(MAX) fields
// Each time when I try to load images from that table, I get nothing
// on my page
}
}
}

Outlook changes html on office Add-In

I try to write an outlook plugin that inserts a link into the email body. I want to give the link a style in order to look as a button, to give the user a more engaging experience.
The issue I got, is that outlook changes the style on the elements, and the inline style I put on that element is getting lost.
I am inserting the HTML as shown below:
var tablePref = '<table align="left" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse;margin: 0;"><tr><td border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse;margin: 0;padding: 10px 18px;background:\'';
var backgroundColor = 'green'; //The color is user-given, I put green as an example
var tableSuf = '\'">Some text</td></tr></table>'
var item = Office.context.mailbox.item;
item.body.setAsync(tablePref+backgroundColor+tableSuf,
{
coercionType: Office.CoercionType.Html,
asyncContext: {}
},
function (asyncResult) {
if (asyncResult.status == Office.AsyncResultStatus.Failed)
{
//Show error dialog
}
else
{
//Successfully set data in item body.
}
});
I get the link on the email successfully, and it looks just right, but when I send the email, the HTML structure of this button looks like this instead:
<table class="MsoNormalTable" border="0" cellspacing="0" cellpadding="0" align="left" style="border-collapse: collapse">
<tbody>
<tr>
<td style="background: 'green';">
<p class="MsoNormal" style="mso-element: frame; mso-element-frame-hspace: 2.25pt; mso-element-wrap: around; mso-element-anchor-vertical: paragraph; mso-element-anchor-horizontal: column; mso-height-rule: exactly">
<a href="https://somelink.com" target="_blank" rel="noreferrer">
<span style="text-decoration: none">Some Text</span>
</a>
<!-- o ignored -->
</p>
</td>
</tr>
</tbody>
</table>
Outlook is changing my a elements, and this causes that mail clients render the element with a line below because the style got overridden. Is there any way to avoid Outlook change my HTML or it is a known bug? This is happening across all platforms (OWA, Outlook for Mac 16.21 and Outlook for Windows)
Thanks for any help

Change the direction of Hebrew Character during PDF creation by laravel DomPdf

I have a serious problem,
I want to show the Hebrew words in RTL format after PDF creation, but it's not showing. It always shows LTR.
I have some words combinations of English and Hebrew language.
I did some search on google but no luck.
I am using Laravel DomPdf.
I have checked my dompdf core file DOMPDF_UNICODE_ENABLED and its value is "DOMPDF_UNICODE_ENABLED" => true, still not abel to get the solution.
Here is my blade file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!-- Meta, title, CSS, favicons, etc. -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<html xmlns="http://www.w3.org/1999/xhtml" dir="rtl">
</head>
<body>
<table class="lead" cellspacing="0" width="100%" style="font-size: 12px; font-family: 'firefly, DejaVu Sans, sans-serif'; ">
<thead>
<tr>
<th width="10%" style="font-weight: bold;">Date</th>
<th width="15%" style="font-weight: bold;">Name</th>
<th width="20%" style="font-weight: bold;">Details</th>
<th width="10%" style="font-weight: bold;">Contact Origin</th>
<th width="15%" style="font-weight: bold;">Status</th>
<th width="10%" style="font-weight: bold;">Comment</th>
<th width="10%" style="font-weight: bold;">Country</th>
</tr>
</thead>
<tbody>
<?php
foreach($leadInfo as $k=>$v){
$continent = getAllContinentName($v->country);
if(strtolower($continent) == strtolower("Asia")){
$backGround = "#FFB300";
} else if(strtolower($continent) == strtolower("Africa")){
$backGround = "#FFB300";
} else if(strtolower($continent) == strtolower("North America")){
$backGround = "#009792";
} else if(strtolower($continent) == strtolower("South America")){
$backGround = "#FF7E00";
} else if(strtolower($continent) == strtolower("Antarctica")){
$backGround = "#15E6E8";
} else if(strtolower($continent) == strtolower("Europe")){
$backGround = "#0074FF";
} else if(strtolower($continent) == strtolower("Australia")){
$backGround = "#05A900";
} else {
$backGround = "#FFFFFF";
}
if($v->email_status_id == 10){
$statusBackGround = "#a9d18d";
} else if($v->email_status_id == 11){
$statusBackGround = "#ff0000";
} else if($v->email_status_id == 12){
$statusBackGround = "#b3c6e7";
} else if($v->email_status_id == 13){
$statusBackGround = "#c09200";
} else if($v->email_status_id == 14){
$statusBackGround = "#ffff00";
} else {
$statusBackGround = "#FFFFFF";
}
?>
<tr>
<td> {{ date('m-d-Y',strtotime($v->created_date)) }} </td>
<td>{{ $v->name }}</td>
<td>{{ mb_substr($v->message, 0, 300) }}</td> <!-- This line has combination of english and hebrew language-->
<td>{{ $v->contact_origin }}</td>
<td style="direction: rtl !important; unicode-bidi: bidi-override; color:black; background-color: {{ $statusBackGround }};">{{ $v->status_name }}</td> <!-- This line has only hebrew language -->
<td>{{ $v->comment }}</td>
<td style="color:black; background-color: {{ $backGround }}" >{{ getAllCountryName($v->country) }}</td>
</tr>
<?php } ?>
</tbody>
</table>
</body>
</html>
It would be great if anyone helps me to get out of this.
Dompdf (up to and including 0.8.1) does not currently support RTL text (see issue 1009). There is a work around, but the results are passable at best.
If you're interested in trying it out modify the Text rendered by adding the following code at line 83:
if (strtolower($style->direction) === 'rtl') {
preg_match_all('/./us', $text, $ar);
$text = join('',array_reverse($ar[0]));
// if there are numbers in the string so the next line reverse the number back treat also numbers with dot (decimal) and email
$text = preg_replace_callback('/\d+-\d+|\d+|\d+\.\d+|\S+#\S+/', function (array $m) { return strrev($m[0]); }, $text);
}
you can use this package which supports rtl languages such as persian and arabic
https://github.com/barryvdh/laravel-snappy
in order to change the direction , just within the html tag which is going to be converted to pdf , use dir="rtl"

The event dispatched from a html page is not received by main.js in my firefox extension

In my firefox extension I need user input to do further computations on my extension.
I used a panel to do this. With panels I can get input form user and pass it to my content script and emit this from there using self.port.emit and receive it on main.js using panel.port.on. But my problem is panels auto hide. I want to show my panel until user closes it.
I tried getting the above scenario by opening a html page using window window.open. But I could not pass the user input from my html window to main.js. I used the following code.
MY SR.html code
<!DOCTYPE HTML>
<html>
<head>
<title>Title</title>
<script>
var t= {
CallExtension : function(e) {
var text = document.getElementById("p").value;
var element = document.createElement("MyExtDE");
element.setAttribute("phNu", text);
document.documentElement.appendChild(element);
var evt = document.createEvent("Events");
evt.initEvent("SREvent", true, false);
element.dispatchEvent(evt);
}
}
</script>
<style>
table{ padding-top:30px;}
h1{ color:orange; }
td{ font-family:"Arial"; font-size:12px; }
</style>
</head>
<body>
<table cellspacing=5 cellpadding=5 align="center" border=0>
<tr>
<td colspan=3><h1>MyRMN Start Registration</h1></td>
</tr>
<tr>
<td>Phone Number</td><td>:</td><td><input type="text" id="p" name="pn"/>
</td>
</tr>
<tr>
<td><input type="button" id="btnSSubmit" value="Submit"
onclick="t.CallExtension(event);" /></td>
</tr>
</table>
</body>
My main.js code
function SR(){
try {
win = window.open(data.url("SR.html"), "SR",
"chrome,centerscreen");
win.document.defaultView.addEventListener("SREvent", S1Submit, false, true);
//window.window.document.defaultView.addEventListener("SREvent", S1Submit, false,
true);
} catch(e) {
prompts.alert(null, "main() SR", " Exception: " + e);
}
}
function S1Submit(evt){
var text = evt.target.getAttribute("phNu");
prompts.alert(null, "main() S1Submit", text);
if (text) {
mSR(text);
}
}
UPDATE
I introduced page-mod in my main.js page and i could not still communicate with my main.js
from my webpage.
main.js
var data = require("sdk/self").data;
var pageMod = require("sdk/page-mod");
function StartRegistration(){
try {
winSReg = window.open(null, data.url("SR.html"), "Title",
"chrome,centerscreen", null);
} catch(e) {
prompts.alert(null, "Title", "SR Exception: " + e);
}
}
pageMod.PageMod({
include: data.url("SR.html"),
contentScriptFile: data.url("SR.js"),
onAttach: function(worker) {
worker.port.on("gotInput", function(inputValue) {
doSomethingWith(inputValue);
});
}
});
SR.JS
function SubmitSReg(){
try {
var text = document.getElementById("p").value;
alert("SR.js text:" + text);
self.port.emit("gotInput", text);
} catch(e) {
alert(e);
}
}
SR.Html
<!DOCTYPE HTML>
<html>
<head>
<title>SR</title>
<script type="text/javascript" src="SR.js"></script>
<style>
table{ padding-top:30px;}
h1{ color:orange; }
td{ font-family:"Arial"; font-size:12px; }
</style>
</head>
<body>
<table cellspacing=5 cellpadding=5 align="center" border=0>
<tr>
<td colspan=3><h1>Title</h1></td>
</tr>
<tr>
<td>Phone Number</td><td>:</td><td><input type="text" id="p"
name="pn" /></td>
</tr>
<tr>
<td><input type="button" id="btnSSubmit" value="Submit" onclick =
"SubmitSReg()"/></td>
</tr>
</table>
</body>
</html>
Any kind of help is greatly appreciated.
Thanks in advance
Your approach is right but there's a missing part: in order to allow communication between the main.js and your static page you need to use a page-mod matching your static page local url.
Add this to your main.js:
var data = require("sdk/self").data;
var pageMod = require("sdk/page-mod");
pageMod.PageMod({
include: data.url("SR.html"),
contentScriptFile: [data.url("script.js")],
onAttach: function(worker) {
worker.port.on("gotInput", function(inputValue) {
doSomethingWith(inputValue);
});
}
});
And also create a data/script.js file containing:
/* Here add a listener to the form's submit event and then
get the input element and its value.
Then do this with yhe input value:
*/
self.port.emit('gotInput', inputValue);
This way you achieve communication between your page and the addon main.js.

jquery error this.source is not a function

Hi I am trying to catch an array of string from a class called AjaxFacade using DWR and I am using jquery to autocomplete a text box snippetof my jsp code is as follows
<%
String path = request.getContextPath();
%>
<script type='text/javascript' src='<%=path%>/dwr/interface/ajaxFacade.js'></script>
<script type='text/javascript' src='<%=path%>/dwr/engine.js'></script>
<script type='text/javascript' src='<%=path%>/dwr/util.js'></script>
<script>
$(function()
{
var countries ;
countries = ajaxFacade.getCountries();
$("#tags").autocomplete({source : countries});
});
</script>
<tr>
<td align="left" valign="top" bgcolor="e3ddc7">
<div align="right"><strong> <font color="red">*</font>Old E-mail Address:</strong></div>
</td>
<td align="left" valign="top" bgcolor="#FFFFFF">
<html:text name="amsUserRequestForm" property="oldEmail" size="20" styleClass="ui-widget" styleId="tags">
</html:text></td>
</tr>
Function in AjaxFacade class is as follows
public String[] getUsers() {
String[] countries = {
"India",
"Iran",
"Iraq",
"Indoneshia",
"Ireland"
};
return countries;
}
No matter what I do it keeps me giving error this.source is not a function. Any help is greatly appreciated
make sure that the countries are filled with data make sync json call if needed.

Resources