Building Dojo 1.7 for Mobile PhoneGap App - javascript

I am trying to build dojo 1.7 to use in my phonegap application. I am currently using dojo 1.6.1. I built my current dojo.js file by going to build.dojotoolkit.org and selecting everything under dojox.mobile as well as a dojo.store.JsonRest module. That works great.
My issue is trying to create a profile file to create a build similiar to the one I got from the dojo build website.
I downloaded dojo 1.7 stable release src.
I went into the buildScripts folder from the command line and tried to run a build with the following command:
>build profile=path/myMobileProfile.js action=release releaseName=test
I used the sample profile from the profiles folder:
dependencies = {
stripConsole: "normal",
layers: [
{
name: "dojo.js",
customBase: true,
dependencies: [
"dojox.mobile.parser",
"dojox.mobile",
"dojox.mobile.compat"
]
},
{
name: "../dojox/mobile/_compat.js",
layerDependencies: [
"dojo.js"
],
dependencies: [
"dojox.mobile._compat"
]
}
],
prefixes: [
[ "dijit", "../dijit" ],
[ "dojox", "../dojox" ]
]
}
It built with no errors. The dojo.js generated from the build was then dropped into my phonegap application. I changed my index file to the following just for testing:
<!DOCTYPE HTML>
<html>
<head>
<title>PhoneGap</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/>
<meta http-equiv="cache-control" content="no-cache"/>
<meta http-equiv="pragma" content="no-cache"/>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojox/mobile/themes/android/android.css" type="text/css" media="screen" title="no title">
<script type="text/javascript" src="libs/dojo/dojo/dojo.js" djConfig="parseOnLoad:true"></script>
<script type="text/javascript" charset="utf-8" src="phonegap-1.1.0.js"></script>
</head>
<body style="background-color:white">
Phonegap
</body>
</html>
Everytime I run the app I get a white page. When I replace the dojo.js file with my working copy I see the Phonegap output.
I would like to be able to use dojo 1.7 mobile and some of the new features such as the SpinWheel.
Can someone please help me with my build?
Thanks

I'm having the same type of issues. I think it has to do with the new AMD loader.
It seems as if the parser is not parsing the declarative widgets but rather is waiting to do it on demand or that it just never gets called.
I did find some docs that mention we should use dojo/ready, but couldn't get it to work with it and phoneGap. The same code works fine on a desktop without phoneGap, which is weird.
See live docs: http://livedocs.dojotoolkit.org/dojo/ready
As well as: http://livedocs.dojotoolkit.org/loader/amd
"To put the loader in the AMD mode, set the async configuration variable to truthy:
<script data-dojo-config="async:1" src="path/to/dojo/dojo.js"></script>
<script>
// ATTENTION: nothing but the AMD API is available here
</script>
Note that you can only set the async flag before dojo.js is loaded, and that in AMD mode, neither Dojo nor any other library is automatically loaded - it is entirely up to the application to decide which modules/libraries to load."

For me this Profile works fine with dojo 1.7 and PhoneGap:
dependencies = {
selectorEngine: "acme",
layers: [
{
// This is a specially named layer, literally 'dojo.js'
// adding dependencies to this layer will include the modules
// in addition to the standard dojo.js base APIs.
name: "dojo.js",
dependencies: [
"dijit._Widget",
"dijit._Templated",
"dojo.fx",
"dojo.NodeList-fx",
//this wasn't included in the standard build but necessary
"dojo._firebug.firebug",
//my used dojo requirements
"dojox.mobile.parser",
"dojox.mobile",
"dojox.mobile.Button",
"dojox.mobile.SwapView",
"dojox.mobile.ScrollableView",
"dojox.mobile.TabBar",
"dojox.mobile.SpinWheelTimePicker",
"dojox.mobile.compat"
]
}
],
prefixes: [
["dijit", "../dijit" ],
["dojox", "../dojox" ]
]
}
But with this Profil the CSS Files are not included, so you have to copy all the CSS folder structure.
My HTML file looks like this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 5.0//EN" "http://www.w3.org/TR/html5/strict.dtd">
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"></meta>
<meta name="apple-mobile-web-app-capable" content="yes"></meta>
<title>dojox.mobile Demo</title>
<link href="css/themes/iphone/iphone.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="phonegap.js" charset="utf-8"></script>
<script type="text/javascript" src="dojo.js" djConfig="isDebug:true, parseOnLoad:true"></script>
<script type="text/javascript">
require([
"dojox/mobile/parser", // (Optional) This mobile app uses declarative programming with fast mobile parser
"dojox/mobile", // (Required) This is a mobile app.
"dojox/mobile/Button",
//Some other dojo Widgets
"dojox/mobile/compat" // (Optional) This mobile app supports running on desktop browsers
],
function(parser, mobile, compat){
//Optional module aliases that can then be referenced inside callback block
}
// Do something with mobile api's. At this point Dojo Mobile api's are ready for use.
);
//to make sure dojo and PhoneGap was loaded use this
document.addEventListener("deviceready", init(), false);
function init(){
dojo.ready(function(){
//do something
});
}
</script>
</head>
<body>
</body>
HTH

