Chatter Controller
public with sharing class ChatterController { public class Response { public Boolean success; public String errorMessage; public List<SObject> records; public Integer total; Response() { records = new List<SObject>(); success = true; } } //One of the parameters supplied by the DirectProxy read method. public class QueryRequest { Integer start; Integer recordCount; List<Map<String, String>> sortParams; Public QueryRequest() { start = 1; recordCount = 1; } Public QueryRequest(Integer pStart, Integer pRecordCount) { start = pStart; recordCount = pRecordCount; } } @RemoteAction public static Response Add(List<FeedItem> chatterData){ return insertLeadList(chatterData); } @RemoteAction public static Response Destroy(List<FeedItem> chatterData){ return deleteChatterList(chatterData); } @RemoteAction public static Response Edit(List<FeedItem> chatterData){ return editChatterList(chatterData); } @RemoteAction public static Response EditComment(List<String> chatterCommentData){ return editCommentChatterList(chatterCommentData); } @RemoteAction public static Response Query(QueryRequest qr){ Response resp = new Response(); //Enforce a limit on the number of rows requested. final integer QUERY_LIMIT = 500; if( qr.start >= QUERY_LIMIT ){ resp.success = false; resp.errorMessage = 'Maximum number of records (' + String.valueOf(QUERY_LIMIT) + ') exceeded!'; return resp; } try { getAllChatter(qr, resp); } catch (Exception e) { resp.success = false; resp.errorMessage = 'Query failed: ' + e.getMessage(); } return resp; } private static Response insertCommentOrLike(List<FeedComment> chatterComment, List<FeedLike> chatterLike) { Response resp = new Response(); resp.success = true; try { insert chatterComment; insert chatterLike; } catch (Exception e) { resp.success = false; resp.errorMessage = 'Insert failed: ' + e.getMessage(); } return resp; } private static void getAllChatter(QueryRequest qr, Response resp){ //Page size is set in the Sencha store as recordCount. Integer pageSize = qr.recordCount; //Page number will be calculated. Integer pageNumber = 0; //Start is the record number indicating the start of the page. if( qr.start > 0 ){ pageNumber = qr.start / pageSize; } //Calculate the offset for SOQL. Integer offset = pageNumber * pageSize; //Build the query in pieces. String fieldList = 'Id, Title, Body, LikeCount,CommentCount'; //Construct a base query to which the page offsets will be added. String baseQuery = 'SELECT ' + fieldList + ' FROM FeedItem Order By CreatedDate DESC'; //Construct a count query to pass back the total records matching a search criteria. String baseCountQuery = 'SELECT COUNT() FROM FeedItem'; //Construct the fetch query with the offset. String fetchQuery = baseQuery + ' LIMIT ' + pageSize + ' OFFSET ' + offset; try { //Set the count. resp.total = Database.countQuery(baseCountQuery); //Set the fetched recordset. resp.records = Database.query(fetchQuery); //Set the status flag. resp.success = true; } catch (Exception e) { //Set the total count of records matching the query. resp.total = 0; //Set the recordset to return. resp.records = new List<Lead>(); //Set the status flag. resp.success = false; } } private static Response insertLeadList(List<FeedItem> chatterData){ Response resp = new Response(); resp.success = true; try { chatterData[0].ParentId = UserInfo.getUserId(); insert chatterData; } catch (Exception e) { resp.success = false; resp.errorMessage = 'Insert failed: ' + e.getMessage(); } return resp; } private static Response deleteChatterList(List<FeedItem> ChatterData){ Response resp = new Response(); resp.success = true; try { delete ChatterData; } catch (Exception e) { resp.success = false; resp.errorMessage = 'Deletion failed: ' + e.getMessage(); } return resp; } private static Response editChatterList(List<FeedItem> chatterData){ Response resp = new Response(); resp.success = true; try { System.debug('Hier: ' + chatterData); } catch (Exception e) { resp.success = false; resp.errorMessage = 'Deletion failed: ' + e.getMessage(); } return resp; } private static Response editCommentChatterList(List<String> chatterCommentData) { Response resp = new Response(); resp.success = true; try { System.debug('Hier: ' + chatterCommentData); } catch (Exception e) { resp.success = false; resp.errorMessage = 'Deletion failed: ' + e.getMessage(); } return resp; } }
Chatter Component
<apex:component controller="ChatterController"> <script type="text/javascript"> Ext.application({ name: "ChatterPlus", models: ["Chatter"], stores: ["Chatter"], controllers: ["Chatter"], views: ["ChatterList", "ChatterEditor", "ChatterLikeCommentEditor"], launch: function () { var chatterListView = { xtype: "chatterlistview" }; var chatterEditorView = { xtype: "chattereditorview" }; var chatterLikeCommentEditor = { xtype: "chatterlikecommentview" }; Ext.Viewport.add([chatterListView, chatterEditorView, chatterLikeCommentEditor]); } }); Ext.define("ChatterPlus.view.ChatterList", { extend: "Ext.Container", requires: "Ext.dataview.List", alias: "widget.chatterlistview", config: { //Take up the full space available in the parent container. layout: { type: 'fit' }, //Add the components to include within the list view. items: [ { xtype: "toolbar", title: "Chatter", docked: "top", items: [ { xtype: 'spacer' }, { xtype: "button", text: 'New', ui: 'action', itemId: "newButton" } ] }, { xtype: "toolbar", docked: "bottom", itemId: "bottomToolBar", items: [ ] }, { //The main list and its properties. xtype: "list", store: "Chatter", itemId:"chatterList", onItemDisclosure: true, indexBar: true, grouped: false, disableSelection: false, plugins: [ { xclass: 'Ext.plugin.ListPaging', autoPaging: true } ], loadingText: "Loading Feed...", emptyText: '<div class="chatter-list-empty-text">No feeds found.</div>', itemTpl: '<div class="list-item-line-main">{Title}</div>' + '<div class="list-item-line-main">{Body}</div>', }], listeners: [{ delegate: "#newButton", event: "tap", fn: "onNewButtonTap" }, { delegate: "#syncButton", event: "tap", fn: "onSyncButtonTap" }, { delegate: "#chatterList", event: "disclose", fn: "onChatterListDisclose" }, { delegate: "#chatterList", event: "refresh", fn: "onChatterListRefresh", }, { //Listener on the view's Activate event fires when redisplayed by transition. event: "activate", fn: "onChatterListViewActivate", }] }, onSyncButtonTap: function () { console.log("syncChatterCommand"); this.fireEvent("syncChatterCommand", this); }, onNewButtonTap: function () { console.log("newChatterCommand"); this.fireEvent("newChatterCommand", this); }, onChatterListDisclose: function (list, record, target, index, evt, options) { console.log("editChatterCommand"); this.fireEvent('editChatterCommand', this, record); }, onChatterListRefresh: function () { console.log("onChatterListRefresh"); this.updateListCounter(); }, onChatterListViewActivate: function () { console.log("onChatterListViewActivate"); this.updateListCounter(); }, //Function to get count of records in the list and show on the search button's badge. updateListCounter: function () { var listCount = Ext.getStore("Chatter").getCount(); //this.getComponent("bottomToolBar").getComponent("syncButton").setBadgeText(listCount); } }); Ext.define("ChatterPlus.view.ChatterEditor", { extend: "Ext.form.Panel", requires: "Ext.form.FieldSet", alias: "widget.chattereditorview", config: { scrollable: 'vertical', items: [ { xtype: "toolbar", docked: "top", title: "Edit Chatter", items: [ { xtype: "button", ui: "back", text: "Home", itemId: "backButton" }, { xtype: "spacer" }, { xtype: "button", ui: "action", text: "Save", itemId: "saveButton" } ] }, { xtype: "toolbar", docked: "bottom", items: [ { xtype: "button", iconCls: "trash", iconMask: true, itemId: "deleteButton" } ] }, { xtype: "fieldset", title: 'Chatter Info', items: [ { xtype: 'textfield', name: 'Title', label: 'Title', required: true }, { xtype: 'textareafield', name: 'Body', label: 'Body', maxRows: 1, required: true }, { xtype: 'textfield', name: 'CommentCount', label: 'Comment Count', disabled: true }, { xtype: 'textfield', name: 'LikeCount', label: 'Like Count', disabled: true }, ] }, { xtype: "fieldset", title: 'Chatter Comment & Like', items: [ { xtype : 'textareafield', name : 'Comment', label : 'Comment', maxRows: 1 }, { xtype : 'checkboxfield', name : 'Like', label : 'Like' }, ] }, ], listeners: [ { delegate: "#backButton", event: "tap", fn: "onBackButtonTap" }, { delegate: "#saveButton", event: "tap", fn: "onSaveButtonTap" }, { delegate: "#deleteButton", event: "tap", fn: "onDeleteButtonTap" } ] }, onSaveButtonTap: function () { console.log("saveChatterCommand"); this.fireEvent("saveChatterCommand", this); }, onDeleteButtonTap: function () { console.log("deleteChatterCommand"); Ext.Msg.confirm("Delete Feed", "Are you sure?", function(button){ if (button == 'yes') { this.fireEvent("deleteChatterCommand", this); } else { return false; } }, this); }, onBackButtonTap: function () { console.log("backToHomeCommand"); this.fireEvent("backToHomeCommand", this); } }); Ext.define("ChatterPlus.view.ChatterLikeCommentEditor", { extend: "Ext.form.Panel", requires: "Ext.form.FieldSet", alias: "widget.chatterlikecommentview", config: { } }); Ext.define("ChatterPlus.controller.Chatter", { extend: "Ext.app.Controller", config: { refs: { chatterListView: "chatterlistview", chatterEditorView: "chattereditorview", chatterList: "#chatterList", }, control: { chatterListView: { // The commands fired by the list container. syncChatterCommand: "onSyncChatterCommand", newChatterCommand: "onNewChatterCommand", editChatterCommand: "onEditChatterCommand", }, chatterEditorView: { // The commands fired by the note editor. saveChatterCommand: "onSaveChatterCommand", deleteChatterCommand: "onDeleteChatterCommand", backToHomeCommand: "onBackToHomeCommand" } } }, //View Transitions slideLeftTransition: { type: 'slide', direction: 'left' }, slideRightTransition: { type: 'slide', direction: 'right' }, activateChatterEditor: function (record) { var chatterEditorView = this.getChatterEditorView(); chatterEditorView.setRecord(record); Ext.Viewport.animateActiveItem(chatterEditorView, this.slideLeftTransition); }, activateChatterList: function () { Ext.Viewport.animateActiveItem(this.getChatterListView(), this.slideRightTransition); }, onSyncChatterCommand: function () { console.log("onSyncChatterCommand"); this.loadList(); }, onNewChatterCommand: function () { console.log("onNewChatterCommand"); var newChatter = Ext.create("ChatterPlus.model.Chatter"); this.activateChatterEditor(newChatter); }, onEditChatterCommand: function (list, record) { console.log("onEditChatterCommand"); this.activateChatterEditor(record); }, loadList: function () { //Get a ref to the store and remove it. var chatterStore = Ext.getStore("Chatter"); var model = Ext.ModelMgr.getModel('ChatterPlus.model.Chatter'); model.getProxy(); chatterStore.getData().clear(); chatterStore.loadPage(1); //Reshow the list. this.activateChatterList(); }, // Base Class functions. launch: function () { console.log("launch"); this.callParent(arguments); //Load up the Store associated with the controller and its views. console.log("load Chatter"); this.loadList(); }, onSaveChatterCommand: function () { console.log("onSaveChatterCommand"); var chatterEditorView = this.getChatterEditorView(); var currentChatter = chatterEditorView.getRecord(); var newValues = chatterEditorView.getValues(); this.getChatterEditorView().updateRecord(currentChatter); var errors = currentChatter.validate(); if (!errors.isValid()) { var msg = ''; errors.each(function(error) { msg += error.getMessage() + '<br/>'; }); console.log('Errors: ' + msg); Ext.Msg.alert('Please correct errors!', msg, Ext.emptyFn); currentChatter.reject(); return; } //Get a ref to the store. var chatterStore = Ext.getStore("Chatter"); var chatterCommentStore = Ext.getStore("ChatterComment"); //var newChatterComment = Ext.create("ChatterPlus.model.ChatterComment"); //Add new record to the store. if (null == chatterStore.findRecord('id', currentChatter.data.id)) { chatterStore.add(currentChatter); //chatterCommentStore.add(newChatterComment); } chatterCommentStore.sync(); //Resync the proxy and activate the list. chatterStore.sync(); this.activateChatterList(); }, onDeleteChatterCommand: function () { console.log("onDeleteChatterCommand"); //Get a ref to the form and its record. var chatterEditorView = this.getChatterEditorView(); var currentChatter = chatterEditorView.getRecord(); var chatterStore = Ext.getStore("Chatter"); chatterStore.remove(currentChatter); chatterStore.sync(); this.activateChatterList(); }, onBackToHomeCommand: function () { console.log("onBackToHomeCommand"); this.activateChatterList(); }, init: function() { this.callParent(arguments); console.log("init"); //Listen for exceptions observed by the proxy so we can report them and clean up. Ext.getStore('Chatter').getProxy().addListener('exception', function (proxy, response, operation, options) { // only certain kinds of errors seem to have useful information returned from the server if (response) { if (response.errorMessage) { Ext.Msg.alert('Error', response.errorMessage); } else { Ext.Msg.alert('Error', operation.config.action + ' failed: ' + response.errorMessage); } } else { Ext.Msg.alert('Error', operation.config.action + ' failed for an unknown reason: proxy = ' + proxy); } }); }, }); Ext.define("ChatterPlus.model.Chatter", { extend: "Ext.data.Model", config: { idProperty: 'Id', fields: [ { name: 'Id', type: 'string', persist: false}, { name: 'Title', type: 'string'}, { name: 'Body', type: 'string'}, { name: 'LikeCount', type: 'string', persist: false}, { name: 'CommentCount', type: 'string', persist: false}, { name: 'Comment', type: 'string', persist: false}, { name: 'Like', type: 'string', persist: false}, { name: 'ParentId', type: 'string'} ], validations: [ { type: 'presence', field: 'Title', message: 'Enter a Title' }, { type: 'presence', field: 'Body', message: 'Enter a Body' } ], //Bind each CRUD functions to a @RemoteAction method in the Apex controller proxy: { type: 'direct', api: { read: ChatterController.Query, create: ChatterController.Add, update: ChatterController.Edit, destroy: ChatterController.Destroy }, limitParam: 'recordCount', // because "limit" is an Apex keyword sortParam: 'sortParams', // because "sort" is a keyword too pageParam: false, // we don't use this in the controller, so don't send it reader: { type: 'json', rootProperty: 'records', messageProperty: 'errorMessage' }, writer: { type: 'json', root: 'records', writeAllFields: false, // otherwise empty fields will transmit as empty strings, instead of "null"/not present allowSingle: false, // need to always be an array for code simplification encode: false // docs say "set this to false when using DirectProxy" } } }, }); Ext.define("ChatterPlus.model.ChatterComment", { extend: "Ext.data.Model", config: { idProperty: 'Id', fields: [ { name: 'Comment', type: 'string'} ], validations: [ ], //Bind each CRUD functions to a @RemoteAction method in the Apex controller proxy: { type: 'direct', api: { update: ChatterController.EditComment }, writer: { type: 'json', root: 'records', writeAllFields: false, // otherwise empty fields will transmit as empty strings, instead of "null"/not present allowSingle: false, // need to always be an array for code simplification encode: false // docs say "set this to false when using DirectProxy" } } }, }); ChatterController.Query.directCfg.method.getArgs = function (params, paramOrder, paramsAsHash) { console.log('getArgs: ' + params.data); return [params]; } Ext.data.proxy.Direct.prototype.createRequestCallback = function(request, operation, callback, scope){ var me = this; return function(data, event){ console.log('createRequestCallback: ' + operation); me.processResponse(event.status, operation, request, data, callback, scope); }; }; Ext.define("ChatterPlus.store.Chatter", { extend: "Ext.data.Store", requires: "Ext.data.proxy.LocalStorage", config: { model: "ChatterPlus.model.Chatter", autoLoad: true, pageSize: 25, }, listeners: { load: function(){ console.log('store.load(): loaded!'); }, } }); </script> </apex:component>
Heya im for the first time here. I discovered this board and I to uncover It truly helpful & it helped me out a whole lot. I hope to supply something back and aid other people such as you helped me. decgdeaffkgk