1
votes

I am trying to use a Kendo UI Splitter widget in an Aurelia JS project, which is started through aurelia-cli (the au program).

To have a reproducible example, I have added a bash script below, which uses au to start a new project (since au new is interactive only, and has no options that would be useful to specify in batch mode, I had to use expect in the script to automate it), then add the relevant source files, finally building and exporting it. Here are my problems:

  • Regardless of what I do, the horizontal split has its height set to 300px; I would like to set its height as percentage of parent - how can I do this?
  • When I "export" a "production" "bundled" site, it cannot load - it fails; it only works through au run on http://localhost:9000. How can I "export" a proper "bundled" site?

About the size/height issue - this is what I get when I view the index.html via au run/localhost:9000:

aur-ff.png

Note that the height setting I've used on my CSS class for the left pane div element, are overwritten by the Kendo framework which explicitly writes in height into an inline style attribute of the element. Related to this, I've found http://docs.telerik.com/kendo-ui/controls/layout/splitter/how-to/expand-splitter-to-100-height and Kendo UI Splitter height, which suggest JavaScript might be needed to do this - but I'm not sure how to apply it in an Aurelia JS context.

About the bundling issue: I've found this documentation (btw, is it possible to refer to a specific framework version in the aurelia hub URL?):

http://aurelia.io/hub.html#/doc/article/aurelia/framework/latest/the-aurelia-cli/4

Aurelia CLI apps always run in bundled mode, even during development. To build your app, simply run au build. ...
By default, the Aurelia CLI creates two bundles, an app-bundle.js, and a vendor-bundle.js.

The way I've understood this, is that every needed dependency in node_modules gets "compiled in" in the two .js files in the scripts/ subfolder of the app. So, in order to "export" a "production" site (given that the au cli has no commands to do this) one can just copy the project folder without its node_modules subfolder, and then simply view index.html from the copy in a browser - and all should work. In fact, this did work for me, until I tried using the Kendo UI components.

The script below basically creates the project in /tmp/testsplit, builds it with au build, copies the project folder without node_modules/ to /tmp/testsplit-export and then runs au run --watch in the original project folder. When I view http://localhost:9000/ or file:///tmp/testsplit/index.html, all is well - but when I view file:///tmp/testsplit-export/index.html, nothing is rendered, and Firefox console log tells me:

...
DEBUG [templating] importing resources for mainpage.html <unavailable>  vendor-bundle.js:13938
ERROR [app-router] <unavailable>  vendor-bundle.js:13968
ERROR [app-router] Router navigation failed, and no previous location or fallbackRoute could be restored.  vendor-bundle.js:13968

My versions are:

$ node --version
v4.2.6
$ npm --version
2.14.12
$ npm show aurelia-framework version
1.0.8
$ npm show aurelia-cli version
0.23.0

Here is the bash script:

#!/usr/bin/env bash
# uses `expect` and `rsync`: sudo apt-get install expect rsync
set -x
cd /tmp

REINSTALL=true # comment this var assignment to not recreate the project

if [ "$REINSTALL" == "true" ] ; then
  rm -rf /tmp/testsplit
  # npm install aurelia-cli -g # so we have `au` command
  # `au new` also creates new dir
  # note `au new --here` asks different questions!
  # wout --here: 1. Default ESNext (Default)
  # with --here: 1. Yes (Default) Would you like to create this project?
  #~ echo -r "1\r1\r" | au new testsplit # NOWORK, must use `expect`

  expect -c '
    set timeout -1
    proc abort {} {
      puts "Timeout or EOF\n"
      exit 1
    }
    spawn au new testsplit
    expect {
      "\\\[Default ESNext\\\]>"        { send "1\r" ; }
      default          abort
    }
    expect {
      "\\\[Yes\\\]>"          { send "1\r";  }
      default          abort
    }
    # note: the next q is the "Would you like to install the project dependencies?"
    # it downloads into node_modules (182MB), and may take a while
    expect {
      "\\\[Yes\\\]>"          { send "1\r";  }
      default          abort
    }
    expect eof
    catch wait result
    puts "Finished OK\n"
  '
fi

cd /tmp/testsplit

