Showing posts with label Tech. Show all posts
Showing posts with label Tech. Show all posts

Monday, May 30, 2016

Crazy Mistakes in Force.com Development I - System.StringException: Invalid id

I have faced so many issues when I’m doing the development and could able to resolve almost all of them with the help of force.com developer forum and SFSE. When I’m thinking of the time I had to spend for them and the difficulties I have faced, I thought to share those problems as well as the appropriate solutions that I could made. Because I believe it may save some other developer’s time.
I’ll keep updating this post series time to time when I catch more other birds.

Prob: System.StringException: Invalid id tempStr

Possibilities:
1). Mostly this will happen when trying to assign query parameters into variables like below
If the value that has passed for accId is not in correct Id format, this exception will be thrown and hard to find out. It's better to assign the value to a variable type of String

or use try catch to validate properly

2). Also if you try to compare a variable type of Id with a String there's a chance of throwing this since the applied String is not in the standard Id format
To overcome this issue it can be used the string value of the Id to compare. 

Thursday, October 8, 2015

Crazy Mistakes in Force.com Development II - Validation Error: Value is not valid - Salesforce apex:selectList

I have used <apex:selectList /> many times but recently I had a trouble with it; onchange event not firing only for some values.

<apex:actionRegion id="salesItemActionRegion">
         <apex:outputLabel value="Sales Item : "></apex:outputLabel>
         <apex:selectList id="drpSalesItem" value="{!selectedProduct}" size="1" >
              <apex:selectOptions id="optnSalesItem" value="{!ProductList}"></apex:selectOptions>
              <apex:actionSupport rerender="pnlProductInfo" action="{!LoadProductDetails}" event="onchange" />
         </apex:selectList>
 </apex:actionRegion>

Below are the selectOptions when I put them in a debug statement.

System.SelectOption[value="value abc", label="value abc", disabled="false"],
System.SelectOption[value="value  def", label="value  def", disabled="false"],
System.SelectOption[value="value ghi", label="value ghi", disabled="false"]

onchange action is firing for first and third values but nothing happens for second value. It's not hitting the action LoadProductDetails but surprisingly there are no any script errors in the console. Wasted a day and put an <apex:pageMessages /> component inside pnlProductInfo which gets rerender from my <apex:actionSupport/>.

Wooooh! here it's


But what's the validation that's failing here? It's some salesforce server side validation that checks for selectList options. If you noticed, in my second selectOption value, there is a DOUBLE SPACE between the words. Replaced it with a single space and working perfectly!

Cheers!


Monday, July 13, 2015

Pagination in apex with StandardSetController

When record count get increased, typical solution for most common problems like page size getting large, render time getting increased is applying pagination. Salesforce has a powerful mechanism to introduce pagination into your data set easily, with StandardSetController.

Here how you'll do it.

Your controller
public with sharing class ControllerPagination {
    Public Integer noOfRecords{get; set;}
    Public Integer size{get;set;}
    public ApexPages.StandardSetController standardSetCtrl {
        get{
            if(standardSetCtrl == null){
                size = 10;
                string queryString = 'Select Name, Type, BillingCity, BillingState, BillingCountry from Account order by Name';
standardSetCtrl = new ApexPages.StandardSetController(Database.getQueryLocator(queryString));
standardSetCtrl.setPageSize(size);
                noOfRecords = standardSetCtrl.getResultSize();
            }
            return standardSetCtrl;
        }set;
    }
     
    Public List<Account> getAccounts(){
        List<Account> accList = new List<Account>();
        for(Account a : (List<Account>)standardSetCtrl.getRecords())
            accList.add(a);
        return accList;
    }
     
    public pageReference refresh() {
        standardSetCtrl = null;
        getAccounts();
        standardSetCtrl.setPageNumber(1);
        return null;
    }
}
Your VF Page
<apex:page controller="ControllerPagination">
    <apex:form >
        <apex:pageBlock id="pb">
            <apex:pageBlockTable value="{!Accounts}" var="a">
                <apex:column value="{!a.Name}"/>
                <apex:column value="{!a.Type}"/>
                <apex:column value="{!a.BillingCity}"/>
                <apex:column value="{!a.BillingState}"/>
                <apex:column value="{!a.BillingCountry}"/>
            </apex:pageBlockTable>
            <apex:panelGrid columns="7">
                <apex:commandButton status="fetchStatus" reRender="pb" value="|<" action="{!standardSetCtrl.first}" disabled="{!!standardSetCtrl.hasPrevious}" title="First Page"/>
                <apex:commandButton status="fetchStatus" reRender="pb" value="<" action="{!standardSetCtrl.previous}" disabled="{!!standardSetCtrl.hasPrevious}" title="Previous Page"/>
                <apex:commandButton status="fetchStatus" reRender="pb" value=">" action="{!standardSetCtrl.next}" disabled="{!!standardSetCtrl.hasNext}" title="Next Page"/>
                <apex:commandButton status="fetchStatus" reRender="pb" value=">|" action="{!standardSetCtrl.last}" disabled="{!!standardSetCtrl.hasNext}" title="Last Page"/>
                <apex:outputText >{!(standardSetCtrl.pageNumber * size)+1-size}-{!IF((standardSetCtrl.pageNumber * size)>noOfRecords, noOfRecords,(standardSetCtrl.pageNumber * size))} of {!noOfRecords}</apex:outputText>
                <apex:commandButton status="fetchStatus" reRender="pb" value="Refresh" action="{!refresh}" title="Refresh Page"/>
                <apex:outputPanel style="color:#4AA02C;font-weight:bold">
                    <apex:actionStatus id="fetchStatus" startText="Fetching..." stopText=""/>
                </apex:outputPanel>
            </apex:panelGrid>
        </apex:pageBlock>
    </apex:form>
