Dailycode.info

Short solution for short problems

Adding Web controls dynamically

Often ASP pages need to be created dynamically, based on data from a database for example. It is not possible to use the designer, unless you can use a repeater. When you can't, then it can be a stressfull time. Here is a small example. Don't forget, when you create your controls in the CreateChildControls method, they are stateless. After a postback they lose state. So best add the controls in the constructor.

I have a control that inherits from table row. Here is the code to fill this control:

public CCCActivityRow(string activityGuid, string unitGuid, string modGuid, bool insertMode)
{
//un = Units.GetUnit(unitGuid);
_activityGuid = activityGuid;
_unitGuid = unitGuid;
_modGuid = modGuid;
_insertMode = insertMode;
if (InsertMode)
{
BuildTable();
}
else
{
BuildTableUpdate();
}
}
private void BuildTableUpdate()
{
List<CCGrade> activegrades = Grades.GetGradesForUnit(_unitGuid);
if (activegrades != null)
{
TableCell tdDescr = new TableCell();
Label lblDescr = new Label();
lblDescr.Text = "Opzetten kamer";
tdDescr.Controls.Add(lblDescr);
HiddenField hdd = new HiddenField();
tdDescr.Controls.Add(lblDescr);
Controls.Add(tdDescr);
foreach (CCGrade grade in activegrades)
{
TableCell td = new TableCell();
td.Attributes.Add("class", "detailright");
TextBox txt = new TextBox();
txt.ID = "update." + grade.Guid;
txt.Width = 40;
td.Controls.Add(txt);
Controls.Add(td);
}
TableCell tdAction = new TableCell();
tdAction.Attributes.Add("class", "detailright");
Button btnSave = new Button();
btnSave.Click += new EventHandler(btnSave_Click);
btnSave.Text = "Save";
tdAction.Controls.Add(btnSave);
Controls.Add(tdAction);
}
else
{
TableCell tdDescr = new TableCell();
Label lblDescr = new Label();
lblDescr.Text = "This unit has no active grades!";
tdDescr.Controls.Add(lblDescr);
Controls.Add(tdDescr);
}
}

The onclick event of the save button is called when the button is clicked. Now we need to get the values out of the control. We loop over all controls in this class and read the ones we need.

void btnSave_Click(object sender, EventArgs e)
{
//Eerst een activity object aanmaken
CCActivity act = new CCActivity();
act.ModuleGuid = _modGuid;
 
foreach (Control c in this.Controls)
{
if (c.GetType() == typeof(TableCell))
{
Control txt = ((TableCell)c).Controls[0];
if (txt.GetType() == typeof(TextBox))
{
string id = ((TextBox)txt).ID;
string value = ((TextBox)txt).Text;
if (String.IsNullOrEmpty(value))
{
value = "0";
}
if (id.StartsWith("insertD"))
{
act.Description = value;
}
else
{
CCActivityGrade acgr = new CCActivityGrade();
acgr.Hours = int.Parse(value);
acgr.GradeGuid = id.Replace("insertT.","");
act.ActivityGrades.Add(acgr);
}
}
}
}
//Save Activity
}

 

 


Add en remove items from asp listboxes using javascript

As I told you before, I'm working on a ASP.Net program. Because of the minimal use, I decided to use plain javascript and no AJAX. Also for deployment issues. I have a simple scenario, 2 listboxes. When I add a value to one, it should disappear in the other. Here is the setup:



 

I add the javascript via the code behind to the asp:images. The code is called in the page load event. This is the code that does the trick:

StringBuilder script = new StringBuilder();        
script.Append("javascript:");        
script.AppendFormat("var ind = {0}.selectedIndex;", lstOut.ClientID);        
script.Append("if (ind>-1){");        
script.AppendFormat("var sel = {0}.value;", lstOut.ClientID);        
script.AppendFormat("var len = {0}.length;",lstIn.ClientID); 
script.AppendFormat("{0}.options[len] = new Option({1}.options[ind].text,sel);" 
, lstIn.ClientID, lstOut.ClientID);        
script.AppendFormat("{0}.options[ind] = null;", lstOut.ClientID);        
script.Append("}");        
btnRight.Attributes.Add("onclick", script.ToString());         