if [ "$REINSTALL" == "true" ] ; then
  npm install jquery kendo-ui-core aurelia-kendoui-bridge --save
fi

{ set +x ; } 2>/dev/null
function setfilename { FILENAME="$1"; echo $FILENAME; }

if [ "$REINSTALL" == "true" ] ; then
echo "    Patching files:"
export LOOKFOR="" REPLACER=""

setfilename "aurelia_project/aurelia.json" ;
IFS='' read -r -d '' REPLACER <<'EOF'
          "jquery",
          {
            "name": "kendo-ui-core",
            "path": "../node_modules/kendo-ui-core/js/",
            "main": "kendo.ui.core"
          },
          {
            "name": "aurelia-kendoui-bridge",
            "path": "../node_modules/aurelia-kendoui-bridge/dist/amd",
            "main": "index"
          },
EOF
IFS='' read -r -d '' LOOKFOR <<'EOF'
          "aurelia-templating-binding",
EOF
perl -pi -e 's/($ENV{"LOOKFOR"})/$1$ENV{"REPLACER"}/' "$FILENAME"

setfilename "src/main.js" ;
IFS='' read -r -d '' LOOKFOR <<'EOF'
    .feature('resources');
EOF
IFS='' read -r -d '' REPLACER <<'EOF'
    .feature('resources')
    // .plugin('aurelia-kendoui-bridge', kendo => kendo.core());
    .plugin('aurelia-kendoui-bridge');
EOF
perl -pi -e 's/(\Q$ENV{"LOOKFOR"}\E)/$ENV{"REPLACER"}/' "$FILENAME"
fi

echo "    Adding files:"

setfilename "src/app.html" ; cat > "$FILENAME" << 'EOF'
<template>
  <div>Test App</div>

  <div id="container">
    <router-view></router-view>
  </div>
</template>
EOF

setfilename "src/app.js" ; cat > "$FILENAME" << 'EOF'
export class App {
  configureRouter(config, router){
    config.title = 'Test App Title';
    config.map([
      { route: ['','mainpage'], name: 'mainpage', moduleId: './mainpage', nav: true, title:'Main Page' },
    ]);

    this.router = router;
  }
}
EOF