</apex:page>

Thursday, June 25, 2015

Efficient SOQL For Loop

There are several governor limits to be considered when you are developing on Force.com platform. Among these, hitting the maximum number of queries allowed is the most common governor exception. Run time exception will be thrown as  System.Exception: Too many SOQL queries: 101.

This mainly occurs when you have put SOQL queries inside a loop as below.
for(Integer i=0; i<200; i++){
    Account act = [SELECT Id, Name FROM Account WHERE some_condition];
}


To avoid this you should somehow build the logic to meet the business matter and keep the query outside the loop.

Now the interesting part

Salesforce document says, "Developers should always use a SOQL for loop to process query results that return many records, to avoid the limit on heap size". What does this mean?

When you execute a standard SOQL query, it retrieve all the records while a for loop query does the same in chunks with SOAP API queryMore calls.


In addition to this, there are two formats of SOQL for loop in Force.com

  • Single sObject format where the for loop’s code block get executed once per sObject record(mostly used way).
  • sObject list format where the for loop’s code block get executed once per list of 200 sObjects

In this article what I need to highlight is the second format since it’s rarely seen in Force.com development. Have a look at the below snippet to get more clear idea
// keeping a savepoint so that transaction can be rolledback
Savepoint sp = Database.setSavepoint(); 

insert new Account[]{new Account(Name = 'AAA'), 
                     new Account(Name = 'AAA'), 
                     new Account(Name = 'AAA')};  //insert some data that can be identified

Integer i = 0;
Integer j;
for (Account[] tmp : [SELECT Id FROM Account WHERE Name = 'AAA']) {
    j = tmp.size();
    i++;
}
System.assert(j == 3); // The list should have contained the three accounts
                       // named 'AAA'
System.assert(i == 1); // Since a single batch can hold up to 200 records and,
                       // only three records should have been returned, the 
                       // loop should have executed only once

// Revert the database to the original state
Database.rollback(sp); 
Notes
  • You are safe to perform DMLs inside list format for loop queries than in a normal for loop
    query since the records are processed in chunks in list format (anyway this is not
    an encourage to perform DML inside a loop).
  • Since the queries having aggregate functions doesn't support queryMore function,
    you might get a runtime exception if you have such a query with more records in SOQL for loops.
  • When using the keyword ‘continue’ in list format for loops, it’ll skip to the next list
    of sObjects.

Monday, July 28, 2014

GoogleMap Custom Tooltip for Android with InfoWindowAdapter

When we are using Google Map services for Android application most of the times clients are expecting custom tooltips (markers contents) with more details and with more HTML formatting. This is a headache to developers. This post is describing a how to on this.

First create an layout xml file and place it under res > layout. This post is using a layout called "marker_window" as below. Goal hear is to view an HTML formatted detailed marker window with a name, address and some date value.
marker_window.xml
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/address"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />       

    <TextView
        android:id="@+id/report_date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
   
    <TextView
        android:id="@+id/report_time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

