API Questions on Kentico API.
Version 6.x > API > Dynamic Form Fileds View modes: 
User avatar
Member
Member
tommie.goad-chickasaw - 8/10/2012 11:28:54 AM
   
Dynamic Form Fileds
We have multiple locations to enter into our website. Each location can have multiple phone numbers and the phone number can be used by multiple locations. We created a document type and need the form in that document type to allow us to select a location and based off of that selection, populate the phone numbers associated with that location.

User avatar
Certified Developer 8
Certified Developer 8
Jiveabillion - 8/10/2012 4:12:35 PM
   
RE:Dynamic Form Fileds
Let me just clarify what you are asking for.

You need to be able to determine the location of the parent document that you are adding this child document to and you need to be able to change the options in the dropdown list for this new item based on that location. Does that sound right?

If so, I don't know that the target node's information is available in that context. I can research it, but I think one of the Kentico folks would be able to find out quicker than I can.


User avatar
Certified Developer 8
Certified Developer 8
Jiveabillion - 8/10/2012 4:14:19 PM
   
RE:Dynamic Form Fileds
Here is a post with a similar question:

http://devnet.kentico.com/Forums/f54/fp3/t21931/Macros-in-SQL-for-Multiple-Choice-Type-Fields.aspx

That is for version 5.5 though.

User avatar
Member
Member
TG - 8/10/2012 4:22:39 PM
   
RE:Dynamic Form Fileds
Let me try to explain better.

I have one drop down (DrpDown1) that I need to populate (dynamically, by SQL or whatever).
I need to be able to populate DrpDown2 based off the value chosen in DrpDown1.

Hope that helps...

User avatar
Kentico Support
Kentico Support
kentico_jurajo - 8/11/2012 12:12:56 AM
   
RE:Dynamic Form Fileds
Hi,

You need to create a custom form control which will consist of two drop down list controls. First one you will load with items dynamically from DB or whatever and then in the events like selected item change or index change, based on the selected item you will load values to the second drop down.

Best regards,
Juraj Ondrus

User avatar
Certified Developer 8
Certified Developer 8
Jiveabillion - 8/11/2012 2:25:53 PM
   
RE:Dynamic Form Fileds
Here is another thread that will explain how to use the GetOtherValues method of a custom form control so you can use one control to fill more than one property, which is what you will need to do.

http://devnet.kentico.com/Forums.aspx?forumid=55&threadid=30037

User avatar
Member
Member
TG - 8/14/2012 10:55:10 AM
   
RE:Dynamic Form Fileds
I am doing my fields as follows:
Field 1 is "Location" (like the Office example on the Corporate site)

When the Location is chosen I populate Field 2 "Phone Numbers" with all phone numbers associated with that particular location. This is working great!

I am having trouble with saving the Phone Number. I chose a location and then the phone list populates, I hit save and it stays on the screen, but if I navigate away and come back the phone does not save. The location does save. Here is my code (It is not finished and is a work in progress):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

// Kentico Specific
using CMS.FormControls;
using CMS.GlobalHelper;
using System.Text.RegularExpressions;
using CMS.DataEngine;
using CMS.SettingsProvider;
using System.Data;


