65.9K
CodeProject 正在变化。 阅读更多。
Home

MyFamily.Show:一个简单的JQuery Mobile家庭树

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.74/5 (6投票s)

2015年3月4日

CPOL

11分钟阅读

viewsIcon

18972

downloadIcon

236

MyFamily.Show:一个简单的家庭树移动应用程序,用于保存家庭树的详细信息。

引言

该项目的目的是演示如何创建一个单页应用程序,以便在不增加额外页面的情况下,在不同的选项卡中存储人员信息。它还探索了JQuery Mobile中的日期选择器小部件、滑块、水平单选按钮和开关控件。这还演示了如何从LocalStorage中存储的数据动态加载SelectMenu,以及如何将SelectMenu文本左对齐。对于家庭成员的列表,我演示了如何用成员的年龄填充计数气泡,并在每个家庭成员的列表视图项上显示联系方式。有趣的是,无论你如何添加他们,所有家庭成员都将始终按升序排列。这是通过一个脚本在网络应用程序执行保存时对JSON进行排序来实现的。

这是MyFamily.Show的完整源代码。 下载 MyFamily.Show.zip

背景

我想要了解如何在我的 JQuery Mobile 应用程序中使用导航选项卡将表单分成不同的信息部分。同时,我还想知道如何从我的 LocalStorage 中存储的信息动态加载 SelectMenu,并且这些信息应该是相关的,例如,一个人的父母。我希望一个人的信息部分驻留在一个页面内,通过 div 元素分隔,而不是从另一个页面加载。

在开发家庭树时,需要一个人的基本信息。我总结这些部分与以下项目相关

  • 个人信息(性别、全名、称谓、身份证号/社保号、出生日期、年龄、是否在世?和出生地点)
  • 联系方式 - (手机/移动电话号码、电子邮件地址)
  • 关系 - (父亲和母亲) 和
  • 死亡 - (死亡日期、死亡地点)

这个应用程序当然可以定制以包含更多信息,但为了本次演示,我希望只保留基本信息。

捕获到的信息会存储在 LocalStorage 中。

使用代码

像所有HTML5网络应用一样,用户界面应该被设计,然后创建用于保存、检索和删除信息的各种按钮的链接。我们将定义一个包含四个导航栏项的页面,它们分别是个人信息、联系方式、关系和死亡。每个选项卡都将包含向用户请求的信息,用户在死亡屏幕上保存家庭成员的详细信息。我仍在探索如何将其制作成向导式界面。

我正在遵循我在创建 NoteKeeper 应用程序时使用的相同方法,用于 CRUD 应用程序开发,详见此处。 

我将深入探讨重要的内容,您可以查阅源代码以获取更多详细信息。这将定义导航栏、页面以及链接它们的源脚本。

导航栏 - html定义和输出

<div id="pgAddFamilyMember" data-role="page">

<header id="pgAddFamilyMemberheader" data-role="header" data-position="fixed">
<h1>MyFamily.Show > Add Family Member</h1>
<a data-role="button" id="pgAddFamilyMemberBack" data-icon="arrow-l" class="ui-btn-left">Back</a>
<div id="pgAddFamilyMemberHdrNav" data-role="navbar">
<ul>
<li><a href="#" data-href="pgAddFamilyMemberPersonalInformation" id="pgAddFamilyMemberPersonalInformationBtn" class="ui-btn-active">Personal Information</a>
</li>
<li><a href="#" data-href="pgAddFamilyMemberContactDetails" id="pgAddFamilyMemberContactDetailsBtn">Contact Details</a>
</li>
<li><a href="#" data-href="pgAddFamilyMemberRelationships" id="pgAddFamilyMemberRelationshipsBtn">Relationships</a>
</li>
<li><a href="#" data-href="pgAddFamilyMemberDeath" id="pgAddFamilyMemberDeathBtn">Death</a>
</li>
</ul>
</div>
</header>