This problem is solved with Dojo 1.7.2

Also found this: http://livedocs.dojotoolkit.org/dojo/parser
and tried to force parse on the entire dom or just the specific element, but still nothing.

I did find the following that may shed some more light on this issue: "Dojo and PhoneGap? both have their own event to acknowledge when the page is ready. We are finding that the dojo.ready is too early for things like deviceDetection APis when running within a PhoneGap? container and it would be better off being done inside of the PG deviceReady method. ..."
Full thread can be found here: http://bugs.dojotoolkit.org/ticket/14062
It is discussing dojo 1.6.1, but sounds like some changes in dojo 1.7 may suffer more severe reactions. There is a suggested workaround, but I'm not sure it will solve the 1.7 issue.

Related

Blazor WebAssembly Environment Variables

I'm currently working on a .NET Standard 2.1 Blazor WebAssembly application.
I try to include or exclude Stylesheets according to an environment variable.
In .NET Core there are usually Environment Tag Helpers like in the following example:
<environment include="Development">
<link rel="stylesheet" href="css/style.css" type="text/css" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="css/style.min.css" type="text/css" />
</environment>
This works perfectly fine in a Blazor Server application, but doesn't in Blazor WASm, as this is client-side code.
Thus I try to find a good solution to include/exclude Style sheets according to the Environment variable in Blazor WebAssembly.
My current approach is to call a JavaScript helper method from my Blazor WASm Program.cs file with JSInterop and remove the Stylesheets according to the environment variable:
await jsInterop.InvokeVoidAsync("helpers.setup", "Development");
My JavaScript on the client looks like this:
window.helpers = {
setup: (environment) => {
if (environment === "Development") {
// remove production styles
}
if (environment !== "Development") {
// remove development styles
}
}
};
The problem with this solution is, I want to put my styles into my header file and group them into a <section> element or something similar - which doesn't work in valid HTML5.
How do you handle your Development/Production environment in Blazor WebAssembly?
How can you exclude or include specific CSS files according to the set environment variable in the project settings (launchsettings.json)?
Disclaimer:
This is just something I tried that seems to work. I could not find any documentation supporting doing it this way, nor anything saying not to do it this way. if there is any official documentation please let me know.
The documentation state:
When running an app locally, the environment defaults to Development.
When the app is published, the environment defaults to Production.
Further down it does mention how to set the environment via the web.config that gets generated when publishing the file to IIS.
There are also references to Use multiple environments in ASP.NET Core. and Host and deploy ASP.NET Core Blazor WebAssembly
However this is what I did.
Looking at the Program.cs file that was generated by the new web assembly project template, the builder is created by WebAssemblyHostBuilder.CreateDefault(args); This must mean that all the default services must already be registered in the services container.
This would include the IWebAssemblyHostEnvironment configuration service.
The next line down builder.RootComponents.Add<App>("app"); adds the App <app></app> root component that is used in the index.html file.
So, Why not try to create a Head <head></head> component and see what happens.
I created a Head razor component and named it Head.razor containing all the html that would usually live between the <head></head> tags.
#using Microsoft.AspNetCore.Components.WebAssembly.Hosting
#inject IWebAssemblyHostEnvironment hostEnv
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/app.css" rel="stylesheet" />
#*Check the environment value*#
#if (hostEnv.IsDevelopment())
{
<title>BlazorWasmApp - In Debug</title>
<link href="css/debug.css" rel="stylesheet" />
}
else
{
<title>BlazorWasmApp - Not Debug</title>
<link href="css/live.css" rel="stylesheet" />
}
#code {}
Because it is a component you can inject the IWebAssemblyHostEnvironment and check the .IsDevelopment(),.IsProduction() etc.. extension method values.
I left the original <head> tag as is in the index.html file as the content of the <head>...gets overwritten...</head> seems to be completely overwritten.
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>BlazorWasmApp</title>
<base href="/" />
<link href="css/app.css" rel="stylesheet" />
</head>
<body>
<app>Loading...</app>
...
...
Also leaving the <head>tag with the reference to the cs/app.css file does not change the way it looks when the app is Loading....
I registered the Head class to the builder.RootComponents collection in the Program class.
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
//Add the Head to root components
builder.RootComponents.Add<Head>("head");
builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
await builder.Build().RunAsync();
}
I added 2 css files to the wwwroot/css folder debug.css and live.css each containing a simple body { background-color:*red or blue* } style.
In the launchSettings.json file, in the profiles section, set the IIS Express : environmentVariables : ASPNETCORE_ENVIRONMENT to "Development" and under the [YourAppName] : environmentVariables : ASPNETCORE_ENVIRONMENT to "Production".
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}"
},
"BlazorWasmApp": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}"
}
}
When launching the app with the IIS Express profile (Development) the background is red and when launching the app with [YourAppName] profile (Production) the background is blue.
When looking at the <head></head> tags using the developer tools the content of the head tag contains the css references according to the environment.
IIS Express:
BlazorWasmApp (my app profile):