public partial class CMSFormControls_LocationPicker : FormEngineUserControl
{
/// <summary>
/// Gets or sets the value entered into the field
/// </summary>

public override Object Value
{
get
{
return DrpLocation.SelectedItem.Value;
}
set
{
// Ensure drop down list options
EnsureItems();
DrpLocation.SelectedValue = System.Convert.ToString(value);
}
}

/// <summary>
/// Property used to access the Location parameter of the form control.
/// </summary>
public string Phone
{
get
{
return ValidationHelper.GetString(DrpPhoneList.SelectedItem.Value,"");
}
set
{
SetValue("Phone", value);
}
}

/// </summary>

/// <returns>It returns an array where the first dimension is the attribute name and the second is its value.</returns>

public override object[,] GetOtherValues()
{
if (!String.IsNullOrEmpty(Phone))
{
object[,] result = new object[1, 2];
result[0, 0] = "Phone";
result[0, 1] = DrpPhoneList.SelectedItem.Value; //this is the variable that you will need to set to your selected state name.
return result;
}
else
{
return base.GetOtherValues();
}
}

//public override object[,] GetOtherValues()
//{
// object[,] array = new object[1, 2];
// array[0, 0] = "Phone";
// array[0, 1] = DrpPhoneList.SelectedItem.Value;
// return array;
//}

/// <summary>
/// Returns true if selected. Otherwise, it returns false and displays an error message.
/// </summary>

public override bool IsValid()
{
if ((string)Value != "")
{
return true;
}
else
{
// Set form control validation error message.
this.ValidationError = "Please choose a location.";
return false;
}
}


/// <summary>
/// Sets up the internal DropDownList control.
/// </summary>
protected void EnsureItems()
{

if (DrpLocation.Items.Count == 0)
{
DrpLocation.Items.Add(new ListItem("(select a location)", ""));

// Get SQL query text
string sqlText = "SELECT TestOfficeID, DocName FROM custom_TestOffice";

if (!sqlText.Contains("@"))
{
DataSet ds = null;

try
{
ds = ConnectionHelper.ExecuteQuery(sqlText, null, QueryTypeEnum.SQLQuery, false);
}
catch { }

if (!DataHelper.DataSourceIsEmpty(ds))
{
// Initialize control
DrpLocation.DataSource = ds;
DrpLocation.DataValueField = ds.Tables[0].Columns[0].ColumnName;
DrpLocation.DataTextField = ds.Tables[0].Columns[1].ColumnName;
DrpLocation.DataBind();

// Register OnAfterDataLoad handler
//this.Form.OnAfterDataLoad += new BasicForm.OnAfterDataLoadEventHandler(Form_OnAfterDataLoad);
////// HERE IS WHERE i COMMENTED IT OUT ///////

}
}
}
}

/// <summary>
/// Handler for the Load event of the control.
/// </summary>

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Ensure drop-down list options
EnsureItems();
}
}

protected void DrpLocation_SelectedIndexChanged(object sender, EventArgs e)
{
string LocationID = DrpLocation.SelectedItem.Value;
DrpPhoneList.Items.Clear();
if (DrpPhoneList.Items.Count == 0)
{
//DrpPhoneList.Items.Add(new ListItem("(select a location)", ""));

// Get SQL query text
string sqlText = "SELECT customtable_cnphones.PhoneNumber, customtable_cnphones.PhoneNumber FROM customtable_cnphones INNER JOIN custom_TestOffice ON custom_TestOffice.TestOfficeID=customtable_cnphones.PhoneLocation WHERE customtable_cnphones.PhoneLocation =" + LocationID;

if (!sqlText.Contains("@"))
{
DataSet ds = null;

try
{
ds = ConnectionHelper.ExecuteQuery(sqlText, null, QueryTypeEnum.SQLQuery, false);
}
catch { }

if (!DataHelper.DataSourceIsEmpty(ds))
{
// Initialize control
DrpPhoneList.DataSource = ds;
DrpPhoneList.DataValueField = ds.Tables[0].Columns[0].ColumnName;
DrpPhoneList.DataTextField = ds.Tables[0].Columns[1].ColumnName;
DrpPhoneList.DataBind();

// Register OnAfterDataLoad handler
//this.Form.OnAfterDataLoad += new BasicForm.OnAfterDataLoadEventHandler(Form_OnAfterDataLoad);
////// HERE IS WHERE i COMMENTED IT OUT ///////

}
}
}
}
}

User avatar
Certified Developer 8
Certified Developer 8
Jiveabillion - 8/14/2012 1:57:57 PM
   
RE:Dynamic Form Fileds
Make sure that the name of the 2nd field is "Phone" so it matches. You should actually expose that value as a setting for your custom form control so you can use it in more than one instance and set the name of the fields to what they need to be for that particular document type.




