第二部分:使用 JQM.Show 从您的移动设备创建和运行 CRUD JQuery Mobile 应用 (医院)





5.00/5 (5投票s)
演示使用 JQM.Show(一个 RAD JQuery Mobile 开发平台)创建应用程序:文章的第二部分。
引言
这是文章的第二部分:第一部分:使用 JQM.Show 从您的移动设备创建和运行 CRUD JQuery Mobile 应用。
在第一篇文章中,我们讨论了 JQM.Show 的设置,详细介绍了医院管理系统,并创建了具有相应用户界面的医生文件。我们还讨论了 RAD 应用程序的工作原理以及 JQM.Show 的预期。目前,我们正在努力添加 IndexedDB 和 XML 后端,类似于我们在这篇文章中之前讨论的单个 JSON 文件记录。
一些合理的假设:您已经阅读了本系列的第 1 部分。
为您的 Android 移动设备下载 JQM.Show 2。
背景
使用 JQM.Show,可以通过遵循 AMF 方法(即 A-pplication(应用程序)、M-odel(模型)和 F-ields(字段))的三个简单步骤来创建 CRUD JQuery Mobile 原型应用程序。这为您提供了三个简单步骤来创建一个功能齐全的 HTML5 Web 应用程序,该应用程序既响应迅速,又可以在任何移动设备上运行。此外,创建的应用程序还将与 PhoneGap 构建兼容,并可转换为混合应用程序,正如我在这里的文章中所述。
在这期关于使用 JQM.Show 构建这些 Web 应用程序的介绍中,我们将继续之前的讨论。我们将为我们的医院管理系统(称为 HMS)创建医院用户界面和相应的后端 JavaScript。
对于每家医院,我们将仅存储基本信息。这些信息将包括医院名称、地址行 1、地址行 2、城市和邮政编码。对于我们的医院模型,我们还将创建一个列表屏幕,通过 listview 显示医院详细信息,并允许选择以进行编辑。此 listview 将可搜索、可分组,并将成为一个 data-inset listview。
我们还将创建一个报告来列出所有可用的医院,并且可以导出到 Excel 以便进一步处理。当我们添加病人时,我们将创建医生和医院以及病人之间的关系,并使用我喜欢的 d3 绘图框架绘制这些关系。
此 HMS 应用程序中的信息将存储在 LocalStorage 中,但是通过更改后端属性,我们将创建 JSON 后端和 WEBSQL 后端。当关于创建 XML 后端数据库的未来文章发布时,您将看到如何采用此类系统进行 XML 存储,以及以后进行 IndexedDB 和可能的 MySQL 存储。
为了更清晰地说明,我将用图片来展示我们想要实现的目标。
图 1:医院列表 -显示 HMS 中所有已录入医院的列表。Listview 采用 data-inset,按字母分组并可搜索。左侧面板还允许您添加新医院、返回以及查看报告。
图 2:添加医院 -这是根据我们设置的属性将新医院添加到列表中的屏幕。
图 3:编辑医院 -当您从列表中选择一家医院时,会出现此屏幕,以便您更新医院详细信息。用户可以从此屏幕选择更新/删除医院。
图 4:医院报告 -当用户从列表屏幕访问报告时,会生成一个表格。此处列出了所有可用的医院,并且表格可按列过滤。
图 5:Excel 医院报告 -点击医院报告屏幕上的“导出到 Excel”将从可用的医院列表中生成 Excel 报告。
图 6:病人医院关系 -此屏幕使用 D3 图表绘制医院与病人之间的关系。它就像一个小型信息门户,以动画方式列出每家医院的病人。点击医院名称旁的圆形按钮可折叠每个医院的详细信息。点击右上角的“导出”可将您的 d3 关系导出为 png。您可以使用它来呈现信息。这在我这篇文章中有详细解释。
使用代码
既然您已经看到了用户界面及其外观,让我们使用 JQM.Show 来创建医院模块,以便快速生成此应用程序。
1. 从您的移动设备启动 JQM.Show。如果您还没有,可以从此链接下载。
2. 我假设您已经从我们第 1 部分的文章中创建了 HMS,如果是这样,请先按照该文章操作。
3. 我正在使用 Genymotion 进行开发,并将使用该框架进行演示。
4. 登录您的个人资料后,选择“Let's Play”将带您进入登录后可用的项目列表。
5. 从可用项目中选择 **HMS 1.00**,您可以参考本篇文章中的趣味点 1-3 来了解如何完成此操作。下面的图 7 描绘了您的列表可能出现的样子。
图 7:JQM.Show 中的应用程序列表
选择一个项目将打开其属性,您可以进行更新和保存。这些信息将用于创建您想要的 SPA 应用程序。
图 8:HMS 属性 - 让 HMS 活起来。
应用程序名称:这是我们正在创建的应用程序的名称。app.js 文件中的第 3 行如下定义了该应用程序:
var HMS = {};
作者:创建此应用程序的人员姓名
版权:此应用程序的最终所有者
版本:目前我们正在开发 HMS 的 1.00 版本。
过渡:这是我们将在应用程序的所有页面中使用的页面过渡。页面可以滑动、淡入、弹出等。如我在增强家谱的文章中所述,这里也添加了自定义过渡。JQuery Mobile 过渡在此处有详细说明。
选择的滑动效果在 app.js 的第 4 行中定义,那里是您应用程序的源代码。
var pgtransition = 'slide';
启用安全:我们希望我们的 HMS 应用程序允许用户登录和注册。启用此选项将创建登录和注册模型及其字段以及我们选择的任何后端源代码。
启用 PhoneGap:这将加载我们应用程序中相应的 cordova.js,以便我们可以访问任何设备特定的功能。目前我正在尝试访问相机以拍照作为此体验的一部分。暂时将其关闭。
选择“下一步”以更新更多 HMS 属性。
出现图 9:这些是该项目的高级属性。
在此处输入作者信息,如电子邮件、支持网站和项目描述。我想您可能想知道这些信息有什么用以及它们去哪里。如果您打开 index.html 文件和附带的 config.xml 文件,您会看到这些信息用在其中,让我们看看下面的内容。这是 index.html 文件开头的 4 行。
<!DOCTYPE html>
<html manifest="index.appcache">
<head>
<title>HMS</title>
同一文件的第 17-21 行将包含此内容,具体取决于您在此处指定的选项。
<meta name='copyright' content='Anele Mbanga ' />
<meta name='author' content=' Anele Mbanga' />
<meta name='email' content='anele@mbangas.com' />
<meta name='website' content='http://www.mbangas.com/jqmshow/hms' />
<meta name='description' content='Web app to manage hospital patients. Available from Android Play Store at https://play.google.com/store/apps/details?id=com.b4a.JQMShow' />
您会注意到,主要的 index.html 文件还加载了脚本来添加您的 CSS 和 JS 文件。您也可以更新这些文件,并在自定义应用程序时添加自己的 CSS 和 JS 文件。例如,您可能希望通过替换这些行中引用的 png 文件来更新应用程序中使用的图标。
<link rel="apple-touch-icon" href="apps.png">
<link rel="icon" type="image/png" href="apps.png">
<link rel="shortcut icon" type="image/png" href="apps.png">
<link rel="apple-touch-icon" sizes="57x57" href="apps57.png">
<link rel="apple-touch-icon" sizes="72x72" href="apps72.png">
<link rel="apple-touch-icon" sizes="80x80" href="apps80.png">
<link rel="apple-touch-icon" sizes="114x114" href="apps114.png">
<link rel="apple-touch-icon-precomposed" href="appsIconPreComposed.png">
<link rel="apple-touch-startup-image" href="appsIconStartUp320by460.png">
这些是 JQM.Show 从 3.0 版本开始包含在所有应用程序中的 CSS 文件。
<link rel="stylesheet" href="jquery.mobile-1.4.5.min.css">
<link rel="stylesheet" href="toastr.min.css">
<link rel="stylesheet" href="jqm-datebox.css">
<link rel="stylesheet" href="animate.css">
<link rel="stylesheet" href="addtohomescreen.css">
toastr.min.css 用于处理弹出的绿色消息通知,告知您记录已添加/更新/删除。
jqm-datebox.css 用于 JQM.Show 应用程序中所有日期字段的日期选择器小部件。
animate.css 用于 JQM.Show Web 应用程序中可用的自定义过渡。
addtohomescreen.css 用于在应用程序主屏幕上添加图标时使用。
JQM.Show 使用的 JS 文件如下:
<script src="jquery.min.js" type="text/javascript"></script>
<script src="navbar.js" type="text/javascript"></script>
<script src="jquery.mobile-1.4.5.min.js" type="text/javascript"></script>
<script src="jqm-datebox.core.js" type="text/javascript"></script>
<script src="jqm-datebox.mode.slidebox.js" type="text/javascript"></script>
<script src="jqm-datebox.mode.flipbox.js" type="text/javascript"></script>
<script src="jqm-datebox.mode.datebox.js" type="text/javascript"></script>
<script src="jqm-datebox.mode.customflip.js" type="text/javascript"></script>
<script src="jqm-datebox.mode.custombox.js" type="text/javascript"></script>
<script src="jqm-datebox.mode.calbox.js" type="text/javascript"></script>
<script src="toastr.min.js" type="text/javascript"></script>
<script src="fastclick.js" type="text/javascript"></script>
<!--[if IE]>
<script src="html5.js" type="text/javascript"></script>
<![endif]-->
<script src="stanfordcryptolibrary.js" type="text/javascript"></script>
<script src="excellentexport.min.js" type="text/javascript"></script>
<script src="iscroll.js" type="text/javascript"></script>
<script src="password.js" type="text/javascript"></script>
<script src="d3.min.js" type="text/javascript"></script>
<script src="d3tree.js" type="text/javascript"></script>
<script src="addtohomescreen.min.js" type="text/javascript"></script>
<script src="app.js" type="text/javascript"></script>
navbar.js 用于处理基于 div 的标签导航。这在我们之前的家谱应用程序中首次得到探索,并在此处用于病人屏幕。
jqm-datebox... 用于所有日期选择器
fastclick.js - 用于处理点击事件延迟。这在我们的 app.js 文件的第 27 行中实现,如下所示:
FastClick.attach(document.body);
stanfordcryptolibrary.js - 这在我这里的文章中进行了讨论。我们将其用于密码。
我们的 app.js 文件中的第 954 行使用此库加密密码,如下所示:
UserRec.ConfirmPassword = sjcl.encrypt('MashJQMShow', UserRec.ConfirmPassword);
在第 984 行,我们解密它。
UserRec.ConfirmPassword = sjcl.decrypt('MashJQMShow', UserRec.ConfirmPassword);
MashJQMShow is the salt key.
iscroll.js - 元素滚动,目前用于 listviews。我们已经像这样为我们的 listviews 初始化了 iscroll:
var pgDoctorListScroller = new IScroll('#pgDoctorList', {mouseWheel:true, scrollbars:true, bounce:true, zoom:false});
var pgUserListScroller = new IScroll('#pgUserList', {mouseWheel:true, scrollbars:true, bounce:true, zoom:false});
var pgHospitalListScroller = new IScroll('#pgHospitalList', {mouseWheel:true, scrollbars:true, bounce:true, zoom:false});
正如您所见,这些是用于我们现有的 listviews,它们显示在医生列表、用户列表和医院列表中。对于我们默认拥有的每个模型,我们都有一个列出记录的 listview,因此它会自动为用户创建。
d3.min.js, d3tree,js - 用于您的关系屏幕的图表库,如图 6 所示。这在我这里的文章中也首次进行了讨论。
addtohomescreen.js - 用于将应用程序图标添加到设备主屏幕的代码。
我们 app.js 文件的第 28-29 行如下所示地处理此设备图标:
addToHomescreen();
var addToHomeConfig = {returningVisitor: true, expire: 720, autostart: false};
从 Web 首次运行时,添加到主屏幕会运行。
app.js - JQM.Show 生成的应用程序代码。
我们 HMS 的后端是LocalStorage,所以这次选择它。您也可以在第 3 版中选择SQL用于 WebSQL,JSON,XML。
选择“下一步”,现在将提供 HMS 可用模型的列表。模型定义我们的表(数据库术语),它们只是代表我们想要记录的内容。我们已经创建了医生模型及其字段,现在我们将创建 Hospitals 来存储我们的医院的简单详细信息。
图 10:HMS 模型列表
要创建 Hospitals 模型,请点击“新建”(创建新模型),如图 11 所示。
图 11:模型创建。
模型名称:在模型名称中,键入 Hospital。
显示名称应为 Hospitals。这是将显示在页面标题部分中的文本。显示名称通常是模型名称的复数形式。
在“上一页”中,选择 pgMenu,这是应用程序的 SpringBoard 页面的名称。但是,您可以选择任何您想要的页面名称。每个模型都会创建 3 个页面:添加页面、更新页面和列表页面。
将“下一页”留空,这通常是应访问的下一个页面的名称。
访问上一页和下一页是通过标题按钮实现的。一个在屏幕的左侧,一个在右侧。
Mini 是此模型的可添加、可编辑页面的控件的data-mini。撰写本文时,当使用 mini 控件时,滑块控件存在一个错误。选中 Mini 会确保表单中的所有控件都具有 data-mini 属性 = true,从而使它们变小。
无标签可确保在选中时,所有表单都没有标签。上面的图 2 和图 3 是带有标签的添加更新屏幕,以指示字段名称。取消选中此项将从页面中移除标签。
In Field Contain 可确保页面所有子控件都包含在一个具有 fieldcontain data-role 的 div 中。
将导航栏项目留空。我们尚未将此模型拆分为各种部分。但是,我们将拆分病人详细信息,以便它们能很好地适应屏幕。拥有导航选项卡可以改善应用程序的导航。我们完成了模型定义,需要赋予它更多属性,例如字段名称,然后单击“下一步”。如图 12 所示,这是 ListView 参数的定义,用于医院列表页面。
图 12:医院的 ListView 定义和其他属性
SplitView - 选中后,它会创建一个模型的拆分视图,将 listview 和数据输入放在一个屏幕上。我们不希望这样处理医院,因此将其取消选中。
Inset - 我们希望 listview 具有 data-inset 属性,以便在页面内显示。取消选中此项会使 listview 填充页面的完整宽度。
Auto Dividers - 我们希望医院名称按字母顺序排序,并且列表要分隔。
Searchable - 我们希望 listview 被过滤,也请勾选此项。
仅设置这些属性,就会创建图 1,并将具有以下 HTML 定义。
医院列表 ListView 定义
<div data-model="Hospital" id="pgHospital" data-role="page">
<div data-position="left" data-display="reveal" data-position-fixed="true" id="pgHospitalPnl" data-role="panel">
<ul data-role="listview" id="pgHospitalPnlLV">
<li data-icon="plus"><a data-transition="slide" href="#pgAddHospital">New</a></li>
<li data-icon="eye"><a data-transition="slide" href="#pgRptHospital">Report</a></li>
<li data-icon="carat-l"><a data-transition="slide" href="#pgMenu">Back</a></li>
</ul>
</div>
<header id="pgHospitalHdr" data-role="header" data-position="fixed">
<h1>HMS</h1>
<a data-role="button" id="pgHospitalMenu" href="#pgHospitalPnl" data-icon="bars" data-transition="slide" class="ui-btn-left">Menu</a>
<a data-role="button" id="pgHospitalNew" data-icon="plus" data-theme="b" class="ui-btn-right">New</a>
</header>
<div id="pgHospitalCnt" data-role="content">
<h3>Hospitals</h3><ul data-role="listview" data-inset="true" id="pgHospitalList" data-autodividers="true" data-filter="true" data-filter-placeholder="Search Hospitals">
<li data-role="list-divider">Your Hospitals</li>
<li id="noHospital">You have no hospitals</li>
</ul>
</div>
</div>
从上面的 HTML 定义中,让我们回顾一下,我们的模型名称是 Hospital,因此所有与 hospital 模型相关的都会有这样的前缀。页面被定义为 pgHospital。我们还自动在列表中添加了一个左侧面板,用于添加、报告和返回上一屏幕。这是为了方便导航。左侧面板的显示属性是 reveal。我最初在我这里的文章中讨论过侧面板。
正如您所见,滑动过渡已应用于我们这里的所有锚点,因为这是我们的选择。在我们的 listview 定义之前,医院的显示名称在上面的 h3 中。
我们的 inset 属性转换为data-inset="true",auto dividers 转换为data-autodividers="true",而Searchable 转换为data-filter="true" 并带有data-filter-placeholder="Search <displayname>"。
对于每个模型,我们始终遵循这些原则。
图 13:医院模型字段
上面的图 13 详细说明了医院模型的字段名称。我们很容易像这样创建它们。
1. 点击“新建字段”,这将打开下面的图 14。
图 14:医院 -> 添加字段
2. 输入医院模型的字段名称,即 Hospital Name;Address Line 1;Address Line 2;City;Postal Code。请注意,此处的字段应以分号分隔。**注意:您指定的第一个字段应该是您模型的*主键*。** 我们的主键是 Hospital Name。
3. 选择“下一步”,您就完成了医院模型的字段属性的定义。您将返回到医院的字段列表,如图 13 所示。我们需要更改每个字段的几个属性。
更改字段属性
图 15:医院名称字段(我将让您自行更新,如需)
图 16:地址行 1
图 17:地址行 2
图 19:城市
图 20:邮政编码
就是这样,我们完成了关于医院的所有定义。万一您犯了错误,您可以按住列表中的任何字段,如图 21 所示。
图 21:删除/移动字段(制表符顺序和定位)
现在我们的模型已按我们期望的方式定义,现在让 JQM.Show 为您创建源代码和所有内容的 HTML 定义。由于这是一个续篇,所有内容都将从头开始重写,因此,重要的是,一旦 JQM.Show 完成您的系统,您进行的任何定制都将完成。
选择后退菜单按钮,然后返回到应用程序定义屏幕,如图 10 所示。
图 21:应用程序菜单
在应用程序菜单上,按下蓝色的类似 Chrome 的按钮来创建您基于本地存储的名为 HMS 的 Web 应用程序。让我们看看医院模型的输出。
执行的操作如下...
1. 创建一个医院列表页面来列出所有医院(图 1)。
2. 创建一个添加新医院的屏幕(图 2)。
3. 创建一个编辑/更新/删除医院的屏幕(图 3)。
3. 还创建了一个医院报告屏幕,并具有导出到 Excel 的功能(图 4 和图 5)。
所有这些页面都有其相应的源代码和 HTML 定义。对于您创建的每个模型,JQM.Show 都将遵循此过程。如果您为每个模型定义了关系,您的左侧面板将具有链接到这些关系的附加功能。我们将在本系列的第 3 篇文章中通过查看病人来演示这一点。
上面讨论了医院列表的 HTML 定义。我们应用程序的第 16-20 行与列表相关的代码如下。
// variable definitions go here
var HospitalLi = '<li ><a data-id="Z2"><h2>Z1</h2><p>DESCRIPTION</p></a></li>';
var HospitalHdr = '<li data-role="list-divider">Your Hospitals</li>';
var noHospital = '<li id="noHospital">You have no hospitals</li>';
var pgHospitalListScroller = new IScroll('#pgHospitalList', {mouseWheel:true, scrollbars:true, bounce:true, zoom:false});
这些只是我们 ListView 的变量以及它的工作原理。在显示医院列表页面之前,会检查 LocalStorage 中是否有任何可用的医院,如果存在,则加载它们,如果不存在,则显示默认值。
$(document).on('pagebeforechange', function (e, data) {
//get page to go to
var toPage = data.toPage[0].id;
switch (toPage) {
case 'pgHospital':
$('#pgRptHospitalBack').data('from', 'pgHospital');
// restart the storage check
app.checkForHospitalStorage();
break;
在更改之前调用 app.checkForHospitalStorage,它执行以下操作:
// check LocalStorage for Records. This initializes LocalStorage if there are no records
//display records if they exist or tell user no records exist.
app.checkForHospitalStorage = function () {
//get records from LocalStorage.
var HospitalObj = app.getHospital();
// are there existing Hospital records?
if (!$.isEmptyObject(HospitalObj)) {
// yes there are. pass them off to be displayed
app.displayHospital(HospitalObj);
} else {
// nope, just show the placeholder
$('#pgHospitalList').html(HospitalHdr + noHospital).listview('refresh');
}
};
这会调用 app.getHospital,它返回一个已解析的 JSON 对象,其中包含所有现有的医院,如果它不为空,则使用 app.displayHospital 显示医院。
app.getHospital 执行此操作:
app.getHospital = function () {
// get Hospital records
var HospitalObj = localStorage['hms-hospital'];
if (!HospitalObj) {
//if there are no existing records, create an empty object
HospitalObj = {};
//save empty object to LocalStorage
localStorage['hms-hospital'] = JSON.stringify(HospitalObj);
} else {
//records exist, parse them into an array as they are stored as text
HospitalObj = JSON.parse(HospitalObj);
}
return HospitalObj;
};
我们的应用程序名称是 HMS,我们有一个名为 hospital 的模型,因此我们的 LocalStorage 存储位置将是 hms-hospital,这可以区分我们所有的模型,同时又能轻松地告诉用户应用程序的名称。在 app.getHospital 执行并返回这些医院的数组后,app.displayHospital 将它们显示在 listview 中。在添加了一些医院后,在您的浏览器中按 F12 即可访问开发人员菜单。
图 22:LocalStorage
从上面可以看出,我们拥有的每个模型都以应用程序名称 hms 作为前缀。因此,当您将 LocalStorage 用作后端时,没有两个应用程序名称相同是很重要的。一旦 app.getHospital 执行并返回这些医院的数组,app.displayHospital 就会在 listview 中显示它们。
//display records in listview during runtime.
app.displayHospital = function (HospitalObj) {
// create an empty string to contain html
var html = '';
// make sure your iterators are properly scoped
var n;
// loop over records and create a new list item for each
//append the html to store the listitems.
for (n in HospitalObj) {
//get the record details
var HospitalRec = HospitalObj[n];
// clean the primary key
var pkey = HospitalRec.HospitalName;
pkey = pkey.split('-').join(' ');
HospitalRec.HospitalName = pkey;
//define a new line from what we have defined
var nItem = HospitalLi;
nItem = nItem.replace(/Z2/g,n);
//update the title to display, this might be multi fields
var nTitle = '';
//assign cleaned title
nTitle = n.split('-').join(' ');
//replace the title;
nItem = nItem.replace(/Z1/g,nTitle);
//there is a description, update the list item
var nDescription = '';
nDescription += HospitalRec.AddressLine1;
nDescription += ', ';
nDescription += HospitalRec.AddressLine2;
nDescription += ', ';
nDescription += HospitalRec.City;
//replace the description;
nItem = nItem.replace(/DESCRIPTION/g,nDescription);
html += nItem;
}
//update the listview with the newly defined html structure.
$('#pgHospitalList').html(HospitalHdr + html).listview('refresh');
};
如果您还记得,当图 1 中列出每家医院时,我们希望地址行 1、地址行 2 和城市显示在每个 listview 项目的描述行(第二行)上。您还记得这是如何完成的吗?当我们创建每个字段时,我们检查了**Description** 属性,从而告诉 JQM.Show 将该字段放在我们想要的每个 listview 项目中。然后 app.displayHospital 执行此操作,我们将从 LocalStorage 返回的 Hospital 对象传递给它,然后对于每家医院,都会读取字段值,并在循环中生成每个项目。
我们获取我们想要的每家医院...
var HospitalRec = HospitalObj[n];
默认情况下,医院,由于是主键,将始终是每个 listview 项目的标题。
我们创建每个医院条目...
var nItem = HospitalLi;
目前是...
var HospitalLi = '<li ><a data-id="Z2"><h2>Z1</h2><p>DESCRIPTION</p></a></li>';
Z2,获取未经清理格式的医院名称。当我们选择每家医院时,就会读取此 data-id 属性并将其传递给编辑屏幕。
nItem = nItem.replace(/Z2/g,n);
然后更新标题,其中包含医院名称的清理版本,不带“-”。
var nTitle = '';
//assign cleaned title
nTitle = n.split('-').join(' ');
//replace the title;
nItem = nItem.replace(/Z1/g,nTitle);
然后,描述从选定的字段(即地址行 1、2 和城市)构建。
//there is a description, update the list item
var nDescription = '';
nDescription += HospitalRec.AddressLine1;
nDescription += ', ';
nDescription += HospitalRec.AddressLine2;
nDescription += ', ';
nDescription += HospitalRec.City;
//replace the description;
nItem = nItem.replace(/DESCRIPTION/g,nDescription);
html += nItem;
当每个医院的 HTML 构建完成后,listview 将被更新并刷新内容。
//update the listview with the newly defined html structure.
$('#pgHospitalList').html(HospitalHdr + html).listview('refresh');
添加新医院。
添加新医院的页面也很简单。根据我们在上面模型中指定的字段,会添加一个链接到该页面的屏幕。添加页面称为 pgAddHospital,基于我们的模型。指定的输入控件将以该页面名称作为前缀,以区别于任何其他控件。让我们看看这个。根据图 2,此页面有一个页眉、一个页脚和中间的一些控件。它的定义如下。
<div data-model="Hospital" id="pgAddHospital" data-role="page">
<div data-position="left" data-display="reveal" data-position-fixed="true" id="pgAddHospitalPnl" data-role="panel">
<ul data-role="listview" id="pgAddHospitalPnlLV">
<li data-icon="plus"><a data-transition="slide" href="#pgAddHospital">New</a></li>
<li data-icon="eye"><a data-transition="slide" href="#pgRptHospital">Report</a></li>
<li data-icon="carat-l"><a data-transition="slide" href="#pgHospital">Back</a></li>
</ul>
</div>
<header id="pgAddHospitalHdr" data-role="header" data-position="fixed">
<h1>HMS</h1>
<a data-role="button" id="pgAddHospitalMenu" href="#pgAddHospitalPnl" data-icon="bars" class="ui-btn-left">Menu</a>
</header>
<div id="pgAddHospitalCnt" data-role="content">
<h3>Add Hospital</h3><form action="#" method="post" id="pgAddHospitalForm" name="pgAddHospitalForm">
<div data-role="fieldcontain">
<label for="pgAddHospitalHospitalName">Hospital Name<span style='color:red;'>*</span></label>
<input required title="Enter hospital name here." type="text" name="pgAddHospitalHospitalName" id="pgAddHospitalHospitalName" placeholder="Enter hospital name here." autocomplete="off" data-clear-btn="true"></input>
</div>
<div data-role="fieldcontain">
<label for="pgAddHospitalAddressLine1">Address Line 1<span style='color:red;'>*</span></label>
<input required title="Enter address line 1 here." type="text" name="pgAddHospitalAddressLine1" id="pgAddHospitalAddressLine1" placeholder="Enter address line 1 here." autocomplete="off" data-clear-btn="true"></input>
</div>
<div data-role="fieldcontain">
<label for="pgAddHospitalAddressLine2">Address Line 2</label>
<input type="text" name="pgAddHospitalAddressLine2" id="pgAddHospitalAddressLine2" placeholder="Enter address line 2 here." autocomplete="off" data-clear-btn="true"></input>
</div>
<div data-role="fieldcontain">
<label for="pgAddHospitalCity">City<span style='color:red;'>*</span></label>
<input required title="Enter city here." type="text" name="pgAddHospitalCity" id="pgAddHospitalCity" placeholder="Enter city here." autocomplete="off" data-clear-btn="true"></input>
</div>
<div data-role="fieldcontain">
<label for="pgAddHospitalPostalCode">Postal Code<span style='color:red;'>*</span></label>
<input required title="Enter postal code here." type="number" name="pgAddHospitalPostalCode" id="pgAddHospitalPostalCode" placeholder="Enter postal code here." autocomplete="off" data-clear-btn="true"></input>
</div>
</form>
</div>
<footer id="pgAddHospitalFtr" data-role="footer" data-position="fixed">
<div id="pgAddHospitalFtrNavBar" data-role="navbar">
<ul>
<li><a id="pgAddHospitalBack" data-icon="carat-l">Cancel</a>
</li>
<li><a type="submit" id="pgAddHospitalSave" data-icon="action">Save</a>
</li>
</ul>
</div>
</footer></div>
选择此屏幕上的菜单将打开左侧滑动面板,该面板提供访问新医院、查看医院报告以及转到列表屏幕的权限。在页面内容中,我们的 h3 包含“Add Hospital”。
我们希望每个字段都在字段容器内,因此每个看起来都像:
<div data-role="fieldcontain">
<label for="pgAddHospitalHospitalName">Hospital Name<span style='color:red;'>*</span></label>
<input required title="Enter hospital name here." type="text" name="pgAddHospitalHospitalName" id="pgAddHospitalHospitalName" placeholder="Enter hospital name here." autocomplete="off" data-clear-btn="true"></input>
</div>
每个字段的其余属性基于我们给它起的名字。查看 title 属性以及 placeholder,还有这些...
name="pgAddHospitalHospitalName" id="pgAddHospitalHospitalName"
此屏幕的页脚有取消和保存按钮。取消将我们带回列表屏幕,而保存确保我们的医院记录已保存到 localstorage。您可以参考之前的文章,了解如何获取和保存屏幕内容到 localstorage,因为我已经对此进行了很好的讨论。JQM.Show 始终生成相同的源代码,只是链接到模型名称,因此我不会重复太多,请耐心等待。
更新现有医院。
<div data-url="HospitalName" data-model="Hospital" id="pgEditHospital" data-role="page">
<div data-position="left" data-display="reveal" data-position-fixed="true" id="pgEditHospitalPnl" data-role="panel">
<ul data-role="listview" id="pgEditHospitalPnlLV">
<li data-icon="plus"><a data-transition="slide" href="#pgAddHospital">New</a></li>
<li data-icon="eye"><a data-transition="slide" href="#pgRptHospital">Report</a></li>
<li data-icon="carat-l"><a data-transition="slide" href="#pgHospital">Back</a></li>
</ul>
</div>
<header id="pgEditHospitalHdr" data-role="header" data-position="fixed">
<h1>HMS</h1>
<a data-role="button" id="pgEditHospitalMenu" href="#pgEditHospitalPnl" data-icon="bars" class="ui-btn-left">Menu</a>
</header>
<div id="pgEditHospitalCnt" data-role="content">
<h3>Edit Hospital</h3><form action="#" method="post" id="pgEditHospitalForm" name="pgEditHospitalForm">
<div data-role="fieldcontain">
<label for="pgEditHospitalHospitalName">Hospital Name<span style='color:red;'>*</span></label>
<input required readonly="readonly" data-clear-btn="true" autofocus="true" title="Enter hospital name here." type="text" name="pgEditHospitalHospitalName" id="pgEditHospitalHospitalName" placeholder="Enter hospital name here." autocomplete="off"></input>
</div>
<div data-role="fieldcontain">
<label for="pgEditHospitalAddressLine1">Address Line 1<span style='color:red;'>*</span></label>
<input required title="Enter address line 1 here." type="text" name="pgEditHospitalAddressLine1" id="pgEditHospitalAddressLine1" placeholder="Enter address line 1 here." autocomplete="off" data-clear-btn="true"></input>
</div>
<div data-role="fieldcontain">
<label for="pgEditHospitalAddressLine2">Address Line 2</label>
<input type="text" name="pgEditHospitalAddressLine2" id="pgEditHospitalAddressLine2" placeholder="Enter address line 2 here." autocomplete="off" data-clear-btn="true"></input>
</div>
<div data-role="fieldcontain">
<label for="pgEditHospitalCity">City<span style='color:red;'>*</span></label>
<input required title="Enter city here." type="text" name="pgEditHospitalCity" id="pgEditHospitalCity" placeholder="Enter city here." autocomplete="off" data-clear-btn="true"></input>
</div>
<div data-role="fieldcontain">
<label for="pgEditHospitalPostalCode">Postal Code<span style='color:red;'>*</span></label>
<input required title="Enter postal code here." type="number" name="pgEditHospitalPostalCode" id="pgEditHospitalPostalCode" placeholder="Enter postal code here." autocomplete="off" data-clear-btn="true"></input>
</div>
</form>
</div>
<footer id="pgEditHospitalFtr" data-role="footer" data-position="fixed">
<div id="pgEditHospitalFtrNavBar" data-role="navbar">
<ul>
<li><a data-transition="slide" id="pgEditHospitalBack" href="#pgHospital" data-icon="carat-l">Cancel</a>
</li>
<li><a type="submit" id="pgEditHospitalUpdate" data-icon="action">Update</a>
</li>
<li><a id="pgEditHospitalDelete" data-icon="delete">Delete</a>
</li>
</ul>
</div>
</footer></div>
编辑/更新/删除屏幕允许用户更新或删除现有医院。此页面的名称是
pgEditHospital
您会注意到输入控件是相同的,只是这次它们前面加上了 pgEditHospital 前缀。
报告现有医院
<div data-model="Hospital" id="pgRptHospital" data-role="page">
<header id="pgRptHospitalHdr" data-role="header" data-position="fixed">
<h1>HMS</h1>
<a data-role="button" id="pgRptHospitalBack" data-icon="carat-l" class="ui-btn-left">Back</a>
<a data-role="button" id="pgRptHospitalNew" href="#pgAddHospital" data-icon="plus" data-theme="b" data-transition="slide" class="ui-btn-right">New</a>
</header>
<div id="pgRptHospitalCnt" data-role="content">
<table id="RptHospital" data-column-btn-text="Columns To Display" data-column-btn-theme="b" data-role="table" data-mode="columntoggle" data-column-popup-theme="a" class="ui-responsive table-stroke table-stripe ui-shadow">
<caption>Hospitals Report</caption>
<thead>
<tr class="ui-bar-c">
<th class="ui-bar-c">Hospital Name</th>
<th data-priority="2" class="ui-bar-c">Address Line 1</th>
<th data-priority="3" class="ui-bar-c">Address Line 2</th>
<th data-priority="4" class="ui-bar-c">City</th>
<th data-priority="5" class="ui-bar-c">Postal Code</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr><td></td></tr>
<tr><td colspan="5">Powered by JQM.Show - https://play.google.com/store/apps/details?id=com.b4a.JQMShow</td></tr></tfoot>
</table>
<div data-role="fieldcontain">
<a download="Hospital.xls" onclick="return ExcellentExport.excel(this, 'RptHospital', 'Hospital');" id="pgRptHospitalExport" data-corners="true" href="#" class="ui-btn ui-corner-all ui-shadow">Export to Excel</a></div>
</div>
</div>
关于报告创建的第一篇文章是我的家谱文章,请参考该文章。这里的关键是,当我们定义字段时,我们为我们想要出现在报告中的每个字段勾选了 Report 复选框。当 JQM.Show 创建报告屏幕时,它会查看这些字段并根据指定的字段生成标题。此外,在显示屏幕之前,通过调用此方法来更新此报告的内容。
//display records in table during runtime. app.HospitalRpt = function () { //clear the table and leave the header $('#RptHospital tbody tr').remove(); // get Hospital records. var HospitalObj = app.getHospital(); // create an empty string to contain all rows of the table var newrows = ''; // make sure your iterators are properly scoped var n; // loop over records and create a new row for each // and append the newrows with each table row. for (n in HospitalObj) { //get the record details var HospitalRec = HospitalObj[n]; //clean primary keys n = n.split('-').join(' '); //create each row var eachrow = '<tr>'; eachrow += '<td class="ui-body-c">' + n + '</td>'; eachrow += '<td class="ui-body-c">' + HospitalRec.AddressLine1 + '</td>'; eachrow += '<td class="ui-body-c">' + HospitalRec.AddressLine2 + '</td>'; eachrow += '<td class="ui-body-c">' + HospitalRec.City + '</td>'; eachrow += '<td class="ui-body-c">' + HospitalRec.PostalCode + '</td>'; eachrow += '</tr>'; //append each row to the newrows variable; newrows += eachrow; } // update the table $('#RptHospital').append(newrows); // refresh the table with new details $('#RptHospital').table('refresh'); };
这结束了我们的医院模型及其相应的 HTML 定义和源代码。请探索附带的源代码,它将为本文提供更多见解。所有附带的 HTML 定义、源代码都由 JQM.Show 生成,可让您在几分钟内生成一个基本的、可工作的 Web 应用程序。
关注点
JQM.Show 目前正在逐步发展。这是第二篇详细讨论如何使用此概念化框架创建应用程序的文章。通过三个简单的步骤,您就可以在几分钟内创建一个功能齐全的 Web 应用程序,只需清晰的数据定义即可。在本文中,我们为我们的医院管理系统创建了一个医院模型,并试图解释 JQM.Show 如何帮助您快速缩短开发时间。大多数应用程序都涉及数据的存储和检索,我们旨在通过遵循最佳实践和现有建议,使这项工作变得轻松。由于 JQM.Show 现在能够生成特定后端的源代码,因此我包含了 HMS 的 WebSQL 和 JSON 版本。将来我们会添加其他后端。祝您使用愉快。