diff -r ccb4b4b1984f transifex/addons/lotte/media/js/tx.lotte2.js
--- a/transifex/addons/lotte/media/js/tx.lotte2.js	Thu Jan 27 17:52:21 2011 -0200
+++ b/transifex/addons/lotte/media/js/tx.lotte2.js	Sat Feb 12 15:29:01 2011 +0530
@@ -107,6 +107,8 @@
 
 /*    The target language*/
     this.to_lang = to_lang;
+    /* True if there is error during saving translations */
+    this.error = null;
 
 /*    This array contains all the TranslationString objects of StringSet */
 /*    IMPORTANT! This keeps the table row index as a key!!! */
@@ -188,9 +190,11 @@
                                 this_stringset.current_box.parents('td.trans').find('div.error_notes').show();
                             } else
                                 this_stringset.current_box.parents('td.trans').find('div.error_notes').hide();
+                                stringset.error = false;
                         }else{ // Handle the error
                             this_stringset.current_box.parents('td.trans').find('div.error_notes').text(json_response_dict[ts.id]['message']);
                             this_stringset.current_box.parents('td.trans').find('div.error_notes').show();
+                            stringset.error = true;
                         }
                     } else {
                         /* For save_all button */
@@ -218,10 +222,12 @@
                                         // Hide the error div if it is visible
                                         $('textarea#translation_'+j).parents('td.trans').find('div.error_notes').hide();
                                     }
+                                    stringset.error = false;
                                 }else{ // Handle the error
                                     messages=true;
                                     $('textarea#translation_'+j).parents('td.trans').find('div.error_notes').text(json_response_dict[this_stringset.strings[j].id]['message']);
                                     $('textarea#translation_'+j).parents('td.trans').find('div.error_notes').show();
+                                    stringset.error = true;
                                 }
                             }
                         }
diff -r ccb4b4b1984f transifex/addons/lotte/templates/translate.html
--- a/transifex/addons/lotte/templates/translate.html	Thu Jan 27 17:52:21 2011 -0200
+++ b/transifex/addons/lotte/templates/translate.html	Sat Feb 12 15:29:01 2011 +0530
@@ -97,6 +97,27 @@
     target_source_codes = source_lang + ' {{ resource.source_language.code_aliases }}';
     target_codes = target_lang + ' {{ target_language.code_aliases }}';
 
