Having first read this http://www.danyow.net/jquery-ui-datepicker-with-aurelia/ and with inspiration from https://gist.github.com/charlespockert/6a1fef3f546f6d37d1dc here follows my attempt to implement the https://github.com/eternicode/bootstrap-datepicker version of bootstrap datepicker:
http://plnkr.co/edit/TkbT6E?p=preview
I'm getting self.datePicker.datepicker is not a function(…) although I've checked that bootstrap-datepicker is correctly installed with jspm and that the .js is loaded. The datepicker does show up (which confirms that the js is loaded correctly), and I can select a date, but the value is not set.
What am I doing wrong here?
Update:
A friendly soul ,#SamDeBlock, in gitter.im/Aurelia put together this http://plnkr.co/edit/hKit8pigwL1ijr2DmbGP?p=preview with the dependencies so it'll run. I keep getting the above error however, when running this in my own application. I'm gonna investigate it problem further and update here, if I get to the bottom of this.
Update 2:
I've now located the problem down to being an issue with system.js/jspm. That's also why the above plunkr works, since it just reference the files directly instead of defining them in config.js.
If I add the file manually like proposed in the above plunkr - AND if I change the following in moment.js file from:
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
global.moment = factory()
}(this, function () { 'use strict';
...
to:
(function (global = typeof window !== "undefined" ? window : this, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
global.moment = factory()
}(this, function () { 'use strict';
...
the global = typeof window !== "undefined" ? window : this part..
THEN it seems to work, with the Aurelia navigation skeleton as well.
But why is this necessary? And how can I get this to work, without all the hacks? I've built my application on the Aurelia Navigation Starter project
https://github.com/aurelia/skeleton-navigation
Chances are that jspm caused this when doing jspm install -y npm:bootstrap-datepickerso check in config.js
Look for this:
"npm:bootstrap-datepicker#1.5.0": {
"fs": "github:jspm/nodelibs-fs#0.1.2",
"jquery": "npm:jquery#2.1.4"
},
And change it to this:
"npm:bootstrap-datepicker#1.5.0": {
"fs": "github:jspm/nodelibs-fs#0.1.2",
"jquery": "github:components/jquery#2.1.4"
},
The important part being: "jquery": "github:components/jquery#2.1.4"
Then everything should work through System.config without the need for the moment.js workaround or anything else.
http://plnkr.co/edit/OeVeiLXwfpTlorDZjBQe?p=preview
Related
I have a keyboard navigation system. When you press ArrowUp or ArrowDown, an event is emitted FROM app.js (best place I found to listen to these keypresses since they need to be system-wide) TO the mounted() in the component.
The Event.$on() INSIDE the mounted() part of the component then calls a function that uses $refs to identify the currently selected item and, when ENTER is pressed, show it's modal.
app.js code (listen to the keypresses):
else if (event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.key === 'Enter') {
event.preventDefault()
switch (this.$router.currentRoute.path) {
case "/pedidos":
Event.$emit('navegarSetasPedidos', event.key)
break;
case "/clientes":
Event.$emit('navegarSetasClientes', event.key)
break;
}
}
mounted() section of the component in question:
mounted() {
Event.$on('navegarSetasPedidos', (key) => {this.navegarSetas(key)})
}
function responsible for the navigation (sorry for bad formating, haven't figured how stackoverflow's codeblock thing works yet):
navegarSetas(key) {
if (this.navegacaoSetasAtiva == false) {
this.navegacaoSetasAtiva = true
this.navegacaoAtual = 0
} else if (this.modalAtivado == false && this.navegacaoSetasAtiva == true) {
if (key == 'ArrowDown' && this.navegacaoAtual < this.pedidos.length - 1) {
this.navegacaoAtual++
let elementoSelecionado = this.$refs['pedido'+this.navegacaoAtual][0].$el
let boundaries = elementoSelecionado.getBoundingClientRect()
if (boundaries.top < 0 || boundaries.top > (window.innerHeight || document.documentElement.clientHeight)){
elementoSelecionado.scrollIntoView({behavior: 'smooth'})
}
} else if (key == 'ArrowUp' && this.navegacaoAtual <= this.pedidos.length && this.navegacaoAtual > 0) {
this.navegacaoAtual--
let elementoSelecionado = this.$refs['pedido'+this.navegacaoAtual][0].$el
let boundaries = elementoSelecionado.getBoundingClientRect()
if (boundaries.top < 0 || boundaries.top > (window.innerHeight || document.documentElement.clientHeight)){
elementoSelecionado.scrollIntoView({behavior: 'smooth'})
}
} else if (key == 'Enter') {
let pedidoSelecionado = this.pedidos[this.navegacaoAtual].id
Event.$emit('changeShow', pedidoSelecionado)
}
}
This works very well the first time it is acessed. The problem is, if I change the current route to show another component and then return to the previous component, I get a lot of "this.$refs['pedido'+this.navegacaoAtual][0].$el is undefined" errors, but the system still works normally, albeit erratically.
The funny thing is: if I console log "this.$refs['pedido'+this.navegacaoAtual][0].$el is undefined", I'll get an EMPTY log before the errors, then ANOTHER one right below it, this time, not empty.
Everywhere else I've searched this says that the problem is due to how Vue re-renders things, and that I'm calling this event BEFORE it's rendered, which shouldn't be possible since I'm calling it inside mounted().
Any help is greatly appreciated, thank you!
Turns out, after a LOT of searching, the Event.$on event setters also work as the normal JavaScript ones (which makes a lot of sense now that I'm thinking about it)—meaning that you have to destroy them whenever your component is unmounted (aka Destroyed).
Even though VUE Dev Tools was picking only one event after the re-route, it was still firing two (seen through console.log() returning one empty value, a bunch of errors, and another value with filled array AFTER the errors).
The solution to this was simply adding Event.$off('eventName') on the destroyed() function of the component.
Like
<template>
<h1 :style={ filter: 'blur(1px)' }>My Template!!</h1>
</template>
I used style and webkit to search source code from node_modules/Vue and node_modules/#Vue, but had no luck.
How Vue knows which prefix should prepend when different browser?? So magic it is!!
https://v2.vuejs.org/v2/guide/class-and-style.html#Auto-prefixing
I suppose I found the answer.
The code is under vue/src/platforms/web/runtime/modules/style.js line 32
const vendorNames = ['Webkit', 'Moz', 'ms']
let emptyStyle
const normalize = cached(function (prop) {
emptyStyle = emptyStyle || document.createElement('div').style
prop = camelize(prop)
if (prop !== 'filter' && (prop in emptyStyle)) {
return prop
}
const capName = prop.charAt(0).toUpperCase() + prop.slice(1)
for (let i = 0; i < vendorNames.length; i++) {
const name = vendorNames[i] + capName
if (name in emptyStyle) {
return name
}
}
})
The emptyStyle here is CSSStyleDeclaration from browser.
Vue will check every attribute with prefix in CSSStyleDeclaration or not.
If yes then will append it and cache it.
However, it looks like the filter attribute is an exception here.
Most of CSS we will write in CSS file then it will be compiled by PostCSS and Autoprefixer. Consider the runtime, the code above I guess is the easiest and smallest way to achieve, yet still have some surprises.
There is a reliable way to check from QML/JavaScript if a component has a signal?
At the moment I found that this code work as intended:
if (myCustomComponent.myCustomSignal)
myCustomComponent.myCustomSignal();
Where myCustomComponent is even as simple as this:
Item {
id: root
signal myCustomSignal()
}
The signal is executed only if myCustomComponent has it but I'm not sure if is the correct way.
No, more reliable way should be to check if component has a signal could be:
if (typeof root.myCustomSignal !== 'undefined' && typeof root.myCustomSignal === 'function') { ... }
or
if (typeof root.myCustomSignal === 'function') { ... }
Using boolean is not realiable. Change your sample target item to:
Item {
id: root
property bool myCustomSignal: true
}
In this case your condition will be true and you will try invoke a property what will lead to crash.
This approach is less error prone and it ensure that signal exists and is invokable/function.
Is there an option to let Elm know which module system you're targeting during compile time? E.g. something like a --target flag. I must admit that I haven't dug into elm-make that much.
Currently it seems that it only occurs during runtime:
elm-make/issues/50
src/Pipeline/Generate.hs
For my situation I'm:
Using Electron which defines it's own module object and a global window.
Only using Elm for a portion of the project (See HTML interop).
By default, the compiled output defaults to exposing Elm on module.exports:
if (typeof define === "function" && define['amd'])
{
define([], function() { return Elm; });
return;
}
if (typeof module === "object")
{
module['exports'] = Elm;
return;
}
var globalElm = this['Elm'];
if (typeof globalElm === "undefined")
{
this['Elm'] = Elm;
return;
}
In debug tools:
Instead, I want it to expose it on this/window and not overwrite module.exports with the Elm object.
I was able to hack together a solution that abuses the AMD check:
<script>
window.define = (arr, fn) => {
const Elm = fn();
window.Elm = Elm;
};
window.define.amd = true;
</script>
<script src="build/tronwm.js"></script>
<script>
const node = document.getElementById('elm-render');
const app = window.Elm.TronWM.embed(node);
</script>
This works for now, but curious of alternate solutions if any.
As of 0.18, no there is not. The Elm compiler does not know about details of JS Loaders etc.
I'm trying to use PhantomJS with a script that's compiled by Babel from ES6 to ES5.
For some of the features, Babel puts in some helper functions at the end of the file (like _asyncToGenerator and _typeof) to evaluate the code.
But in Phantom, there's a function evaluate(function(){…}) which is executed in the browser context, so it doesn't have access to those helper functions babel puts in.
Ex, if I have a code:
var page = require('webpage').create();
page.open(url, function(status) {
var title = page.evaluate(function() {
typeof(document.title);
});
});
It compiles to
var page = require('webpage').create();
page.open(url, function(status) {
var title = page.evaluate(function Executed_in_Browser_Context() {
_typeof(document.title);
});
});
function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; }
Notice the typeof has been changed to _typeof (for some feature involving ES6 Symbols)
Here, the function Executed_in_Browser_Context is executed in browser context, and so it doesn't have access to the function _typeof defined in the file at the bottom. And so it results in error
Can't find variable: _typeof
How to solve this?
I tried copying the _typeof inside Executed_in_Browser_Context (pre-compilation) but then upon compiling, Babel sees that and thinks that it may be some other function that I have in my code, and just renames its own to _typeof2 resulting in same error.