script = new StringBuilder();        
script.Append("javascript:");        
script.AppendFormat("var ind = {0}.selectedIndex;", lstIn.ClientID);        
script.Append("if (ind>-1){");        
script.AppendFormat("var sel = {0}.value;", lstIn.ClientID);        
script.AppendFormat("var len = {0}.length;",lstOut.ClientID); 
script.AppendFormat("{0}.options[len] = new Option({1}.options[ind].text,sel);" 
, lstOut.ClientID, lstIn.ClientID);        
script.AppendFormat("{0}.options[ind] = null;", lstIn.ClientID);        
script.Append("}");        
btnLeft.Attributes.Add("onclick", script.ToString()); 

 

This is the Javascript that is generated for the right arrow image:

var ind = ctl00_CPHMiddle_lstOut.selectedIndex;
if (ind>-1){var sel = ctl00_CPHMiddle_lstOut.value;
var len = ctl00_CPHMiddle_lstIn.length;
ctl00_CPHMiddle_lstIn.options[len] = new Option(ctl00_CPHMiddle_lstOut.options[ind].text,sel);
ctl00_CPHMiddle_lstOut.options[ind] = null;}

 

When the user is finished with the listboxes he presses a save button that gets all items out of the right listbox and writes them to the database. This is the second challenge, because you will notice that the Listbox loses the state after a postback. This problem can be solved with a hidden field and more javascript!

This code is placed on the page load, behind the code of the listboxes. This is executed before the postback occurs and it doesn't interfear with the asp event. 