This post assumes your map service activity is MapServiceActivity and google map instance is googleMap.
Add below code snippet in the MapServiceActivity wherever it needs to be refreshed(of course in the onCreate)
if (googleMap == null) {  
  googleMap = ((SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
  //if  you are using MapFragment instead of SupportMapFragment, alter the code appropriately,
  //googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap(); 
}
googleMap.clear();

googleMap.setInfoWindowAdapter(new InfoWindowAdapter() {
  
  @Override
  public View getInfoWindow(Marker marker) {
    // TODO Auto-generated method stub
    return null;
  }
  
@Override
public View getInfoContents(Marker marker) {
    View view = getLayoutInflater().inflate(R.layout.marker_window,null);
    TextView locationView = (TextView)view.findViewById(R.id.name);
    TextView addressView = (TextView)view.findViewById(R.id.address);
    TextView dateView = (TextView)view.findViewById(R.id.report_date);
    TextView timeView = (TextView)view.findViewById(R.id.report_time);
   
    String formatLocator = "<b>Locator:</b> "+name;
    String formatAddress = "<b>Address:</b> "+addressText;
    String formatDate = "<b>Report date:</b> "+reportDate;
    String formatTime = "<b>Report time:</b> "+reportTime;
    //Likewise you can introduce some HTML formatting to the content
   
    locationView.setText(Html.fromHtml(formatLocator));
    addressView.setText(Html.fromHtml(formatAddress));
    dateView.setText(Html.fromHtml(formatDate));
    timeView.setText(Html.fromHtml(formatTime));
   
    return view;
  }
});

Done.
Below is a screen shot of what you can see of.

Friday, July 18, 2014

How to create a Salesforce.com Android Mobile app(hybrid_local)

This post assumes that you have already set up the development environment for Salesforce.com Mobile development. If you don't have, visit here and set it up first (for windows)

To connect the mobile application with your Salesforce.com instance, we need to create a some trusted connection between the app and target environment. Salesforce.com connected apps helps you here.
First we'll configure a connected app and then create the mobile app.

1). Login to your Salesforce.com instance and navigate into Setup ->  Create -> Apps,
2). Under Connected apps click on New
3). Fill the fields as required.
4). Under "API (Enable OAuth Settings)" tick the checkbox "Enable OAuth Settings".
5). Select the required OAuth scopes and click Save.
You should see the newly created Connected app something like below
Note that this Consumer key is going to do the main role to keep the connection between Salesforce.com and the app. Now it's time to create the mobile app. This post explain developing a hybrid_local app.

6). open a command prompt and run "forcedroid create"
7). Choose your options for each prompt. Below is a snap shot of what it has been chosen for this demo.

The command prompt output is itself describing the next steps.
After importing the projects into eclipse, open the MyFirstSFDCMobile/assets/www/bootconfig.json file. You have to update this file as below.
                        remoteAccessConsumerKey = Consumer key in your connected app
                        oauthRedirectURI = Call back URL of your connected app

Below is sample of bootconfig.json
{
    "remoteAccessConsumerKey": "my_consumer_key",
    "oauthRedirectURI": "sfdc://success",
    "oauthScopes": ["api refresh_token"],
    "isLocal": true,
    "startPage": "index.html",
    "errorPage": "error.html",
    "shouldAuthenticate": true,
    "attemptOfflineLoad": false,
    "androidPushNotificationClientId": ""
}

Done. Right click on MyFirstSFDCMobile and select Run As Android Project.
Have a look at index.html and inline.js inside www directory. These are the key files you have to modify to build your own application.

Cheers!

Salesforce Mobile Development

Salesforce.com has introduced their own Mobile SDKs to develop native, HTML5, hybrid mobile apps easily. There are some background works to be done before starting the development. Here is a quick overview of setting up the environment for Salesforce Mobile Development and next article we'll discuss how to build a Salesforce Android mobile app.

This is the home page for Salesforce.com Mobile SDK for Android (forcedroid) - https://github.com/forcedotcom/SalesforceMobileSDK-Android

There are couple of ways you can set up the SDK. Here it's described setting up with npm which is the quickest way as per the Salesforce.com itself.

First of all you should have Android development environment set up already. If you don't have it that's the first thing to do. It's fast and easy to use Android ADT bundle package which comes with the eclipse IDE+ADT as well as the Android SDK

1). Go to the command line and type "npm" and hit run to check whether npm has been already configured.

