The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

JQuery::Mobile - interface to jQuery Mobile

SYNOPSIS

use JQuery::Mobile;

my $jquery_mobile = JQuery::Mobile->new(config => {'app-title' => 'Hello Mobile World'});

# create a listview
my $list = $jquery_mobile->listview(
  anchor => {rel => 'dialog', transition => 'pop'},
  items => [
    {value => 'Quick List', divider => 1},
    {aside => '02/06', count => '6', image => 'http://placehold.it/100x100', title => 'One', href => '#item-link'},
    {aside => '03/07', count => '8', image => 'http://placehold.it/100x100', title => 'Two', href => '#item-link'},
    {aside => '04/08', count => '10', image => 'http://placehold.it/100x100', title => 'Three', href => '#item-link'},
  ],
  filter => 'true',
);

# renders a complete HTML page using a "multi-page" template (see reference http://jquerymobile.com/test/docs/pages/page-anatomy.html)
print $jquery_mobile->pages(
  pages => [
    {
    	id => 'home', 
    	header => {content => '<h1>Home</h1>'}, 
    	content => $list
    },
    {
    	id => 'item-link', 
    	header => {content => '<h1>Item Heading</h1>'}, 
    	content => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit'
    },
  ]
);

DESCRIPTION

JQuery::Mobile is an interface to jQuery Mobile. It generates HTML markups, such as navbars, forms, and listviews, that are compatible with jQuery Mobile.

METHODS

new

To instantiate a new JQuery::Mobile object:

my $jquery_mobile = JQuery::Mobile->new();

Here is a list of optional parameters when instantiating a JQuery::Mobile object:

# default values are shown
my $jquery_mobile = JQuery::Mobile->new(
   config => {
    'head' => 1, # include <html>, <head>, and <body> tag when rendering a page
    'viewport' => 'width=device-width, initial-scale=1', # default viewport
    'apple-mobile-web-app-capable' => 1, # enable as apple web app
    'apple-touch-icon' => '', # path to apple web app icon image
    'apple-touch-icon-72' => '', # path to apple web app icon image (72x72 pixels)
    'apple-touch-icon-114' => '', # path to apple web app icon image (114x114 pixels)
    'apple-touch-startup-image' => '', # path to apple web app startup image
    'jquery-mobile-css' => 'http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.css',
    'jquery-mobile-js' => 'http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.js',
    'jquery' => 'http://code.jquery.com/jquery-1.9.1.min.js',
    'app-css' => [], # global application CSS files
    'app-js' => [], # global application JS files
    'app-inline-css' => '      span.invalid{color:#F00000;line-height: 1.5;}', # inline CSS code
    'app-inline-js' => '', # inline JS code
    'app-title' => '', # <title> in <head>
   }
);

The allowed HTML and data-* attributes for each UI component can be customised. By default, HTML attributes are very strict to ensure a clean markup. For data-* attributes, see reference: http://api.jquerymobile.com/data-attribute/.