添加家庭成员的页面称为 pgAddFamilyMember,更新页面称为 pgEditFamilyMember,它们具有相似的导航栏。导航栏中的每个元素都有一个 data-href 属性,用于存储点击每个按钮时要导航到的 div 的名称。我不得不为每个按钮添加一个 id 属性,因为每次添加此页面时,我都希望它默认显示第一个屏幕,即“个人详细信息”,无论用户上次在哪里。这是通过使用 id 触发标题按钮的点击事件来实现的。该触发器是以下代码的一部分,它在页面显示之前触发。

上述标题的最终输出如下图1所示,运行于iPad Ripple模拟器。

图 1

 

// code to run before showing the page that lists the records.
//before records listing is shown, check for storage
$(document).on('pagebeforechange', function(e, data){
//get page to go to
var toPage = data.toPage[0].id;
switch (toPage) {
case 'pgFamilyMember':
// restart the storage check
app.checkForFamilyMemberStorage();
break;
case 'pgEditFamilyMember':
// clear the add page form fields
pgEditFamilyMemberClear();
//load related select menus before the page shows
app.pgEditFamilyMemberLoadFather();
app.pgEditFamilyMemberLoadMother();
//show the first nav item.
$('#pgEditFamilyMemberPersonalInformationBtn').trigger('click');
break;
case 'pgAddFamilyMember':
// clear the add page form fields
pgAddFamilyMemberClear();
//load related select menus before the page shows
app.pgAddFamilyMemberLoadFather();
app.pgAddFamilyMemberLoadMother();
//show the first nav item.
$('#pgAddFamilyMemberPersonalInformationBtn').trigger('click');
break;
default:
}
});

 

上面的代码主要做了以下事情:

1. 在列出家庭成员之前,检查LocalStorage中是否有保存的成员并更新列表视图。

2. 在显示编辑家庭成员的屏幕之前,清除该屏幕中所有控件的内容,加载父亲和母亲的下拉菜单,其中包含已存储在家庭树记录中的姓名,然后

3. 触发点击事件以显示第一个屏幕,即个人信息。

使导航与div协同工作的代码位于随附的navbar.js文件中,此文件应在jquery mobile.js脚本调用之前包含。

// include this file before your jquery-mobile script tag
$(document).delegate('.ui-navbar ul li > a', 'click', function() {
  //search the navbar to deactivate the active button
  $(this).closest('.ui-navbar').find('a').removeClass('ui-btn-active');
  //change the active tab
  $(this).addClass('ui-btn-active');
  //hide the siblings
  $('#' + $(this).attr('data-href')).show().siblings('.tab-content').hide();
  return false;
});

对于导航栏列表中的每个项目,当其被选中时,移除该按钮的活动指示器,即最后一个活动按钮,然后向选定的按钮添加一个活动指示器。之后,读取data-href属性并显示链接的div,并隐藏其他所有内容。每个div都有一个名为tab-content的类,如下所示,并且已在源中添加了样式以确保这一切正常工作。

为了使这一切工作,即无需页面跳转即可导航,添加的样式是

.tab-content {display:none;}
.tab-content:first-child { display: block;}

我们已经解释了导航栏,现在让我们处理各种信息部分。

个人信息 - HTML 定义与输出。

下图2描述了如上所述的个人详细信息屏幕的输出。

图 2