If it's showing above error, then you have to install and setup npm first. If you have npm configured in your machine you can jump into step 6.

2). Go to http://nodejs.org/download/ and download the compatible version with your platform (Windows installer 64bit in my case)

3). Run the downloaded installer and proceed installation.

4). Edit your PATH variable and add
;C:\Program Files\nodejs

5). Open a new command line and try "npm" again. You should see something similar below.
If you still having problems, check whether you have the node.js folder in your Program Files folder and double check the PATH variable.

6). In the command line, type "npm install forcedroid -g" and hit enter

7). Almost done. Now again type "forcedroid" and hit enter to confirm the installation.

You can see the usage of forcedroid command such as types of apps that can be created. For more information visit forcedroid npm package home page.

Cheers!

Next Post : How to create a Salesforce.com Android Mobile app

Thursday, August 15, 2013

Editable HTML Grid View with JQuery


Most of the times we need to have editable grid views in html pages where the user can view the existing records in non-editable mode and if they need to edit data, with a simple click event they can convert the same row of the grid to the editable mode. For example following is a record of the grid view which already exists. 



 Now the user needs to edit the same row without prompting into another section or popup. Which means the user needs the inline edit option. Then it would be appear as follows.


You may note that the ‘edit’ icon has been changed to ‘save’ in the Action column. Also the idea of having ‘Add Row’ button is to add a new row to the grid as the name saying itself. Below is a view with an existing record and newly added row by clicking the ‘Add Row’ button.


In each row, at the end I’m having a ‘delete’ icon so that any row can be deleted independently. Tired with explaining the functionalities, also I know that you are tired with reading :D. It’s time to move to the implementation.

Table
<table id="editablegrid" style="width:100%">
  <thead>
      <th>Action</th>
      <th>Date</th>
      <th>Link</th>
      <th>Currency Type</th>
      <th>Value</th>
      <th>Verified</th>
  </thead>
  <tbody></tbody>
 </table>    

 <input id="btnAddrow" type="button" value="Add Row" onclick="Add(null)" />
Dynamic Functionalities with JQuery
First, lets's have a global variable to hold the number of rows deleted. Later you may get why doing this.
var deletedRows = 0;    //hold the number of rows deleted.
Add : Here I'm assuming there can be some existing records as well. So the Add function will be called from two different places; for each existing record(probably from the $(document).ready), from the Add button click event. To handle both, I'm using the parameter that is passed to the function as follows. Also note that my
instance
object is having some fields as it's using the dot(.) notation.
function Add(instance){
  var rowCount = $('#editablegrid tr').length;
  var delRows = window.deletedRows;
            
  if(instance == null)
  {
     $("#editablegrid tbody").append(
     "<tr id='sdr"+rowCount+"_"+delRows+"'>"+
     "<td><img id='btnSave"+rowCount+"_"+delRows+"' src='images/save.png' /></td>"+
     "<td><input id='date"+rowCount+"_"+delRows+"' type='text' /></td>"+
     "<td><input type='text' /></td>"+
     "<td><select id='currency"+rowCount+"_"+delRows+"'></select></td>"+
     "<td ><input type='text' /></td>"+
     "<td><input type='checkbox'/></td>"+
     "<td><img id='btnDelete"+rowCount+"_"+delRows+"' src='images/delete.png' /></td>"+             
     "</tr>");
                                        
     for(var i=0;i<currencyTypes.length;i++)
     {
       $('#currency'+rowCount+'_'+delRows).append($("<option></option>")
       .attr("value",currencyTypes[i])
       .text(currencyTypes[i]));
     }
                    
     $("#btnSave"+rowCount+"_"+delRows).bind("click", Save);
   }
   else
   {
     var verifiedVal = (instance.Verified == true)?1:0;
     var verifiedChecked = (instance.Verified == true)?'checked="checked"':'';

     $("#editablegrid tbody").append(
     "<tr id='sdr"+rowCount+"_"+delRows+"'>"+
     "<td><img id='btnEdit"+rowCount+"_"+delRows+"' src='images/edit.png' /></td>"+
     "<td>"+instance.date+"</td>"+
     "<td title='"+instance.link+"'>"+instance.link+"</td>"+
     "<td>"+instance.currency+"</td>"+
     "<td >"+instance.number+"</td>"+
     "<td><input type='checkbox' value='"+verifiedVal+"' "+verifiedChecked+"/></td>"+
     "<td><img id='btnDelete"+rowCount+"_"+delRows+"' src='images/delete.png' /></td>"+     
     "</tr>");
                    
     $("#btnEdit"+rowCount+"_"+delRows).bind("click", Edit);
   }                                  
   $("#btnDelete"+rowCount+"_"+delRows).bind("click", Delete);
 };


