+ Start a Discussion
Oldwen AdrianoOldwen Adriano 

Dynamic components and dynamic controls


I am trying to develop a custom process for questions and answers that wil be managed through a VisualForce page.  I could use some help with this complex issues...

So first, here are my three tables I created.  From the image you can see the tables and the relationships.

User-added image

This next images gives you a visual of what I am trying to achieve on my page and a little bit of basic functionality.

User-added image

So, what I would really like is if we could toss around some ideas on how to make this work.  I was originally thinking a datatable, but a datatable must be bound to a query and doesn't allow for much manipulation THAT I CAN TELL.

I've gotten this far with this, but I'm afraid it may not be in the corretion direction:
public Component.Apex.OutputPanel getoutPanel() 
		//Tester, remove next line later
		//Component.Apex.SectionHeader sectionHeader = new Component.Apex.SectionHeader();
		Component.Apex.OutputPanel outPanel = new Component.Apex.OutputPanel();
		Component.Apex.DataTable datatable = new Component.Apex.DataTable(var='row'); 
		Lead myLead = [Select Id, Campaign__c from Lead Where Id =: ldObj.Id];
		List<Questions__c> myQuestions = new List<Questions__c>();		
		myQuestions = [Select Id, Campaign__c, Question__c, Type_of_Field__c, Order__c from Questions__c Where Campaign__c =: myLead.Campaign__c And Active__c = true Order By Order__c ASC];
		vNewLst = database.query('Select Question__c, Type_of_Field__c from Questions__c');
		// Where Campaign__c = ' + myLead.Campaign__c + ' And Active__c = true Order By Order__c ASC
		//Type of Field is the type of object --- Type_of_Field__c
		//1 = drop down
		//2 = Text box
		//3 = radio
		//4 = multipick
		//5 = whatever else
		list<String> displayFieldLst= new list<String>{'Question__c','Type_of_Field__c'};
		Component.Apex.column clm;
		Component.Apex.OutputText outText;
		for(string s: displayFieldLst)
			clm = new Component.Apex.column(headerValue= '' + s + ''); 
			outText = new Component.Apex.OutputText();
			outText.expressions.value = '{!row[\'' + s + '\']}';
			clm.childComponents.add( outText );
			datatable.childComponents.add( clm );
		outPanel.childComponents.add( datatable );
		return outPanel;
		//Select q.Type_of_Field__c, q.Question__c, q.Order__c, q.Id, q.Campaign__c, q.Active__c From Questions__c q	

Thank you in advance for any advice or help with this.
I would do this with visualforce, remote actions (maybe) [1], a list custom setting [2] and a custom object that relates to your account.

You can do this a couple of ways but this is how I would do it.
  1. Create a list custom setting with the following information
    • Name: A unique (probably without spaces) name for the question
    • Question: A string for the text of your question
    • Type: What type of input you'll take in (checkbox, selectoption, text, etc).  I'd make the choices map to specific Visualforce elements for ease in step 2
    • Options: This is an optional field that is only useful if the selectoption is set.  I'd do this as a semicolon delimited list of option values.  It's important to note that you only get 255 characters in custom objects for text fields so you may have to have multiple of these and concat them together
    • Sort order: An integer that show what order the questions should be on the page
  2. Use code similar to what you have above to dymanically generate your Visualforce page
    1. Query the custom setting to get your questions
    2. Generate each part of your panel based on the information there.  The tough part (and I'm not 100% on how to do it and I don't have the time to dig into it) will be how to get the data back to your controller.  The easiest way may be to use remote actions and javascript to save the object back via your controller
  3. Using your controller, save the object back.  I'd have the response object have the following data:
    • Account__c:  A lookup to the Account the questions were being answered for
    • Contact__c: If you are keeping track of each person answering the questions
    • QuestionName__c: The name of the question custom setting
    • Answer__c: The value from the Visualforce page.  I would not try to map all the replies to another object because that's not really the best way to do this sort of thing in Salesforce.  For reporting you're much better off having raw data directly than having to jump through a bunch of lookups.  The only downside of this is that your booleans will have to be stored as text like "true"
This would get you what you want and would make it so that you do not have to re-deploy in order to change any of your questions.  However, if your questions do not change (or don't change frequently) I would recommend against this ^^.  Instead I would recommend a custom Visualforce page that is statically generated and handcrafted to generate a single answer object per account.  And in that answer object I would have a field (with the appropriate type) per question and that way a single questionarie would only generate a single record.  This would make reporting on this data MUCH easier.  Additionally, you may want to look into the AppExchange to see if this is a solved problem that you can get from there to do this type of surveying.

[1] https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_js_remoting.htm
[2] https://help.salesforce.com/apex/HTViewHelpDoc?id=cs_about.htm
William TranWilliam Tran

Depending on your requirements, there's a good chance you can get what you need with a simplified version (or at least on the shorterm).

Have 1 object stored all the questions, answers, and responses.
Add some fields for Campaign, account, and other vital information.

Use the standard controller.

The only thing you need to consider is how to best choose the questions

3 viable options

1) Create a master page and only render the questions/sections based on the campaign or other parameters

2) Create one VF page per campaign (like displayed below)

3) Dynamically build a VF page based on campaign with dynamic components/controls.

If you use approach you could be done by tomorrow.

Good luck


User-added image