Amber & jquerymobile

79 views
Skip to first unread message

Jupiter Jones

unread,
Oct 21, 2013, 5:49:23 PM10/21/13
to amber...@googlegroups.com
Hi All,

Has anyone had any luck loading Amber and JQuery Mobile?

I'm working on a cordova app and I'd love to build it with Amber.

However, when i include query-mobile.js I get:

TypeError: 'undefined' is not a function (evaluating
'smalltalk.initialize()')

I can load it with amber/deploy but not with amber/devel

I thought that might be ok, but I haven't been able to compile any
stand-alone source with amberc yet, and all the tutorials develop in the
browser. So I've got a popup helios button working so I can develop in the
browser and test in cordova. But then I added jquery mobile :)

I've tried an older version of jquery mobile since I notice amber uses older
versions of jquery and ui, and I've tried forcing newer version of jquery
and ui into Amber... all failed with similar results.

Anyone had any success?

Cheers,

Jupiter

Nicolas Petton

unread,
Oct 21, 2013, 6:41:00 PM10/21/13
to amber...@googlegroups.com
Hi!

I don't see any reason why loading jquery-mobile would fail, I haven't
tried myself though. Can you show us how you load it into the page?

Cheers,
Nico
--
Nicolas Petton
http://nicolas-petton.fr

Jupiter Jones

unread,
Oct 21, 2013, 8:55:56 PM10/21/13
to amber...@googlegroups.com
Hi Nico,

Thanks for the quick reply :)

Here's my index page:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="format-detection" content="telephone=no" />
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />

<title>TestProject</title>

<script type="text/javascript" src="assets/amber/support/amber.js"></script>
<script type="text/javascript" src="assets/amber/support/requirejs/require.min.js"></script>
        <link rel="stylesheet" type="text/css" href="assets/stylesheets/jquery.mobile-1.3.2.min.css" />

<script type="text/javascript">
require.config({ paths: {
   'com_test''src/js',
   'com_test/_source''src/st'
   }});
   require([
'amber/devel',
'com_test/Project-Core'
], function (smalltalk) {
   smalltalk.defaultAmdNamespace = "com_test";
   smalltalk.initialize();
   });
</script>
    </head>
    <body>
<button onclick="require('amber/helpers').popupHelios()">class browser</button>
        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript" src="assets/javascripts/jquery.mobile-1.3.2.min.js"></script>
        <script type="text/javascript">
            app.initialize();
        </script>
    </body>
</html>

Thanks for any advice.

Kind Regards,

Jupiter
--
You received this message because you are subscribed to a topic in the Google Groups "amber-lang" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/amber-lang/BCgH0Ke7xms/unsubscribe.
To unsubscribe from this group and all its topics, send an email to amber-lang+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Nicolas Petton

unread,
Oct 21, 2013, 10:25:32 PM10/21/13
to amber...@googlegroups.com
It may not come from there, but the way you load the jquery-mobile.js
doesn't seem right. As jQuery is loaded through require.js, you should
do the same with jQuery mobile, and make sure that jQuery is loaded
*before*.