<div id="pgAddFamilyMemberPersonalInformation" class="tab-content">
<div data-role="fieldcontain">
<fieldset id="fspgAddFamilyMemberGender" data-role="controlgroup" data-type="horizontal" data-mini="true">
<legend>Gender<span style='color:red;'>*</span></legend>
<input type="radio" name="pgAddFamilyMemberGender" id="pgAddFamilyMemberGendermale" autocomplete="off" title="" value="male" required></input>
<label for="pgAddFamilyMemberGendermale" id="lblpgAddFamilyMemberGendermale">Male<span style='color:red;'>*</span></label>
<input type="radio" name="pgAddFamilyMemberGender" id="pgAddFamilyMemberGenderfemale" autocomplete="off" value="female"></input>
<label for="pgAddFamilyMemberGenderfemale" id="lblpgAddFamilyMemberGenderfemale">Female</label>
</fieldset>
</div>
<div data-role="fieldcontain">
<label for="pgAddFamilyMemberFullName" id="lblpgAddFamilyMemberFullName">Full Name<span style='color:red;'>*</span></label>
<input type="text" name="pgAddFamilyMemberFullName" id="pgAddFamilyMemberFullName" placeholder="Enter full name here." autocomplete="off" data-clear-btn="true" title="Enter full name here." required></input>
</div>
<div data-role="fieldcontain">
<fieldset id="fspgAddFamilyMemberSalutation" data-role="controlgroup" data-type="horizontal" data-mini="true">
<legend>Salutation<span style='color:red;'>*</span></legend>
<input type="radio" name="pgAddFamilyMemberSalutation" id="pgAddFamilyMemberSalutationMr" autocomplete="off" value="Mr"></input>
<label for="pgAddFamilyMemberSalutationMr" id="lblpgAddFamilyMemberSalutationMr">Mr</label>
<input type="radio" name="pgAddFamilyMemberSalutation" id="pgAddFamilyMemberSalutationMs" autocomplete="off" value="Ms"></input>
<label for="pgAddFamilyMemberSalutationMs" id="lblpgAddFamilyMemberSalutationMs">Ms</label>
<input type="radio" name="pgAddFamilyMemberSalutation" id="pgAddFamilyMemberSalutationMrs" autocomplete="off" value="Mrs"></input>
<label for="pgAddFamilyMemberSalutationMrs" id="lblpgAddFamilyMemberSalutationMrs">Mrs</label>
<input type="radio" name="pgAddFamilyMemberSalutation" id="pgAddFamilyMemberSalutationDr" autocomplete="off" value="Dr"></input>
<label for="pgAddFamilyMemberSalutationDr" id="lblpgAddFamilyMemberSalutationDr">Dr</label>
<input type="radio" name="pgAddFamilyMemberSalutation" id="pgAddFamilyMemberSalutationProf" autocomplete="off" value="Prof"></input>
<label for="pgAddFamilyMemberSalutationProf" id="lblpgAddFamilyMemberSalutationProf">Prof</label>
</fieldset>
</div>
<div data-role="fieldcontain">
<label for="pgAddFamilyMemberIDNumber" id="lblpgAddFamilyMemberIDNumber">ID Number<span style='color:red;'>*</span></label>
<input type="number" name="pgAddFamilyMemberIDNumber" id="pgAddFamilyMemberIDNumber" placeholder="Enter id number here." autocomplete="off" data-clear-btn="true" title="Enter id number here." required></input>
</div>
<div data-role="fieldcontain">
<label for="pgAddFamilyMemberDateofBirth" id="lblpgAddFamilyMemberDateofBirth">Date of Birth<span style='color:red;'>*</span></label>
<input data-options='{"mode":"flipbox","dateFormat":"%Y-%m-%d","overrideDateFormat":"%Y-%m-%d"}' type="text" name="pgAddFamilyMemberDateofBirth" id="pgAddFamilyMemberDateofBirth" placeholder="Enter date of birth here." autocomplete="off" data-role="datebox" title="Enter date of birth here." required></input>
</div>
<div data-role="fieldcontain">
<label for="pgAddFamilyMemberAge" id="lblpgAddFamilyMemberAge">Age<span style='color:red;'>*</span></label>
<input min="0" max="200" type="range" name="pgAddFamilyMemberAge" id="pgAddFamilyMemberAge" autocomplete="off" title="" required></input>
</div>
<div data-role="fieldcontain">
<label for="pgAddFamilyMemberLiving" id="lblpgAddFamilyMemberLiving">Is Living<span style='color:red;'>*</span></label>
<select name="pgAddFamilyMemberLiving" id="pgAddFamilyMemberLiving" data-role="slider" data-mini="true" dir="ltr" class="required">
<option value="no">No</option>
<option value="yes">Yes</option>
</select>
</div>
<div data-role="fieldcontain">
<label for="pgAddFamilyMemberPlaceofBirth" id="lblpgAddFamilyMemberPlaceofBirth">Place of Birth<span style='color:red;'>*</span></label>
<input type="text" name="pgAddFamilyMemberPlaceofBirth" id="pgAddFamilyMemberPlaceofBirth" placeholder="Enter place of birth here." autocomplete="off" data-clear-btn="true" title="Enter place of birth here." required></input>
</div>
</div>