Save:
function Save(){    
 var par = $(this).parent().parent(); //tr
 var rowIndex = par.attr('id').substring(3);
 var delRows = window.deletedRows;
 var sowDetailRecord = [];
            
 var tdAction = par.children("td:nth-child(1)");
 var tdDate = par.children("td:nth-child(2)");
 var tdLink = par.children("td:nth-child(3)");
 var tdCurrency = par.children("td:nth-child(4)");
 var tdValue = par.children("td:nth-child(5)");
 var tdVerified = par.children("td:nth-child(6)");
 var tdHidden = par.children("td:nth-child(8)");
            
 tdAction.html("<img id='btnEdit"+rowIndex+"_"+delRows+"' src='images/edit.png' class='btnEdit'/>");
 tdDate.html(tdDate.children("input[type=text]").val());
 tdLink.html(tdLink.children("input[type=text]").val());
 tdCurrency.html(tdCurrency.children("select").find(":selected").text());
 tdValue.html(formatCurrency(tdValue.children("input[type=text]").val()));            
        
 $("#btnEdit"+rowIndex+"_"+delRows).bind("click", Edit);

};


EDIT: here for the dropdown I'm trying to show currency types. Please note that the
currencyType
array need to be declared first. Since I'm showing the main functionalities of the grid view thought to remove that. Make sure you initialize that if you are going to have a dropdown.
function Edit(){            
 var par = $(this).parent().parent(); //tr
 var rowIndex = par.attr('id').substring(3);
 var delRows = window.deletedRows;
            
 var tdAction = par.children("td:nth-child(1)");
 var tdDate = par.children("td:nth-child(2)");
 var tdLink = par.children("td:nth-child(3)");
 var tdCurrency = par.children("td:nth-child(4)");
 var tdValue = par.children("td:nth-child(5)");
            
 var existingCurrencyType = tdCurrency.html();
                    
 tdAction.html("<img id='btnSave"+rowIndex+"_"+delRows+"' src='images/save.png' />");
 tdDate.html("<input type='text' id='txtDate"+rowIndex+"_"+delRows+"' value='"+tdDate.html()+"'/>");
 tdLink.html("<input type='text' id='txtLink' value='"+tdLink.html()+"'/>");
 tdCurrency.html("<select id='currency"+rowIndex+"_"+delRows+"' style='width:100%'></select>");
 tdValue.html("<input type='text' id='txtValue' value='"+tdValue.html()+"' />");
        
 for(var i=0;i<currencyTypes.length;i++)
 {
   $('#currency'+rowIndex+'_'+delRows).append($("<option></option>")
     .attr("value",currencyTypes[i])
     .text(currencyTypes[i]));
 }
        
 $('#currency'+rowIndex+'_'+delRows).find('option').each( function() {
  var $this = $(this);
  if($this.text() == existingCurrencyType) {
    $this.attr('selected','selected');
    return false;
  }
 });

 $("#btnSave"+rowIndex+"_"+delRows).bind("click", Save);
};


DELETE:
function Delete(){
            var par = $(this).parent().parent(); //tr
            window.deletedRows++;
            par.remove();
        };
Hope you can guess that deletedRowsvariable is maintaining here to bind the id of each element correctly when a deletion is happen. Cheers!

Wednesday, January 23, 2013

Adding New Fields to an Existing Report Type in Salesforce - SFDC

In SFDC, one of very common complains from the new users is "Some of my fields are disappeared in Reports in SFDC". This is simply because you have not added those fields to the particular report type.

Just go to your report type and add the required fields and save. Follow these instructions.

  • Click Your Name|Setup|Create|Report Types
  • If the introductory message is there, click on Continue
  • Click on the Report Type which you need to edit
  • Click on Edit Layout in the Fields Available for Reports section
  • In the right hand side you can see all the fields of the objects in your report type.
  • Just select the Object from the drop down list in the View section.
  • Already added fields will be appeared as disabled
  • Select the Fields that you need to add and drop them into the section that you need(If there is no any section for your object, create a new section by clicking Create New Section button at the bottom).
  • After selecting all the required fields save the report type.