# default values are shown
my $jquery_mobile = JQuery::Mobile->new(
  config => {
    'header-footer-html-attribute' => ['id', 'class'],
    'header-footer-data-attribute' => ['id', 'fullscreen', 'position', 'theme'],
    'navbar-html-attribute' => ['id', 'class'],
    'navbar-data-attribute' => ['disable-page-zoom', 'enhance', 'fullscreen', 'iconpos', 'tap-toggle', 'theme', 'transition', 'update-page-padding', 'visible-on-page-show'],
    'navbar-item-html-attribute' => ['id', 'class', 'target'],
    'navbar-item-data-attribute' => ['ajax', 'icon', 'iconpos', 'iconshadow','prefetch', 'theme'],
    'page-html-attribute' => ['id', 'class'],
    # combine data-attributes for page and dialog
    'page-data-attribute' => ['add-back-btn', 'back-btn-text', 'back-btn-theme', 'close-btn', 'close-btn-text', 'corners', 'dom-cache', 'enhance', 'overlay-theme', 'role', 'shadow','theme', 'title', 'tolerance', 'url'],
    'popup-html-attribute' => ['id', 'class'],
    'popup-data-attribute' => ['corners', 'overlay-theme', 'shadow', 'theme', 'tolerance', 'position-to', 'rel', 'role', 'transition'],
    'listview-html-attribute' => ['id', 'class'],
    'listview-data-attribute' => ['autodividers', 'count-theme', 'divider-theme', 'enhance', 'filter', 'filter-placeholder', 'filter-theme', 'filtertext', 'header-theme', 'inset', 'split-icon', 'split-theme', 'theme'],
    'listview-item-html-attribute' => ['id', 'class'],
    'listview-item-data-attribute' => ['ajax', 'mini', 'rel', 'theme', 'transition'],
    'collapsible-html-attribute' => ['id', 'class'],
    'collapsible-data-attribute' => ['collapsed', 'collapsed-icon', 'content-theme', 'expanded-icon', 'iconpos', 'inset', 'mini', 'theme'],
    'collapsible-set-html-attribute' => ['id', 'class'],
    'collapsible-set-data-attribute' => ['collapsed-icon', 'content-theme', 'expanded-icon', 'iconpos', 'inset', 'mini', 'theme'],
    'controlgroup-html-attribute' => ['id', 'class'],
    'controlgroup-data-attribute' => ['enhance', 'iconpos', 'theme', 'type'],
    'button-html-attribute' => ['id', 'name', 'class', 'maxlength', 'size', 'type', 'value'],
    'button-html-anchor-attribute' => ['id', 'class', 'href', 'target'],
    'button-data-attribute' => ['ajax', 'corners', 'dialog', 'direction', 'dom-cache', 'external', 'icon', 'iconpos', 'iconshadow', 'inline', 'mini', 'position-to', 'prefetch', 'rel', 'role', 'shadow', 'theme', 'transition'],
    'form-html-attribute' => ['id', 'action', 'class', 'enctype', 'method'],
    'form-data-attribute' => ['enhance', 'theme', 'ajax'],
    'input-html-attribute' => ['id', 'class', 'disabled', 'max', 'maxlength', 'min', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'size', 'type', 'value', 'accept', 'capture'],
    'input-data-attribute' => ['clear-btn', 'clear-btn-text', 'corners', 'highlight', 'icon', 'iconpos', 'iconshadow', 'inline', 'mini', 'shadow', 'theme', 'track-theme'],
    'textarea-html-attribute' => ['id', 'name', 'class', 'rows', 'cols', 'readonly', 'disabled', 'title', 'required', 'placeholder', 'title', 'pattern'],
    'textarea-data-attribute' => ['clear-btn', 'clear-btn-text', 'mini', 'theme'],
    'select-html-attribute' => ['id', 'class', 'size', 'maxlength', 'readonly', 'disabled', 'title', 'required', 'placeholder', 'title', 'pattern'],
    'select-data-attribute' => ['icon', 'iconpos', 'inline', 'mini', 'native-menu', 'overlay-theme', 'placeholder', 'theme'],
    'radio-checkbox-html-attribute' => ['id', 'class', 'readonly', 'disabled', 'title', 'required', 'placeholder', 'title', 'pattern', 'value'],
    'radio-checkbox-data-attribute' => ['mini', 'theme']
   }
);

The label parameter accepts a sub callback to alter how form field labels are being generated:

my $jquery_mobile = JQuery::Mobile->new(
  config => {
    'label' => sub {
      my $args = shift;
      return '<strong>' . $args->{label} . '*</strong>' if $args->{required};
      return $args->{label};
    },
  }
);

head() is called by page() and pages() internally to render the HTML header. Parameters via new() controlls the output of head().

header() generates header toolbars. Text, buttons, or navbar() can be passed to the content parameter.

print $jquery_mobile->header(
  content => $jquery_mobile->button(href => '#', value => 'Home', icon => 'home', iconpos => 'notext') . '<h1>Main Title</h1>',
);

prints:

<div data-role="header">
  <a data-icon="home" data-iconpos="notext" data-role="button" href="#">Home</a>
  <h1>Main Title</h1>
</div><!-- /header -->

Attributes defined in header-footer-html-attribute and header-footer-data-attribute can be passed to header(), based on the default configuration:

print $jquery_mobile->header(
  'content' => '<h1>Header Content</h1>',
  'id' => 'home-main-header',
  'class' => 'site-header',
  'data-id' => 'main-header', # use the 'data-*' prefix since 'id' is both a HTML and data atrribute
  'fullscreen' => 'true',
  'position' => 'fixed',
  'theme' => 'e'
);

Similar to header(), footer() generates footer toolbars. Attributes defined in header-footer-html-attribute and header-footer-data-attribute can be passed to footer().

print $jquery_mobile->footer(
  position => 'fixed',
  content => 'Footer content'
);

popup() generates popup container divs. Content can be passed via the content parameter:

my $popup = $jquery_mobile->popup(id => 'popup', content => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit');

Attributes defined in popup-html-attribute and popup-data-attribute can be passed to popup(). Please note that as of writing (jQuery Mobile 1.2), according to the jQuery Mobile website, popups "must live within the page wrapper (for now)".

page

page() generates a container divs. It accepts the following parameters:

role

role can be either "page" or "dialog", defaulted to "page".

head

page() includes HTML head and body wrapper tags by default. Set head to "0" to disable that:

print $jquery_mobile->page(head => 0);
content

content accepts text string.

header

header includes a header toolbars. header accepts a hashref of parameters that gets passed directly to header().

footer

footer includes a footer toolbars. footer accepts a hashref of parameters that gets passed directly to footer().

For example:

print $jquery_mobile->page(
  header => {
    content => $jquery_mobile->button(href => '#', value => 'Home', icon => 'home', iconpos => 'notext') . '<h1>Main Title</h1>',
  },
  footer => {
    position => 'fixed',
    content => '<h3>Footer content</h3>'
  },
  content => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit'
);

pages

pages() generates a "multi-page" template. It accepts the following parameters:

head

pages() includes HTML head and body wrapper tags by default. Set head to "0" to disable that.

pages

pages accepts an arrayref of parameters acceptable by page().

print $jquery_mobile->pages(
  pages => [
    {id => 'page-1', header => {content => '<h1>Page One Heading</h1>'}, content => 'Cillum dolore eu fugiat nulla pariatur. ' . $jquery_mobile->button(icon => 'arrow-r', value => 'Page 2', href => '#page-2')},
    {id => 'page-2', header => {content => '<h1>Page Two Heading</h1>'}, content => 'Excepteur sint occaecat cupidatat non'},
  ]
);

form

form() generates web forms. It accepts attributes defined in form-html-attribute and form-data-attribute. Fields are passed in via the fields arrayref. See form inputs below for reference.

my $form = $jquery_mobile->form(
  title => 'The Form',
  description => 'A description of the form',
  action => '/',
  method => 'get', # defaulted to 'post'
  fields => [
    {name => 'first_name', required => 'required'},
    {name => 'last_name', label => 'Surname', required => 'required'},
    {name => 'email', type => 'email', required => 'required'},
    {name => 'password', type => 'password'},
    {name => 'avatar', type => 'file', accept => 'image/*', capture=> 'camera'},
    {name => 'comment', type => 'textarea'},
    {type => 'radio', name => 'gender', options => ['Male', 'Female']},
    {type => 'checkbox', name => 'country', options => {'AU' => 'Austalia', 'US' => 'United States'}, value => 'AU'},
    {type => 'select', name => 'heard', label => 'How did you hear about us', options => ['Facebook', 'Twitter', 'Google', 'Radio', 'Other']},
    {type => 'rangeslider', name => 'range', mini => 'true', from => {label => 'Range', name => 'from', min => 18, max => 100}, to => {name => 'to', min => 18, max => 100}},
  ],
  controlgroup => {type => 'horizontal'}, # use controlgroup to group the buttons, default to false, accepts "1" or a hashref
  buttons => [
    {value => 'Submit', type => 'submit', icon => 'arrow-r', theme => 'b'},
    {value => 'Cancel', href => '#', icon => 'delete'}
  ],
);

print $jquery_mobile->page(content => $form);

Javascript validation can be added to the form using jQuery-Mobilevalidate https://github.com/dannyglue/jQuery-Mobilevalidate/:

my $jquery_mobile = JQuery::Mobile->new(
  config => {
    'app-title' => 'Hello Mobile World', 
    'app-js' => ['https://raw.github.com/dannyglue/jQuery-Mobilevalidate/master/jquery.mobilevalidate.min.js'],
    'app-inline-js' => '$(document).bind("pageinit", function(){
      $("form").mobilevalidate({novalidate: true});
    });',
  }
);

my $form = $jquery_mobile->form(
  title => 'Testing Form Validation',
  action => '/',
  fields => [
    {name => 'email', type => 'email', required => 'required'},
    {name => 'password', type => 'password', required => 'required'},
    {type => 'checkbox', name => 'country', options => {'AU' => 'Austalia', 'US' => 'United States'}, value => 'AU', required => 'required'},
    {type => 'select', name => 'heard', label => 'How did you hear about us', options => ['Facebook', 'Twitter', 'Google', 'Radio', 'Other'], required => 'required'},
  ],
  buttons => [
    {value => 'Submit', type => 'submit', icon => 'arrow-r', theme => 'b'},
  ],
);