You could add it to the requirements in the `require(...)' statement.

Jupiter Jones

unread,
Oct 21, 2013, 11:52:37 PM10/21/13
to amber...@googlegroups.com
Thanks Nico,

I had actually tried that, but had mobile loading before amber, which loads jquery, so that was never going to work :)

An easy fix - thank you.

Cheers,

Jupiter

Herby Vojčík

unread,
Oct 22, 2013, 6:09:31 AM10/22/13
to amber...@googlegroups.com


Jupiter Jones wrote:
> Thanks Nico,
>
> I had actually tried that, but had mobile loading before amber, which loads jquery, so that was never going to work :)
>
> An easy fix - thank you.
>
> Cheers,
>
> Jupiter
> On 22/10/2013, at 12:25 PM, Nicolas Petton<petton....@gmail.com> wrote:
>
>> It may not come from there, but the way you load the jquery-mobile.js
>> doesn't seem right. As jQuery is loaded through require.js, you should
>> do the same with jQuery mobile, and make sure that jQuery is loaded
>> *before*.

To make this bulletproof, you should add a few things to requirejs
config, see below.

>> You could add it to the requirements in the `require(...)' statement.
>>
>> Cheers,
>> Nico
>>
>> Jupiter Jones writes:
>>
>>> Hi Nico,
>>>
>>> Thanks for the quick reply :)
>>>
>>> Here's my index page:
>>>
>>> <!DOCTYPE html>
>>> <html>
>>> <head>
>>> <meta charset="utf-8" />
>>> <meta name="format-detection" content="telephone=no" />
>>> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
>>>
>>> <title>TestProject</title>
>>>
>>> <script type="text/javascript" src="assets/amber/support/amber.js"></script>
>>> <script type="text/javascript" src="assets/amber/support/requirejs/require.min.js"></script>
>>> <link rel="stylesheet" type="text/css" href="assets/stylesheets/jquery.mobile-1.3.2.min.css" />
>>>
>>> <script type="text/javascript">
>>> require.config({ paths: {
>>> 'com_test': 'src/js',
>>> 'com_test/_source': 'src/st'
>>> }});

require.config({ paths: {
'com_test': 'src/js',
'com_test/_source': 'src/st',
'jquery-mobile': 'assets/javascripts/jquery.mobile-1.3.2.min'
}, shim: {
'jquery-mobile': { deps: [ 'jquery' ] }
});

>>> require([
>>> 'amber/devel',
>>> 'com_test/Project-Core'
, 'jquery-mobile'
>>> ], function (smalltalk) {
>>> smalltalk.defaultAmdNamespace = "com_test";
>>> smalltalk.initialize();
>>> });
>>> </script>
>>> </head>
>>> <body>
>>> <button onclick="require('amber/helpers').popupHelios()">class browser</button>
>>> <script type="text/javascript" src="cordova.js"></script>
>>> <script type="text/javascript" src="js/index.js"></script>
>>> <script type="text/javascript" src="assets/javascripts/jquery.mobile-1.3.2.min.js"></script>
>>> <script type="text/javascript">
>>> app.initialize();
>>> </script>
>>> </body>
>>> </html>
>>>
>>> Thanks for any advice.
>>>
>>> Kind Regards,
>>>
>>> Jupiter

Not tested, but you get the idea. Look into amber.js to see how it's
done there, you can also load other .js's and .css's similar way.

Herby

Jupiter Jones

unread,
Oct 22, 2013, 7:48:11 AM10/22/13
to amber...@googlegroups.com
Thanks Herby,

I've sorted this out now. I was stuck between looking at the cordova example on the wiki (which uses the old method of loading), and using require.js.

Nico gave me the slap I needed to fully adopt amd (and actually read it's documentation) and it's all looking good now.

But just a quick question - is there a compatibility reason that Amber is using jquery 1.8 rather than 1.9, 10 or maybe even 2? Or is it just that it works nicely so why update?

Cheers,

Jupiter

Nicolas Petton

unread,
Oct 22, 2013, 11:32:09 AM10/22/13
to amber...@googlegroups.com
No, there is no reason. We should update at some point :)

Nico

Herby Vojčík

unread,
Oct 22, 2013, 12:04:39 PM10/22/13
to amber...@googlegroups.com


Nicolas Petton wrote:
> No, there is no reason. We should update at some point :)

Well, when 1.9 came out, I looked at change log and it seemed there
there are big changes, so as for me, I deliberately kept 1.8.x out of
fear of possible issues.

But hopefully it will not be as much painful when time comes to upgrade.

Herby

Jupiter Jones

unread,
Oct 22, 2013, 6:07:52 PM10/22/13
to amber...@googlegroups.com
Hi Again,

