Sunday, January 13, 2019

Resco Mobile CRM Tricks – Implement pagination in Resco Mobile CRM query - Javascript

Due to the server performance constrains Resco Mobile CRM returns 500 records only when we executing the query. There is no available setting to break that limitations. However to retrieve all the records we need then we have to implement the pagination for the query execution. Resco queries are execute in asynchronous way. We have to make sure we retrieve all the records before we proceed further.
We can follow followings steps to retrieve all records using pagination.

  
     1. Retrieve count of all the records we have to retrieve and set that value in global variable
In my case I have to retrieve all the answers belongs to the set of questions. I create fetch xml and retrieve answers count then determine how many pages need to be retrieved. After calculate the pages then built query need to retrieve data from the answers entity.


var NumberOfAnswerPages = 0;
var DataPagingSize = 500;
var ResultAnswers = [];

function GetAllAnswersCountByQuestions() {
 NumberOfAnswerPages = 0;
 Result_Ans = [];
 var FetchXml_Ans = "<fetch resultformat='DynamicEntities' version='1.0' output-format='xml-platform' mapping='logical' no-lock='true' aggregate='true' returntotalrecordcount='true' >" +
  "<entity name='new_answers'>" +
  "<attribute name='new_answersid' alias='recordcount' aggregate='count'  />" +
  "<filter type='and'>" +
  "<condition attribute='new_questionsid' operator='in'>";
  for (var qIndex = 0; qIndex < QuestionsArray.length; qIndex++) {
   FetchXml_Ans = FetchXml_Ans + "<value  uitype='new_questions'>" + QuestionsArray[qIndex].id + "</value>";
  }
 FetchXml_Ans = FetchXml_Ans + "</condition></filter></entity></fetch>";

 MobileCRM.FetchXml.Fetch.executeFromXML(FetchXml_Ans,
  function (data) {                    

   if (data != null && data != undefined && data.length > 0) {                        
    var recordsCount = data[0].properties["recordcount"];

    if (recordsCount > 0) {
     NumberOfAnswerPages = recordsCount / DataPagingSize;
     var questionIds = [];
     for (var qIndex = 0; qIndex < QuestionsArray.length; qIndex++) {
      questionIds.push(QuestionsArray[qIndex].id);
     }

     var answers = new MobileCRM.FetchXml.Entity('new_answers');
     answers.addAttribute('new_answersid');
     answers.addAttribute('new_name');
     answers.addAttribute('createdon');
     answers.addAttribute('new_questionsid');
     answers.addAttribute('new_answercrmvalue');
     answers.orderBy("new_order", true);

     var filter = new MobileCRM.FetchXml.Filter();
     filter.isIn("new_questionsid", questionIds);
     answers.filter = filter;

     var fetch = new MobileCRM.FetchXml.Fetch(answers);
     fetch.count = DataPagingSize;
     fetch.page = 1;

     ExecuteAnswerPaggingFetch(fetch, 1);

    } else {
     Result_Ans = [];
     //Do The Rest
    }

   } else {
    Result_Ans = [];
    //Do The Rest
   }
  },
  function (error) {
   MobileCRM.bridge.alert("Answer Records Retrieving Error : " + error);
   removePanels();
  }, null);
}


      2. Recursively call the data retrieval method and execute other methods after complete the data extraction. This will help to synchronize method flow even Resco execute data retrieval asynchronously. 

function ExecuteAnswerPaggingFetch(fetch, page, success) {
 fetch.page = page;
 fetch.execute("DynamicEntities", function (res) {
  if (res != null && typeof res != 'undefined' && res.length > 0) {
   for (var i = 0; i < res.length; i++) {
    ResultAnswers.push(res[i]);
   }
  }

  if (page > NumberOfAnswerPages) {
   //Now data retrieval is completed call next set of methods
   return;
  }

  ExecuteAnswerPaggingFetch(fetch, page += 1);
 }, MobileCRM.bridge.alert, null);
}

Monday, December 17, 2018

Web App not showing correctly in Dynamic CRM which has different language as default language

We face issue one of our client complaining about components of site map are missing and it shows entity names incorrect way. Once we analysed the issue they use dynamic crm instance with Danish language as default language. We create additional titles in the web app and using Danish and it resolved the problem.


 App Site Map without additional titles



Adding additional title to site map

Go To Model Driven App => Open App => Go to Site Map, then add additional title with correct language




Thursday, February 9, 2017

C# WCF Tips: Fix error “object reference is not set to an instance object” while adding WCF service reference