print $jquery_mobile->pages(
  pages => [
    {id => 'form', content => $form},
    {id => 'errordialog', role => "dialog", header => {content => '<h1>Validating</h1>'}, content => ''},
  ]
);

listview

listview() generates listviews. It accepts attributes defined in listview-html-attribute and listview-data-attribute.

my $list = $jquery_mobile->listview(
  anchor => {rel => 'dialog', transition => 'pop'}, # anchor configuration
  items => [
    {value => 'Quick List', divider => 1},
    {aside => '02/06', count => '6', image => 'http://placehold.it/100x100', title => 'One', href => '#'},
    {aside => '03/07', count => '8', image => 'http://placehold.it/100x100', title => 'Two', href => '#'},
    {aside => '04/08', count => '10', image => 'http://placehold.it/100x100', title => 'Three', href => '#'},
  ],
  inset => 'true',
  filter => 'true',
);

print $jquery_mobile->page(content => $list);

table

table() generates tables. It accepts attributes defined in table-html-attribute and table-data-attribute.

my $table = $jquery_mobile->table(
  class => 'ui-responsive',
  th => {
    'First Name' => {priority => '1'}, 
    'Last Name' => {priority => '2'}, 
    'Email' => {priority => '3'}, 
    'Gender' => {priority => '4'}, 
  },
  headers => ['First Name', 'Last Name', 'Email', 'Gender'],
  rows => [
    ['John', 'Smith', 'john@work.com', 'Male'],
    ['Ann', 'Smith', 'ann@work.com', 'Female'],
  ],
);

print $jquery_mobile->page(content => $table);
numbered

numbered can be set to "1", defaulted to false, i.e. HTML ul.

anchor

anchor accepts a hashref to control the attributes of the item anchor links. It accepts attributes defined in button-html-anchor-attribute and button-data-attribute.

split_anchor

split_anchor accepts a hashref to control the attributes of the item split anchor links (Split button lists). It accepts attributes defined in button-html-anchor-attribute and button-data-attribute.

my $list = $jquery_mobile->listview(
  anchor => {rel => 'dialog', transition => 'pop'},
  split_anchor => {transition => 'fade', theme => 'e'},
  items => [
    {title => 'One', href => '#link-1', split => '#split-link-1', split_value => 'Split Value One'},
    {title => 'Two', href => '#link-2', split => '#split-link-2', split_value => 'Split Value Two'},
    {title => 'Three', href => '#link-3', split => '#split-link-3', split_value => 'Split Value Three'},
  ]
);

print $jquery_mobile->page(content => $list);
items

items accepts an arrayref of items. Each item accepts a hashref of aside, count, image, title, value and href. Alternative, formatted content can be passed in via the content parameter, which takes precedent over the other parameters.

collapsible

collapsible() generates collapsible blocks. It accepts attributes defined in collapsible-html-attribute and collapsible-data-attribute. Content can be passed via the content parameter:

my $collapsible = $jquery_mobile->collapsible(
  content => '<h3>Title Heading</h3><p>Excepteur sint occaecat cupidatat non</p>'
);

print $jquery_mobile->page(
  content => $collapsible
);

collapsible() also accepts title, active, and listview as parameters for creating accordion menus via collapsible_set(). See collapsible_set() below.

collapsible_set

collapsible_set() generates collapsible sets. It accepts attributes defined in collapsible-set-html-attribute and collapsible-set-data-attribute. Collapsible content can be passed via the collapsibles parameter:

my $collapsible_set = $jquery_mobile->collapsible_set(    
  collapsibles => [
    {content => '<h3>Item Heading One</h3><p>Item One Content</p>'},
    {content => '<h3>Item Heading Two</h3><p>Item Two Content</p>'},
  ]
);

print $jquery_mobile->page(
  content => $collapsible_set
);

collapsible_set() can also create accordion menus when using with listview():

my $accordion = $jquery_mobile->collapsible_set(    
  active => {
    option => 'title', # what listview item attribute to check for and set it as active 
    value => 'Menu A Item Two' # open the accordion menu where the listview item has the title: 'Menu A Item Two'
  },
  collapsibles => [
    {
      title => 'Menu A',
      listview => {
        items => [
          {title => 'Menu A Item One', href => '#'},
          {title => 'Menu A Item Two', href => '#'},
        ]
      }
    },
    {
      title => 'Menu B',
      listview => {
        items => [
          {title => 'Menu B Item One', href => '#'},
          {title => 'Menu B Item Two', href => '#'},
        ]
      }
    },
  ]
);

print $jquery_mobile->page(
  content => $accordion
);

