Pages

Showing posts with label more. Show all posts
Showing posts with label more. Show all posts

Thursday, March 12, 2015

Creating More Responsive Applications with Client Handlers and Validators

When it comes to writing UI applications in Apps Script, we get a lot of requests to support event callbacks that are handled in the user’s browser. For example, if your application has a form, you may want to disable a button after it is clicked the first time. Until now, the only way to do that would be by using an event handler on the server to disable that button. Using Client Handlers, your application can now respond to events in the browser without the need to perform a round trip to Google Apps Script servers.

By cutting out the round trip to the server, your app can respond instantly to user input. Imagine, for example, you want to provide your users with instant feedback within your app when a user types text where a number is expected. Ideally, you would want to warn users as they type the value, instead of waiting until the form is submitted. Having a server event handler for each keystroke is definitely overkill for such a simple and common task. Luckily, these use cases are now supported with Apps Script’s new Client Handlers and validators!

Let’s take a look at some code.

Client Handlers

A Client Handler allows you to react to any event in a browser without connecting to the server. What you can do in response to an event is limited to a set of predefined common actions, but you have a lot of flexibility in making your app more responsive.

You can use Client Handlers in any UiApp regardless of whether you are embedding in a Spreadsheet or a Sites Page or publishing as a service. This simple application enables the user to click a button to display the classic “Hello world” message:

function doGet() {
var app = UiApp.createApplication();
var button = app.createButton("Say Hello");

// Create a label with the "Hello World!" text and hide it for now
var label = app.createLabel("Hello World!").setVisible(false);

// Create a new handler that does not require the server.
// We give the handler two actions to perform on different targets.
// The first action disables the widget that invokes the handler
// and the second displays the label.
var handler = app.createClientHandler()
.forEventSource().setEnabled(false)
.forTargets(label).setVisible(true);

// Add our new handler to be invoked when the button is clicked
button.addClickHandler(handler);

app.add(button);
app.add(label);
return app;
}

The Client Handlers in the above example are set up in two steps:

  1. Create a Client Handler just as we would create the server handlers you all know and love.
  2. Define the target widget for this handler. The target widget is the widget on which the handler will take action. We set the handler’s target in one of two ways: (a) By using the forTargets method to define the target widget. (b) By using the forEventSource method which lets widget wire itself to the client handler.

In the above example, we set the handler’s target to be the event source, so that it will apply to the button that is clicked. Finally, we define the action that the handler should take, in this case disabling the button using setEnabled(false). Aside from setEnabled, you can also change styles using setStyleAttribute, change text using setText, and so on. One Client Handler can perform multiple actions — just chain them together - and you can even change the target so that some actions apply to one set of widgets and some actions to another set. In our example, along with disabling the button, we set the handler to display the label when it is invoked, using setVisible.

Validators

Another new addition to Apps Script is support for validators in handlers. Validators allow handlers to check simple and complex conditions before they are invoked. For example, the following application adds two numbers given by the user, while using validators to make sure the server is only called if both of the text boxes contain numbers.

function doGet() {
var app = UiApp.createApplication();

// Create input boxes and button
var textBoxA = app.createTextBox().setId(textBoxA).setName(textBoxA);
var textBoxB = app.createTextBox().setId(textBoxB).setName(textBoxB);
var addButton = app.createButton("Add");

// Create a handler to call the adding function
// Two validations are added to this handler so that it will
// only invoke add if both textBoxA and textBoxB contain
// numbers
var handler = app.createServerClickHandler(add)
.validateNumber(textBoxA)
.validateNumber(textBoxB)
.addCallbackElement(textBoxA)
.addCallbackElement(textBoxB);

addButton.addClickHandler(handler)

app.add(textBoxA);
app.add(textBoxB);
app.add(addButton);
return app;
}

function add(e) {
var app = UiApp.getActiveApplication();
var result = parseFloat(e.parameter.textBoxA) + parseFloat(e.parameter.textBoxB);
var newResultLabel = app.createLabel("Result is: " + result);
app.add(newResultLabel);
return app;
}

There’s a variety of validators to choose from that perform different tasks. You can verify the input to be a number, an integer, or an e-mail address. You can check for a specific length, or for any numerical value in a defined range. You can also use general regular expressions. Lastly, each validator has its negation.