setfilename "src/mainpage.html" ; cat > "$FILENAME" << 'EOF'
<template>
  <require from="./mainpage.css"></require>
  <require from="aurelia-kendoui-bridge/splitter/splitter"></require>
  <!-- these two css must be present, else the drag handles are styled/positioned wrong! -->
  <require from="../node_modules/kendo-ui-core/css/web/kendo.common.core.min.css"></require>
  <require from="../node_modules/kendo-ui-core/css/web/kendo.default.min.css"></require>

  <div>( see also: http://aurelia-ui-toolkits.github.io/demo-kendo/#/samples/splitter-basic-use )</div>
  <div class="splitpane-holder" ak-splitter="k-orientation: horizontal;">
    <div class="pane-left"></div>
    <div class="pane-right"></div>
  </div>
</template>
EOF

setfilename "src/mainpage.js" ; cat > "$FILENAME" << 'EOF'
import * as $ from 'jquery';

//// both of these names seem to work the same:
// import {Splitter} from 'kendo-ui-core';
import {kendoSplitter} from 'kendo-ui-core';

export class Mainpage {

}
EOF

setfilename "src/mainpage.css" ; cat > "$FILENAME" << 'EOF'
html, body {
  height:100%;
  margin:0;
  padding:0;
  overflow:hidden;
}
.splitpane-holder {
  height: calc(100% - 6em);
  width: calc(100% - 2em);
  position: relative;
}
.pane-left, .pane-right { height: 100%; }
.pane-left { background-color: #AAA; }
.pane-right { background-color: #888; }
EOF

au build
rm -rf /tmp/testsplit-export
# add /. at end of source folder in rsync so hidden files are copied, else source will be copied as a folder inside destination
rsync -av /tmp/testsplit/. /tmp/testsplit-export --exclude node_modules
echo -e "Exported /tmp/testsplit-export/index.html\n"

au run --watch
2

2 Answers

1
votes

This code works in all browsers, substitute 'splitpane-holder' for 'horizontal'?

<div id="horizontal"  role="horizontal" style="height: 100%;">

....

<style>
html, 
body {height:100%; padding:0; margin:0;}
body {display:flex; flex-direction:column;}
#horizontal {flex-grow:1;}
0
votes

Ok, I still haven't solved the styling (height in %) issue, so I still hope someone can help me with that; however, I think I may have solved the bundling issue. The trick seems to be:

  • Add the required .css files as resources in the vendor bundle in aurelia.json
  • Use an additional import statement for the aurelia-kendoui-bridge version of the component in mainpage.js

I found about the adding resources from an example for including nprogress from How to import packages within my Aurelia application ; and I got the import trick from here (via improve webpack kendo-core config · Issue #588 · aurelia-ui-toolkits/aurelia-kendoui-bridge · GitHub):

https://gitter.im/adriatic/Aurelia-KendoUI?at=57a0fdf50bd017c16e36424e

@len-ro my experience with aurelia-cli is very limited, but it may be tracing the imports of your javascript files to see which files to include in the bundle. since it doesn't pick up tags, just import tags, you could try to use import 'aurelia-kendoui-bridge/dropdownlist/dropdownlist'; instead and see if that changes anything

So the relevant changed parts in the OP bash script are:

...
setfilename "aurelia_project/aurelia.json" ;
IFS='' read -r -d '' REPLACER <<'EOF'
          "jquery",
          {
            "name": "kendo-ui-core",
            "path": "../node_modules/kendo-ui-core",
            "main": "js/kendo.ui.core",
            "resources": [
              "css/web/kendo.common.core.min.css",
              "css/web/kendo.default.min.css"
            ]
          },
          {
            "name": "aurelia-kendoui-bridge",
            "path": "../node_modules/aurelia-kendoui-bridge/dist/amd",
            "main": "index"
          },
EOF
...
setfilename "src/main.js" ;
IFS='' read -r -d '' LOOKFOR <<'EOF'
    .feature('resources');
EOF
IFS='' read -r -d '' REPLACER <<'EOF'
    .feature('resources')
    // .plugin('aurelia-kendoui-bridge', kendo => kendo.core()); // nope, this imports extra wrappers! Can also do kendo => kendo.core().kendoSplitter() ...
    .plugin('aurelia-kendoui-bridge');
EOF
...
setfilename "src/mainpage.html" ; cat > "$FILENAME" << 'EOF'
<template>
  <require from="./mainpage.css"></require>
  <require from="aurelia-kendoui-bridge/splitter/splitter"></require>
  <!-- these two css must be present, else the drag handles are styled/positioned wrong! -->
  <require from="kendo-ui-core/css/web/kendo.common.core.min.css"></require>
  <require from="kendo-ui-core/css/web/kendo.default.min.css"></require>

  <div>( see also: http://aurelia-ui-toolkits.github.io/demo-kendo/#/samples/splitter-basic-use )</div>
  <div class="splitpane-holder" ak-splitter="k-orientation: horizontal;">
    <div class="pane-left"></div>
    <div class="pane-right"></div>
  </div>
</template>
EOF

setfilename "src/mainpage.js" ; cat > "$FILENAME" << 'EOF'
import * as $ from 'jquery';

//// either of these names seem to work the same:
// import 'kendo-ui-core/js/kendo.splitter';
// import {Splitter} from 'kendo-ui-core';
import {kendoSplitter} from 'kendo-ui-core';

import 'aurelia-kendoui-bridge/splitter/splitter';

export class Mainpage {

}
EOF
...

Now, I can load the file:///tmp/testsplit-export/index.html and it works the same as the localhost:9000 version; meaning that the understanding of export as a copy of the project folder without node_modules seems sound enough.

Btw, note that also .css files are bundled inside scripts/vendor-bundle.js:

$ grep -Eao '.{34}.kendo.common.core.min.css.{12}.' testsplit/scripts/vendor-bundle.js 
define('text!kendo-ui-core/css/web/kendo.common.core.min.css', ['module']
atey(-100%)}\n/*# sourceMappingURL=kendo.common.core.min.css.map */\n"; }