Using html code with a javascript code as a widget in flutter web

I am currently using flutter web and I already have an html button that I want to add inside my flutter app. This html contains a java script as its body. How to add the html with javascript as a widget inside my app? This is the html snippet:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Paytabs Express Checkout V4</title>
</head>
<body>
<script
src="https://paytabs.com/express/v4/paytabs-express-checkout.js"
id="paytabs-express-checkout"
data-secret-key="key"
data-ui-type="button"
data-merchant-id="mid"
data-url-redirect="https://my09713z28.codesandbox.io/"
data-amount="3.3"
data-currency="SAR"
data-title="John Doe"
data-product-names="click"
data-order-id="25"
data-ui-show-header="true"
data-customer-phone-number="5486253"
data-customer-email-address="john.deo#paytabs.com"
data-customer-country-code="973"
data-ui-show-billing-address="false"
data-billing-full-address="test test test"
data-billing-city="test"
data-billing-state="test"
data-billing-country="BHR"
data-billing-postal-code="123"
></script>
<script>
</script>
</body>
</html>
Hope you provide me with some help.
You can go something like this. You should put your html releated code in index.html file and in src you need to put a path for your index.html e.g. 'assets/index.html'
import 'dart:html' as html;
import 'dart:js' as js;
import 'dart:ui' as ui;
String viewID = "your-view-id";
#override
Widget build(BuildContext context) {
// ignore: undefined_prefixed_name
ui.platformViewRegistry.registerViewFactory(
viewID,
(int id) => html.IFrameElement()
..width = MediaQuery.of(context).size.width.toString()
..height = MediaQuery.of(context).size.height.toString()
..src = 'path/to/your/index.html'
..style.border = 'none');
return SizedBox(
height: 500,
child: HtmlElementView(
viewType: viewID,
),
);
}
You can use HtmlElementView for adding html elements inside a flutter web app
https://api.flutter.dev/flutter/widgets/HtmlElementView-class.html
Beware that would only work in flutter web and
Embedding HTML is an expensive operation and should be avoided when a
Flutter equivalent is possible
You should add this html content inside the file web/main.html.
I suggest you to build the button with Flutter and call javascript code with dart like this example calling javascript from Dart
If I understand correctly, your intention is to be able to render your html/javascript as a native widget in flutter.
Unfortunately, I don't think this is technically possible due to the fact that flutter is rendering everything in its own light-weight rendering engine, rather than creating native code that your native runtime executes. The artifact(s) created (even in flutter web) after compilation is a combination of flutter runtime + your compiled code that executes on flutter runtime. Therefore this is not possible to add html/javascript to your flutter code as a widget and run it everywhere.
The solution is to implement your widget in pure Dart code.

System.OutOfMemory Exception on loading Javascript libraries