以上脚本定义了个人信息屏幕背后的HTML。如您所见,脚本的第一行有一个名为“tab-content”的类,告诉应用程序这将作为选项卡的一部分进行处理,这确保了我们的导航同步。

联系方式 - HTML定义和输出

联系方式屏幕并不复杂,只要求输入电子邮件和手机详细信息。

<div id="pgAddFamilyMemberContactDetails" class="tab-content">
<div data-role="fieldcontain">
<label for="pgAddFamilyMemberCellphone" id="lblpgAddFamilyMemberCellphone">Cellphone</label>
<input type="number" name="pgAddFamilyMemberCellphone" id="pgAddFamilyMemberCellphone" placeholder="Enter cellphone here." autocomplete="off" data-clear-btn="true"></input>
</div>
<div data-role="fieldcontain">
<label for="pgAddFamilyMemberEmail" id="lblpgAddFamilyMemberEmail">Email</label>
<input type="email" name="pgAddFamilyMemberEmail" id="pgAddFamilyMemberEmail" placeholder="Enter email here." autocomplete="off" data-clear-btn="true"></input>
</div>
</div>
<div id="pgAddFamilyMemberRelationships" class="tab-content">
<div dir="ltr" data-role="fieldcontain">
<label for="pgAddFamilyMemberFather" id="lblpgAddFamilyMemberFather">Father</label>
<select name="pgAddFamilyMemberFather" id="pgAddFamilyMemberFather" data-native-menu="false" data-mini="true" data-inline="true" dir="ltr">
<option value="null" data-placeholder="true">Select Father</option>
<option value="Father1">Father1</option>
<option value="Father2">Father2</option>
<option value="Father3">Father3</option>
</select>
</div>
<div dir="ltr" data-role="fieldcontain">
<label for="pgAddFamilyMemberMother" id="lblpgAddFamilyMemberMother">Mother</label>
<select name="pgAddFamilyMemberMother" id="pgAddFamilyMemberMother" data-native-menu="false" data-mini="true" data-inline="true" dir="ltr">
<option value="null" data-placeholder="true">Select Mother</option>
<option ></option>
</select>
</div>
</div>

您会注意到,“父亲”的SelectMenu控件在应用程序启动时会默认加载一些选项。然而,当您运行应用程序时,这些“父亲1”、“父亲2”和“父亲3”选项将完全不会被列出,因为“父亲”SelectMenu将动态加载我们存储中已有的全名。下图3是“联系方式定义”的最终输出。

图 3

关系 - HTML定义和输出

下图4要求填写父亲和母亲的全名。这些姓名是从MyFamily.Show网络应用程序中存储在LocalStorage中的现有家庭成员加载的。

图 4

你会注意到,这些下拉列表并不会像通常那样填满整个屏幕。这是因为我应用了一些技巧来确保这种情况发生,我将在下面解释这些技巧。

死亡 - HTML定义和输出

如果某个家庭成员已经去世,您还可以记录他们的死亡日期和地点。这只是为了延续家族历史。这个屏幕/div的定义也很简单,不花哨,如下图5所示。