When we adding service reference to project sometimes we encounter “object reference is not set to an instance object” error. Sometimes it fix after follow following steps.


Step 1: Check are there any errors in WCF service and if there were errors fix it and retry.

Step 2: If there were existing service reference then delete it and add again. 

Step 3: If step 2 not success then delete reference from service reference folder in project location (from hard disc) and try to add reference again.

Step 4: If first three steps not working go to the app config or web config file and remove relevant endpoint settings and try to add again.

Step 5: Host WCF service in iis and add service reference from iis url

Sunday, January 1, 2017

Kendo Grid Tips: Navigate Kendo Grid CellsUsing Tab Key Based on Row and Column

Some time we have requirements to move user to pre determine cells in the kendo grid based on conditions. As example there were kendo grid after user save data it disable correct cells and enable cells which have errors. User has requirement to move only error cells using tab key.

For such kind of requirements can use following code snippets to navigate user.

  $(document).ready(function () {
        $("#Grid").on("keyup", 'tr', function (event) {
            navigateColorGrid(event);

        });     
    });



function navigateColorGrid(e) {

    if (e.keyCode == 9) {

        event.stopPropagation();

        event.stopImmediatePropagation();

        event.preventDefault(); //Prevent default tab key function

        var eCell = $(e.target).closest('td');
        var currentIndex = eCell.index();
        var currentIndexRow = $(e.target).closest('tr').index();
        var dataGrid = $('#Grid').data().kendoGrid;
        var currentRow = $(e.target).closest('tr');
        eCell = $(currentRow).find('td:eq(' + currentIndex + ')');

        if (invalidCells.length > 0) {
            tabToNextCell(currentIndexRow, currentIndex);
        } else {
            setTimeout(function () {
                var grid = $("#Grid").data("kendoGrid");
                if (eCell != null) {
                    grid.editCell(eCell);
                    var inputText = eCell.find("input").length;
                    var cPosition = inputText - 1;
                }

            }, 10);

        }

    }

}


function tabToNextCell(currentIndexRow, currentIndex) {

    var eCell = $("#Grid").children().find("tbody").find("tr:eq(" + currentIndexRow + ")").find("td:eq(" + currentIndex + ")");
    var cellLocation = getNextinvalidCell(currentIndexRow, currentIndex);
    if (cellLocation.length > 0) {
        var rowNumber = cellLocation[0].rowIndex;
        var cellNumber = cellLocation[0].cellIndex;

        eCell = $("#Grid").children().find("tbody").find("tr:eq(" + rowNumber + ")").find("td:eq(" + cellNumber + ")");
    }

    setTimeout(function () {
        var grid = $("#Grid").data("kendoGrid");
        if (eCell != null) {
            grid.editCell(eCell);
            eCell.select();
        }

    }, 10);

}



Following function used array called “InvalidCells”, when updating cells with results save invalid cells in array use that array to determine nearest invalid cell in the grid.

function getNextinvalidCell(currentIndexRow, currentIndex) {

    //Current row contains another invalid cell

    var cellLocation = [];

    var invalidCell = $.grep(invalidCells, function (cell) {

        return cell.rowIndex == currentIndexRow && cell.cellIndex > currentIndex;

    });

    if (invalidCell.length > 0) {
        var sortedInvalidCells = invalidCell.sort(function (a, b) {

            return a.cellIndex - b.cellIndex;

        });
        cellLocation.push({ rowIndex: sortedInvalidCells[0].rowIndex, cellIndex: sortedInvalidCells[0].cellIndex })
    }

return cellLocation;

}



Sunday, November 20, 2016

Kendo Grid Tips: Adding New Row to Kendo Gird with Enter Key Press

There were requirements to add new row to editable gird when user click on last editable cell. Using addRow() function of kendo gird we can add new row to data gird. However to use that function we need to identify the correct key stroke and correct cell to invoke addRow() function. Following code snippet shows how to add new row to grid if user press enter key on 4th column.

We can change javascript key value to modify following script to trigger on any key (e.g. if change (code == 9) you can add new row with Tab key)

    $(document).ready(function () {
        $("#MyGrid").on("keyup", "tr", function (e) {
            var code = (e.keyCode ? e.keyCode : e.which);
            var td = $(e.target).closest('td');


            if (code == 13) {
                var tdIndex = td.index();


                if (tdIndex == 3) {
                    var grid = $("#MyGrid").data("kendoGrid");
                    grid.addRow();
                }
            }
        });
    });