NYCJUG/2011-02-08/HelloWorldInJHS
“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.