1+ <!--
2+ Copyright (c) 2011, salesforce.com, inc.
3+ All rights reserved.
4+
5+ Redistribution and use in source and binary forms, with or without modification, are permitted provided
6+ that the following conditions are met:
7+
8+ Redistributions of source code must retain the above copyright notice, this list of conditions and the
9+ following disclaimer.
10+
11+ Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
12+ the following disclaimer in the documentation and/or other materials provided with the distribution.
13+
14+ Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or
15+ promote products derived from this software without specific prior written permission.
16+
17+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
18+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
19+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24+ POSSIBILITY OF SUCH DAMAGE.
25+ -->
26+ <!--
27+ Sample Visualforce page for Force.com JavaScript REST Toolkit
28+ -->
29+ <apex:page standardStylesheets="false" showHeader="false" sidebar="false">
30+ <head>
31+ <title>
32+ Force.com JavaScript REST Toolkit
33+ </title>
34+ <style type="text/css">
35+ body {
36+ font-family:"Arial";
37+ }
38+ table.main {
39+ border: 1px solid #666;
40+ }
41+ .highlighted {
42+ background-color:#D6EDFC;
43+ }
44+ .odd {
45+ background-color:#fea;
46+ }
47+ form {
48+ margin-bottom: 1em;
49+ }
50+ </style>
51+ <!--
52+ Download jQuery, jQuery UI and Trimpath Template, and put them in a
53+ static resource bundles!
54+ -->
55+ <apex:includeScript
56+ value="{!URLFOR($Resource.static, 'query.js')}" />
57+ <apex:includeScript
58+ value="{!URLFOR($Resource.static, 'jquery-ui.js')}" />
59+ <apex:includeScript
60+ value="{!URLFOR($Resource.static, 'template.js')}" />
61+ <apex:includeScript
62+ value="{!URLFOR($Resource.static, 'forcetk.js')}" />
63+ <apex:stylesheet
64+ value="{!URLFOR($Resource.static, 'jquery-ui.css')}" />
65+
66+ <script type="text/javascript">
67+ // Get a reference to jQuery that we can work with
68+ $j = jQuery.noConflict();
69+
70+ // Make our own startsWith utility fn
71+ String.prototype.startsWith = function(str){
72+ return (this.substr(0, str.length) === str);
73+ }
74+
75+ // Get an instance of the REST API client
76+ var client = new forcetk.Client('{!$Api.Session_ID}');
77+
78+ // We'll use this a lot :-)
79+ var ajaxgif = "<img src='{!URLFOR($Resource.static, 'static/ajax.gif')}'/>";
80+
81+ var $dialog = null;
82+
83+ // Kick things off by doing a describe on Account...
84+ $j(document).ready(function() {
85+ $dialog = $j('<div></div>')
86+ .dialog({
87+ autoOpen: false,
88+ width: 450
89+ });
90+
91+ $j('#prompt').html(ajaxgif+" loading metadata...");
92+ client.describe('Account', metadataCallback);
93+ });
94+
95+ var timeout = null;
96+
97+ function autoFilter() {
98+ if (timeout != null) {
99+ clearTimeout(timeout);
100+ }
101+
102+ var field = $j("#field").val();
103+ var value = $j("#value").val();
104+
105+ filterAccounts(field,value);
106+ }
107+
108+ function metadataCallback(response){
109+ // Using TrimPath Template for now - may switch to jQuery Template at some
110+ // point
111+ $j('#prompt').html(TrimPath.processDOMTemplate("prompt_jst"
112+ , response));
113+
114+ $j("#value").keyup(function(){
115+ if (timeout != null) {
116+ clearTimeout(timeout);
117+ }
118+ timeout = setTimeout("autoFilter()",1000);
119+ });
120+
121+ $j('#go').click(function(e) {
122+ var field = $j("#field").val();
123+ var value = $j("#value").val();
124+
125+ e.preventDefault();
126+ filterAccounts(field,value);
127+ });
128+
129+ $j('#new').click(function(e) {
130+ e.preventDefault();
131+
132+ // Just make Trimpath happy
133+ var dummy = {};
134+ var i;
135+ for (i = 0; i < response.fields.length; i++) {
136+ dummy[response.fields[i].name] = '';
137+ }
138+ $dialog.html(TrimPath.processDOMTemplate("edit_jst", dummy));
139+ $dialog.find('#action').html('Create').click(function(e) {
140+ e.preventDefault();
141+ $dialog.dialog('close');
142+
143+ var fields = {};
144+ $dialog.find('input').each(function() {
145+ var child = $j(this);
146+ if ( child.val().length > 0 ) {
147+ fields[child.attr("name")] = child.val();
148+ }
149+ });
150+
151+ $j('#list').html(ajaxgif+" creating account...");
152+
153+ client.create('Account', fields, createCallback);
154+ });
155+ $dialog.dialog('option', 'title', 'New Account');
156+ $dialog.dialog('open');
157+ });
158+
159+ filterAccounts();
160+ }
161+
162+ function queryCallback(response) {
163+ $j('#list').html(TrimPath.processDOMTemplate("accounts_jst"
164+ , response));
165+
166+ $j('#version').html($j.fn.jquery);
167+ $j('#uiversion').html($j.ui.version);
168+
169+ $j("#list tr:nth-child(odd)").addClass("odd");
170+
171+ $j('#accounts').find('.id')
172+ .hover(function() {
173+ $j(this).addClass("highlighted");
174+ },function(){
175+ $j(this).removeClass("highlighted");
176+ })
177+ .click(showAccountDetail);
178+ }
179+
180+ function detailCallback(response) {
181+ if (response.Website != null
182+ && !response.Website.startsWith('http://')) {
183+ response.Website = 'http://'+response.Website;
184+ }
185+ $dialog.html(TrimPath.processDOMTemplate("detail_jst"
186+ ,response));
187+ $dialog.find('#industry').click(function(e) {
188+ e.preventDefault();
189+ $dialog.dialog('close');
190+ filterIndustry($j(this).html());
191+ });
192+ $dialog.find('#delete').click(function(e) {
193+ e.preventDefault();
194+ $dialog.dialog('close');
195+ $j('#list').html(ajaxgif+" deleting account...");
196+ client.del('Account', $dialog.find('#id').val(), deleteCallback);
197+ });
198+ $dialog.find('#edit').click(function(e) {
199+ e.preventDefault();
200+ $dialog.html(TrimPath.processDOMTemplate("edit_jst"
201+ ,response));
202+ $dialog.find('#action').html('Update').click(function(e) {
203+ e.preventDefault();
204+ $dialog.dialog('close');
205+
206+ var fields = {};
207+ $dialog.find('input').each(function() {
208+ var child = $j(this);
209+ if ( child.val().length > 0 && child.attr("name") != 'id') {
210+ fields[child.attr("name")] = child.val();
211+ }
212+ });
213+
214+ $j('#list').html(ajaxgif+" updating account...");
215+
216+ client.update('Account', $dialog.find('#id').val(), fields, updateCallback);
217+ });
218+ });
219+ }
220+
221+ function createCallback(response) {
222+ $j('#list').html('Created '+response.id);
223+
224+ setTimeout("filterAccounts()",1000);
225+ }
226+
227+ function updateCallback(response) {
228+ $j('#list').html('Updated');
229+
230+ setTimeout("filterAccounts()",1000);
231+ }
232+
233+ function deleteCallback(response) {
234+ $j('#list').html('Deleted');
235+
236+ setTimeout("filterAccounts()",1000);
237+ }
238+
239+ function showAccountDetail() {
240+ // Show the dialog
241+ $dialog.dialog('option', 'title', 'Account Detail');
242+ $dialog.dialog('open');
243+ $dialog.html(ajaxgif+" retrieving...");
244+
245+ // Get account details and populate the dialog
246+ client.retrieve('Account', this.id, 'Name,Industry,TickerSymbol,Website'
247+ , detailCallback);
248+ }
249+
250+ function filterAccounts(field, value) {
251+ $j('#list').html(ajaxgif+" loading data...");
252+
253+ var query = ( typeof value !== 'undefined' && value.length > 0 )
254+ ? "SELECT Id, Name FROM Account WHERE "+field+" LIKE '"+value
255+ +"%' ORDER BY Name LIMIT 20"
256+ : "SELECT Id, Name FROM Account ORDER BY Name LIMIT 20";
257+
258+ client.query(query, queryCallback);
259+ }
260+ </script>
261+ </head>
262+ <body>
263+ <div id="main">
264+ <div id="prompt">
265+ </div>
266+ <div id="list">
267+ </div>
268+ </div>
269+ <textarea id="prompt_jst" style="display:none;">
270+ <form>
271+ <h3 style="display:inline;">Filter on</h3>
272+ <select id="field">
273+ {for f in fields}
274+ {if f.type == 'string'}
275+ <option value="${f.name}">${f.label}</option>
276+ {/if}
277+ {/for}
278+ </select>
279+ <input type="text" id="value" />
280+ <input type="submit" id="go" name="search" value="Search" />
281+ </form>
282+ <form>
283+ <input type="submit" id="new" name="new" value="New" />
284+ </form>
285+ </textarea>
286+
287+ <textarea id="accounts_jst" style="display:none;">
288+ <table class="main" id="accounts">
289+ {for r in records}
290+ <tr><td class="id" id="${r.Id}">${r.Name}</td></tr>
291+ {/for}
292+ </table>
293+ <br/>
294+ <a href="https://login.salesforce.com/secur/logout.jsp" id="logout">Logout</a>
295+ <p>
296+ <i>Running jQuery <span id="version">0.0.0</span>, jQuery UI <span id="uiversion">0.0.0</span></i>
297+ </p>
298+ </textarea>
299+
300+ <textarea id="detail_jst" style="display:none;">
301+ <table>
302+ {if Website != null}
303+ <tr><td>Name:</td><td><a href="${Website}">${Name}</a></td></tr>
304+ {else}
305+ <tr><td>Name:</td><td>${Name}</td></tr>
306+ {/if}
307+ {if Industry != null}
308+ <tr><td>Industry:</td><td><a href="#" id="industry">${Industry}</a></td></tr>
309+ {/if}
310+ {if TickerSymbol != null}
311+ <tr><td>Ticker Symbol:</td><td><a href="http://www.google.com/finance?q=${TickerSymbol}">${TickerSymbol}</a></td></tr>
312+ {/if}
313+ </table>
314+ <br/>
315+ <form>
316+ <input type="hidden" name="id" id="id" value="${Id}" />
317+ <button id="delete">Delete</button>
318+ <button id="edit">Edit</button>
319+ </form>
320+ </textarea>
321+
322+ <textarea id="edit_jst" style="display:none;">
323+ <form id="editform">
324+ <input type="hidden" name="id" id="id" value="${Id}" />
325+ <table>
326+ <tr><td>Name:</td><td><input name="Name" id="Name" value="${Name}"/></td></tr>
327+ <tr><td>Industry:</td><td><input name="Industry" id="Industry" value="${Industry}"/></td></tr>
328+ <tr><td>Ticker Symbol:</td><td><input name="TickerSymbol" id="TickerSymbol" value="${TickerSymbol}"/></td></tr>
329+ </table>
330+ <br/>
331+ <button id="action" />
332+ </form>
333+ </textarea>
334+ </body>
335+ </apex:page>
0 commit comments