Building a SPFx solution with datatables - javascript

I apologize in advance for a wall of text question. SPFx is a new requirement mandated from on high and I don't have any working experience with it at this point.
I created a vanilla SPFx project added to github to make it easier. There are just too many moving parts to try and get them all in the question.
https://github.com/cyberjetx/dtspfx/tree/AddDt
Description of problem:
Trying to make the basic datatable work with zero configuration in SharePoint framework (SPFx) this is new ground for me and it has been mandated from on-high that we will be using SPFx or not on the intranet at all.
I am trying to document the process so that others using dt will have a base to start from or at least be able to see what is needed to to add dt to their SPFxs. This process is started in the readme.md.
in Area51WebPart.ts
import 'datatables.net';
in main.js
$(document).ready(function () {
$('#example').DataTable();
});
In config.json I would IDEALLY like to just use the combined file from dataTables cdn. I have also tried npm install --save datatables.net-dt and linked in config as "path": "/node_modules/datatables.net/js/jquery.dataTables.min.js", earning the following:
[17:03:22] Error - [webpack] 'dist':
"C:\code\dtspfx\node_modules\datatables.net\js\jquery.dataTables.min.js"
does not exist. Ensure the path is correct and relative to the project
root.
however, it is indeed there, if I copy and paste the path and open in notepad it's there.
. . .
"externals": {
"jquery": {
"path": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.0/jquery.min.js",
"globalName": "jQuery"
}
,"datatables.net": {
"path": "/node_modules/datatables.net/js/jquery.dataTables.min.js",
// "path": "https://cdn.datatables.net/v/dt/jszip-2.5.0/dt-1.12.1/af-2.4.0/b-2.2.3/b-colvis-2.2.3/b-html5-2.2.3/b-print-2.2.3/cr- 1.5.6/date-1.1.2/fc-4.1.0/fh-3.2.4/kt-2.7.0/r-2.3.0/rg-1.2.0/rr-1.2.8/sc-2.0.7/sb-1.3.4/sp-2.0.2/sl-1.4.0/sr-1.1.1/datatables.min.js",
"globalName": "jQuery",
"globalDependencies": [
"jquery"
]
}
},
. . .

Try removing the leading slash here => /node_modules/datatables/.... It may be looking at the root of your hard drive, not at the root of the project folder.
Other than that, you are probably using a wrong template, you don't need react or typescript if you are not using it. You can use plain javascript to create your webpart.

You can use DataTable in SPFx web parts using jQuery and DataTable libraries.
Follow below documentation and web parts for detailed code:
Migrate jQuery and DataTables solution built using Script Editor web part to SharePoint Framework
SharePoint Framework DataTable web part sample
DataTable Using MUI table

Related

How do I write flavor specifc code in react-native?

About a week ago I starded developing a white-label app, where the only thing that will differ from app to app are some color values, source of images and API endpoints, but the app itself does the exact same thing.
So the last couple of days I tryied to learn how to build multiple apps from the same project... (lets mainly focus on Android here) thru my journey I found a few guides and I managed to make it work by following this guide and setting product flavors in my build.gradle.
productFlavors {
firstapp {
applicationIdSuffix '.firstapp'
resValue "string", "build_config_package", "com.myapp"
}
secondapp {
applicationIdSuffix '.secondapp'
resValue "string", "build_config_package", "com.myapp"
}
}
Ok, now I can runreact-native run-android --variant=firstappDebug to emulate the app while developing, and latter on release gradlew assembleFirstappRelease and be able to generate multiple (in this case 2) different builds.
But, as im quite a begginer, I couldnt find the proper way to write flavor specific code to be rendered whenever I build for that specific flavor.
In addition, I followed this other guide that more or less shows how to do that, but again, I lack knowledge to proper execute some steps so I failed there. I couldnt figure out in what file should I right the code at STEP 2 and neither what is BuildConfig.FLAVOR, NSBundle.mainBundle(), and at STEP 3 UtilityManager.getTarget(), RNBuildConfig.FLAVOR
In conclusion.. Im still studying hard to grow and Ill look more deeply in environment varibles... but I felt the need to ask the community for help.
The workaround I'm using at the time of this post (That's very important) is:
Product Flavors (Android) and XCode Schemes (iOS) to build different apps with different names and icons.
To write code for specific Flavor/Scheme, I'm using environment variables. I created multiple .env files with the desired config variables. e.g.
//.env.mycustomenv
LOGIN_TITLE_TEXT= "My App"
LOGIN_STATUSBAR_CONTENT= "light-content"
LOGIN_BACKGROUND_COLOR= "#333"
LOGIN_SIMPLE_TEXT_COLOR= "#FFF"
LOGIN_TEXTINPUT_BACKGROUD_COLOR= "#FFF"
LOGIN_LOGIN_BUTTON_COLOR= "#009933"
To tell RN which .env file to look at im using react-native-config from the command line as simple as $env:ENVFILE=".env.mycustomenv" (On windows using powershell).
react-native-config should work to expose those variables above to your .js files, and it does, but for my experience it didn't work when using product flavors. So I started using react-native-build-config to do that task.. So in the end my code looks something like this:
import BuildConfig from "react-native-build-config"
export function MainStyle () {
return(
<>
<StatusBar barStyle={`${BuildConfig.LOGIN_STATUSBAR_CONTENT}`} backgroundColor={BuildConfig.LOGIN_BACKGROUND_COLOR} />
<TitleText>{CoBrandConfig.Login.LOGIN_TITLE_TEXT}</TitleText>
</>
)
}
So on and so on...
I hope that this answer helps other devs that find this post looking to find help.

