Day 38 – Evolution Of Advanced Hello World App

Building just a simple Hello World app in KRL is fairly simple. There are only so many ways to put a notify on the page. Kicking it up a notch and adding in a form and some persistance really opens up the doors to a lot of possibilities and different ways of doing it. I thought it might be interesting to document the evolution as I attempt to create a good advanced Hello World example app for Kynetx.

Version 0

ruleset a60x557 {
  meta {
    name "advanced-hello-world"
    description <<
      advanced-hello-world
    >>
    author "Mike Grace"
    logging on
  }

  rule plain_krl_way {
    select when pageview "example\.com"
    pre {
      form =<<
        <form id="my-form">
          Your Name: <input type="text" name="user-name"/>
          <input type="submit" value="Submit"/>
        </form>
      >>;
    }
    {
      notify("Remembering your name",form) with sticky = true;
      watch("#my-form", "submit");
    }
  }

  rule get_form {
    select when web submit "#my-form"
    pre {
      userName = event:param("user-name");
    }
    {
      notify("Thanks #{userName}!","") with sticky = true;
    }
  }
}
  • put form on page
  • watch form
  • respond to form submit with notify

This is super simple but falls short in several areas

  • nothing to let the user know that the server is currently working on processing the form submit
  • form can be submitted more than once
  • submitted name isn’t stored into persistance
  • interesting but not really useful in my opinion
  • this isn’t how I get data out of forms (will show later)

Action shots:

running app for first time on example.com

submitting form first time

submitting form as many times as I want

Version 1

ruleset a60x557 {
  meta {
    name "advanced-hello-world"
    description <<
      advanced-hello-world
    >>
    author "Mike Grace"
    logging on
  }

  rule what_should_i_do {
    select when pageview "example\.com"
    pre {
      userName = ent:userName || "";
      form =<<
        <form id="my-form">
          Your Name: <input type="text" name="user-name"/>
          <input type="submit" value="Submit"/>
        </form>
      >>;
    }
    if (userName eq "") then {
      notify("Remembering your name",form) with sticky = true;
      watch("#my-form", "submit");
    }
    notfired {
      raise explicit event user_name_known with userName = userName;
    }
  }

  rule user_name_known {
    select when explicit user_name_known
    pre {
      userName = event:param("userName");
    }
    {
      notify("#{userName} is 'da bomb!","") with sticky = true;
    }
  }

  rule get_form {
    select when web submit "#my-form"
    pre {
      userName = event:param("user-name");
    }
    {
      notify("Thanks #{userName}!","") with sticky = true;
    }
    fired {
      set ent:userName userName;
    }
  }

}
  • 14 get user’s name from persistance and set to blank string if not found
  • 22 if the user’s name is not found in persistance then put the form up and watch for the form submit
  • 26 if the user’s name was found in persistance then raise an explicit event to handle user’s name being found
  • 34 get user’s name from passed parameters is raised explicit event. Could have just pulled it from persistance but then you wouldn’t have gotten to see how to pass parameters in explicit events.
  • 50 set the user’s name into persistance when the rule runs responding to form submit event

This example is much better but still leaves a lot out.

  • no form validation
  • no way for user to change set user name once submitted
  • still no indication that form submission is ‘in progress’
  • still able to submit multiple times

Action shots:

running app on example.com for the first time

submitting form for the first time

submitting the form as many times as I want

After page reload and running app again

Version 2

ruleset a60x557 {
  meta {
    name "advanced-hello-world"
    description <<
      advanced-hello-world
    >>
    author "Mike Grace"
    logging on
  }

  global {
    css <<
      a {
        color: white;
      }
    >>;
  }

  rule what_should_i_do {
    select when pageview "example\.com"
    pre {
      userName = ent:userName || "";
      form =<<
        <form id="my-form">
          Your Name: <input type="text" name="user-name"/>
          <input type="submit" value="Submit"/>
        </form>
      >>;
      greeting =<<
        <p>#{userName} is 'da bomb!'</p>
        <p>Clear saved name by running the app on <a href="http://example.com/?clear">example.com/?clear</a></p>
      >>;
      content = (userName eq "") => form | greeting;
    }
    {
      notify("Hello World (advanced)", content) with sticky = true and opacity = 1;
      watch("#my-form", "submit");
    }
  }

  rule get_form {
    select when web submit "#my-form"
    pre {
      userName = event:param("user-name");
    }
    {
      notify("Thanks #{userName}!","") with sticky = true;
    }
    fired {
      set ent:userName userName;
    }
  }

  rule clearing {
    select when pageview "example\.com\/\?clear"
    notify("Cleared","");
    fired {
      clear ent:userName;
    }
  }

}
  • 12 set CSS so link on black background is visible
  • 29 setup greeting HTML at the same time as the form
  • 33 decide what to put on the page using condition expression
  • 54 clear saved name when user runs on specified clear page