<div id="pgAddFamilyMemberDeath" class="tab-content">
<div data-role="fieldcontain">
<label for="pgAddFamilyMemberDateofDeath" id="lblpgAddFamilyMemberDateofDeath">Date of Death</label>
<input data-options='{"mode":"flipbox","dateFormat":"%Y-%m-%d","overrideDateFormat":"%Y-%m-%d"}' type="text" name="pgAddFamilyMemberDateofDeath" id="pgAddFamilyMemberDateofDeath" placeholder="Enter date of death here." autocomplete="off" data-role="datebox"></input>
</div>
<div data-role="fieldcontain">
<label for="pgAddFamilyMemberPlaceofDeath" id="lblpgAddFamilyMemberPlaceofDeath">Place of Death</label>
<input type="text" name="pgAddFamilyMemberPlaceofDeath" id="pgAddFamilyMemberPlaceofDeath" placeholder="Enter place of death here." autocomplete="off" data-clear-btn="true"></input>
</div>
<div><button type="submit" id="pgAddFamilyMemberSave" class="ui-btn ui-corner-all ui-shadow ui-btn-b">Save Family Member</button>
</div>
</div>
</div>

图 5

我决定将“更新家庭成员”按钮放在“死亡”div上,因为用户必须在选项卡中输入所有可用信息,然后保存。下次我将探索“后退”、“前进”导航方法,使其更加无缝。

家庭成员编辑/更新屏幕

添加成员/更新成员屏幕的唯一区别只是控件名称。我不想将相同的屏幕用于添加/更新功能,因为那样有时会给维护带来挑战,是的,可以做到,但为了代码维护,我选择不遵循这种方法。您可能已经注意到,所有与添加相关的控件都以pgAdd为前缀,所有编辑控件都以pgEdit为前缀。这与我为NoteKeeper网络应用程序遵循的方法相同。

列出家庭成员

列出家庭成员的方法比我之前的帖子更进一步,现在包括了计数气泡和联系方式。

<div id="pgFamilyMembercontent" data-role="content">
<ul data-role="listview" data-inset="true" id="pgFamilyMemberList" data-autodividers="true" data-filter="true" data-filter-placeholder="Search Family Members" data-filter-reveal="false">
<li data-role="list-divider">FamilyMemberHdr</li>
<li id="noFamilyMember">You have no family members</li>
</ul>
</div>

虽然家族列表在此处定义,但它依赖于网络应用程序中的各种脚本。这些脚本如下图所示。

var FamilyMemberLi = '<li ><a href="#pgEditFamilyMember?FullName=Z2"><h2>Z1</h2><p>DESCRIPTION</p><span class="ui-li-count">COUNTBUBBLE</span></a></li>';
var FamilyMemberHdr = '<li data-role="list-divider">FamilyMemberHdr</li>';
var noFamilyMember = '<li id="noFamilyMember">You have no family members</li>';

// display existing records in listview of Records listing.
//display records in listview during runtime.
app.displayFamilyMember = function(){
// get Family Member records.
var FamilyMemberObj = app.getFamilyMember();
// 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 FamilyMemberObj){
//get the record details
var FamilyMemberRec = FamilyMemberObj[n];
//define a new line from what we have defined
var nItem = FamilyMemberLi;
//update the href to the key
nItem = nItem.replace(/Z2/g,n);
//update the title to display, this might be multi fields
var nTitle = '';
//assign cleaned title
nTitle = n.replace(/-/g,' ');
//replace the title;
nItem = nItem.replace(/Z1/g,nTitle);
//there is a count bubble, update list item
var nCountBubble = '';
nCountBubble += FamilyMemberRec.Age;
//replace the countbubble
nItem = nItem.replace(/COUNTBUBBLE/g,nCountBubble);
//there is a description, update the list item
var nDescription = '';
nDescription += FamilyMemberRec.Cellphone;
nDescription += ', ';
nDescription += FamilyMemberRec.Email;
//replace the description;
nItem = nItem.replace(/DESCRIPTION/g,nDescription);
html += nItem;
}
//update the listview with the newly defined html structure.
$('#pgFamilyMemberList').html(FamilyMemberHdr + html).listview('refresh');
};