Still getting my head around Amber - so far I love it.

I've come across something I can't find an example of in the documentation and would appreciate some help. I've a button that has been in html while I'm getting started:

<button onclick="require('amber/helpers').popupHelios()">class browser</button>

I would now like to move to amber and display only when it's running on the desktop. 

renderDeveloperToolsOn: html
self isDesktop ifTrue: [
html button
onClick: [ <require('amber/helpers').popupHelios()> ];
with: 'Dev Tools'
]

How would I go about rendering this snippet of javascript?

I thought the st equivalent would be something like:

(document require: 'amber/helpers') popupHelios

but it doesn't render in the browser so I think I'm just missing a basic understanding.

Thanks for any advice.

Cheers,

Jupiter

Herby Vojčík

unread,
Oct 22, 2013, 7:50:42 PM10/22/13
to amber...@googlegroups.com


Jupiter Jones wrote:
> Hi Again,
>
> Still getting my head around Amber - so far I love it.
>
> I've come across something I can't find an example of in the
> documentation and would appreciate some help. I've a button that has
> been in html while I'm getting started:
>
> <button onclick="require('amber/helpers').popupHelios()">class
> browser</button>
>
> I would now like to move to amber and display only when it's running
> on the desktop.
>
> renderDeveloperToolsOn: html
> self isDesktop ifTrue: [
> html button
> onClick: [ <require('amber/helpers').popupHelios()> ];
> with: 'Dev Tools'
> ]
>
> How would I go about rendering this snippet of javascript?
>
> I thought the st equivalent would be something like:
>
> (document require: 'amber/helpers') popupHelios

(require value: 'amber/helpers') popupHelios

(another possibility is "(window require: 'amber/helpers') popupHelios" but using 'window' is seen as worse style, the former is generic use of global 'require')

Jupiter Jones

unread,
Oct 22, 2013, 10:34:18 PM10/22/13
to amber...@googlegroups.com
Thanks Herby - works like a dream :)

Jupiter Jones

unread,
Oct 23, 2013, 4:57:25 AM10/23/13
to amber...@googlegroups.com
Hi Again,

Sorry for all the basic questions - I'm just having too much fun to stop :)

I'm playing with PouchDB in an effort to get local device storage that can also potentially play with http://www.smalltalkhub.com/#!/~jmari/SCouchDBViewServer

The API says...

create a DB with: PouchDB("dbName")
I learnt that one from your answer to my last question.
PouchDB value: 'dbName'

destroy a DB with: PouchDB.destroy("dbName")
hmmm :)

Since PouchDB is a function (BlockClosure) it clearly won't respond to destroy. I've looked at BlockClosure but haven't seen the light.

Thanks again in advance for your help.

Regards,

Jupiter

Herby Vojčík

unread,
Oct 23, 2013, 7:22:25 AM10/23/13
to amber...@googlegroups.com
This is the ugly part. ST to JS is trying to guess (call the functions, get/set the non-functions), and only for JS objects that are not already wrapped (and functions are, by BlockClosure).

I see two ugly solutions and don't know which one to prefer:

"Make it 'JS object' by hand"
(JSObjectProxy on: PouchDB) destroy: 'dbName'
"Get to the property using low-level a
ccess"
(PouchDB basicAt: 'destroy') value: 'dbName'