This is getting closer but still lacks

  • form validation or disallowing user to submit multiple times
  • when persistance is cleared the greeting is also displayed
  • no indication that form submission is ‘in progress’
  • still not the way I would do it

Action Shots:

running app first time

submitting name first time

submitting name many times

running app again after refresh of page

running app on designated clear page

Version 3

ruleset a60x557 {
  meta {
    name "advanced-hello-world"
    description <<
      advanced-hello-world
    >>
    author "Mike Grace"
    logging on
  }

  global {
    css <<
      .kGrowl-notification a {
        color: white;
      }

      #a60x557-working, #a60x557-notice {
        display: none;
      }
    >>;
  }

  rule what_should_i_do {
    select when pageview "example\.com(?!.+clear)"
    pre {
      userName = ent:userName || "";
      form =<<
        <p id="a60x557-notice">Your name input must be more than 2 characters</p>
        <p id="a60x557-form">Your Name: <input type="text" id="a60x557-user-name"/> <button id="a60x557-submit">Submit</button></p>
        <img id="a60x557-working" style="display: none" src="http://kynetx-apps.s3.amazonaws.com/advanced-hello-world/working.gif"/>
      >>;
      greeting =<<
        <p>#{userName} is 'da bomb!'</p>
        <p>Clear saved name by running the app on <a href="http://example.com/?clear">example.com/?clear</a></p>
      >>;
      content = (userName eq "") => form | greeting;
    }
    {
      notify("Hello World (advanced)", content) with sticky = true and opacity = 1;
      emit <|
        $K("#a60x557-submit").bind("click", function() {

          // get user name from input
          var userName = $K("#a60x557-user-name").val();

          // check input
          if (userName.length > 2) {
            // don't allow user to submit more than once
            $K(this).unbind("click");

            // get app object to raise web event
            app = KOBJ.get_application("a60x557");

            // raise web event to system with user name
            app.raise_event("user_name_submitted", {"user-name":userName});

            // show user 'in progress'
            $K("#a60x557-form,#a60x557-notice").remove();
            $K("#a60x557-working").show();
          } else {
            $K("#a60x557-notice").show()
          };
        });
      |>;
    }
  }

  rule get_form {
    select when web user_name_submitted
    pre {
      userName = event:param("user-name");
      reset =<<
        <p>Clear saved name by running the app on <a href="http://example.com/?clear">example.com/?clear</a></p>
      >>;
    }
    {
      emit <|
        // close previous notify
        $K(".kGrowl-notification .close").trigger("click");
      |>;
      notify("Thanks #{userName}!", reset) with sticky = true and opacity = 1;
    }
    fired {
      set ent:userName userName;
    }
  }

  rule clearing {
    select when pageview "example\.com\/\?clear"
    notify("The saved name has been cleared","");
    fired {
      clear ent:userName;
    }
  }

}
  • updated CSS to only change links inside the notify
  • 24 don’t show form/welcome back notify if on the clear page
  • 28 add notice to show if user input doesn’t match validation rule
  • 30 add working notification image to let user know app is ‘in progress’
  • 41 watch for user to submit form using jquery
  • 47 check user input against validation rule
  • 49 release click listener so form only gets submitted once
  • 52 get application JS object to raise web event
  • 55 raise web event with user’s name
  • 58 remove form stuff
  • 59 show working spinner image
  • 61 show notice if user’s input doesn’t pass input validation
  • 79 close previous notify once saved form returns

Now this advanced hello world example app

  • only allows the user to submit name once
  • allows user to clear set name
  • better CSS selectors
  • form validation
  • in progress visual
  • stores user’s name into persistance
  • this is how I would do it

Action shots:

running app first time

submitting name first time

name successfully saved

running app again after reload

running app on designated clear page

Get the bookmarklet to try it out yourself!

Gratuitous day 38 crazy face

About these ads
This entry was posted in Kynetx. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s