Translate

Saturday, March 31, 2012

Call for Applications for 2012 Media Policy Fellowships | Internews

Ten fully-funded fellowships to participate in the 14th annual Annenberg-Oxford Media Policy Summer Institute are available for qualified applicants from the developing world.

For details see: Call for Applications for 2012 Media Policy Fellowships | Internews

jQuery, AJAX, JSON - Mofify Select Box Options


In my Struts action I populate a list, lstDataView, and then use Flexjson to serialize:

public String appTableChange() throws Exception {
 if(request.getParameter("this.appTableID") != null){
  this.appTableID = Integer.parseInt(request.getParameter("this.appTableID"));
 }
 if(this.appTableID != null){
  SessionService.removeAttributeFromSession(request, "LstViewRecords");
  //load the list of views
  loadTableViews();
  //serialize the list
  String jsonResult = new flexjson.JSONSerializer().serialize(lstDataView);
  response.setContentType("text/javascript");
  response.getWriter().write(jsonResult);
 }
 return null;
}


Each entry in the list has two fields, ID and title. ID will be used for the key and title will be used for the value when I create the options. Here is the snippet of script from my JSP page. Using getJSON, I call the Struts action listed above. Then I iterate through the returned result to create the string of options and change the options in the select box.

$.getJSON("../AppTableChange.action", {appTableID: $(this).val(), ajax: 'true'}, function(j){
var options = '<option value=-1>Please Select</option>';
 for (var i = 0; i < j.length; i++) {
  options += '<option value="' + j[i].ID + '">' + j[i].title + '</option>';
 }
 $("select#viewID").html(options);
})

Tuesday, March 27, 2012

PowerShell - Get Exchange Distribution Group Information

Today I was asked to create a list of our Exchange distribution groups showing the name of the group, list owner, and the notes field. Here is the script I used. The Get-Group PowerShell command is used to get the notes field. Output is sent to a csv file.

# Initialize array
$totalObj = @()

# Retrieve all DGs
$temp = Get-DistributionGroup -ResultSize Unlimited | select-Object name, managedby, @{n="Notes";e={(Get-Group $_).Notes}} |

# Loop through all distribution groups
ForEach-Object {

  # Create instance of object of type .NET
  $obj = New-Object System.Object

  # Add the name of the DG to the object
  #if ($i -eq 0) {
   $obj | Add-Member -MemberType NoteProperty -Value $_.name -Name 'Distribution Group' -Force
  #}

  # Add list owner of the DG to the object
  $obj | Add-Member -MemberType NoteProperty -Value $_.managedby -Name 'DG Manager' -Force 

  # Add notes of the DG to the object
  $obj | Add-Member -MemberType NoteProperty -Value $_.Notes -Name 'Description' -Force 
  
  # Add the object to the array
  $totalObj += $obj

}

# Pipe output to .csv file
$totalObj | Export-Csv c:\exchangescripts\ListMembers3-2012man.csv

Friday, March 23, 2012

Mobile App to Improve Information Sharing Amid Crises | Internews

Partnership between Internews' Humanitarian Information Projects and ACAPS wins internal Mobile App Competition

A new mobile app designed to make it easier for humanitarian agencies to share up-to-date information was selected for development in the first internal Mobile App Competition organized by the Internews Center for Innovation & Learning. The app is a collaboration between Internews' Humanitarian Information Projects and the Assessment Capacities Project (ACAPS).

More at: Mobile App to Improve Information Sharing Amid Crises | Internews

Monday, March 12, 2012

Reporting on Girls' Education with Data-Driven Journalism | Internews

Kenyan journalist Wycliffe Masinde knew that the girls in his home county Turkana were getting shortchanged on education. Only one third of school-aged girls attend school. In 2003, 20 girls enrolled in the newly established Longech free primary school. By 2010, only four were left to sit for graduation exams.

More at: Reporting on Girls' Education with Data-Driven Journalism | Internews

Sunday, March 11, 2012

Struts 2 - Dynamic Data Grid Example

The data grid shown below was dynamically created using Struts 2, MyBatis, and jQuery. XML files are used to define the structure of the table being edited and the table relationship of foreign key fields. The structure that is used to dynamically generate the final form can be easily adapted to fit any simple table. This structure gives me the ability to quickly add tables, add or remove table fields, and create a data grid that can be used to view and delete records and edit fields.

The SQL script to create the table.