Note that validators work with both client and server handlers.

Putting it all together

Of course, validators and Client Handlers work best together. For example, in our addition application above, the “Add” button should be disabled as long as the current input is not numeric. We would also like to let the user know why the button is disabled by displaying an error message. To do so, we combine the power of server handlers, Client Handlers, and validators in the following way:

function doGet() {
var app = UiApp.createApplication();

// Create input boxes and button.
var textBoxA = app.createTextBox().setId(textBoxA).setName(textBoxA);
var textBoxB = app.createTextBox().setId(textBoxB).setName(textBoxB);
var addButton = app.createButton("Add").setEnabled(false);
var label = app.createLabel("Please input two numbers");

// Create a handler to call the adding function.
// Two validations are added to this handler so that it will
// only invoke add if both textBoxA and textBoxB contain
// numbers.
var handler = app.createServerClickHandler(add)
.validateNumber(textBoxA)
.validateNumber(textBoxB)
.addCallbackElement(textBoxA)
.addCallbackElement(textBoxB);

// Create handler to enable the button well all input is legal
var onValidInput = app.createClientHandler()
.validateNumber(textBoxA)
.validateNumber(textBoxB)
.forTargets(addButton).setEnabled(true)
.forTargets(label).setVisible(false);

// Create handler to mark invalid input in textBoxA and disable the button
var onInvalidInput1 = app.createClientHandler()
.validateNotNumber(textBoxA)
.forTargets(addButton).setEnabled(false)
.forTargets(textBoxA).setStyleAttribute("color", "red")
.forTargets(label).setVisible(true);

// Create handler to mark the input in textBoxA as valid
var onValidInput1 = app.createClientHandler()
.validateNumber(textBoxA)
.forTargets(textBoxA).setStyleAttribute("color", "black");

// Create handler to mark invalid input in textBoxB and disable the button
var onInvalidInput2 = app.createClientHandler()
.validateNotNumber(textBoxB)
.forTargets(addButton).setEnabled(false)
.forTargets(textBoxB).setStyleAttribute("color", "red")
.forTargets(label).setVisible(true);

// Create handler to mark the input in textBoxB as valid
var onValidInput2 = app.createClientHandler()
.validateNumber(textBoxB)
.forTargets(textBoxB).setStyleAttribute("color", "black");

// Add all the handlers to be called when the user types in the text boxes
textBoxA.addKeyUpHandler(onInvalidInput1);
textBoxB.addKeyUpHandler(onInvalidInput2);
textBoxA.addKeyUpHandler(onValidInput1);
textBoxB.addKeyUpHandler(onValidInput2);
textBoxA.addKeyUpHandler(onValidInput);
textBoxB.addKeyUpHandler(onValidInput);
addButton.addClickHandler(handler);

app.add(textBoxA);
app.add(textBoxB);
app.add(addButton);
app.add(label);
return app;
}

function add(e) {
var app = UiApp.getActiveApplication();
var result = parseFloat(e.parameter.textBoxA) + parseFloat(e.parameter.textBoxB);
var newResultLabel = app.createLabel("Result is: " + result);
app.add(newResultLabel);
return app;
}

All of these features can be used to create more advanced and responsive applications. Client handlers can be used to change several attributes for widgets, and validators can help you check a variety of different conditions from well formed email addresses to general regular expressions.

If youd like to chat about these new features or have other questions about Google Apps Script, please join several members of the Apps Script team in the Google Apps Developer Office Hours on Google+ Hangouts tomorrow, Wednesday November 16th at 10am PST. You can also ask questions at any time in the Apps Script forum.


Omer Strulovich   profile

Omer was an intern on the Google Docs team for the summer of 2011. He is now back to pursuing his master’s degree in the field of cryptography.

Read more »

Wednesday, March 11, 2015

More administrative APIs now available to all Google Apps editions

Google Apps domain administrators have access to a number of APIs to automate their management activities or to integrate with third-party applications, including the Provisioning API to manage user accounts and groups, the Admin Audit API, Admin Settings API, and the Reporting API.

These APIs were only available in Google Apps for Business, Education and ISP editions but many administrators of the free version of Google Apps also requested access to them. I’m glad to say that we listened to your feedback and, starting today, we made the these APIs available to all Google Apps editions.