In my application I have referenced JQWidget libraries and styles using Bundle options like below.
bundles.Add(new ScriptBundle("~/bundles/jqwidgets").Include(
"~/JQWidgets/jqx-all.js",
"~/JQWidgets/jqxcore.js",
"~/JQWidgets/jqxdata.js",
"~/JQWidgets/jqxgrid.js",
"~/JQWidgets/jqxgrid.selection.js",
"~/JQWidgets/jqxgrid.pager.js",
"~/JQWidgets/jqxlistbox.js",
"~/JQWidgets/jqxbuttons.js",
"~/JQWidgets/jqxscrollbar.js",
"~/JQWidgets/jqxdatatable.js",
"~/JQWidgets/jqxtreegrid.js",
"~/JQWidgets/jqxmenu.js",
"~/JQWidgets/jqxcalendar.js",
"~/JQWidgets/jqxgrid.sort.js",
"~/JQWidgets/jqxgrid.filter.js",
"~/JQWidgets/jqxdatetimeinput.js",
"~/JQWidgets/jqxdropdownlist.js",
"~/JQWidgets/jqxslider.js",
"~/JQWidgets/jqxeditor.js",
"~/JQWidgets/jqxinput.js",
"~/JQWidgets/jqxdraw.js",
"~/JQWidgets/jqxchart.core.js",
"~/JQWidgets/jqxchart.rangeselector.js",
"~/JQWidgets/jqxtree.js",
"~/JQWidgets/globalize.js",
"~/JQWidgets/jqxbulletchart.js",
"~/JQWidgets/jqxcheckbox.js",
"~/JQWidgets/jqxradiobutton.js",
"~/JQWidgets/jqxvalidator.js",
"~/JQWidgets/jqxpanel.js",
"~/JQWidgets/jqxpasswordinput.js",
"~/JQWidgets/jqxnumberinput.js",
"~/JQWidgets/jqxcombobox.js",
"~/JQWidgets/jqxgrid.edit.js",
"~/JQWidgets/jqxgrid.columnsresize.js",
"~/JQWidgets/jqxgrid.columnsreorder.js",
"~/JQWidgets/jqxdata.js",
"~/JQWidgets/jqxgrid.export.js",
"~/JQWidgets/jqxdata.export.js",
"~/JQWidgets/jqxgrid.grouping.js",
"~/JQWidgets/jqxgrid.aggregates.js",
"~/JQWidgets/jqxtabs.js",
"~/JQWidgets/jqxwindow.js"
));
bundles.Add(new StyleBundle("~/JQWidgets/Styles/css").Include(
"~/JQWidgets/Styles/jqx.base.css",
"~/JQWidgets/Styles/jqx.arctic.css",
"~/JQWidgets/Styles/jqx.black.css",
"~/JQWidgets/Styles/jqx.bootstrap.css",
"~/JQWidgets/Styles/jqx.classic.css",
"~/JQWidgets/Styles/jqx.darkblue.css",
"~/JQWidgets/Styles/jqx.energyblue.css",
"~/JQWidgets/Styles/jqx.fresh.css",
"~/JQWidgets/Styles/jqx.highcontrast.css",
"~/JQWidgets/Styles/jqx.metro.css",
"~/JQWidgets/Styles/jqx.metrodark.css",
"~/JQWidgets/Styles/jqx.office.css",
"~/JQWidgets/Styles/jqx.orange.css",
"~/JQWidgets/Styles/jqx.shinyblack.css",
"~/JQWidgets/Styles/jqx.summer.css",
"~/JQWidgets/Styles/jqx.web.css",
"~/JQWidgets/Styles/jqx.ui-darkness.css",
"~/JQWidgets/Styles/jqx.ui-lightness.css",
"~/JQWidgets/Styles/jqx.ui-le-frog.css",
"~/JQWidgets/Styles/jqx.ui-overcast.css",
"~/JQWidgets/Styles/jqx.ui-redmond.css",
"~/JQWidgets/Styles/jqx.ui-smoothness.css",
"~/JQWidgets/Styles/jqx.ui-start.css",
"~/JQWidgets/Styles/jqx.ui-sunny.css",
"~/JQWidgets/Styles/bootstrap.css",
"~/JQWidgets/Styles/site.css"
));
BundleTable.EnableOptimizations = true;
And in my _Layout.cshtml I have referenced them like this in head and body tags respectively.
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - Gulf Piping Company</title>
#Styles.Render("~/Content/css")
**#Styles.Render("~/jqwidgets/styles/css")**
#Scripts.Render("~/bundles/modernizr")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
**#Scripts.Render("~/bundles/jqwidgets")**
#Scripts.Render("~/bundles/ajax")
#RenderSection("scripts", required: false)
Now, since my application is in development stage, so I keep running the application, make changes and refresh the browser as required. After certain number of refreshes (cant tell how many), i get this error message.
I have to close browser, close Visual Studio and then re run Visual studio, load solution again and then run the appliction to overcome this error. Can any one tell me what is going on here?
Also, i have different views/pages in my application and some pages reference some of above JQWidget libraries and some don't (i.e. not all pages use all of these libraries), so is Bundling really the right way to use or there is a better way to reference libraries?

Widget from Angular 2 app webpack