CREATE TABLE [dbo].[cjxProjectStaff](
 [RecordID] [int] NULL,
 [AppUserID] [int] NULL,
 [StaffRoleID] [int] NULL,
 [BudgetAuthority] [bit] NULL
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[cjxProjectStaff]  WITH CHECK ADD  CONSTRAINT [FK_cjxProjectStaff_AppUser] FOREIGN KEY([AppUserID])
REFERENCES [dbo].[AppUser] ([ID])
GO

ALTER TABLE [dbo].[cjxProjectStaff] CHECK CONSTRAINT [FK_cjxProjectStaff_AppUser]
GO

ALTER TABLE [dbo].[cjxProjectStaff]  WITH CHECK ADD  CONSTRAINT [FK_cjxProjectStaff_luStaffRole] FOREIGN KEY([StaffRoleID])
REFERENCES [dbo].[luStaffRole] ([ID])
GO

ALTER TABLE [dbo].[cjxProjectStaff] CHECK CONSTRAINT [FK_cjxProjectStaff_luStaffRole]
GO

ALTER TABLE [dbo].[cjxProjectStaff]  WITH CHECK ADD  CONSTRAINT [FK_cjxProjectStaff_Project] FOREIGN KEY([RecordID])
REFERENCES [dbo].[Project] ([ID])
GO


I use two XML files. One XML file defines the structure of the table and is used in the application to provide information on what fields to display, the types of fields, and whether or not the field can be edited. Here is the file that defines the fields in the ProjectStaff table:

<list>
  <FieldDescriptor>
    <fieldName>recordID</fieldName>
    <fieldLabel>Project ID</fieldLabel>
    <fieldType>1</fieldType>
    <fieldSize>0</fieldSize>
    <editable>false</editable>
    <listable>false</listable>
  </FieldDescriptor>
  <FieldDescriptor>
    <fieldName>appUserID</fieldName>
    <fieldLabel>Staff ID</fieldLabel>
    <fieldType>1</fieldType>
    <fieldSize>0</fieldSize>
    <editable>true</editable>
    <listable>true</listable>
    <fkeyName>lstKeyStaff</fkeyName>    
  </FieldDescriptor>
  <FieldDescriptor>
    <fieldName>StaffRoleID</fieldName>
    <fieldLabel>Role ID</fieldLabel>
    <fieldType>1</fieldType>
    <fieldSize>0</fieldSize>
    <editable>true</editable>
    <listable>true</listable>
    <fkeyName>lstStaffRole</fkeyName>     
  </FieldDescriptor>
  <FieldDescriptor>
    <fieldName>budgetAuthority</fieldName>
    <fieldLabel>Budget Authority</fieldLabel>
    <fieldType>5</fieldType>
    <fieldSize>0</fieldSize>
    <editable>true</editable>
    <listable>true</listable>    
  </FieldDescriptor>
</list>


When this file is read in to the application, it creates a List of type FieldDescriptor, describing all of the fields in the table and relationships to other tables if the field is a foreign key.

Another XML file defines tables that are related to the main table by a foreign key. The fkeyName field from the XML file above is used to link to the fields defined in the following XML file.

<list>
  <KeyDescriptor>
    <name>lstKeyStaff</name>
    <mapper>KeyValueDescriptionMapper</mapper>
    <method>selectAllKeyValue</method>
    <luTable>vwAllKeyStaff</luTable>
    <luTableField>DescValue</luTableField>    
  </KeyDescriptor>
  <KeyDescriptor>
    <name>lstStaffRole</name>
    <mapper>KeyValueDescriptionMapper</mapper>
    <method>selectAllKeyValue</method>
    <luTable>luStaffRole</luTable>
    <luTableField>DescValue</luTableField>    
  </KeyDescriptor>
</list>



When this file is read in to the application, it creates a List of type KeyDescriptor. The "KeyDescriptor" tells the application how to load in values to create a list of Key/Value pairs. The list will be used by Struts to create the select lists in our JSP page.

Now for the main part of the application. Besides my Struts action class, there are two classes with five main fields that are used.

public abstract class BaseTable {
protected List<Object> lstRecord;//list of records from the table
protected BaseTableDescriptor baseTableDescriptor;//the table descriptor for the table records that are being viewed or edited
protected HashMap<Object, Map<Object, String>> selectMap; //map of selection values for foreign key tables

public abstract class BaseTableDescriptor {
protected List<FieldDescriptor> lstFieldDescriptor;
protected List<KeyDescriptor> lstKeyDescriptor;

The list, lstRecord, is populated with the table records from the ProjectStaff table. The list, lstFieldDescriptor, is created from the XML file displayed above and as stated before this list describes the database fields.
The list, lstKeyDescriptor, is created from the XML file displayed above and the information in this list is used to create the selectMap HashMap. For each entry in "selectMap", the key is "KeyDescriptor.name" and the value is the list of Key/Value pairs for the named table.

This information is then used in the Struts tags in the following JSP page to create the table.

<!--Iterate through our list of records-->
<s:iterator value="baseTable.lstRecord"  var="element" status="stat">
<tr>
<!--For each record, iterate through our list of field descriptors-->
<s:iterator value="baseTable.baseTableDescriptor.lstFieldDescriptor" var="fdelement" status="fdstat">
<s:if test="listable">
  <s:if test="#stat.odd == true">
  <td style="background-color:#F9F9d9;white-space:nowrap;height:23px;">
  </s:if>
  <s:else>
  <td style="background-color:#F9F9F9;white-space:nowrap;height:23px;">
  </s:else>
  <s:if test="#fdstat.index == 1">
   <img id="imgDel${stat.index}" src="../images/del1.gif" style="border:0px" alt="Delete" title="Delete"/>
  <script type="text/javascript">
    //delete the record
    $('#imgDel${stat.index}').click(function() {
      //clear the value to mark the record for deletion
      $('#${fieldName}${stat.index}').val('');
      //hide the row
      $(this).parent().parent().hide();
    });
  </script>
  </s:if>
  <!--If this is a foreign key field-->
  <s:if test="fkeyName != null">
      <s:select name="baseTable.lstRecord[%{#stat.index}].%{#fdelement.fieldName}" id="%{#fdelement.fieldName}%{#stat.index}" list="baseTable.selectListMap(fkeyName)" headerKey="" headerValue="Please Select" theme="simple"/>
  </s:if>
  <s:else>
    <!--If this is a boolean field-->
    <s:if test="fieldType == 5">
      <s:checkbox name="baseTable.lstRecord[%{#stat.index}].%{#fdelement.fieldName}" theme="simple"  title="%{fieldLabel}"/>
    </s:if>
    <!--The following is just used for debugging-->
    <s:else>
      <s:if test="fkeyName != null">
        <s:property value="keyValue(fkeyName, '#element.' + #fdelement.fieldName)"/>
      </s:if>
      <s:else>
        ${element[fdelement.fieldName]}
      </s:else>
    </s:else>
  </s:else>
  </td>
</s:if>
</s:iterator>
</tr>
</s:iterator>
<tr>
  <s:if test="baseTable.lstRecord.size() < 5">
    <td id="tdAddNew" style="background-color:#a0F0d9;" colspan="1"> <img id="imgAddNew" src="../images/max1t.gif" style="border:0px"/> <b>Add New Project Staff</b></td>
    <script type="text/javascript">
    //add a new record
    $('#tdAddNew').click(function() {
      //clear the result message
      $("#tdResMsg").val("")
      //save the records and reload the table
      $("#${baseTable.ajaxTarget}").load('../${namespace}/AddCustomTableRecord.action?btName=${baseTable.tableName}&btRecID=${baseTable.recordID}&rtSize=${baseTable.lstRecord.size()}&rNew=true&target=${baseTable.ajaxTarget}', $("#saveRecord").serialize());
    });
    </script>
  </s:if>
  <s:else>
    <td colspan="1"><b> Max records allowed reached.</b></td>
  </s:else>
  <td id="tdResMsg"colspan="2"><s:property value="baseTable.resMsg"/></td>
</tr>
<tr>
  <td><SPACER height="5" type="block"></td>
</tr>
<tr>
  <td colspan="2" align="center" style="white-space: nowrap">
  <s:submit action="SaveCustomTable" id="saveCustomTable" value="Save" onclick="return false;" theme="simple"/>
    <s:submit action="ReloadCustomTable" id="reloadCustomTable" value="Reload" onclick="return false;" theme="simple"/>
  </td>
</tr>
<script type="text/javascript">
//submit the records
$('#saveCustomTable').click(function() {
  $("#tdResMsg").val("Saving records. Please wait.")
  $("#${baseTable.ajaxTarget}").load('../${namespace}/SaveCustomTable.action?btName=${baseTable.tableName}&btRecID=${baseTable.recordID}&rtSize=${baseTable.lstRecord.size()}&target=${baseTable.ajaxTarget}', $("#saveRecord").serialize());
});
//reload the records
$('#reloadCustomTable').click(function() {
  $("#tdResMsg").val("Reloading records. Please wait.")
  $("#${baseTable.ajaxTarget}").load('../${namespace}/ReloadCustomTable.action?btName=${baseTable.tableName}&btRecID=${baseTable.recordID}&rtSize=${baseTable.lstRecord.size()}&target=${baseTable.ajaxTarget}', $("#saveRecord").serialize());
});
</script>


This is a very brief explanation of the process I use. Please comment if you would like some additional information or have any questions.

Thursday, March 1, 2012

Christophe Manzanga Boyomba | Internews

Born in a village in Congo’s south and educated in a Catholic missionary school, Christophe Manzanga demonstrates that Internews’ strength lies in the capacity of our local team members.
Christophe Manzanga Boyomba | Internews