+    var saveError_response = true;
+    function saveError(){
+        if ($("#toggle_autosave").is(":checked")){
+          if (stringset.translated_modified || stringset.untranslated_modified || !saveError_response){
+            stringset.error = false;
+            if (stringset.translated_modified || stringset.untranslated_modified)
+              stringset.push();
+            if (stringset.error){
+               var r = confirm("Error during saving! Do you want to continue?");
+               if (r){}
+               else {
+                saveError_response = r;
+                return true;
+               }
+            }
+          }
+          else
+            saveError_response = true;
+        }
+      return false;
+     }
     google.setOnLoadCallback(function() {
         /* Global variables */
         source_lang = supported_language(target_source_codes)
@@ -108,7 +129,217 @@
             is_supported_source_lang = false;
             is_supported_lang = false;
         }
+    $.fn.dataTableExt.oPagination.iFullNumbersShowPages = 5;
+    $.fn.dataTableExt.oPagination.custom_full_numbers = {
+			"fnInit": function ( oSettings, nPaging, fnCallbackDraw )
+			{
+				var nFirst = document.createElement( 'span' );
+				var nPrevious = document.createElement( 'span' );
+				var nList = document.createElement( 'span' );
+				var nNext = document.createElement( 'span' );
+				var nLast = document.createElement( 'span' );
 
+				nFirst.innerHTML = oSettings.oLanguage.oPaginate.sFirst;
+				nPrevious.innerHTML = oSettings.oLanguage.oPaginate.sPrevious;
+				nNext.innerHTML = oSettings.oLanguage.oPaginate.sNext;
+				nLast.innerHTML = oSettings.oLanguage.oPaginate.sLast;
+
+				var oClasses = oSettings.oClasses;
+				nFirst.className = oClasses.sPageButton+" "+oClasses.sPageFirst;
+				nPrevious.className = oClasses.sPageButton+" "+oClasses.sPagePrevious;
+				nNext.className= oClasses.sPageButton+" "+oClasses.sPageNext;
+				nLast.className = oClasses.sPageButton+" "+oClasses.sPageLast;
+
+				nPaging.appendChild( nFirst );
+				nPaging.appendChild( nPrevious );
+				nPaging.appendChild( nList );
+				nPaging.appendChild( nNext );
+				nPaging.appendChild( nLast );
+
+				$(nFirst).click( function () {
+					if (saveError()){
+					  fnCallbackDraw( oSettings);
+					}
+					if ( oSettings.oApi._fnPageChange( oSettings, "first" ) )
+					{
+						fnCallbackDraw( oSettings );
+					}
+				} );
+
+				$(nPrevious).click( function() {
+					if (saveError()){
+					  fnCallbackDraw( oSettings);
+					}
+					if ( oSettings.oApi._fnPageChange( oSettings, "previous" ) )
+					{
+						fnCallbackDraw( oSettings );
+					}
+				} );
+
+				$(nNext).click( function() {
+					if (saveError()){
+					  fnCallbackDraw( oSettings);
+					}
+					else{					
+						if ( oSettings.oApi._fnPageChange( oSettings, "next" ) )
+						{
+							fnCallbackDraw( oSettings );
+						}
+					}
+				} );
+
+				$(nLast).click( function() {
+					if (saveError()){
+					  fnCallbackDraw( oSettings);
+					}
+					if (oSettings.oApi._fnPageChange(oSettings, "last")) {
+						fnCallbackDraw(oSettings);
+					}
+				} );
+
+				/* Take the brutal approach to cancelling text selection */
+				$('span', nPaging)
+					.bind( 'mousedown', function () { return false; } )
+					.bind( 'selectstart', function () { return false; } );
+				
+				/* ID the first elements only */
+				if ( oSettings.sTableId !== '' && typeof oSettings.aanFeatures.p == "undefined" )
+				{
+					nPaging.setAttribute( 'id', oSettings.sTableId+'_paginate' );
+					nFirst.setAttribute( 'id', oSettings.sTableId+'_first' );
+					nPrevious.setAttribute( 'id', oSettings.sTableId+'_previous' );
+					nNext.setAttribute( 'id', oSettings.sTableId+'_next' );
+					nLast.setAttribute( 'id', oSettings.sTableId+'_last' );
+				}
+			},
+			
+			/*
+			 * Function: oPagination.full_numbers.fnUpdate
+			 * Purpose:  Update the list of page buttons shows
+			 * Returns:  -
+	 		 * Inputs:   object:oSettings - dataTables settings object
+			 *           function:fnCallbackDraw - draw function to call on page change
+			 */
+			"fnUpdate": function ( oSettings, fnCallbackDraw )
+			{
+				if ( !oSettings.aanFeatures.p )
+				{
+					return;
+				}
+				
+				var iPageCount = $.fn.dataTableExt.oPagination.iFullNumbersShowPages;
+				var iPageCountHalf = Math.floor(iPageCount / 2);
+				var iPages = Math.ceil((oSettings.fnRecordsDisplay()) / oSettings._iDisplayLength);
+				var iCurrentPage = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1;
+				var sList = "";
+				var iStartButton, iEndButton, i, iLen;
+				var oClasses = oSettings.oClasses;
+				
+				/* Pages calculation */
+				if (iPages < iPageCount)
+				{
+					iStartButton = 1;
+					iEndButton = iPages;
+				}
+				else
+				{
+					if (iCurrentPage <= iPageCountHalf)
+					{
+						iStartButton = 1;
+						iEndButton = iPageCount;
+					}
+					else
+					{
+						if (iCurrentPage >= (iPages - iPageCountHalf))
+						{
+							iStartButton = iPages - iPageCount + 1;
+							iEndButton = iPages;
+						}
+						else
+						{
+							iStartButton = iCurrentPage - Math.ceil(iPageCount / 2) + 1;
+							iEndButton = iStartButton + iPageCount - 1;
+						}
+					}
+				}
+				
+				/* Build the dynamic list */
+				for ( i=iStartButton ; i<=iEndButton ; i++ )
+				{
+					if ( iCurrentPage != i )
+					{
+						sList += '<span class="'+oClasses.sPageButton+'">'+i+'</span>';
+					}
+					else
+					{
+						sList += '<span class="'+oClasses.sPageButtonActive+'">'+i+'</span>';
+					}
+				}
+				
+				/* Loop over each instance of the pager */
+				var an = oSettings.aanFeatures.p;
+				var anButtons, anStatic, nPaginateList;
+
+				var fnClick = function() {
+					if (saveError()){
+					  fnCallbackDraw( oSettings );
+					  return false;
+					}
+					
+					/* Use the information in the element to jump to the required page */
+					var iTarget = (this.innerHTML * 1) - 1;
+					oSettings._iDisplayStart = iTarget * oSettings._iDisplayLength;
+					fnCallbackDraw( oSettings );
+					return false;
+				};				
+
+				var fnFalse = function () { return false; };
+				
+				for ( i=0, iLen=an.length ; i<iLen ; i++ )
+				{
+					if ( an[i].childNodes.length === 0 )
+					{
+						continue;
+					}
+					
+					/* Build up the dynamic list forst - html and listeners */
+					var qjPaginateList = $('span:eq(2)', an[i]);
+					qjPaginateList.html( sList );
+					$('span', qjPaginateList).click( fnClick ).bind( 'mousedown', fnFalse )
+						.bind( 'selectstart', fnFalse );
+					
+					/* Update the 'premanent botton's classes */
+					anButtons = an[i].getElementsByTagName('span');
+					anStatic = [
+						anButtons[0], anButtons[1], 
+						anButtons[anButtons.length-2], anButtons[anButtons.length-1]
+					];
+					$(anStatic).removeClass( oClasses.sPageButton+" "+oClasses.sPageButtonActive+" "+oClasses.sPageButtonStaticDisabled );
+					if ( iCurrentPage == 1 )
+					{
+						anStatic[0].className += " "+oClasses.sPageButtonStaticDisabled;
+						anStatic[1].className += " "+oClasses.sPageButtonStaticDisabled;
+					}
+					else
+					{
+						anStatic[0].className += " "+oClasses.sPageButton;
+						anStatic[1].className += " "+oClasses.sPageButton;
+					}
+					
+					if ( iPages === 0 || iCurrentPage == iPages || oSettings._iDisplayLength == -1 )
+					{
+						anStatic[2].className += " "+oClasses.sPageButtonStaticDisabled;
+						anStatic[3].className += " "+oClasses.sPageButtonStaticDisabled;
+					}
+					else
+					{
+						anStatic[2].className += " "+oClasses.sPageButton;
+						anStatic[3].className += " "+oClasses.sPageButton;
+					}
+				}
+			}
+		};
+    
     /* document ready. do stuff */
     $(document).ready(function(){
 
@@ -131,7 +362,7 @@
                 }
             },
             "bJQueryUI": false,
-            "sPaginationType": "full_numbers",
+            "sPaginationType": "custom_full_numbers",
             "aaSorting": [[ 0, "asc" ]],
             "bServerSide": true,
             "bProcessing": true,
@@ -277,9 +508,9 @@
                * then we create the StringSet object which holds all the 
                * Translation objects in memory.
               */
-
               // Show the loading indicator
               $("div#notification-container div").html('{% trans "Loading strings..."|escapejs %}');
+              //alert("outside push");
               $("div#notification-container").fadeIn("slow");
 
               // Add filtering parameters to the POST data dictionary
