No Results
Search Tips:
- Please consider misspellings
- Try different search keywords
Newer Version Available
An Example of Using Remote Objects with jQuery Mobile
Visualforce Remote Objects is designed to “blend” well with JavaScript frameworks.
This extended but simple example shows how to use Remote Objects with jQuery Mobile to view a list of contacts and to add, edit,
and delete them.
This example uses jQuery Mobile from the Salesforce Mobile Packs and is based on sample code that is included with the Mobile Pack for jQuery. Remote Objects and jQuery Mobile make it easy to create a simple contact manager page for a phone.
A Simple Contact Editor with Remote Objects and jQuery Mobile
1<apex:page docType="html-5.0" showHeader="false" sidebar="false">
2
3 <!-- Include jQuery and jQuery Mobile from the Mobile Pack -->
4 <apex:stylesheet value="{!URLFOR($Resource.MobilePack_jQuery,
5 'jquery.mobile-1.3.0.min.css')}"/>
6 <apex:includeScript value="{!URLFOR($Resource.MobilePack_jQuery,
7 'jquery-1.9.1.min.js')}"/>
8 <apex:includeScript value="{!URLFOR($Resource.MobilePack_jQuery,
9 'jquery.mobile-1.3.0.min.js')}"/>
10
11 <!-- Remote Objects declaration -->
12 <apex:remoteObjects jsNamespace="RemoteObjectModel">
13 <apex:remoteObjectModel name="Contact" fields="Id,FirstName,LastName,Phone">
14 <apex:remoteObjectField name="Notes__c" jsShorthand="Notes"/>
15 </apex:remoteObjectModel>
16 </apex:remoteObjects>
17
18 <head>
19 <title>Contacts</title>
20 <meta name="viewport"
21 content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
22
23 <script type="text/javascript">
24 var $j = jQuery.noConflict();
25
26 // Config object with commonly used data
27 // This keeps some hard-coded HTML IDs out of the code
28 var Config = {
29 Selectors: {
30 list: '#cList',
31 detailFields: "#fName #lName #phone #notes #error #contactId".split(" ")
32 },
33 Data: {
34 contact: 'contact'
35 }
36 };
37
38 // Get all contacts, and display them in a list
39 function getAllContacts() {
40 $j.mobile.showPageLoadingMsg();
41
42 var c = new RemoteObjectModel.Contact();
43 // Use the 'limit' operator to increase the default limit of 20
44 c.retrieve({ limit: 100 }, function (err, records) {
45 // Handle any errors
46 if (err) {
47 displayError(err);
48 } else {
49 // Empty the current list
50 var list = $j(Config.Selectors.list).empty();
51 // Now add results records to list
52 $j.each(records, function() {
53 var newLink = $j('<a>'+ this.get('FirstName')+ ' ' +
54 this.get('LastName')+ '</a>');
55 newLink.data(Config.Data.contact, this.get('Id'));
56 newLink.appendTo(list).wrap('<li></li>');
57 });
58
59 $j.mobile.hidePageLoadingMsg();
60 list.listview('refresh');
61 }
62 });
63 }
64
65 // Handle the Save button that appears on both
66 // the Edit Contact and New Contact pages
67 function addUpdateContact(e){
68 e.preventDefault();
69
70 var record = new RemoteObjectModel.Contact({
71 FirstName: $j('#fName').val(),
72 LastName: $j('#lName').val(),
73 Phone: $j('#phone').val(),
74 Notes: $j('#notes').val()
75 // Note use of shortcut 'Notes' in place of Notes__c
76 });
77
78 var cId = $j('#contactId').val();
79 if( !cId ) { // new record
80 record.create(updateCallback);
81 } else { // update existing
82 record.set('Id', cId);
83 record.update(updateCallback);
84 }
85 }
86
87 // Handle the delete button
88 function deleteContact(e){
89 e.preventDefault();
90 var ct = new RemoteObjectModel.Contact();
91 ct.del($j('#contactId').val(), updateCallback);
92 }
93
94 // Callback to handle DML Remote Objects calls
95 function updateCallback(err, ids){
96 if (err) {
97 displayError(err);
98 } else {
99 // Reload the contacts with current list
100 getAllContacts();
101 $j.mobile.changePage('#listpage', {changeHash: true});
102 }
103 }
104
105 // Utility function to log and display any errors
106 function displayError(e){
107 console && console.log(e);
108 $j('#error').html(e.message);
109 }
110
111 // Attach functions to the buttons that trigger them
112 function regBtnClickHandlers() {
113 $j('#add').click(function(e) {
114 e.preventDefault();
115 $j.mobile.showPageLoadingMsg();
116
117 // empty all the clic handlers
118 $j.each(Config.Selectors.detailFields, function(i, field) {
119 $j(field).val('');
120 });
121
122 $j.mobile.changePage('#detailpage', {changeHash: true});
123 $j.mobile.hidePageLoadingMsg();
124 });
125
126 $j('#save').click(function(e) {
127 addUpdateContact(e);
128 });
129
130 $j('#delete').click(function(e) {
131 deleteContact(e);
132 });
133 }
134
135 // Shows the contact detail view,
136 // including filling in form fields with current data
137 function showDetailView(contact) {
138 $j('#contactId').val(contact.get('Id'));
139 $j('#fName').val(contact.get('FirstName'));
140 $j('#lName').val(contact.get('LastName'));
141 $j('#phone').val(contact.get('Phone'));
142 $j('#notes').val(contact.get('Notes'));
143 $j('#error').html('');
144 $j.mobile.changePage('#detailpage', {changeHash: true});
145 }
146
147 // Register click handler for list view clicks
148 // Note: One click handler handles the whole list
149 function regListViewClickHandler() {
150 $j(Config.Selectors.list).on('click', 'li', function(e) {
151
152 // show loading message
153 $j.mobile.showPageLoadingMsg();
154
155 // get the contact data for item clicked
156 var id = $j(e.target).data(Config.Data.contact);
157
158 // retrieve latest details for this contact
159 var c = new RemoteObjectModel.Contact();
160 c.retrieve({
161 where: { Id: { eq: id } }
162 }, function(err, records) {
163 if(err) {
164 displayError(err);
165 } else {
166 showDetailView(records[0]);
167 }
168
169 // hide the loading message in either case
170 $j.mobile.hidePageLoadingMsg();
171 });
172 });
173 }
174
175 // And, finally, run the page
176 $j(document).ready(function() {
177 regBtnClickHandlers();
178 regListViewClickHandler();
179 getAllContacts();
180 });
181
182 </script>
183 </head>
184
185 <!-- HTML and jQuery Mobile markup for the list and detail screens -->
186 <body>
187
188 <!-- This div is the list "page" -->
189 <div data-role="page" data-theme="b" id="listpage">
190 <div data-role="header" data-position="fixed">
191 <h2>Contacts</h2>
192 <a href='#' id="add" class='ui-btn-right' data-icon='add'
193 data-theme="b">Add</a>
194 </div>
195 <div data-role="content" id="contactList">
196 <ul id="cList" data-filter="true" data-inset="true"
197 data-role="listview" data-theme="c" data-dividertheme="b">
198 </ul>
199 </div>
200 </div>
201
202 <!-- This div is the detail "page" -->
203 <div data-role="page" data-theme="b" id="detailpage">
204 <div data-role="header" data-position="fixed">
205 <a href='#listpage' id="back2ContactList" class='ui-btn-left'
206 data-icon='arrow-l' data-direction="reverse"
207 data-transition="flip">Back</a>
208 <h1>Contact Details</h1>
209 </div>
210 <div data-role="content">
211 <div data-role="fieldcontain">
212 <label for="fName">First Name:</label>
213 <input name="fName" id="fName" />
214 </div>
215 <div data-role="fieldcontain">
216 <label for="lName">Last Name:</label>
217 <input name="lName" id="lName" />
218 </div>
219 <div data-role="fieldcontain">
220 <label for="phone">Phone:</label>
221 <input name="phone" id="phone"/>
222 </div>
223 <div data-role="fieldcontain">
224 <label for="notes">Notes:</label>
225 <textarea name="notes" id="notes"/>
226 </div>
227
228 <h2 style="color:red" id="error"></h2>
229
230 <input type="hidden" id="contactId" />
231 <button id="save" data-role="button" data-icon="check"
232 data-inline="true" data-theme="b" class="save">Save</button>
233 <button id="delete" data-role="button" data-icon="delete"
234 data-inline="true" class="destroy">Delete</button>
235 </div>
236 </div>
237 </body>
238</apex:page>Note that although all four Remote Objects operations are demonstrated, there are only three callback
handlers.
- getAllContacts() calls retrieve() to load a list of contacts and provides an anonymous function for the callback. The callback checks for errors and then iterates through the results, adding them to the page.
- Similarly, showDetailView() calls retrieve() to load a single contact for the detail page, and the results are also handled by an anonymous function.
- addUpdateContact() and deleteContact() handle adding, updating, and deleting contacts. Both methods pass updateCallback() as the callback function. updateCallback() doesn’t use the results of the Remote Objects operation. It only checks for errors, logs them to the console, and then calls getAllContacts() to refresh the page.