Loading customer sapui5 library inside component.js

According to the documentation here:
https://scn.sap.com/thread/3502503
http://jsbin.com/openui5-notepad-control-with-its-own-library-used-in-xmlview/1/edit?html,output
I build the following folder structure with following files:
/my/themes/sap_bluecrystal/library.css
/my/library.js
/my/Square.js
Now I am asking me how to load the library (inside Component.js) correct.
I tried following in Component.js
jQuery.sap.registerModulePath("my", "./my");
And in some View:
jQuery.sap.require("my.Square");
...
new my.Square({
text : "Test",
size : "200px"
})
All in all the Square control seems to be usable but the library.js and library.css is not loaded at all.
Any idea how to do it right?
Using bootstrap XML code inside index.html would not work if the app is running inside Fiori Launchpad.
Bonus question: Where to deploy a custom library inside SAP to be usable by multiple apps? One idea (but maybe that's wrong) is to create a BSP application just containing the library code?
The right way to load the library would be (instead of jQuery.sap.require):
sap.ui.getCore().loadLibrary("my");
This will load a "library-preload.json" file (if available) and also include the theme resources.
See https://openui5.hana.ondemand.com/#docs/api/symbols/sap.ui.core.Core.html#loadLibrary
First question I could solve for my own:
Replace
jQuery.sap.require("my.Square");
with
jQuery.sap.require("my.library");
Second question is still open :)

How to bring an application from Sublime Text to a web IDE for sharing?

I generally work on my projects locally in Sublime Text but sometimes need to share them with others using things like Jsfiddle, codepen, or plunker. This is usually so I can get unstuck.
Is there an easier way to share code that doesn't involve purely copy pasting and the hassle of getting all the dependencies right in a new environment?
It's taking me hours to get some of my angular apps working in plunker and I'm wondering if there's a better way.
There is no built-in way to upload multiple files to Plunker.
Users have built tools to facilitate this. Please see: https://www.npmjs.org/package/plunk which is a command-line utility that will let you create plunks from the contents of a directory.
Basically, what it will let you do is plunk [dir] from the commandline.
You can also bootstrap plunks by making POST requests to http://plnkr.co/edit/ where the payload has the following format:
{
"description": "Plunk description", // Optional
"tags": ["tag1", "tag2", ..., "tagN"], // Optional
"files": {
"filename1.ext": "contents of filename1.ext",
"filename2.ext": "and so on.."
}
}
Code for this handler: https://github.com/filearts/plunker_www/blob/0c608ae80ef30d59bfdfeaf3c2a28563f7b730e4/app.coffee#L105-L121

Dojo build css and custom javascript