If it is unclear than let's try this again.
In my research I learned that some call it a micro-loader, which is what I am trying to achieve. In the webpack configuration I have this in the plugin section
new HtmlWebpackPlugin({
template: 'src/index.html',
title: METADATA.title,
chunksSortMode: 'dependency',
metadata: METADATA,
inject: 'head'
}),
which turns an html file without any script tags (or even placeholders for them) during compilation in something like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My angular widget</title>
<meta name="description" content="My angular widget">
<!-- base url -->
<base href="/">
<link href="main.23ca1423b5f74b9e7d3a76e9eed69f71.css" rel="stylesheet"><script type="text/javascript" src="polyfills.60dbe827b1b8353af66f.bundle.js" defer></script><script type="text/javascript" src="vendor.0f040ba30b8e909c6a82.bundle.js" defer></script><script type="text/javascript" src="main.d6e9175158901f87b307.bundle.js" defer></script></head>
<body>
<app class="skin-green gbp">
Loading...
</app>
</body>
</html>
It magically adds those 4 files (1 css, 3 js) into the head section.
Now what I want is something like this (the angular-widget.js file)
function loadCss(url) {
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = url;
document.getElementsByTagName("head")[0].appendChild(link);
}
loadCss('https://my-domain.com/app/main.1928b5b43a58428e7798d12176de68e3.css');
require(['https://my-domain.com/app/polyfills.60dbe827b1b8353af66f.bundle.js'], function() {
require(['https://my-domain.com/app/vendor.623bbcbf99de3526eab8.bundle.js'], function() {
require(['https://my-domain.com/app/main.d4f6aea1525a044b41da.bundle.js'], function() {
});
});
});
Which is a file I came up which does what I want it to do, but takes manual work everytime and utilizes require.js for now (but can be anything, I don't really care), which is the only point of entry and gets automatically generated during the compilation so I don't have to manually change the hashes everytime something changes and gets redeployed.
-- Old Post starts here
I have an angular 2 project using webpack for compiling. But I do not want the entry point to be the index.html, because the app is to be embeded into another webpage, which I do not have full control over.
I am trying to find a way to output something similar to the index.html but inside a .js file which I than can include on the webpage.
www.some-domain.com/webpage
[...]
<script type="text/javascript" src="https://my-domain.com/angular-widget.js"></script>
<app>
Loading...
</app>
[...]
Is there a way to generate that angular-widget.js during the webpack process? I tried to hijack the HtmlWebpackPlugin, but that expects to output HTML. I am fairly new to the whole webpack process, but my approach right now would be some template where I just can output the different files which are produced by webpack, for example using require.js. But maybe the whole thing is even possible only via webpack?

Use of Modernizr.load

I am using Modernizr for conditional loading of resources. My code is
<link rel="stylesheet" type="text/css" media="all" href="stylesheet/style.css" />
<script type="text/javascript" src="javascript/jQuery/jquery-1.8.1.min.js"></script>
<script src="javascript/stickyheader/jquery.fixedheadertable.js"></script>
<link rel="stylesheet" type="text/css" media="all" href="javascript/stickyheader/defaultTheme.css" />
<script type="text/javascript" src="javascript/modernizr/modernizr.2.6.2.js"></script>
<script type="text/javascript">
Modernizr.load([ {
// If browser supports touch
test : Modernizr.touch,
//Load iPad related resorces
yep : [ 'javascript/ipad-default.js', 'javascript/touchscroll.js', 'javascript/ipad-scroll.js',
'javascript/mobile.js' ],
// Load common resorces
load : ['javascript/ipad-default.js']
} ]);
</script>
This is working fine. But I am wondering if I can load all resources in Modernizr.load when I test for Modernizr.touch.
To be clear I want to load all resources within Modernizr.load.
How can I do this? And is this a good approach?
Yes you can. It definitely is a good approach to use a resource loader for a web application. However, I found the page rendering to be a little shattering when loading all CSS through Modernizr.
// You can load CSS just like JS
Modernizr.load("stylesheet/style.css", [
{
test : Modernizr.touch,
yep : [ 'javascript/touchscroll.js', 'javascript/ipad-scroll.js', 'javascript/mobile.js' ],
load : [ 'javascript/ipad-default.js' ] // No need to specify this in 'yep' too
}]);
Because Modernizr.load is built on yepnope.js, the yepnope documentation is a little more interesting for resource loading than the Modernizr tutorials. If you don't mind yet another framework, I can recommend requirejs. This one really helps to decouple and load your components.

Categories