UNPKG

12.7 kBMarkdownView Raw
1**Documentation**
2
3Clay uses an MVC framework to build Javascript web applications that
4fully communicate and integrate with Salesforce. This framework is the
53VOT-Model NPM package, which serves as the base to your apps, and the
6core of its MVC architecture is based on the Spine.js framework.
7
8Spine.js Framework integrates class support for Javascript, as
9internally it uses CoffeeScript classes, which can be used in 3vot Model
10aswell.
11
12
13
14If you need guidance for more advanced coding patterns and structures
15and can’t find it here yet, you can refer to Spine.js documentation, or
16send us an e-mail, to which we’ll be happy to answer. 
17
18<p>For a web version, go to http://docs.clayforsalesforce.com. <br /></p>
19
20
21
22
23**Directory structure of the model app**
24
25
26```
27|-app
28
29|-assets
30
31|-code
32
33|  |-controllers
34
35|  |-models
36
37|  |-views
38
39|-node_modules
40
41|  |-3vot
42
43|  |-3vot-model
44
45|  |-jqueryify
46
47|-start
48
49|  |-3vot.js
50
51|  |-desktop.js
52
53|  |-phone.js
54
55|  |-tablet.js
56
57|-templates
58
59|  |-head.html
60
61|  |-layout.html
62
63|-package.json
64```
65
66
67**App folder** is where the compiled app goes. Don’t edit the files in
68this folder. They will be overwritten everytime the app is compiled.
69(folder is not showing expanded).
70
71
72
73**Assets folder** is where you put the assets for your app, such as
74images and stylesheets. It’s empty by default when the app is created.
75
76
77
78**Code folder** is where you should put all your scripts files, such as
79the controllers, models and views files for the 3VOT Model. On the root
80of the code folder is the index.js file, which is the main controller
81that gets called when the app starts and where you can define the models
82and controllers to be used and initialized, as well as making initial
83data requests to Salesforce.
84
85
86**Node_modules** is the directory for your dependencies (not showing
87expanded), which are defined on the package.json file on the root of
88your app folder. By default, Clay requires 3VOT, 3VOT-Model and
89Jqueryify packages. To install dependencies for your app, see below
90reference for package.json file.
91
92
93
94**Start folder** is where you setup how you want your app to show in
95each platform. 
96
973vot.js is the main app starter file, and desktop.js, phone.js and
98tablet.js is where you define the controllers and layouts for each of
99this platforms, and whether you need to login oAuth providers, define
100api tokens, etc.
101
102
103
104**Templates folder** is where you have the head and layout html files
105for you app. If your app has different layouts for different platforms,
106this is where you should store them. Note that inside layout.html or
107head.html you need not to include \<head\> or \<body\> tags, and while
108having different layouts, it’s not possible to change the head file for
109every one of them, it has to be the same.
110
111
112
113Package.json file is where you define your dependencies and other
114compile options for your app:
115
116"**platforms**": "The file that will be dynamically loaded once we know
117the screen size. Located in the /start folder";
118
119"**extensions**": "Compile Option: require files with using it's
120extension";
121
122"**transforms**": "Compile Option: The NPM Browserify Transforms applied
123when compiling App";
124
125"**external**": "Performance Option: Allows to extract the common
126depedencies between apps ex: jquery, cache and speed all apps";
127
128"**gitDependencies**": "Bower and Github based Libraries that can be
129required within an app. ex: Angular";
130
131"**dependencies**": "NPM Browser Compatible Dependencies that can be
132required within an app. ex: 3vot-model";
133
134
135
136
137
138<p><br /></p>
139**3VOT-Model MVC specifics**
140
141
142**Models **
143
144Models should be the viewed only as a connector to Salesforce, and
145should not include other logics, such as controller logic. Inside the
146Model file you should only declare the model and the fields required, and then export it to be required by the
147controllers.
148
149Model data is obtained through Ajax connection to Salesforce.
150
151**Implementation**
152
1533vot-model is an NPM Dependency that connects with Visualforce API
154Controller.
155
156
157
158Hence, it’s necessary to initiate it, by requiring 3vot-model on your
159model file.
160
161```var _3Model = require("3vot-model");```
162
163
164
165After that, we have to create a model, which is done by subclassing the
1663vot-model Model object through the setup method, passing the desired
167model name (string) and the desired attributes:
168
169```NewModel = _3Model.Model.*setup*("ModelName", “attribute1”, “attribute
1702”, …, “attribute n”);```
171
172
173
174This Model is a constructor for new instances of the model.
175
176
177
178For better standards, we advise on the following code structure:
179
180
181//Declare the desired attributes inside an array
182```var fields = [“attribute1”, “attribute 2”, …, “attribute n”]; ```
183
184//Create the Model
185
186```NewModel = _3Model.Model.*setup*("ModelName", fields);```
187
188
189**Methods and classes can be added to the model.**
190
191
192
193Use the extend method for adding/overriding class methods, and the
194include method to add/override instance methods.
195
196```
197NewModel.extend({
198
199  find: function(){
200
201    /\* ... \*
202
203  }
204
205});
206
207
208
209NewModel.find(); //calling the new method 
210
211
212
213NewModel.include({
214
215  name: "Default Name"
216
217});
218
219
220
221((new NewModel).name === "Default Name" ); //returns true
222```
223
224
225**New Model Instances and Classes**
226
227
228
229You can create new Model instances using the constructor method, via
230new:
231
232
233
234```var model = new Model({object_attributes: “optional”});```
235
236
237
238You can also use the Model.create method:
239
240
241
242```var model = Model.create({object_attributes: “optional”});```
243
244
245
246
247
248To add classes to Models, use the Model.setup method:
249
250
251```
252NewModel = _3Model.Model.setup("NewModel", fields);
253
254
255
256NewModel.Setup(“NewModelName”);
257```
258
259
260Saving and Retrieving Objects
261
262
263
264
265**Saving and retrieving records**
266
267
268
269Saving and updating
270```
271var _3Model = require("3vot-model") //requiring npm package
272
273var fields = ["Name","Type", "Website"] // declaring the fields
274
275Account = _3Model.Model.setup("Account", fields); // creating the
276account Model
277
278
279
280var account = new Account({first_name: “John”, last_name: “Smith”});
281//Account.create(); can be used aswell
282
283
284
285account.save(); //Saves the object in Salesforce.
286```
287
288
289When you save the instance, an id property is created for the object if
290one isn’t created already. 
291
292
293
294If you change a property, use the same method to update the model.
295
296
297```
298account.last_name  = “Doe”;
299
300
301
302account.save(); //
303
304
305
306account; // {first_name: “John”, last_name: “Doe”}
307```
308Retrieving Records
309
310
311
312Model Methods to retrieve matching instances: 
313
314.first(integer(opcional)), ex: Account.first(); / Account.first(10);
315
316.last(integer(opcional)), ex: Account.last(); / Account.last(3);
317
318.all(), ex: Account.all()
319
320.splice(start_position(integer, optional), ex: Account.splice(10); /
321Account.splice(2,6);
322
323.each(CallbackFunction()) – the function should be returning
324this.desiredProperty or argument.desiredPropery, ex: return
325account.firstname; This iterates every record on the model, and returns
326their disered property values
327
328ex: 
329```
330Account.each(CallbackFunction(account) {
331
332  return account.first_name;
333
334});
335```
336
337
338.select(function()) – will select the instances that have the property
339you 
340
341ex:
342```
343Account.select(function(account) {
344
345  return account.first_name;
346
347});
348```
349
350
351
352
353**EVENTS**
354
355
356
357It’s easy to implement callback functions on Model events. Using the
358Model.bind method, callbacks will be automatically associated.
359
360
361
362Use: ```Model.bind(“event”,callbackFunction());```
363
364 
365
366Available events:
367
368save - record was saved (either created/updated)
369
370update - record was updated
371
372create - record was created
373
374destroy - record was destroyed
375
376change - any of the above, record was created/updated/destroyed
377
378refresh - when records are invalidated or appended using the refresh
379method
380
381error - validation failed
382
383 
384
385ex: ```PartyGuests.bind(“create”,buyMoreBooze());```
386
387
388
389You can trigger events manually with the Model.trigger method, passing
390as arguments the event and the arguments required for the callback
391function thats going to be executed. You can use this to create custom
392events.
393
394
395
396You can use the Model.listenTo method to have objects waiting for events
397on other objects. Use Model.listenTo(object,”event”,callbackFunction());
398ex:
399```Invites.listenTo(PartyGuests,”create”,sendInvitationEmail(newPartyGuest));```
400
401
402
403Model.ListenToOnce will be listening for the next time the event occurs,
404and only that one. Same arguments as the previous model.
405
406
407
408Events can be unbind using Model.unbind method.
409
410For deeper incursion on the SpineJs Models:
411http://spinejs.com/api/models
412
413
414
415
416**Controllers**
417
418
419
420Generally, controllers deal with adding and responding to DOM events,
421rendering templates and keeping views and models in sync.
422
423
424
425To connect to the DOM objects, 3vot Model, like Spine, uses the el
426property. El represents the current controller's HTML element, and is
427instantiated when the former is first created. You can attribute el to
428CSS classes or HTML tags. You assign the el object property as argument
429when instanciating, or later:
430```
431var contacts = Contact.create({el: \$(“div\>li”)}); //JQuery selector
432
433var Contact.el = \$(".contact-list"); 
434
435var Contact.el = \$("\#contactThingy");
436```
437
438The el property should be attached to a html tag, which is stored on the
439Model’s tag property. By default it’s set to “div”, but you can change
440it:
441
442
443
444```var Contact.tag = “li”;```
445
446
447
448**3Vot Model has events on controllers too**
449
450
451
452Just set the events property to an array of object literals, in the
453following format: {"eventType selector": "functionName"}. If no selector
454is provided, then the event will be set directly on el. Otherwise the
455events will be delegated to any of el's children matching the selector.
456
457
458
459
460
461**Model methods apply to controllers as well.**
462
463
464
465**Controller methods which change el and elements property.**
466
467
468
469```Controller.html(html);```
470
471
472
473Replaces el's property’s html by passing in either a piece of HTML, a
474jQuery element, or another controller instance. 
475
476
477
478```Controller.append(elementOrController);```
479
480
481
482Appends the given element, or controller instance, to el property. 
483
484
485
486```Controller.appendTo(elementOrController);```
487
488
489
490Appends el property to the given element or controller instance.
491
492
493
494```Controller.prepend(elementOrController);```
495
496
497
498Prepends el to the given element or controller instance.
499
500
501
502```replace(element);```
503
504
505
506Replaces el’s current value with the given element.
507
508
509
510**Views / Templates**
511
512
513
514Views are defined through small html templates that get dinamically
515rendered and refreshed.
516
517
518
5193vot Model uses  HYPERLINK "https://github.com/sstephenson/eco" Eco:
520Embedded CoffeeScript templates for its ease of use and
521integration/versatility, compiling the templates via node.js.
522
523
524
525To compile the views, you have to require it and than pass it the Model
526instances to fill the assigned el elements, passing them to the html.
527Like so:
528
529
530```
531render: function(){
532
533  var accounts = Account.all();
534
535  var tempEl = "";
536
537  for(index in accounts){
538
539    var account = accounts[index];
540
541    tempEl += accountItemTemplate(account); //returns each rendered
542template as a string
543
544  }
545
546  el.html( tempEl ); //updates the el.property’s element in the app’s
547html.
548
549}
550```
551
552
553For more info, you should refer to the website for more information on
554the use, but here are a few importante directions on integrating it on
555.eco template files:
556
557
558
559\<% expression %\>: Evaluate a CoffeeScript expression without printing
560its return value.
561
562\<%= expression %\>: Evaluate a CoffeeScript expression, escape its
563return value, and print it.
564
565\<%- expression %\>: Evaluate a CoffeeScript expression and print its
566return value without escaping it.
567
568\<%= @property %\>: Print the escaped value of the property property
569from the context object passed to render.
570
571\<%= @helper() %\>: Call the helper method helper from the context
572object passed to render, then print its escaped return value.
573
574\<% @helper -\> %\>...\<% end %\>: Call the helper method helper with a
575function as its first argument. When invoked, the function will capture
576and return the content ... inside the tag.
577
578\<%% and %%\> will result in a literal \<% and %\> in the rendered
579template, respectively.
580
581
582
583An exemple for a Salesforce contact list template view:
584
585
586```
587\<li class="list-group-item contact-item"\>
588
589  \<span data-id="\<%= @id %\>" class="editable btn_edit"\>
590
591    \<%= @Name %\>
592
593    \<%= @Email%\>
594
595  \</span\>
596
597  \<span class="badge btn_delete" data-id="\<%= @id %\>"\>x\</span\>
598
599\</li\>
600```
601
602
603If you need to use JQuery to manipulate your templates DOM, just use a
604.jeco extension for your template file instead of .eco.
605
606
\No newline at end of file