NYCJUG/2011-02-08/HelloWorldInJHS

From J Wiki
Jump to: navigation, search

“Hello, World” in JHS – an Example

The following is an excerpt (lightly edited) from the J Google Group in which Gosi gives an example of how to assemble a basic web page using JHS.

Topic: JHS the easiest web server

Bjorn Helgason < gosinn@gmail.com > Jan 31 12:23AM -0800 ^

What do you need to get things going in JHS? Are we overlooking something trivial? We sometimes get blinded by something we think is trivial and forget to tell others about the initial steps needed.

There have been some discussions about how hard it is to create applications in J7. There is probably less to it than many people think. Here, below, I take a simple application and describe how to get it going.

I want this here line to display in a browser:

'hello world'

And it should be sent from the JHS server.

Once you have seen how simple it is, you can take that one and you can take the demos you see provided with JHS and do the same with them and you are well on your way to creating very advanced applications using J and browsers.

And note that even if we say you do need HTML5 in order to run the new J in browsers, it is only partly true. You can make applications and use J in older browsers too but then the applications are of course simpler so we like to say J7 needs HTML5 because we like to have the options HTML5 makes available.

I wanted to find out what is the minimum I need to do to get an html page from the JHS server. I ended up with a script 7 lines long and it should show anyone that JHS applications can be very easy.

What I do first is create a script and in it I place the info from demos.

------------- from description of demos

 coclass'appname'
 coinsert'jhs'

 HBS=: ... NB. J sentences that produce html body
 CSS=: ... NB. styles
 JS=: ... NB. javascript (event handlers)

 jev_get=: create NB. browser get request

 create=: 3 : 0 NB. create page and send to browser
 ...
 'title'jhr...
---------------- script ends

This sounds pretty easy and, by changing this a tiny bit, then this is what I ended up with

--------- my smallest script

 coclass'test2'
 coinsert'jhs'
 HBS=: 0 : 0
 jhh1 'hello world'
 )
 create=: 3 : '''hello''jhr'''''
    jev_get=: create

------------ script ends

Now there are just a few more things to do. Start the JHS server, which is easy enough, by opening a console and issue the command JHS or click on the JHS start icon.