That's it. Cheers!!!

Last Modified Date in Salesforce - SFDC

This may be a somewhat silly thing to say to the outer world. But I thought to write this post, assuming that there is at least one people who is suffering from this problem ;)

 In SFDC for all the Standard objects as well as for the custom objects, there is a standard field called LastModifiedDate which is invisible in the field list. But if we are accessing these objects through API calls, then we can replicate this field as well into SQL Database or similar. There we can see that, the field is in DataTime format.

Even though the field is invisible in the field list, when we run a report on SFDC we can see that that field is available in the left panel. Ok, now I'll turn into the problem that I faced and the workaround.

I wanted to check the last modified time of each record(let say Opportunity object). But when I ran a report what the last modified date was giving is only the last modified date(as the name is saying itself ;) ). But I got to know that this field is in the type of DataTime. So, with following workaround, I could able to get the DataTime format of this field.

  • Add a new field to the particular object. In my case, for the Opportunity object.
  • Click on Your Name|Setup|Customize|Opportunities|Fields
  • Under Opportunity Custom Fields & Relationships, click on New 
  • Select the Formula as the Data Type of the field 
  • Give a name to the field and select DataTime as the Return Type and click Next 
  • In the Insert Field section, select the Last Modified Date 
  • Now this is your formula.In the formula area it should only appear LastModifiedDate 
  • That's it. Click Next and Follow the formal instructions if any. 

Finally go back to your report type and add the newly added field there. If you unfamiliar with adding a new fields to existing report type, have a look at here. It should now show the DateTime format of the LastModifiedDate field.

Wednesday, January 16, 2013

Creating HTML elements dynamically with JavaScript

When we are developing web pages using markup languages like HTML, the web page will be appeared as we have already written with HTML. But what if we need to add some more HTML elements, add/edit some of properties of HTML elements even after rendering to browser? JavaScript comes into the game here. Below I have given a JavaScript function to add a row for an existing HTML table with some of HTML elements inside table cells.

function addRow(tableId){
   var table = document.getElementById(tableId);
   var row = table.insertRow(rowCount);

   var cell1 = row.insertCell(0);
   var element1 = document.createElement("label");
   element1.innerHTML = "Cell One-Label";
   cell1.appendChild(element1); 

   var cell2 = row.insertCell(1);
   var element2 = document.createElement("input");
   element2.type = "text";
   element2.value - "Cell Two-Input Text";

   cell2.appendChile(element2); 
   var cell3 = row.insertCell(2);
   var element3 = document.createElement("textarea");
   element3.value = "Cell Three-Text Area";
   cell3.appendChild(element3);
}

By calling this function(using a button click event, etc.) with the 'id' of the relevant table as an argument, we can add a label, input text and a textarea there.

Also when we need to set some attributes to be set dynamically, it also can be done. Below I'm explaining this by using the element1.

element1.setAttribute('id','myLabel'); 
element1.setAttribute("onChange",someFunction());
element1.setAttribute("onkeypress",someFunction());
element1.setAttribute("style","width:65px; text-align:right");

This way, we can add almost all the attributes for an HTML element dynamically. 





Tuesday, September 11, 2012

CodeIgniter URL Repeating Issue

CodeIgniter is one of good PHP framework to develop full featured web applications. Also it has very good, clean user guides and resources as well. With using its large number of built-in functions, it's really easy to develop functionalities in your web application rather than developing from the scratch.

Since it follows the MVC architecture, your application is capable of MVC features like,

  • Code Reusing
  • Separating of Concerns
  • Less Coupling between the layers.
At least now, let's move to the Title :D. Most of the CodeIgniter beginners suffering from this URL repeating issue when submitting forms specially.

Ex: Here I'm trying to create a new news item with using the create function which is in the news model class in my application. The link to load the news form is
                    localhost/CodeIgniter_2.1.2/index.php/news/create in my case.

When submit the form after adding the news item, application trying to go to a URL, localhost/CodeIgniter_2.1.2/index.php/news/create/localhost/CodeIgniter_2.1.2/index.php/news/create 
(repeating the URL)

I could able to fix this problem by modifying the config.php file(located at application\config directory) as follows.
$config[‘base_url’] = ‘http://localhost/file_upload/’;
$config[‘index_page’] = ‘index.php’;

