So I want to use requirejs, kendo ui and knockout JS together.
I read Using Kendo with RequireJS and the Knockout JS article Asynchronous Module Definition (AMD) With RequireJs and then I found the Knockout-Kendo library via Knockout.js and Kendo UI - a Potent Duo and I thought to myself - this is awesome - I'm about to be in a beautiful world of rainbows, MVVM, AMD and HTML5 lusciousness.
But now it seems more like I'm in a dark underground world of pain and suffering. Here's the deal...
I have a simple web site that has a js folder that has the following inside:
jquery-2.0.3.min.js
knockout-2.3.0.js
knockout-kendo.min.js
require.js
kendo-ui/** all the kendo files under here
and an index.html file that I have put in the root containing this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script type="text/javascript" src="js/require.js"></script>
</head>
<body>
<div id="grid" data-bind="kendoGrid: items"> </div>
<script type="text/javascript">
require.config({
baseUrl : 'js',
paths: {
'jquery': 'jquery-2.0.3.min',
'knockout': 'knockout-2.3.0',
'kendo': 'kendo-ui',
'knockout-kendo': 'knockout-kendo.min',
},
shim: {
'jquery': {
exports: 'jQuery'
}
}
});
define('mainViewModel', ['knockout'], function (ko) {
return function mainViewModel(){
this.items = ko.observableArray([
{ id: "1", name: "apple"},
{ id: "2", name: "orange"},
{ id: "3", name: "banana"}
]);
};
});
require(['jquery','knockout','mainViewModel','knockout-kendo'],
function($, ko, mainViewModel) {
ko.applyBindings(new mainViewModel());
});
</script>
</body>
</html>
As far as I can fathom, that should be basically correct but I am getting this exception:
GET http://localhost/ko-kendo/js/kendo-ui.js [HTTP/1.1404 Not Found 1ms]
Error: Script error for: kendo
http://requirejs.org/docs/errors.html#scripterror #http://localhost/ko-kendo/js/require.js:163
Seems that knockout-kendo is trying to load up kendo-ui.js but it, unsurprisingly since it doesn't exist, can't find it.
In an attempt to verify the mappings I knocked up this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script type="text/javascript" src="js/require.js"></script>
</head>
<body>
<div id="grid" data-bind="kendoGrid: items"> </div>
<script type="text/javascript">
require.config({
baseUrl : 'js',
paths: {
'jquery': 'jquery-2.0.3.min',
'knockout': 'knockout-2.3.0',
'kendo': 'kendo-ui',
'knockout-kendo': 'knockout-kendo.min',
},
shim: {
'jquery': {
exports: 'jQuery'
}
}
});
define('mainViewModel', ['knockout'], function (ko) {
return function mainViewModel(){
this.items = ko.observableArray([
{ id: "1", name: "apple"},
{ id: "2", name: "orange"},
{ id: "3", name: "banana"}
]);
};
});
require(['jquery','knockout','mainViewModel','kendo/kendo.grid.min'],
function($, ko, mainViewModel) {
var vm = new mainViewModel();
$(document).ready(function () {
$('#grid').kendoGrid({
dataSource: new mainViewModel().items()
});
});
ko.applyBindings(vm);
});
</script>
</body>
</html>
That worked fabulously (well, it worked) - you can see that the difference between the two is that in the second case I am not using knockout-kendo and therefore, the binding does not apply, which is why I do that kendoGrid thing in the document ready function.
So, does anyone know how on this green and beautiful earth I can get knockout-kendo working with require JS? I feel like there might be something fancy with a shim that would get it going but I can't work it out...
Knockout-Kendo is set to depend on a kendo module. The easiest thing to do is point kendo at the kendo.web file like: kendo: kendo.web.min (in whatever directory kendo.web.min.js is in).
Related
I'm trying to get the MiradorImageTools plugin to work with mirador image viewer.
I'm using a very basic html page to test:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mirador-Test</title>
</head>
<body>
<h1>Title</h1>
<div>
<p>blah</p>
<div id="my-mirador" />
<script src="https://unpkg.com/mirador#latest/dist/mirador.min.js"></script>
<script src="https://unpkg.com/mirador-image-tools#0.10.0/umd/mirador-image-tools.min.js"></script>
<script type="text/javascript">
const config = {
"id": "my-mirador",
"manifests": {
"https://iiif.lib.harvard.edu/manifests/drs:48309543": {
"provider": "Harvard University"
}
},
"windows": [
{
"imageToolsEnabled": "true",
"manifestId": "https://iiif.lib.harvard.edu/manifests/drs:48309543",
}
]
};
// var mirador = Mirador.viewer(config);
var mirador = Mirador.viewer(config, [MiradorImageTools]); // <-- Error!
</script>
</div>
</body>
</html>
This gives me the following error:
Uncaught ReferenceError: MiradorImageTools is not defined
<anonymous> ./test3.html:36
test3.html:36:45
If I leave the plugin out, replacing the problematic line with the commented-out line above it, the whole thing works and I get mirador showing as it should.
So clearly I'm referencing the plugin wrong. But what would be the right way to do it?
To use MiradorImageTools, and any other Mirador plugin (as of v3.0.0), you will need to import the packages and create a build of the project using a tool like Webpack or parcel.
An example of this type of setup can be seen here: https://github.com/projectmirador/mirador-integration that includes examples using both Webpack and parcel.
./src/index.js
import Mirador from 'mirador/dist/es/src/index';
import { miradorImageToolsPlugin } from 'mirador-image-tools';
const config = {
id: 'demo',
windows: [{
imageToolsEnabled: true,
imageToolsOpen: true,
manifestId: 'https://purl.stanford.edu/sn904cj3429/iiif/manifest',
}],
theme: {
palette: {
primary: {
main: '#1967d2',
},
},
},
};
Mirador.viewer(config, [
...miradorImageToolsPlugin,
]);
See the README there for more information about how to build for the specific tools.
I am trying to access a simple javascript variable / object I defined in an external file. My question is how to load it by dojo. Here is my plunker code that didn't work:
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Tutorial: Hello Dojo!</title>
</head>
<body>
<!-- load Dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"
data-dojo-config="async: true"></script>
<script type="text/javascript">
require({
packages: [
{
name: 'myApp',
location: window.location.href.replace(/\/$/, "")
}]},
["dojo/dom", "myApp/config", "dojo/domReady!"], function(dom, config) {
console.log(config.keys);
});
</script>
</body>
</html>
config.js
var keys = {
"key_1": {
"your_name": "jimmy",
"your_msg": "hello world"
},
"key_2": {
"your_name": "billy",
"your_msg": "foo equals bar"
}
};
As you can see I tried to load the config.js file as config, and tried to access it as config in my code. I am getting undefined in the console.
I did some research and what I need to use looks like the dojo's define function so that config.js looks like this:
define({
keys : {
"key_1": {
"your_name": "jimmy",
"your_msg": "hello world"
},
"key_2": {
"your_name": "billy",
"your_msg": "foo equals bar"
}
}
})
You should define a module for your configuration file.
This can be achieved using the define passing as argument your object.
Basic example:
define({ yourProperty: yourValue});
More information can be found here: https://dojotoolkit.org/documentation/tutorials/1.10/modules/
I'm trying to build a WebSite but i'm running into some porblems when it comes down to use 2 versions of jquery qith the bootstrap system (also with bootstrap validator).
First of all, i do already know there is a lot of questions in here about 2 versions of jquery, but i spent the last 2 days reading and trying to make this work, but i just can't!
This is why i'm here.
So, in my head tag i had set up the 2 versions i need to run.
1- is to make the bootstrap scripts work, like the dropdown menu and the form validation.
2- is to run the magnific popup script.
This is my head code so far:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="validator/vendor/jquery/jquery-1.10.2.min.js"></script>
the part of the script i'm trying to use with the noConflict () but i had no success.
This is what i did.
*the script i need to change the version of the jquery is for the magnificpopup
<script>
jq1111 = jQuery.noConflict(true);
</script>
<script type="text/javascript">
jq1111(document).ready(function() {
jq1111('.zoom-gallery').magnificPopup({
delegate: 'a',
type: 'image',
closeOnContentClick: false,
closeBtnInside: false,
mainClass: 'mfp-with-zoom mfp-img-mobile',
image: {
verticalFit: true,
titleSrc: function(item) {}
},
gallery: {
enabled: true
},
zoom: {
enabled: true,
duration: 500, // don't foget to change the duration also in CSS
opener: function(element) {
return element.find('img');
}
}
});
});
</script>
Can anyone please help me? Because i'm out of ideas and i'm not that advanced in jquery, of course.
Thanks!
You need to run the jQuery.noConflict between the 2 script tags that include jQuery, including the one for magnificPopup and magnificPopup first:
<script src="jquery-1.11.1.min.js"></script>
<script src="magnific-popup.min.js"></script>
<script type="text/javascript">
var j1111 = jQuery.noConflict() ;
</script>
<script type="text/javascript" src="jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="bootstrap.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
j1111.magnificPopup(/* ... */) ;
});
</script>
Use require.js and make whatever module dependant of the necessary jQuery version. For example :
require.config({
enforceDefine: true,
baseUrl: '/js',
shim: {
'jquery#1.11.1': {
exports: '$'
},
'jquery#2.1.1': {
exports: '$'
},
'bootstrap#3.1.1': {
deps: [ 'jquery' ], // use jQuery 2.1.1 !
exports: '$' // need to export something.... so... export jQuery!
},
'magnific': {
deps: [ 'jquery#1.11.1' ],
exports: '$.fn.magnificPopup'
}
},
paths: {
'jquery#1.11.1': 'http://code.jquery.com/jquery-1.11.1.min', // or a CDN...
'jquery#2.1.1': 'lib/jquery.min', // local copy!,
'bootstrap#3.1.1': 'lib/bootstrap.min', // local copy!
'magnific': 'http://dimsemenov.com/plugins/magnific-popup/dist/jquery.magnific-popup.min'
},
map: {
'*': {
'jquery': 'jquery#2.1.1',
'bootstrap': 'bootstrap#3.1.1'
}
}
});
Then, simply require your jQuery library
require(['jquery', 'jquery#1.11.1', 'jquery#2.1.1', 'magnific'], function ($, $1, $2) {
console.log($.fn.jquery, $.fn.magnificPopup);
console.log($1.fn.jquery, $1.fn.magnificPopup);
console.log($2.fn.jquery, $2.fn.magnificPopup);
});
Which, of course, will result in the correct output
2.1.1 undefined
1.11.1 function (n){_();var i=e(this);if("string"==typeof n)if("open"===n){var o,r=b?i.data("magnificPopup"):i[0].magnificPopup,a=parseInt(arguments[1],10)||0;r.items?o=r.items[a]:(o=i,r.delegate&&(o=o.find(r.delegate)),o=o.eq(a)),t._openClick({mfpEl:o},i,r)}else t.isOpen&&t[n].apply(t,Array.prototype.slice.call(arguments,1));else n=e.extend(!0,{},n),b?i.data("magnificPopup",n):i[0].magnificPopup=n,t.addGroup(i,n);return i}
2.1.1 undefined
I need to display an instance of a javascript class that's loaded with data from .json file with using require.js in backbone.
I have the following js and json files:
collections/Companies.js
define([
'models/Company'
], function(CompanyModel) {
'use strict';
var CompanyCollection = Backbone.Collection.extend({
model: CompanyModel
});
return CompanyCollection;
});
data/companies.json
[{
"id": 1000001,
"name": "Test Company 1",
"description": "this is a test company that should be displayed"
},
{
"id": 1000002,
"name": "Test Company 2",
"description": "this is another test company that should be displayed as well"
}]
Also, I have the following code snippet:
<script type="text/javascript" data-main="data/companies.json" src="collections/Companies.js"></script>
<script type="text/javascript">
require(["collections/Companies"],
function(Companies){
$("#json").append(Companies[0].id);
alert("test");
}
);
</script>
<div id="json"></div>
Of course it is not working as I intended and I can't figure out the correct syntax and/or iteration logic.
How can I load the .js class with the data from the .json file?
My <script type="text/javascript" data-main... line doesn't seem to work.
Thanks in advance and sorry if I'm not clear enough.
requirejs is usually used to load scripts and template files but you can use it to load a .json file as well. but you have to parse it yourself using JSON.parse.
You have 2 different options,
using requirejs text plugin, like:
require(["collections/Companies", "text!data/companies.json"],
function(Companies, CompaniesJSONStr) {
var CompaniesJSON = JSON.parse(CompaniesJSONStr);
}
);
or using requirejs plugins, which it again uses text! plugin:
require.config({
paths : {
json: 'data'
}
});
define([ 'collections/Companies', 'json!companies.json' ],
function(Companies, CompaniesJSON){
}
);
I'm working through the example at http://dojotoolkit.org/documentation/tutorials/1.7/hello_dojo/demo/module.html and I've created a directory structure as follows
w:/djt2/index.html
w:/djt2/js/mymodule.js (exact copy of http://dojotoolkit.org/documentation/tutorials/1.7/hello_dojo/demo/myModule.js)
I then set the Tinyweb web-server to serve localhost from w:/djt2
I've changed index.html a tiny bit, to adjust for putting mymodule.js inside the js subdirectory (I've removed comments too below):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Tutorial: Hello Dojo!</title>
<script>
var dojoConfig = {
async: true,
packages: [{
name: "djt2",
location: '/js' /* Location #1 */
}]
};
</script>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.7.2/dojo/dojo.js"></script>
</head>
<body>
<h1 id="greeting">Hello</h1>
<script>
require(["djt2/mymodule"], function(myModule){ /* Location #2 */
myModule.setText("greeting", "Hello Dojo!");
setTimeout(function(){
myModule.restoreText("greeting");
}, 3000);
});
</script>
</body>
</html>
This works, but I'm not entirely sure I understand why... In particular, at Location #1, the original had location.pathname.replace(/\/[^/]+$/, '') which evaluates to the empty string and makes the loader look for mymodule.js at the CDN location (I also tried to set location to "/", but that made it search at http://mymodule.js/).
At Location #2 it is a little mystical that the prefix should be djt2/...
If someone could explain it, or direct me to the documentation (I'm a bit overwhelmed with learning a new framework :-).
Add an extra djt2 directory in your structure
w:/djt2/js/djt2/mymodule.js
Set the baseUrl in the configuration.
var dojoConfig = {
async: true,
baseUrl: '/js'
packages: [{
name: "djt2",
location: 'djt2'
}]
};
Setting the baseUrl will tell dojo where to look for custom modules. The location that is part of the package is relative to the baseUrl.
I always think of modules/packages as namesapces. To extend your example with an additional package, it would look like the following:
w:/djt2/js/another/anotherModule.js
var dojoConfig = {
async: true,
baseUrl: '/js'
packages: [{
name: "djt2",
location: 'djt2'
}, {
name: "another",
location: 'another'
}]
};