Please check the documentation as the starting point to explore the possibilities of the APIs and post on our forum if you have questions or comments.

Claudio Cherubino   profile | twitter | blog

Claudio is a Developer Programs Engineer working on Google Apps APIs and the Google Apps Marketplace. Prior to Google, he worked as software developer, technology evangelist, community manager, consultant, technical translator and has contributed to many open-source projects, including MySQL, PHP, Wordpress, Songbird and Project Voldemort.

Read more »

Monday, March 9, 2015

User Stories in more detail

Several people at the conference last week asked me for more information about how to write user stories.  I could write a long blog with lots of examples and explanation, but someone has already done that. Check out Scott Amblers post here.

While Scott recommends capturing stories on cards, I like to capture them initially in a spreadsheet because it makes it easier to organize and prioritize.  Once the project starts I print out the cards - instructions are in one of my earlier blogs.
Read more »

Monday, March 2, 2015

More Than ONE MILLION Views on SlideShare! Congrats!



ONE MILLION+ VIEWS!

If this was a Gagnam Style, or Harlam Shake video viewing achievement, it would be nothing special (Just below average). Yes, if this was a Sneezing Baby Panda (155+ million views), or a YouTube viewing achievement, it would also not be much to celebrate (especially if you are uploading cute baby or puppy videos). 

But, having your educational content (currently 60 presentations) being viewed more than one million times on SlideShare is something worth celebrating a bit! Congrats, Zaid(Learn)! Al-Hamdullilah!

Also, I would like thank everyone that has viewed any of my SlideShare presentations over the years, and more importantly hopefully you have learned something interesting, and better yet been able to use, or apply some of the ideas and resources shared into your learning and teaching environments. Congrats to Everyone! 




MY SLIDESHARE PRESENTATIONS

If you have never experienced (or want to revisit) my presentations shared on SlideShare since 2007, here is a good starting point:


Click here for all my SlideShare presentations at once.

Sometimes it is nice to celebrate our own achievements in our distorted self-glorifying minds...Congrats :)
Read more »

Friday, February 13, 2015

Pentaho CDE Dashboard complete example Adding few more functionality to it

Sales Dashboard Demo in Pentaho CDE :



Drill down functionality on 2nd Chart (State wise individual details) which is a tabular display of data


Features:
1. Superb Layout (Back ground color, rows, columns structured based one)
2.Charts
      a. Pie Chart ( 1st row 1st 2 charts -SQL based charts & 3rd one is MDX based)
  • Pie charts are converted to circulared
  • Percentage values, actual values(featured any one of them we can remove)
  • Drill down from 2nd pie chart to another dashboard(tabular display of data) - passing field value from one dashboard to another dashboard.
      b. Bar Charts(4 and 5) - SQL based charts 
  • Dynamic with number of bars 
  • X-axis labels are rotated.
  • Dynamic with date input controls.
  • Currency symbol is added.
      c. Line Chart
  • Two lines are plotted
  • Dynamic with date input controls
SQL queries :
Complex queries are written to get the exact result sets ... for instance, JOINS, aggregate functions

CSS and JavaScript
To design the lay out written CSS code and to get the Advanced functionalities written java script..


Export Functionality :
Provide "Button Component" in one of the columns in Lay out section as shown in figure.
Write below code in Expression
function f() { window.print() }

NOTE :
Currently it is exporting XPS .. i.e, the window will be exported..
If you have pdf installed for your printer , you can save your file in the PDF format.

Source code : Click this link
 NOTE: 
1) You need to change database connection details .
2) For 5.0.1 CE, you need to use the Import/Export(Upload/Download) facility to fetch the .zip file as project in the server.
3) For 4.8 CE, you need place the folder of the source code(not zip file) in pentaho-solutions folder.
4) Note that this example may not work with older C-Tools. It was developed on 13.06. If you deploy it in older versions you might get comparability issues.

References:
1. On drill down
i) http://forums.pentaho.com/archive/index.php/t-84586.html
ii) forums.pentaho.com/showthread.php?95413-confused-about-drilldowns-on-cde




Sadakar
BI developer

I believe in "Learning Never Exhausts The Mind" 






Read more »