Earlier I had those fields like this,

$config[‘base_url’] = ‘localhost/file_upload/’;
$config[‘index_page’] = ‘’;

You may note that in $config[‘base_url’] field, I have added the 'http://'  at the starting. This may happen because, the URL version without "http://" is considered as a relative path (which is added to the actual URL when setting an anchor :)).

Hope this may useful to some others on the planet :D.
Cheers!!!

Tuesday, August 14, 2012

Simple Date Picker application with Java

Most of the time when developing desktop applications, it may need calendar components(or Date Picker in the term :)). This is a very simple Date Picker example to those who are little bit familiar with java swing.


  • Go into your favourite java editor and create a file TestDatePicker.java
  • Copy following code and paste at there and save it.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class DatePicker {
    int month = java.util.Calendar.getInstance().get(java.util.Calendar.MONTH);
    int year = java.util.Calendar.getInstance().get(java.util.Calendar.YEAR);;
    JLabel l = new JLabel("", JLabel.CENTER);
    String day = "";
    JDialog d;
    JButton[] button = new JButton[49];

    public DatePicker(JFrame parent) {
            d = new JDialog();
            d.setModal(true);
            String[] header = { "Sun", "Mon", "Tue", "Wed", "Thur", "Fri", "Sat" };
            JPanel p1 = new JPanel(new GridLayout(7, 7));
            p1.setPreferredSize(new Dimension(430, 120));

            for (int x = 0; x < button.length; x++) {
                    final int selection = x;
                    button[x] = new JButton();
                    button[x].setFocusPainted(false);
                    button[x].setBackground(Color.white);
                    if (x > 6)
                            button[x].addActionListener(new ActionListener() {
                                    public void actionPerformed(ActionEvent ae) {
                                            day = button[selection].getActionCommand();
                                            d.dispose();
                                    }
                            });
                    if (x < 7) {
                            button[x].setText(header[x]);
                            button[x].setForeground(Color.red);
                    }
                    p1.add(button[x]);
            }
            JPanel p2 = new JPanel(new GridLayout(1, 3));
            JButton previous = new JButton("<< Previous");
            previous.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent ae) {
                            month--;
                            displayDate();
                    }
            });
            p2.add(previous);
            p2.add(l);
            JButton next = new JButton("Next >>");
            next.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent ae) {
                            month++;
                            displayDate();
                    }
            });
            p2.add(next);
            d.add(p1, BorderLayout.CENTER);
            d.add(p2, BorderLayout.SOUTH);
            d.pack();
            d.setLocationRelativeTo(parent);
            displayDate();
            d.setVisible(true);
    }

    public void displayDate() {
            for (int x = 7; x < button.length; x++)
                    button[x].setText("");
            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(
                            "MMMM yyyy");
            java.util.Calendar cal = java.util.Calendar.getInstance();
            cal.set(year, month, 1);
            int dayOfWeek = cal.get(java.util.Calendar.DAY_OF_WEEK);
            int daysInMonth = cal.getActualMaximum(java.util.Calendar.DAY_OF_MONTH);
            for (int x = 6 + dayOfWeek, day = 1; day <= daysInMonth; x++, day++)
                    button[x].setText("" + day);
            l.setText(sdf.format(cal.getTime()));
            d.setTitle("Date Picker");
    }

    public String setPickedDate() {
            if (day.equals(""))
                    return day;
            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(
                            "dd-MM-yyyy");
            java.util.Calendar cal = java.util.Calendar.getInstance();
            cal.set(year, month, Integer.parseInt(day));
            return sdf.format(cal.getTime());
    }
}

public class TestDatePicker {
 
 public static void main(String[] args) {  
   /////////////Picker/////////////////////////
  JLabel selectDate = new JLabel("Select Date Here ->");
  JLabel selectedDate= new JLabel("Selected Date ->");
        final JTextField text = new JTextField(20);       
        JButton b = new JButton("Select"); //button for calendar popup
        JButton close = new JButton("Close"); //button for close the application
        JPanel pPic = new JPanel();
        pPic.setLayout(new GridLayout(3,2));
        pPic.add(selectDate);       
        pPic.add(b);
        pPic.add(selectedDate);
        pPic.add(text);
        pPic.add(close);
        final JFrame f = new JFrame("Simple Date Picker");
        f.getContentPane().add(pPic);
        f.pack();
        f.setVisible(true);
        b.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent ae) {
                 text.setText(new DatePicker(f).setPickedDate());
                }
        });
        ////////////////////////Picker////////////////////////////
      
        close.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
             f.dispose();
            }
        });                
 }  
}
When you run the program, firstly you will see the main frame of the application which looks like,