script = new StringBuilder();
script.Append("javascript:");
script.AppendFormat("var len = {0}.length;var values='';", lstIn.ClientID);
script.Append("for (i = 0; i < len; i++){");
script.AppendFormat("values = values + {0}.options[i].text 
+'*'+{0}.options[i].value+'/';", lstIn.ClientID);
script.Append("}");
script.AppendFormat("{0}.value = values;",unitsIn.ClientID);
btnSave.Attributes.Add("onclick", script.ToString());

 

As you can see we place the text and the value in the values array, split up the text and value by a '*' and split up the items with '/'. When we want to extract the values in the event handler of the button, we use the string.split method. The code looks like this:

//Write all untis to the selected department.

List<CCUnit> units = new List<CCUnit>();
string [] strArrunitsIn = unitsIn.Value.Split('/');
foreach (string str in strArrunitsIn)
{
	if (!String.IsNullOrEmpty(str))
        {
        	string[] item = str.Split('*');
                CCUnit unit = new CCUnit();
                unit.Guid = item[1];
                unit.Description = item[0];
                units.Add(unit);
        }
}
//Update
 

You can ask questions or request the complete code be commenting or email.

 

Find user in active directory and get the properties

When you are developing an application that uses active directory users, without using the default membership provider, you'll need to write some default login logic. In my application a perform a login check and when users are added to the application, I perform a check if the users exists.

First the login check:

/// <summary>

/// Checks if the user exists in active directory and if the password is correct

/// </summary>

/// <param name="domain">Domain of the user</param>

/// <param name="username">Login name</param>

/// <param name="pwd">Password</param>

/// <returns>True=user is authenticated</returns>

public static bool IsAuthenticated(string domain, string username, string pwd)

{

    string domainAndUsername = domain + @"\" + username;

    string path = "";

 

    DirectoryEntry entry = new DirectoryEntry(path, domainAndUsername, pwd);

 

    try

    {

        DirectorySearcher search = new DirectorySearcher(entry);

 

        search.Filter = "(SAMAccountName=" + username + ")";

        search.PropertiesToLoad.Add("cn");

        SearchResult result = search.FindOne();

 

        if (null == result)

        {

            return false;

        }

    }

    catch (Exception ex)

    {

        throw ex;

    }

 

    return true;

}

This function simply checks if a user with password and login name exists in AD. We use username and password to create the directory entry and perform an action with this entry. If the username or the password is invalid, we get this error: Logon failure: unknown user name or bad password. 

The next AD action is to lookup if the user exists: 

/// <summary>

/// Checks if a user exists in active directory

/// </summary>

/// <param name="userName">Users name</param>

/// <returns>True=user exists</returns>

public static bool FindUserInAD(string userName)

{

    //string domainAndUsername = domain + @"\" + username;

    string path = "";

    //DirectoryEntry entry = new DirectoryEntry(path, @"pmi\g-labautomation", "Ordina$78");

    DirectoryEntry entry = new DirectoryEntry(path);

    try

    {

        DirectorySearcher search = new DirectorySearcher(entry);

 

        search.Filter = "(SAMAccountName=" + userName + ")";

        search.PropertiesToLoad.Add("cn");

        SearchResult result = search.FindOne();

 

        if (null == result)

        {

            return false;

        }

    }

    catch (Exception ex)

    {

        throw ex;

    }

 

    return true;

}

 

Here's an example of active directory properties with dummy values!

Last a simple function to get the basic properties for a user from AD:

/// <summary>

/// Returns Ilist with account info

/// </summary>

/// <param name="userName">Users name</param>

/// <returns>List

/// index 1: displayname

/// index 2: accountname

/// index 3: email</returns>

public static List <string> GetUserFromAD(string userName)

{

    //string domainAndUsername = domain + @"\" + username;

    string path = "";

    //DirectoryEntry entry = new DirectoryEntry(path, @"pmi\g-labautomation", "Ordina$78");

    DirectoryEntry entry = new DirectoryEntry(path);

    List<string> returnList = new List<string>();

    entry.AuthenticationType = AuthenticationTypes.FastBind;

 

    try

    {

        DirectorySearcher search = new DirectorySearcher(entry);

 

        search.Filter = "(SAMAccountName=" + userName + ")";

        //search.PropertiesToLoad.Add("cn");

        search.PropertiesToLoad.Add("mail");

        search.PropertiesToLoad.Add("displayName");

        search.PropertiesToLoad.Add("SAMAccountName");

       

        SearchResult result = search.FindOne();

 

        if (null == result)

        {

            return null;

        }

        else

        {

            returnList.Add(result.Properties["displayName"][0].ToString());

            returnList.Add(result.Properties["SAMAccountName"][0].ToString());

            try

            {

                returnList.Add(result.Properties["mail"][0].ToString());

            }

            catch

            {

                returnList.Add("no_email");

            }

            return returnList;

        }

    }

    catch (Exception ex)

    {

        throw ex;

    }

 

}


Using Javascript to get values from asp.Net listbox

If you are not so familiar with Ajax, or just not using it, it could be nice to know Javascripting.

I had to extract a value from a listbox and put it into a textbox, also I wanted to keep the selectedvalue somewhere.

This is how I did it:

ListBox1.Attributes.Add("onclick", "javascript:var w = " + ListBox1.ClientID + ".selectedIndex;
" + txtDepartment.ClientID + ".value = " + ListBox1.ClientID + ".options[w].text; 
" + selItem.ClientID + ".value=" + ListBox1.ClientID + ".value");
 

You can go even further, when you want a Text in the listbox and 2 values, you can use string concatination in Javascript. This is a little more complicated, but still easy programming. In the following code I get the values from the listbox, seperate them and set the selected item of a dropdown and the value of a hidden field! In .Net always use the clientID property, because the name of the field depends on where the field is on.

script = "javascript:arrres= " + ListBox1.ClientID + ".value.split('*');";
script += selItem.ClientID + ".value=arrres[0];";
script += drpUserRoles.ClientID + ".value = arrres[1];";
ListBox1.Attributes.Add("onclick", script);

 

I'm not using Ajax for this project, so maybe there will be some more javascript posts in the near future.

 

Get value from Listbox using javascript.

If you are not so familiar with Ajax, or just not using it, it could be nice to know javascipting.

I had to extract a value from a listbox and put it into a textbox, also I wanted to keep the selectedvalue somewhere.

This is how I did it:

ListBox1.Attributes.Add("onclick", "javascript:var w = " + ListBox1.ClientID + ".selectedIndex;
" + txtDepartment.ClientID + ".value = " + ListBox1.ClientID + ".options[w].text; 
" + selItem.ClientID + ".value=" + ListBox1.ClientID + ".value");
 

You can go even further, when you want a Text in the listbox and 2 values, you can use string concatination in javascript. This is a little more complicated, but still easy programming. In the following code I get the values from the listbox, seperate them and set the selected item of a dropdown and the value of a hidden field!

script = "javascript:arrres= " + ListBox1.ClientID + ".value.split('*');";
script += selItem.ClientID + ".value=arrres[0];";
script += drpUserRoles.ClientID + ".value = arrres[1];";
ListBox1.Attributes.Add("onclick", script);

 

I'm not using Ajax for this project, so maybe there will be some more javascript posts in the near future.