DEV Community

loading...
Cover image for Making a Form on the Canvas

Making a Form on the Canvas

zimlearn profile image Dr Abstract ・4 min read

Here is a survey form on the HTML Canvas https://zimjs.com/survey/index.html?id=dev

Survey on Canvas

In this example we put a question on a page and use the arrows or swipe to go to the next question - but we could put as many questions on a page we want. We use a ZIM Indicator() at the bottom to show which page we are on and how many there are.


COMPONENTS

There are many components in ZIM that help with questions. There are traditional ZIM RadioButtons, CheckBox, TextArea, Button, etc. In this survey we feature a Stepper() - seen above - which steps through numbers or strings and a Selector() which can work in a grid or row or column - seen below.

ZIM Selector Component


BIND

We set up ZIM Bind() to handle the data we want to send to the database:

const bind = new Bind({
    connection:"https://zimjs.com/survey/data.php", 
    bindType:POST, // set to GET to test from local file
    master:id, // this comes from the query string
    report:true // see data reports in the console
}); 
Enter fullscreen mode Exit fullscreen mode

STEPPER

Here is the code for a page with a Stepper and we bind the stepper currentValue to a bindID that is received on the server side:

const page4 = new Page(backing.width, backing.height, orange, green);
new Label({text:"How many YEARS have you used ZIM?", group:"question"})
    .pos(0,padding,CENTER,TOP,page4);
new Stepper({
    list:[0,.5,1,1.5,2,3,4,5,6],
    width:250
}).center(page4).mov(0,20).bind("years", "currentValue");
Enter fullscreen mode Exit fullscreen mode

STYLE

The components are styled with ZIM STYLE. Note that all labels will be Reuben but labels grouped with "question" will be arial. So group styles are similar to classes in CSS.

STYLE = {
    type:{
        Label:{
            color:dark,
            font:"Reuben",
            size:30
        },        
        Stepper:{
            backgroundColor:yellow.lighten(.1),
            color:dark
        }
    },
    group:{
        question:{
            font:"arial",
            size:35
        }
    }    
}
Enter fullscreen mode Exit fullscreen mode

SUBMIT

Alt Text

Here is the code for the page with the Submit button and where we send the data in Bind to the server. We receive a callback function and go to the final page or pop up an error message:

const page10 = new Page(stageW, backing.height, yellow, orange);
new Label({text:"Please submit the survey...", group:"question"})
    .pos(0,padding,CENTER,TOP,page10);
new Button({label:"SUBMIT"})
    .center(page10).mov(0,padding/2).tap(()=>{                
        bind.to({
            call:result=>{
                if (result.success) pages.go(page11, null, "fan");
                else error.show();
            }
        });        
    });    
const error = new Pane(300, 220, "ERROR", red);
Enter fullscreen mode Exit fullscreen mode

PAGES

The pages are all added to ZIM Pages() which handles swiping including traditional transitions or cool ZIM Emitter() transitions. ZIM Arrow() objects work with pages to travel through the pages.

const pages = new Pages([
    page1, page2, page3, page4, page5, 
    page6, page7, page8, page9, page10, 
    page11
], "lineZIM", .4, null, backing)
    .center(backing);

const next = new Arrow(blue, blue.lighten(.2), pages, RIGHT, "thick")
    .sca(1.5).pos(40,30,RIGHT,BOTTOM);
const prev = new Arrow(blue, blue.lighten(.2), pages, LEFT, "thick")
    .sca(1.5).rot(180).pos(40,30,LEFT,BOTTOM);
Enter fullscreen mode Exit fullscreen mode

INDICATOR AND WIRED

The ZIM Indicator is wired to the Pages index to automatically change as the pages change. ZIM wire() and wired() are an alternative to traditional on() methods in ZIM - we could have just used a change method. The Pages have one extra results page so we use a filter on wired() to turn off the indicator when on the last page. Bind also has filters.

new Indicator(400,35,10,green)
    .pos(0,49,CENTER,BOTTOM)
    .wired({
        source:pages, 
        input:"index",
        prop:"selectedIndex", 
        // turn indicator off for last page
        filter:function(v) {return v>=10?-1:v;} 
    });
Enter fullscreen mode Exit fullscreen mode

BASE

On the server side we use ZIM Base to wrap MySQLi at 1/3 the size. Here is the PHP:

<?php
require_once('../zim_base.php'); // see https://zimjs.com/base

// ZIM Bind() is sending a master id for each person we contact 
$data = [uid=>$master, date=>"NOW()"];

// often the data is just added to the database as JSON 
// but here we want to make individual fields for reporting 
// so use simplify() which flattens the data as a key value array
// add this to the custom data above
$data = array_merge($data, $base->simplify());

$result = $base->insert("zim_survey", $data);

if ($result->affected_rows > 0) $base->reply("success", "data added"); 
else $base->reply("error", "cannot store data"); 
?>
Enter fullscreen mode Exit fullscreen mode

Here is a ZIM Explore video that takes you through all this and more in one amazing hour! Really... considering ZIM is a front-end Canvas Framework for visual apps - can the data handling get much better? https://www.youtube.com/watch?v=Bt6mMKTrzlk


If you have not checked out the Canvas recently - you simply must! Here is the ZIM Dev Site and some In-depth Guides by Dr Abstract including Your Guide to Coding Creativity on the Canvas.

Discussion (1)

pic
Editor guide
Collapse
zimlearn profile image
Dr Abstract Author

Here is the report in the console that Bind is giving

ZIM Bind Report