Then when you hit on 'Select' button, the calendar will be popup as follows

Select what ever the date you like(you can even navigate for other months as well with 'Previous' and 'Next' buttons). The selected date will be included in the text field below the 'Select' button, as follows.

It's done :)
Cheers!!!

Saturday, March 10, 2012

Transferring a Joomla website from one host to another

Most of the time website developers are dealing with the process of transferring websites to another hosts. Sometimes it has encountered certain problems as the correct procedure to do the transferring has not been followed, like I have done :D.

Following is the step by step procedure to do the job.

1. Create a location in your remote host, to install Joomla!
  • If you are going to host a new site, this location will be the HTML home directory of your remote host.
  • If you are having an existing site and want keep both, you may create a subdomain. i.e www.domain.com/subdirectory.
2. Copy the files and folders from your localhost to the remote host
There are two options that can be performed for this.
  •   Upload the site content using an FTP client program like FileZilla.
      Copy the all file from your localhost (with WAMP, the directory will be wamp/www/directory) to the HTML directory that was created in you domain or the subdomain.
  • Upload the site content with a compressed file.
files and folders to be compressed
Compress all the files and folders from the localhost Joomla installation directory. Upload the compressed file to the remote domain or subdomain HTML directory(use cPanel services of your host provider).
Extract the compressed file there.









3. Copy the Database

  • Go to the phpMyAdmin page of your local system. If you are having a password with the database, you will bi prompted for it.
  • In the top main menu, select the Export link.


  • Select your Joomla database from the list appear in the top left.
  • Remain the default Export option and check the "Save as file" checkbox at the bottom and click "Go" button at the right bottom.

  • Save the sql file to your preferred location
  • Open the phpMyAdmin page of your remote host server .
  • Click on "Import" link and upload the exported sql file.
  • Click "Go" and import the database successfully. 
4. Configure the Site
This is the step that most of the time people have missed and confusing with. When the Joomla installation has been done, the configuration.php file will be created according to the local system. It is in the main Joomla installation directory. So it should change some properties of this file according to the new remote host server.
Following figure shows properties to be changed, which is from a Windows WAMP system.


These two paths has to be changed according to your host server paths. 
Ex:
  •  If you are using the main domain of the host,
  • If you are using a subdomain of the host
  • Also for the following fields, give the suitable values.

That's all and go to your preferred web browser and check whether it is working.
If you have installed it in the root directory
Try, www.domain.com 
       www.domain.com/administrator for navigate to the admin panel.


If you have installed it in a subdirectory.
Try, www.domain.com/subdirectory
       www.domain.com/subdirectory/administrator  for navigate to the admin panel.


Or if you have registered a new subdomain for the site, use that URL.
      www.subdomain.domain.com
      www.subdomain.domain.com/administrator to navigate to the admin panel.

Wednesday, January 11, 2012

Host Key Verification Failed in SSH



When I was trying to connect to a remote host through a server, I faced this key verification failure. This can be happened due to different reasons.
1. The remote server has re-installed the SSH server.
2. Remote server has generated a new host key.

 In my case I could able to fix this as follows and think this will helpful for someone else as well.


Error : \@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
17:c7:8f:e7:6b:09:87:9b:13:65:ac:2c:76:47:a8:69.
Please contact your system administrator.
Add correct host key in /home/madhura/.ssh/known_hosts to get rid of this message.
Offending key in /home/madhura/.ssh/known_hosts:17
RSA host key for 10.40.18.160 has changed and you have requested strict checking.
Host key verification failed.

Solution : 
Normally, our host keys are saved in "~/ssh/known_hosts”. 
1. Open this file and remove the line which is notifying the specific remote host key that you are getting trouble.

  •   Here it's good to turn on the Line Numbers in your text editor. Then it's easy to figure out which part to remove.
If you don't know how to remove that specific host key, then you need to,
2. Remove your known_hosts file. 
  • But then you lost your other remote host keys as well. However your SSH-Client will create a new "~/ssh/known_hosts” 
If you are prompting a warning that saying authenticity can't established and asking to continue, type "yes" and enter. 

Cheers...