I feel slightly more inclined to first one, maybe there could even be 'asJSObject' added which would do ^JSObjectProxy on: self except JSObjectProxy itself which would do ^self. But I am not even 100% sure it works (try it), the latter works, but is plain ugly (if I am forced to do this, I'd rather create dedicated method for it, like

pouchDestroy: aString
<return PouchDB.destroy(aString)>

in appopriate place and call it.

Jupiter Jones

unread,
Oct 23, 2013, 6:25:25 PM10/23/13
to amber...@googlegroups.com
Hi Herby,

Again thanks. I really appreciate the help - i'm prototyping a really simple app for a project I'm working on, and your and Nico's timely answers is making it possible to give our client confidence in smalltalk - which they are also considering for other in-house systems.

Is it appropriate to subclass JSObjectProxy to wrap something like this? It doesn't appear to have any subclasses now.

Maybe an even uglier "solution" - a dnu in BlockClosure that forwards to a created JSProxyObject. It's looks nice in code sending messages to functions - just an ugly patch causing possibly weird side effects.

I was wondering why:

(JSObjectProxy on: PouchDB) at: 'destroy'
… returns the function 'destroy' ie. another BlockClosure

but

(JSObjectProxy on: PouchDB) destroy
…raises JavaScriptException?

The pattern used for most of the PouchDB calls is: 
PouchDB.destroy('dbname', function(err, info) { });

How do I get a handle on the err and info if this in inline javascript? 

In smalltalk I tried:
((JSObjectProxy on: PouchDB) at: 'destroy') value: 'dbName' value: [ :err :result | { err. result } ]
…which returns nil

Thanks again.

Cheers,

Jupiter

Herby Vojčík

unread,
Oct 24, 2013, 6:18:05 AM10/24/13
to amber...@googlegroups.com


Jupiter Jones wrote:
> Hi Herby,
>
> Again thanks. I really appreciate the help - i'm prototyping a really
> simple app for a project I'm working on, and your and Nico's timely
> answers is making it possible to give our client confidence in
> smalltalk - which they are also considering for other in-house systems.
>
> Is it appropriate to subclass JSObjectProxy to wrap something like
> this? It doesn't appear to have any subclasses now.
>
> Maybe an even uglier "solution" - a dnu in BlockClosure that forwards
> to a created JSProxyObject. It's looks nice in code sending messages
> to functions - just an ugly patch causing possibly weird side effects.
>
> I was wondering why:
>
> (JSObjectProxy on: PouchDB) at: 'destroy'
> … returns the function 'destroy' ie. another BlockClosure
>
> but
>
> (JSObjectProxy on: PouchDB) destroy
> …raises JavaScriptException?

Because it calls it. As i wrote already, JSObjectProxy makes a guess when transforming message into JS actio
n; in case unary message represents a function, it calls it directly with no args, if it's non functions, it reads it. Of course, at: will always read the value.

It is similar with keyword messages: first keyword sans colon is used to find a property and if it is a function, it is called with all params, if it is not, first param is assigned to a property (again, at:put: always assigns).

> The pattern used for most of the PouchDB calls is:
> PouchDB.destroy('dbname', function(err, info) { });
>
> How do I get a handle on the err and info if this in inline javascript?
>
> In smalltalk I tried:
> ((JSObjectProxy on: PouchDB) at: 'destroy') value: 'dbName' value: [
> :err :result | { err. result } ]

That said, you can call it directly without ugly at: using

(JSObjectProxy on: PouchDB) destroy: 'dbName' thenDo: [
:err :result | ... ]

> …which returns nil

As for '[ :err :result | { err, result } ]', what did you expect? It is typical JS async pattern - what destroy retu
rn does not matter at all, the callback will be called _eventually_ _later_ (and you must fill it with appropriate code that react to either error or sucess (it's when error isNil, then result is interesting)).

Darius Clarke

unread,
Oct 24, 2013, 11:09:07 AM10/24/13
to amber...@googlegroups.com

Could (JSObjectProxy on: PouchDB) also be saved to a variable and used later?

- Darius 

Herby Vojčík

unread,
Oct 24, 2013, 11:23:10 AM10/24/13
to amber...@googlegroups.com


Darius Clarke wrote:
>
> Could (JSObjectProxy on: PouchDB) also be saved to a variable and
> used later?

It remembers the value so unless it changes over time (which is unlikely) there is no problem with that.

> - Darius

Herby
Reply all
Reply to author
Forward
0 new messages