结果更接近于下图6所示。

图 6

您会注意到,家庭成员在添加时,列表显示时始终按升序排列。选择每个家庭成员当然会打开“更新家庭成员”屏幕。这种对已保存家庭成员的排序发生在记录保存到LocalStorage时。

这通过添加到保存方法中的这段小代码来实现。

排序家庭成员详细信息 JSON

//update local storage object

FamilyMemberObj[FullName] = FamilyMemberRec;
//sort the objects
var keys = Object.keys(FamilyMemberObj);
keys.sort();
var sortedObject = Object();
var i;
for (i in keys) {
key = keys[i];
sortedObject[key] = FamilyMemberObj[key];
}
FamilyMemberObj = sortedObject;
//save all existing records to localstorage
localStorage['myfamilyshow-familymember'] = JSON.stringify(FamilyMemberObj);

这段小代码脚本的速度可能是一个变量,也许可以通过某种方式进行优化,我感觉对于非常大的数据集,可能需要显示一个进度条来表明屏幕上正在发生某些事情。我将在后续文章中探讨进度条。上面的代码在保存家庭成员详细信息后获取JSON的所有键。每个家庭成员的主键是全名。对于姓名相同的家庭成员,我们或许可以在姓名后面添加I、II、III等后缀,因为网络应用程序会覆盖现有成员。然后将 sortedObject 赋给要字符串化并保存到 LocalStorage 的对象。

将父亲和母亲加载到 SelectMenu

除了我想要添加的单页导航,动态加载SelectMenus是一个我非常想做的有趣任务。我的想法不仅仅是关于这个,而是关于其他网络应用程序,它们在各种模型之间会有关系,我需要例如在产品屏幕上添加一个类别。我需要一个通用的东西,可以轻松地为我的RAD工具定制。

三个方法基本实现了 SelectMenu 的更新。我们想要父亲和母亲,因此我们需要首先从所有存储的记录中获取所有全名,我们定义了该函数。请注意,函数名是 ModelName 和 FieldName 的组合。因此,对于您可能想要使用的每个模型,这样的组合可能就足够了。

//get all existing FamilyMember-FullName
app.getFamilyMemberFullName = function(){
// get Family Member records
var FamilyMemberObj = app.getFamilyMember();
// loop through each record and get the fields we want
// make sure your iterators are properly scoped
var n;
var dsFields = [];
for (n in FamilyMemberObj){
//get the record details
var FamilyMemberRec = FamilyMemberObj[n];
var dsField = FamilyMemberRec.FullName;
dsFields.push(dsField);
}
return dsFields;
};

 

1. 这将获取所有家庭成员并将其分配给 FamilyMemberObj。

2. 我们遍历每个家庭成员记录,获取全名并将这些全名推送到一个数组中。

然后,下一个函数解析此数组并在页面显示之前更新特定的 Select Menu,如上所述。

//load the field names for data sources to control 
app.pgAddFamilyMemberLoadFather = function(){
//read the data source data field combination array
var FamilyMemberObj = app.getFamilyMemberFullName();
var dsdf;
//clear the select menu
$('#pgAddFamilyMemberFather').empty();
//ensure its refreshed
$('#pgAddFamilyMemberFather').selectmenu('refresh');
//loop through each item and load it.
var options = [];
options.push('<option value="null" data-placeholder="true">Select Father</option>');
for (dsdf in FamilyMemberObj){
var Father = FamilyMemberObj[dsdf];
options.push("<option value='" + Father + "'>" + Father + "</option>");
}
$('#pgAddFamilyMemberFather').append(options.join("")).selectmenu();
//refresh the select menu, just in case
$('#pgAddFamilyMemberFather').selectmenu('refresh');
};