----------- starting JHS in a console in Windows

 Microsoft Windows [Version 6.0.6002]
 Copyright (c) 2006 Microsoft Corporation. All rights reserved.

 C:\>'''cd \j701\bin'''
 C:\j701\bin>'''jhs'''
 C:\j701\bin>'''rem C:\j701\bin\jconsole ~addons/ide/jhs/core.ijs -js "<<BR>> init_jhs_ 65 001 0 "'''
 C:\j701\bin>"'''C:\j701\bin\jconsole" ~addons/ide/jhs/core.ijs -js "<<BR>> init_jhs_'' "<<BR>> '''
 J HTTP Server - init OK

 Requires a modern browser (later than 2005) with Javascript.

 A : separates ip address from port. Numeric form ip can be faster than name.

 Start a web browser on this machine and enter URL: http://127.0.0.1:65001/jijx

---------------------- end console output

Now the JHS server is up and running and the last line I can just copy to a browser. Then I get an ijx window to execute J sentences and what I need to do a load of my script

 load 'C:/Users/bjorn/j701-user/projects/testjhs/test2.ijs'
I then open a tab in the browser and type in
 http://127.0.0.1:65001/test2

Now I have got a page with a blue J and a hello on the tab and the hello world on the page.

The script creates a locale when loaded and it is easy enough to investigate or change it there

 names_test2_''
 HBS create jev_get
 HBS_test2_
 jhh1 'hello world'
 create_test2_
 3 : '''hello''jhr'''''

I tried creating HBS on one line instead of three:

 HBS=: 0 : 0
 jhh1 'hello world'
 )

Interestingly enough, it is not the same. Even when I added LF at the end it is not the same. I analyzed it with a.i.HBS_test2_ and it gave different results and one worked in the app and the other did not.

Anyway, without the HBS it still worked but then it did not show any text on the page and just the title on the tab and a blank page.

Seven lines in a script is not very much.

I guess many people are missing the rest of the instructions of how to display the page from the server.

If I now want to add some html text into the page then one way of doing it would be to put the html into a noun and put the name of that noun into the HBS something like this

----------- the smallest script with html addition

 coclass'test2'
 coinsert'jhs'
 HBS=: 0 : 0
 jhh1'hello world'
 jhbr
 text
 )
 create=: 3 : '''hello''jhr'''''
 jev_get=: create

 text=: 0 : 0
 <html>

 <head>
 <title>The Magic of J</title>
 </head>

 <body>

 <h2>How to use Browser <font face=monospace>from J</font> ...</h2>
 <p>Labs<br>
 Demos<br>
 Tutorials<br>
 Forums<br>
 Games</p>
 <p>This page is (C) Copyright 2008-2037 Björn Helgason. All rights
 reserved.</p>
 <p>Portions of this program use J Utils -- J software.<br/>
 (C) Copyright ISI :
 <a target=_blank href="http://jsoftware.com/zippy.htm">
 http://jsoftware.com/zippy.htm</a></p>
 <p>Provided AS IS. Guaranteed for demos.</p>

 </body></html>
 )

-------------- script ends

After editing the script I save it and load it in the ijx window. I find it easier to do the editing in the GTK part of J but it works in the JHS part as well.

So, as you see, then it is not that difficult to create JHS apps. I tested this in Chrome and Mozilla

It is easy to take copies of the demos provided with JHS and use them as a starting point for similar experiments and then get a lot of experience using interactions with the browser.

Notice that the html text cannot be entered directly in the HBS. I put it in a noun called text but it could be called anything.

jhbr I used in the HBS is a utility noun surrogate for '
'. Similarly, jhh1 is a utility verb that puts a wrapper around the title

 jhh1=: 3 : 0
    '<h1>',y,'</h1>'
 )

 jhh1 'hello world'

There are a number of utils to assist in the application you create. Here are two very useful help verbs

 doch_jhs_'' NB. J utilities
 docjs_jhs_'' NB. javascript overview

When you issue them in the ijx window they give good hints what can be done.

As an example, this is what I got now.


 docjs_jhs_''

 see ~addons/ide/jhs/utiljs.ijs for complete information

 html element ids are mid[*sid] (main id and optional sub id)

 functions defined by you:

 ev_body_load() - page load (open)
 ev_body_unload() - page unload (close)
 ev_body_focus() - page focus

 ev_mid_event() - event handler - click, change, keydown, ...

 js event handler:
 jevev is event object
 event ignored if not defined
 jsubmit() runs J ev_mid_event and response is new page
 jdoajax([...],"...") runs J ev_mid_event
 ajax(ts) (if defined) is run with J ajax response
 ev_mid_event_ajax(ts) is run if ajax() not defined
 returns true (to continue processing) or false
 doch_jhs_''

 see ~addons/ide/jhs/utilh.ijs for complete information

 HBS verbs with id
 jhab id jhab text - anchor button
 jhb id jhb text - button
 jhcheckbox id jhcheckbox text;checked (checked 0 or 1)
 jhdiv id jhdiv text - <div id...>text</div>
 jhdiva id jhdiva text - <div id...>text
 jhdivadlg id jhdivadlg text - <div id... display:none...>text
 jhec id jhec '' - contenteditable div
 jhhidden id jhhidden value - <input type="hidden"....>
 jhmab id jhmab text - menu anchor button (shortcut ^s)
 jhmg id jhmg text;decor;width - menu group
 decor 0 for '' and 1 for dropdown
 jhml id jhml text - menu anchor link - (shortcut ^s)
 jhpassword id jhpassword text;size - text ignored
 jhradio id jhradio value;checked;set (set groups radios)
 jhref id jhref text - <a href="id">text</a>
 jhselect id jhselect texts;size;selected - selection control
 jhspan id jhspan text - <span id...>text</span>
 jhtext id jhtext text;size
 jhtextarea id jhtextarea text;rows;ccols

 HBS verbs without id
 jhfix html jhfix list - add styles and attributes to html
 html jhfix 'float:left';'tabindex="-1"';
 jhh1 jhh1 text - <h1>text</h1>
 jhjmlink jhjmlink'' - ide link menu
 jhma jhma'' - menu start
 jhmz jhmz'' - menu end
 jhresize jhresize'' - separate fixed div from resizable div
 jhtr jhtr rowdata - list of boxed row data html

 HBS nouns
 jhtablea jhtablea - <table>
 jhtablez jhtablez - </table>
 jhbr jhbr - <br/>
 jhhr jhhr - <hr/>

 utilities
 doch doch_jhs_'' - framework verbs and nouns
 docjs docjs_jhs)'' - framework javascript overview
 jhbshtml jhbshtml_jdemo1_'' - show HBS sentences and html
 jnv jnv_jhs_ 1 - toggle display of event name/value pairs

 html response verbs
 jhr title jhr names;values - names to replace with values
 send html response built from HBS CSS JS names values
 jhrajax jhrajax data - JASEP delimited data
--------- end from the ijx window now

It is better to do it fresh in your own ijx window because this may change.

To create applications in the GTK part of J there are some easy demos available and if anyone finds it hard to find or understand, just ask. At the end, I send here in the script test1 I tried before test2. It is based on demo6 which is doing grid.

I put in some text here and there to see what effect it would have. I think it is important to test a lot of silly things in order to get a feeling for how things work.

I made the small script here above - test2 - as a next step after test1 to see what I needed and what not. Having a baseline is important and I think that anyone should be able to understand and set up test2 and from then on, make their own application.

The small steps needed may seem trivial but if you do not know them it may be a difficult task finding out what to do. We working with high tech have to look at the simple things as well sometimes.

What I found difficult sometimes working with browser is to know when a restart or a refresh is needed and how to do it.

---------------- test1.ijs

coclass'test1'
coinsert'jhs'

HBS=: 0 : 0
 jhdemo''
 jhh1'Griddu test töflureiknir Demo'
 jhhr
 jhbr
 'texti jjj'
 jgridnumedit'g0';'';'';'gdata0__'
 jhhr
 jhbr
 'texti sflgjszgjsldj'
 jhbr
 jhdemo''
 jhbr
 jgridnumedit'g1';'';'';'gdata1__'
 jhhr
 desc
 jgridnumedit'g2';'';'';'gdata2__'
 jhdemo''
)

create=: 3 : 0
   gdata0__=:?4 5$5 3 2 1 313 66
   gdata1__=:?5 5$5 3 2 1 313 66
   gdata2__=:?6 3$5 3 2 1 313 66
   CSS=: jgridnumeditcss'g0';'80px'
   CSS=: CSS,jgridnumeditcss'g1';'40px'
   'test1'jhr''
)

jev_get=: create NB. browser get request

ev_g0_dd_enter=: gup
ev_g1_dd_enter=: gup

gup=: 3 : 0
   mid=. getv'jmid'
   sid=. getv'jsid'
   gid=. mid{.~mid i.'_'
   name=. getv gid,'_hh'
   r=. (sid i.'*'){.sid
   c=. (>:sid i.'*')}.sid
   v=. {.0".getv gid,'_vv' NB. new grid cell value
   d=. ".name
   d=. v (P=: <(".r);".c)}d
   ".name,'=: d'
   ctotal=. ":(".c){+/d
   rtotal=. ":(".r){+/"1 d
   d=. mid,'*',sid,JASEP, (":v), JASEP, gid, '_cf*0*', c, JASEP, ctotal, JASEP, gid, '_rf*', r, '*0', JASEP,rtotal
 NB. htmlresponse d,~hajax rplc '<LENGTH>';":#d
   jhrajax d
)

desc=: 0 : 0
 <br/>Edit global nouns gdata0__ and gdata1__.<br><br>

 Tilraun með heað breyta demo6

 <br><br>grid numeric editor uses ajax. When a cell value is changed, just 3 numbers (value,row,column) are sent to to the server. The server updates the noun, calculates new totals, and sends back 3 numbers (possibly corrected value,new column total,new row total),
 and then javascript updates just the affected cells.
 <br><br>
)

JS=: 0 : 0
 function gup()
 { var t= jform.jmid.value;
   var gid= t.substring(0,t.indexOf("_"));
   jform.jtype.value= 'enter'; // change becomes enter
   jbyid( gid + "_vv").value= jbyid( gid + "_dd*" + jform.jsid.value).value;
   jdoajax([gid + "_hh",gid + "_vv"],"");
 }

 function ev_g0_dd_enter(){gup();}
 function ev_g1_dd_enter(){gup();}

 // leaving changed cell (tab,mouse,...)
 // process as enter and return true to continue tab or ...
 function ev_g0_dd_change(){gup();return true;}
 function ev_g1_dd_change(){gup();return true;}

 function ajax(ts)
 { if(6!=ts.length)alert("wrong number of ajax results");
   jbyid(ts[0]).value=ts[1];
   jbyid(ts[2]).value=ts[3];
   jbyid(ts[4]).value=ts[5];
 }
 )
----------------- end test1

Well, if you are still reading. I would like to know if you learned anything from it. Or you can also tell me this was complete waste of time and energy. Anyway, I think that genius lies in simplicity and that is a hallmark of J.

Ok, I am going to set in one of the tutorial scripts from the GTK part of the new J

 ----------------- script for showing hello world in a form in GTK
 NB. GTK+2.0 tutorial example 2
 NB.
 NB. note the connect_swapped call to destroy the window is moved
 NB. into the connect handler.

require 'gui/gtk'

coclass 'm2'
coinsert 'jgtk'

hello=: 3 : 0
   'widget data'=. y
   smoutput 'Hello World'
   0
)

window_delete=: 3 : 0
   'widget event data'=. y
   smoutput 'delete event occurred'
   0 NB. 0=do delete, 1=cancel delete
 )

Destroy=: 3 : 0
   'widget data'=. y
   smoutput 'destroy event occurred'
   if. -.IFGTK do. gtk_main_quit '' end.
   destroy ''
   0
)

main=: 3 : 0
   if. -.IFGTK do. gtkinit'' end.
   window=: gtk_window_new GTK_WINDOW_TOPLEVEL
   consig3 window;'delete-event';'window_delete'
   consig window;'destroy';'Destroy'
   gtk_container_set_border_width window, 10
   button=. gtk_button_new_with_label <'Hello World'
   consig button;'clicked';'hello'
   gtk_container_add window, button
   gtk_widget_set_size_request button, 200 100
   gtk_widget_show button
   gtk_widget_show window
   if. -.IFGTK do. gtk_main '' end.
   0
)

NB. =========================================================
destroy=: 3 : 0
   cbfree ''
   codestroy ''
)

cocurrent 'base'
main_m2_''
--------------- end script

It would be interesting to hear if people think the gtk part of J is easier than the jhs part. My own opinion goes back and forth between the two. You may hear me say one is easier than the other and then the next day I may have changed to the other. It is basically based on what I am doing at the time.

Now I actually like to combine them and even call one from the other is also interesting and probably no need to favor either one. Because of historical reasons, I am writing this and I write most of my scripts using GTK even if I then use it in JHS.

--

. Björn Helgason, Verkfræðingur . Fornustekkum II . 781 Hornafirði, . t-póst: gosinn@gmail.com . http://groups.google.com/group/J-Programming

. Tæknikunnátta höndlar hið flókna, sköpunargáfa er meistari einfaldleikans góður kennari getur stigið á tær án þess að glansinn fari af skónum

          /|_      .---------------------------.
        ,'  .\  /  | Með léttri lund verður    |
    ,--'    _,'    | Dagurinn í dag            |
   /       /       | Enn betri en gærdagurinn  |
  (   -.  |        `---------------------------'
  |     ) |         (\_ _/)
 (`-.  '--.)       (='.'=)  ♖♘♗♕♔♙
  `. )----'        (")_(")  ☃☠
`. )----' (")_(")
Topic: twitter

Bjorn Helgason < gosinn@gmail.com > Jan 31 12:09AM -0800 ^

I am so new to twitter and have not done anything yet - only logged in for a few minutes so far. If handle means username then I chose flugfiskur. It means Flyfish - I have a company called Fugl&Fiskur which means bird and fish.