if (!String.IsNullOrEmpty(Phone))
{
object[,] result = new object[1, 2];
result[0, 0] = "Phone"; // MAKE SURE THIS VALUE IS THE NAME OF YOUR FIELD
result[0, 1] = Phone; // Use the same variable you are checking for nullorempty for consistency.
return result;
}
else
{
return base.GetOtherValues();
}

User avatar
Member
Member
TG - 8/14/2012 2:08:29 PM
   
RE:Dynamic Form Fileds
The name of my field on the Document Type is "Phone". Do I need to have a field on the Custom Form Control named "Phone" as well?

User avatar
Certified Developer 8
Certified Developer 8
Jiveabillion - 8/15/2012 1:42:12 PM
   
RE:Dynamic Form Fileds
No, that should work. Did make it so your Phone field is not visible in the editor? You need to do that.

User avatar
Member
Member
TG - 8/21/2012 9:40:26 AM
   
RE:Dynamic Form Fileds
I got all of this to work. Thanks for your help.

I then tried to pass a variable into the code behind from a form control property so I could add the form control to a document multiple times. It basically passes in the name of the field on the document type that will hold the value of the second drop down. It worked when I added the second control, but when I added the third control it stopped working. Is there something in Kentico that will not allow multiple uses of a control in this way?

User avatar
Certified Developer 8
Certified Developer 8
Jiveabillion - 8/24/2012 12:59:34 PM
   
RE:Dynamic Form Fileds
Not that I know of. I would check everything to make sure you aren't creating ambiguous field names or something of that nature. Try debugging it in VS to see what might be happening.

User avatar
Kentico Support
Kentico Support
kentico_jurajo - 8/27/2012 5:32:56 AM
   
RE:Dynamic Form Fileds
Hi,

Could you please share your current code so we can take a closer look? I am also not aware of anything that should be preventing this from working correctly.

Best regards,
Juraj Ondrus

User avatar
Member
Member
TG - 8/27/2012 8:49:52 AM
   
RE:Dynamic Form Fileds
I am trying to load phone number values into a drop down based off of a location drop down. So on my aspx page I have a location drop down and a phone drop down. I have a custom form control that uses that aspx page with the code behind below to try and accomplish the task. It worked with one location and phone, but when I added a field called "PhoneVar" that will allow you to enter the name of the field to be used on the Document Type instead of having it hard coded, it would only work with 2 locations and phones.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

// Kentico Specific
using CMS.FormControls;
using CMS.GlobalHelper;
using System.Text.RegularExpressions;
using CMS.DataEngine;
using CMS.SettingsProvider;
using System.Data;
using CMS.FormEngine;