app.getFamilyMemberFullName 调用了一个 getFamily member 方法,该方法基本上从 LocalStorage 中读取以这种格式存储的每个成员的信息。

{"Anele-Mbanga":{"Image":"","Gender":"male","FullName":"Anele Mbanga","Salutation":"Mr","IDNumber"

"7304155526089","DateofBirth":"2015-03-02","Age":"42","Living":"yes","PlaceofBirth":"East London",

"Father":"null","Mother":"null","Cellphone":"0817366739","Email":"anele@mbangas.com",

"DateofDeath":"","PlaceofDeath":""},"Esona":{"Image":"","Gender":"female","FullName"

"Esona","Salutation":"Ms","IDNumber":"20100401","DateofBirth":"2010-04-02","Age":"5",

"Living":"yes","PlaceofBirth":"Johannesburg","Father":"Anele Mbanga","Mother":"null",

"Cellphone":"","Email":"esona@mbangas.com","DateofDeath":"","PlaceofDeath":""},

"Olothando-Mbanga":{"Image":"","Gender":"female","FullName":"Olothando Mbanga",

"Salutation":"Ms","IDNumber":"","DateofBirth":"2015-03-02","Age":"6","Living":"no",

"PlaceofBirth":"Johannesburg","Father":"Anele Mbanga","Mother":null,"Cellphone":"",

"Email":"olothando@mbangas.com","DateofDeath":"","PlaceofDeath":""},

"Usibabale-Mbanga":{"Image":"","Gender":"male","FullName":"Usibabale Mbanga",

"Salutation":"Mr","IDNumber":"","DateofBirth":"2015-03-02","Age":"12",

"Living":"yes","PlaceofBirth":"Johannesburg","Father":"Anele Mbanga","Mother":"null",

"Cellphone":"","Email":"usibabale@mbangas.com","DateofDeath":"","PlaceofDeath":""}}

这存储在 LocalStorage 键中

myfamilyshow-familymember

myfamilyshow 是网络应用程序的名称,familymember 是我们存储信息的模型的名称。

关注点

由此我了解到,在进行添加或编辑之前,我需要清除我的控件,以确保所有内容都已重置。我还发现了如何在不从一个页面导航到另一个页面的情况下使用导航栏按钮。为单选按钮组设置值被证明具有挑战性,我最终通过使用如下脚本在代码中设置实际值:

//use the actual value of the radio button to set it
var opts = 'pgEditFamilyMemberGender' + FamilyMemberRec.Gender;
$('#' + opts).prop('checked', true);
$('#' + opts).checkboxradio('refresh');
$('#pgEditFamilyMemberFullName').val(FamilyMemberRec.FullName);
//use the actual value of the radio button to set it

例如,这将把名为 pgEditFamilyMemberGendermale 的控件设置为 true,因为使用 name 属性设置属性对我来说就是无法正常工作。不幸的是,关于如何进行这些简单的编码练习的信息仍然散布在网络上。我不得不检查我找到的大多数声称有效但对我无效的方法,最终才找到了解决方案。由于我对 JQuery 及其 API 的经验不足,生成此内容一直是一个试错过程。然而,我正在开发一个名为 JQM.Show 的 RAD 工具,以在三个简单的步骤中自动化大部分开发。

另一个发现是日期选择器小部件,它在用户选择日期时以图7所示的格式显示日期。您可以查看包含该控件的js源代码,并访问他们的网站以了解如何自定义它。

历史

这些文章的基础源于我关于NoteKeeper的文章。与那篇文章相比,在保存JSON之前对JSON进行排序的算法让我大开眼界。此外,能够根据我选择的选项自定义列表视图也令人惊叹。

© . All rights reserved.