I've set up a single html page that uses three dojo widgets and I'm trying to create a custom build from it using dojo 1.7.5. The build succeeds leaving me with a dojo.js that includes the files I need using this build file:
var dependencies = {
action: "release",
selectorEngine: "acme",
stripConsole: "none",
cssOptimize: "comments.keepLines",
layers: [
{
name: "dojo.js",
dependencies: [
"dijit.form.ValidationTextBox",
"dijit.form.DropDownButton",
"dijit.form.Button",
"dijit.form.Form",
"dijit._base",
"dijit._Container",
"dijit._HasDropDown",
"dijit.form.ComboButton",
"dijit.form.ToggleButton",
"dijit.form._ToggleButtonMixin",
"dojo.parser",
"dojo.date.stamp",
"dojo._firebug.firebug"
]
}, {
name: "../test/test.js",
dependencies: [
"test.test"
]
}
],
prefixes: [
[ "dijit", "../dijit" ],
[ "dojox", "../dojox" ],
[ "ourpeople", "../ourpeople" ]
]
};
The questions I can't seem to find an answer to:
I'm using cssOptimize, I was expecting a single css file in which all the used css files were imported. However I can't find such a file. Is this the way dojo compresses it's css or are my expectations wrong? If so where can I find it in my release folder?
My test.js contains a function test1() if I call it from my built js it states test1 is not defined. I call that function directly without dojo. I'm assuming that building custom js only works if it is a dojo class using declare?
Final question, I needed to include several dojo files in the build manually such as dojo._firebug.firebug since after my initial build it was still using xhr calls to get those files. After including the files manually I still see xhr calls from dojo to specific resources: dojo/nls/dojo_ROOT and dijit/form/nls/validate.js. Those files are created during the build process and therefore can't be included in the dependencies in the build profile. Anyone any thoughts on this matter since I'm looking to distribute dojo in a single file.
I'm fairly new to the dojo build system and (especially) so perhaps I'm expecting things that the dojo build system isn't designed to do or maybe om going about this the wrong way if so any tips or suggestions are more than welcome.
Cheers!
Test.js:
function test1() {
console.log("test1");
}
Index.php:
<script type="text/javascript" src="js/release/dojo/dojo/dojo.js"></script>
<script type="text/javascript" src="js/release/dojo/test/test.js"></script>
<script type="text/javascript">
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.Form");
dojo.ready(function() {
test1();
});
</script>
I'm using cssOptimize, I was expecting a single css file in which all the used css files were imported. However I can't find such a file. Is this the way dojo compresses it's css or are my expectations wrong? If so where can I find it in my release folder?
When you use cssOptimize, the Dojo build optimizes and flattens CSS files in place. So for example, if you're using Dijit's Claro theme, when you load dijit/themes/claro/claro.css from source, it contains a series of #import statements which in turn load more files. When you load claro.css from a build with cssOptimize, it is one file containing all of the styles previously referenced via those separate files.
My test.js contains a function test1() if I call it from my built js it states test1 is not defined. I call that function directly without dojo. I'm assuming that building custom js only works if it is a dojo class using declare?
Dojo doesn't expect every JS file to be a "class" using declare but it does expect each file to be a module which doesn't implicitly define globals (since globals should be avoided in modules anyway). When the build process encounters a module that it thinks or knows isn't AMD, it assumes it's a legacy Dojo module and wraps it in a boilerplate to convert it to AMD. This boilerplate ends up encapsulating your globals into a function scope, so they are no longer globals.
Given that you're using Dojo 1.7, you should ideally be using the AMD format to define and consume modules. dojotoolkit.org has a tutorial introducing AMD modules, and if you're migrating from Dojo 1.6 or earlier, there's also a tutorial to help you transition.
Final question, I needed to include several dojo files in the build manually such as dojo._firebug.firebug since after my initial build it was still using xhr calls to get those files. After including the files manually I still see xhr calls from dojo to specific resources: dojo/nls/dojo_ROOT and dijit/form/nls/validate.js. Those files are created during the build process and therefore can't be included in the dependencies in the build profile. Anyone any thoughts on this matter since I'm looking to distribute dojo in a single file.
I'm not sure why you're seeing dojo/_firebug/firebug being automatically loaded, but based on what you've said/shown above I would immediately suggest the following:
Convert your modules/code to AMD format
Add async: true to your dojoConfig which will cause the loader to operate in asynchronous mode, which means:
It loads modules through script injection instead of synchronous XHR
It won't unconditionally load all of dojo/_base
Add customBase: true to your dojo/dojo layer which will prevent the build from defaulting to include all of dojo/_base
As for the nls modules, to an extent it's normal to still see NLS files requested, though if your build is configured properly there would ordinarily just be one NLS file per layer and that's it (the fact that you're seeing a separate request for validate leads me to think you haven't covered all of your dependencies). The reason NLS remains separate is because there is one NLS bundle per locale, and it doesn't make sense to build all locales into one layer - that would force people to pay for resources in 20 languages they don't care about.

KendoUi format broken after require.js optimize

I have a Backbone application with multiple KendoUi components e.g. Grid, NumericTextBox. To display this value "12,5 h" in a numericTextBox I use this format:
this.$('.kendoHourInput').kendoNumericTextBox({
format: '#.0 h'
});
For the development Version (not optimized), everything works as expected. For the production Version, after the require.js-optimizer, this format breaks the app:
Uncaught Bad number format specifier: #
The predefined formats like "c2" or "p" works without a problem. Could it be a problem with the kendo.culture('de-DE') I use? I had similar problems with the library globalize.js, which overrides the kendo.culture. Is there a known dependency to another library who could break the optimized-code?
UPDATE
I found the library which caused the error: globalize.js There is a 2nd library with dependencies to globalize.js:
require.js-config
shim: {
...
someLib: {
deps: ['globalize']
}
}
There is a forum entry on the kendo site, with a similar problem. The solution should be to load the kendo library before the globalize library. If I take a look to the script-tags on the index.html, kendo comes before globalize. So, this is not a solution that works for me.
UPDATE
Just use the newer version of globalize.js to get it work. I use version 1.0.0-alpha.3 of globalize.js now and everything works. There is a good how to. Keep in mind that kendo should be loaded after globalize.js. The order changed
For more information, please let me know.
Thanks
Sascha

Categories

Resources