navbar() generates navbars that are often used in header() and footer(). It accepts attributes defined in navbar-html-attribute and navbar-data-attribute.

my $navbar = $jquery_mobile->navbar(
  items => [
    {value => 'Item One', href => '#'}, 
    {value => 'Item Two', href => '#', active => 1, persist => 1},
    {value => 'Item Three', href => '#'}
  ]
);

print $jquery_mobile->page(
  header => {content => $navbar},
);

items accepts an arrayref of items (i.e. generates HTML li tags). Navbar item attributes are controlled by navbar-item-data-attribute and navbar-item-html-attribute. active adds the 'ui-btn-active' class to the item's CSS. persist adds the 'ui-btn-persist' class to the item's CSS.

button

button() generates anchor and input buttons.

# an anchor button
print $jquery_mobile->button(
  role => 'button', # could be 'button' or 'none', defaulted to 'button'
  href => 'https://www.google.com',
  mini => 'true',
  value => 'Learn More',
  icon => 'arrow-r',
  iconpos => 'right',
  inline => 'true',
  ajax => 'false',
);

# a submit button
print $jquery_mobile->button(
  type => 'submit',
  value => 'Join Now',
  theme => 'e'
);

Please note that anchor buttons accepts button-html-anchor-attribute as data-* attributes, whereas input buttons uses button-data-attribute. HTML attributes for both are defined in button-html-attribute.

panel

panel() generates panel containers. Content can be passed via the content parameter:

my $panel = $jquery_mobile->panel(
	content => 'Panel Content'
);

It accepts attributes defined in panel-html-attribute and panel-data-attribute.

controlgroup

controlgroup() generates controlgroup containers. Content (usually buttons) can be passed via the content parameter:

my $controlgroup = $jquery_mobile->controlgroup(
	mini => 'true',
	type => 'horizontal',
	content => '<a href="#" data-role="button">Yes</a><a href="#" data-role="button">No</a>'
);

It accepts attributes defined in controlgroup-html-attribute and controlgroup-data-attribute. form() uses controlgroup() internally.

input

input() generates various input elements, such as text, email, password, and file. It accepts attributes defined in input-html-attribute and input-data-attribute. form() uses input() internally.

print $jquery_mobile->input(
  id => 'logo', # optional element ID. If not defiend, input 'name' will be used as the 'id'
  name => 'avatar', # MUST have a 'name'
  label => 'Member Avatar', # optional 'label' for the input. If not defined, JQuery::Mobile will generate a label based on the input 'name'
  type => 'file', # optional HTML input types, e.g. 'email', 'password', 'file'. Defaulted to 'text'
  accept => 'image/*', # accepts only images (iOS 6+)
  capture => 'camera'  # allow taking new pictures (iOS 6+)
);

The generated HTML conforms to jQuery Mobile form elements. For instance, inputs are wrapped in a 'fieldcontainer' div.

select

select() generates select boxes. It accepts attributes defined in select-html-attribute and select-data-attribute.

print $jquery_mobile->select(
  name => 'into',
  options => ['Movies', 'Music', 'Photography', 'Everything'],
  value => 'Everything'
);

options can be arrayref or hashref.

checkbox

checkbox() generates checkboxes. It accepts attributes defined in radio-checkbox-html-attribute and radio-checkbox-data-attribute.

print $jquery_mobile->checkbox(
  name => 'web_language',
  options => ['PHP', 'Perl', 'Python', 'Ruby']
);

radio

radio() generates radio button groups. It accepts the same parameters as checkbox().

print $jquery_mobile->radio(
  name => 'country', 
  options => {'AU' => 'Austalia', 'US' => 'United States'}
);

textarea

textarea() generates textareas. It accepts attributes defined in textarea-html-attribute and textarea-data-attribute.

print $jquery_mobile->textarea(
  name => 'comments', 
  rows => '3',
  cols => '50'
);

rangeslider

rangeslider() generates rangesliders. It accepts attributes defined in rangeslider-html-attribute and rangeslider-data-attribute.

print $jquery_mobile->rangeslider(
  type => 'rangeslider', 
  name => 'range', 
  mini => 'true', 
  from => {
    label => 'Range', name => 'from', min => 18, max => 100}, to => {name => 'to', min => 18, max => 100}
);

SEE ALSO

http://jquerymobile.com, https://github.com/dannyglue/jQuery-Mobilevalidate

AUTHOR

Xufeng (Danny) Liang (danny.glue@gmail.com)

COPYRIGHT & LICENSE

Copyright 2013 Xufeng (Danny) Liang, All Rights Reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.