public partial class CMSFormControls_LocationPicker : FormEngineUserControl
{
/// <summary>
/// Gets or sets the value entered into the field
/// </summary>

public override Object Value
{
get
{
return DrpLocation.SelectedItem.Value;
}
set
{
// Ensure drop down list options
PopulateLocations();
DrpLocation.SelectedValue = System.Convert.ToString(value);
}
}

/// <summary>
/// Property used to access the Width parameter of the form control.
/// </summary>
public string PropertyValue
{
get
{

return ValidationHelper.GetString(this.GetValue("PhoneVar"), "");
}
set
{
//SetValue(ValidationHelper.GetString(this.GetValue("PhoneVar"), ""), value);
}
}


/// <summary>
/// Property used to access the Location parameter of the form control.
/// </summary>
public string Dependant
{

get
{
return ValidationHelper.GetString(DrpPhoneList.SelectedItem.Value, "");

}
set
{
this.SetValue(PropertyValue, value);
}
}

/// </summary>

/// <returns>It returns an array where the first dimension is the attribute name and the second is its value.</returns>
///

public override object[,] GetOtherValues()
{
if (!String.IsNullOrEmpty(Dependant))
{
object[,] result = new object[1, 2];
result[0, 0] = PropertyValue; // MAKE SURE THIS VALUE IS THE NAME OF YOUR FIELD
result[0, 1] = Dependant; // Use the same variable you are checking for nullorempty for consistency.
return result;
}
else
{
return base.GetOtherValues();
}
}

/// <summary>
/// Returns true if selected. Otherwise, it returns false and displays an error message.
/// </summary>

public override bool IsValid()
{
if ((string)Value != "")
{
return true;
}

else
{
// Set form control validation error message.
this.ValidationError = "Please choose a location.";
return false;
}
}

/// <summary>
/// Sets up the internal DropDownList control.
/// </summary>
protected void PopulateLocations()
{
if (DrpLocation.Items.Count == 0)
{
DrpLocation.Items.Add(new ListItem("(select a location)", ""));

// Get SQL query text
string sqlText = "SELECT LocationID, OfficeName FROM custom_location";

if (!sqlText.Contains("@"))
{
DataSet ds = null;

try
{
ds = ConnectionHelper.ExecuteQuery(sqlText, null, QueryTypeEnum.SQLQuery, false);
}
catch { }

if (!DataHelper.DataSourceIsEmpty(ds))
{
// Initialize control
DrpLocation.DataSource = ds;
DrpLocation.DataValueField = ds.Tables[0].Columns[0].ColumnName;
DrpLocation.DataTextField = ds.Tables[0].Columns[1].ColumnName;
DrpLocation.DataBind();
}
}
}
}

/// <summary>
/// Handler for the Load event of the control.
/// </summary>

protected void Page_Load(object sender, EventArgs e)
{

if (!IsPostBack)
{
// Ensure drop-down list options
PopulateLocations();
string SelectedPhone = ValidationHelper.GetString(Form.Data.GetValue(PropertyValue), "");

if (DrpLocation.SelectedItem.Value != "")
{
PopulatePhoneList();

if (SelectedPhone != "")
{
DrpPhoneList.SelectedValue = SelectedPhone;
}
}
}
}

protected void DrpLocation_SelectedIndexChanged(object sender, EventArgs e)
{
string LocationID = DrpLocation.SelectedItem.Value;
DrpPhoneList.Items.Clear();

if (DrpPhoneList.Items.Count == 0)
{
PopulatePhoneList();
}
}

protected void PopulatePhoneList()
{
string LocationID = DrpLocation.SelectedItem.Value;
DrpPhoneList.Items.Add(new ListItem("(select a phone number)", ""));

// Get SQL query text
string sqlText = "SELECT PhonenumberID, PhoneNumber FROM custom_phonenumber WHERE PhoneLocation =" + LocationID;

if (!sqlText.Contains("@"))
{
DataSet ds = null;

try
{
ds = ConnectionHelper.ExecuteQuery(sqlText, null, QueryTypeEnum.SQLQuery, false);
}
catch { }

if (!DataHelper.DataSourceIsEmpty(ds))
{
// Initialize control
DrpPhoneList.DataSource = ds;
DrpPhoneList.DataValueField = ds.Tables[0].Columns[0].ColumnName;
DrpPhoneList.DataTextField = ds.Tables[0].Columns[1].ColumnName;
DrpPhoneList.DataBind();
}
}
}
}

User avatar
Kentico Support
Kentico Support
kentico_jurajo - 9/3/2012 2:11:07 AM
   
RE:Dynamic Form Fileds
Hi,

could you please move the code from Page_Load to OnInit event and also do not use the post back check IsPostBack?
I think this may be preventing the correct life cycle for a form control.

Best regards,
Juraj Ondrus

User avatar
Member
Member
TG - 9/6/2012 2:49:15 PM
   
RE:Dynamic Form Fileds
This is fixed now! While writing the code and testing values that I was passing into the control, I made my hidden fields visible in order to see what was being populated from the code. Once I made those fields hidden again it started working. Thanks for all the help with this issue.