Pages

Saturday, March 13, 2010

Introducing the Javascript Grid Editor

I’m very happy to announce the project that kept me away from the CRM Developer forums for several months is now ready for the public.  The Javascript Grid Editor has been setup in a repository on GitHub, and available for general download and use under a Creative Commons license.  See the Javascript Grid Editor page for details.

If you ever wished that you could modify or add records through a CRM grid, today is your day!

61 comments:

  1. Dear Dave,

    It is very interesting and useful article. A lot of our users complaint about usability in CRM because they have to open a lot of forms to key-in data. I hope it will solve most of the issues.

    I have one question about your add-on. If I want to use this add-on for multiple entities, how can I configure it. According to your instruction, I saw only one configuration setting at the very fist step. Please advice.

    With many thanks!
    Thuta Hlaing
    http://www.thuta.info

    ReplyDelete
  2. You basically follow all the steps once for each entity for which you want to deploy the code. If it ends up being a significant number of entities, you may have an easier time sticking the majority of the code in a separate file--but I don't have good instructions for that yet, so you're on your own for now on figuring it out. But if you can manage a large and growing ISV.config.xml file, then you should be able to deploy the code to any entity in your system.

    ReplyDelete
  3. Thanks Dave. I will try it out :-)

    ReplyDelete
  4. Hi David,

    I really appreciate your efforts in building this script and making it available for us.

    I have configured this in one of our test environments. The edit mode is working great, but the insert mode is giving me some troubles:
    1. If I have more then 9 fields in the grid, only the first 9 fields are editable/.
    2. So far, I haven't been able to save a record when using the insert mode. I don't get an error and the screen is refreshed, but the records are not saved. When I leave the grid I do get a Javascript error.

    Are you able to help me out on this?

    Kind regards,

    Bas

    ReplyDelete
  5. Bas,

    I'd be more than happy to help, if possible. I can assure you that I didn't include a "9 field" limit, so the code must be choking somewhere on the last field being displayed, or the one after it. What can you tell me about those two fields?

    I had an interesting report of a reversal of your problem in the CRM Developer Forums, basically that Edit mode worked, but Insert mode did not. I'd be confident to suggest that the script may not have been mirrored identically to the Javascript attribute of each Button element. Please check that.

    Feel free to post your configuration here for analysis.

    -Dave

    ReplyDelete
  6. I just tested my development environment, and was able to open input fields for 11 columns.

    ReplyDelete
  7. Hi Dave,

    I have the same problem as you mentioned, edit is working, insert did not. I have checked the ISV config and I have the same code in both the Javascript sections. I have used XMLEscapeTool as you suggested.

    I have now editted the grid layout and I have now 13 fields, but the last 2 are empty. The 11th field is a lookup to a custom entity. The 12th field is the owner field, the 13th field is a loolup to another custom entity.

    I have tried to create a grid very few fields, but the records are not saved.

    Is it possible to send you some files or screenshots?

    Thanks in advance...
    - Bas

    ReplyDelete
  8. I have found the post on the developers forum and that was indeed a reversal of my problem. I'm using it on custom entities with some lookups to other custom entities. Edit works great, insert isn't.

    I will have a developer look at the code tomorrow to find a solution for the generic part of the code. I think we can manage to put that code in a seperate file and load it from the isvconfig. That way, the ISV config won't be that big and the code won't be duplicated for every entity...

    -Bas

    ReplyDelete
  9. The Owner field is not valid for the Update message on most entities. The reason for this, is that it's updated with the Assign message, and I haven't worked code for that into my script. However, you may use the standard "Assign" button on the grid to manipulate the Owner.

    I've updated my blogger profile so you can locate my email address from the Profile link on the right side of this page.

    ReplyDelete
  10. Do you receive an error when you attempt to enter Insert mode?

    ReplyDelete
  11. Hi Dave,

    I don't receive an error when pressing the insert mode button. I just receive an error when I have saved the records and then leave the page.

    I had added the owner column because this is a reguired field and you mentioned that all required fields should be visible on the grid.

    I will send you some screenshots and files later today.

    ReplyDelete
  12. Hi Dave,

    I tested it out yesterday. It's great. But, I found one thing. It does not check mandatory (business required) fields when it is saved. But, all the logic checking using plug-in are work fine.

    Thanks for your great job!

    Thuta

    ReplyDelete
  13. I forgot one of the privs in my instructions; you needed all three Metadata privileges: Entity, Attribute, and Relationship. Otherwise, the Javascript is unable to assess certain configuration data for the entity, and may not work, or throw an error.

    ReplyDelete
  14. You're right, Thuta. Edit mode doesn't concern itself with mandatory fields, but the platform will indeed still make its appropriate checks. This is a feature I intend to make in the future. I just didn't need it for my purposes.

    ReplyDelete
  15. Hi Dave,

    I have the system admin role so the priviledges should be no problem...

    ReplyDelete
  16. Due to a little bug, I've updated the code to version 1.0.1. Some fields that couldn't have proper controls (mostly unimplemented Email fields), would leave values in the code that shouldn't have been left. I don't think this answers the problem I'm working out with you, Bas.

    ReplyDelete
  17. Hi Dave,

    I've exported my ISV.config, added in your example XML (for my own custom entity), and tried to import it - however, CRM tells me the file is not a valid customisation file. After some trial and error it seems to be the "Javascript" attribute (which I have left empty) of the "Button" node thatm it doesn't like. If I take the "Javascript" attribute out it imports OK (but is obviously useless).
    Any ideas why I can't import this ?

    Thanks,
    Chris

    ReplyDelete
  18. Hi Dave I have the same problem as Chris, on other deployment I can import isv.config file like this: Button Icon="" JavaScript="" but when I put your code CRM doesnt import it... Maybe you could post somewhere a complete isv.config file for download...

    Thank you Jan

    ReplyDelete
  19. Are you sure you ran the script through the XML Escape Tool? This is required because the script needs to be sanitized of special characters and replaced with HTML/XML encodings. I'll see what I can do to post a sanitized version of the script in the repository.

    ReplyDelete
  20. I've tested the latest code to my satisfaction, and I'm confident that it would work. I warned against using certain types of XML editors--notably XML Notepad. Please be sure you refrain from using those.

    The reason I will not be making or posting an isv.config file, is that doing so represents a unacceptable risk for me of causing unintended issues with the deployments of others. My assembly and installation instructions are thorough, comprehensive, and tested.

    If you're still having troubles, I admonish you to post the utilities you're using to accomplish different steps so I can examine them for compatibility with the process. Otherwise, you may contact me directly via the Profile area on the right side of this page and attach your isv.config.xml file so that I can analyze it.

    ReplyDelete
  21. Hi Jan,

    I put all codes into external java script file and load the file from isv.config. Each entity will need one external file. Below is the code i am using:

    function loadScript(scriptFile)
    {
    var netRequest = new ActiveXObject('Msxml2.XMLHTTP');

    scriptFile = window.location.protocol + '//' + window.location.host + scriptFile;

    netRequest.open('GET', scriptFile, false);netRequest.setRequestHeader('If-Modified-Since', 'Sat, 1 Jan 2000 00:00:00 GMT');

    netRequest.send(null);
    eval(netRequest.responseText);
    }

    //external code file
    loadScript('/ISV/dvmScripts/countrygrid.js');


    Below is the code that need to change in js code:

    var GEO_ENTITYNAME = "{your entity name here}";
    var SERVER_URL_NAME="window.location.protocol" + '//' + "window.location.host";

    Find and replace SERVER_URL with SERVER_URL_NAME. Because SERVER_URL will return http://:5555/ and you will not find the page "/AdvancedFind/AdvFind.aspx" in code.

    Hope it works!
    Thuta

    ReplyDelete
  22. Hi Dave,

    I salute you. I am sure, you have done a lot of time and effort to get this thing out. Thanks for your sharing for community

    I also found a few things in V1.0.0. I tried to play it in Associate View. Found that, it cannot create new record. But it's fine! I understand that we cannot populate data mapping automatically at that moment.

    It can work for Edit Mode. Found that first time edit process is OK. If I click for edit second time, I found that I can edit only first column. I have THREE columns in grid. First one is Lookup control and the rest are picklist controls. Just inform you :)

    Keep the hard work!

    With many thanks
    Thuta

    ReplyDelete
  23. Thuta,

    You could conceivably remove the lines at the top of the script and initialize them when before you call the external file, that way you don't need a file for each entity.

    Here's the relevant part you could extract and use at the beginning of each Button element's Javascript attribute:

    // Define the entity for which the Grid Editor Object will be activated
    var GEO_ENTITYNAME = "";

    // Declare any attributes restricted from acquiring controls for create and update in an Array
    var GEO_RESTRICTEDATTRIBUTES = new Array();

    // Setup the container for default values used for new records, if none are established by other code
    if (typeof(GEO_ADD_DEFAULTVALUES) == "undefined" || GEO_ADD_DEFAULTVALUES == null) {
    var GEO_ADD_DEFAULTVALUES = new Object();
    GEO_ADD_DEFAULTVALUES.Properties = new Object();
    GEO_ADD_DEFAULTVALUES.Collections = new Object();

    // Define default values if not previously defined
    }

    // Define universally default values; overrides

    // Setup the container for attributes that should have disabled controls, if not already established
    // Note: this differs from restricted attributes in that a value may be specified for saving, but restricted from edit
    if (typeof(GEO_DISABLEATTRIBUTES) == "undefined" || GEO_DISABLEATTRIBUTES == null) {
    var GEO_DISABLEATTRIBUTES = new Array();
    }

    // Define universally disabled attribute controls

    ReplyDelete
  24. Thuta,

    You may want to upgrade to the latest script version; there could be a bug I fixed that's causing the trouble with your editing. However, if this does not get resolved by upgrading, please alert me so I can work with you to determine the cause.

    ReplyDelete
  25. Thanks Dave. I will try it out and let you know :)

    ReplyDelete
  26. I am sorry but mine still doesnt work, I'm getting yellow triange on the bottom left saying:
    this.ActionButtons.EditSave.RegisteredText is null or not an object
    Could you help me?
    Thank you Jan

    ReplyDelete
  27. Hi Dave,

    This is amazing! Easy to implement and works really nicely. However I have found an issue, or at least I think I have, when using insert on a custom entity. It seems that for custom entities CRM is not storing attribute information in the correct way, this might be due to the rollup I am on, but requirement levels and lookup targets are not in the tables in the regular place and are not being returned properly, not really sure how this could be.

    I will email through a screen shot.

    ReplyDelete
  28. Hi Dave,

    I'm not having a lot of luck getting this to work. I'm currently trying to set this up for Opportunities and have successfully put in the buttons on the grid and copied in the Javascript. However, when I try to click either of the buttons, nothing seems to happen.

    I've put in the setting for the GEO_ENTITYNAME only and tried to run it. I'm not sure exactly what to put in the GEO_RESTRICTEDATTRIBUTES or GEO_ADD_DEFAULTVALUES fields.

    If you are able to shed any light on this that would be fantastic and greatly appreciated.

    ReplyDelete
  29. Hi Dave,

    I was having the same issue as Jan Adamec and a couple of others and after a few hours of trying to figure out what was wrong with the ISV.Config I figured out the sample ISV.Config XML you provided does not have JavaScript with a capital "S". It took me a good 4-5 hours to discover it!

    ReplyDelete
  30. Matt, thank you for the information regarding my errant ISV.config example. I'm fixing that right now!

    ReplyDelete
  31. Jan,

    If you would like, my contact information is available from the profile information available on this blog, you may send me the relevant portions of your ISV.config for analysis and debugging.

    ReplyDelete
  32. Hi Dave,

    Great job! It works great!
    I only have one problem. When editing or inserting, Javascript code on OnChange, OnLoad or OnSave events is not working. Any solution?

    ReplyDelete
  33. Anonymous: If you had read the caveats, you would know that there's no solution for that problem as of yet. Stay tuned to this blog for updates to the project.

    ReplyDelete
  34. Is it true that integer fields and money fields are not available to change with the editor?

    ReplyDelete
  35. Integer fields should be available. Money fields, as you have probably discovered, are not. There are additional considerations with money fields that have not yet been made in the script. The same is true of memo fields.

    ReplyDelete
  36. I tried attaching this to a grid with a custom entity and I cannot get the insert mode to work. When I click "Save New", it returns the grid to normal mode but does not save the record. When I go to another entity, I get the error screen of do I want to send an error report to Microsoft and in the details it has:

    'Targets.0' is null or not an object

    ReplyDelete
  37. I've made a script update to fix problems with the Owner fields as reported by many. Please see my latest post.

    ReplyDelete
  38. Just tested and I am unable to add/edit Integer fields as well for my custom entity

    ReplyDelete
  39. John van der WaltMay 3, 2010 at 6:29 AM

    Hi Dave

    Thanks for a brilliant piece of work. I have one question / issue:

    When in "Edit" mode, make a change to a field and then select the next row the changes made to the previous row is lost. Is this by design? An alternative would be to prompt the user to save when selecting the next row...

    I assumed that since the save button is called "Save All" that it will allow multiple changes to be made before saving.

    Other than that, thanks for a much needed crm tool.

    ReplyDelete
  40. John,

    That is more or less by design. The idea is that you can undo changes to a single record by simply deselecting it from Edit Mode. However, a prompt is a great idea, and I'll see what I can do to implement one while maintaining selections.

    Your assumption is correct. "Save All" does just that--saves changes to any record you have changed in Edit Mode.

    You're quite welcome to the tool, and I hope it proves useful to you in the iterations yet to come.

    ReplyDelete
  41. Hi Dave,
    I am having the same problem mentioned above by some people. I have done the same changes as you have mentioned in your steps. My isv.config.xml file has been imported successfully but neither I able to see the Edit/Insert Button or neither any regarding functionality. Could you please help me out? It would be really appreciating.
    Regards

    ReplyDelete
  42. danish, I'm uncertain which problem you're speaking of. Could you elaborate? If the buttons aren't showing up, try importing without any of Javascript. If they still don't show up, then something's wrong with your configuration.

    ReplyDelete
  43. Hallo Berry,

    first of all great job. I did everything like described. I´ve added the Buttons I encoded the script, I put an entity in there. I imported everything. When I press the Button now there is only an "error on Page". No alert nothing else. When I opened the MS error repot it says "error in 155"
    Please help!!

    ReplyDelete
  44. If you're using a language other than American English (Lang ID: 1033), you'll need additional configuration which I haven't yet provided instructions for. Look for those to get published today.

    ReplyDelete
  45. Hallo Berry,

    Thanks a lot! it works now, I just changed the language code.

    Now I tried to put the script to another Entity like Account. And I got an error again.

    Does this Script only work whith the activities?

    p.s. I'll build you a shrine

    With many thanks!
    Slim

    ReplyDelete
  46. Dave, I have tried it without javascript but still no buttons showing. Can you please help me? If I send you my isv.config.xml file??

    ReplyDelete
  47. hi Dave,
    Could we able to save all changes made on that Grid?? As there is no server side SAVE button. Please can you help!

    ReplyDelete
  48. Needed to do a filtered lookup in a edit mode. It is posible?

    ReplyDelete
  49. Filtered lookups at this point are going to be rather improbable. I have a development path and some ideas for implementation, but one of the biggest issues, aside from deploying a filter, is making it unique for every record in the grid. This is not nearly as simple as meeting the same requirement for a single entity in a form.

    Honestly, I want to develop a CRM-deployed solution for managing, including, versioning and dynamically executing scripts using relational data structures, much like the Workflow implements, and allow it to be used both in the forms, and with a sensible API that allows it to be naturally extended into the Grid Editor. This, to me, is the most comprehensive approach.

    However, there are tools available within the script that you could use to short-cut a broad solution like I desire, with a single-purpose utility like you desire. I just have no intention of writing it that way.

    ReplyDelete
  50. Hi Dave,
    From reading your product description, this is a fantastic piece of code. So I am very eager to install and use it.
    I installed the 1.0.9 version in the salesorderdetail entity grid. The buttons show up, and I managed to import the javascrip successfully. But, I have one issue and one question:

    Problem: When I press either one of the buttons, I receive an error message "unable to identify a valid state for the entity on this grid. cancelling".

    Question: In the installation instructions I did not find how to select attributes that I want to show up in the editor. Will all attributes show up, unless I disable some ?

    Your help is very much appreciated !
    Leon

    ReplyDelete
  51. Leon,

    The script relies on the presence of the "statecode" attribute, which does not exist for special child-entities like quotedetail, salesorderdetail, and invoicedetail. I'm working on a solution for this that involves "virtual" attributes, as well as "local" and "remote" attributes for grids showing information from related records. The idea here is to present the ability to modify related record data simultaneously with local record data.

    ReplyDelete
  52. Hi Dave,


    I've installed the Javascript Grid Editor all works fine, but I need only the Edit Mode, Save All and Cancel All buttons the Insert Mode button I don't need to appear near the Edit Mode button.


    What should I change in the Javascript code so In the default mode I'll have only the Edit Mode button, and in the Edit mode to have only the Save All and Cancel All buttons ?


    Thank you.

    ReplyDelete
  53. I mean 752. The previous one will remove Edit functionality. You must make sure that the button has a name that the script can find, so that it can at least turn the button into the "Cancel" button. An empty name won't work either. Whatever you give it, be sure to set it up in the GEO_REGISTEREDBUTTONLABELS.

    ReplyDelete
  54. Hi Dave,

    Thank you for your response regarding my question about:

    ----
    I've installed the Javascript Grid Editor all works fine, but I need only the Edit Mode, Save All and Cancel All buttons the Insert Mode button I don't need to appear near the Edit Mode button.


    What should I change in the Javascript code so In the default mode I'll have only the Edit Mode button, and in the Edit mode to have only the Save All and Cancel All buttons ?

    ----

    But what I really need is that the "Insert Mode" button should not appear at all.

    Example:

    When the user comes first time on the entity I need only "Edit Mode" button (the "Insert Mode" should be hidden on client side, or better removed from the The Javascript Grid Editor, because I don't need the functionality for Insert)

    If user wants to edit, one or more records, he has to click on "Edit Mode". After user has clicked on "Edit Mode" button the "Edit Mode" button will become "Save All" button and near "Save All" button should appear "Cancel All" button.

    So I need only 3 buttons (if possible): "Edit Mode" (one button when user loads the entity, before he click on "Edit Mode" button) and other 2 buttons "Save All", "Cancel All" when user clicked on "Edit Mode".

    Thank you.

    ReplyDelete
  55. Hi,
    I'm using the grid editor within an asociated view. When I Insert a new record the ID to the parent record is empty.
    To fill this ID I use GEO_ADD_DEFAULTVALUES:

    var lookupItem = new Array;
    lookupItem = crmForm.all.accountid.DataValue;
    if (lookupItem[0] != null)
    {
    GEO_ADD_DEFAULTVALUES.Properties['rd_accountid'] = lookupItem[0].id;
    GEO_ADD_DEFAULTVALUES.Properties['rd_accountidname'] = lookupItem[0].name;
    GEO_ADD_DEFAULTVALUES.Properties['rd_accountidtype'] = 'account';
    }

    but I get a message crmForm is undefined

    any idea how I can access form fields?

    Many thks,
    Geert

    ReplyDelete
  56. Anonymous: You're on your own in figuring out how to change the button behavior. I wrote it to work a certain way, based on the limitations of the environment.

    ReplyDelete
  57. Geert,

    I'm glad you asked. You've given me just the motivation I need to complete the "Advanced Scenarios" area of the JGE documentation. When I originally developed the JGE, I needed to use it in an embedded view, as you have. Please go read the updated documentation.

    ReplyDelete
  58. Many Thanks dave!

    When clicking on a item in the navigationbar left you can use something like this:

    var SANav = document.all.nav_;
    SAOnReadyState= function() {
    if (SANav.readyState == "complete") {
    var SAFrame = document.all.Frame;
    SAOnReadyStateFrame= function() {
    if (SAFrame.readyState == "complete") {
    SAScript = "GEO_ADD_DEFAULTVALUES = new Object();"
    + "GEO_ADD_DEFAULTVALUES.Properties = new Object();"
    + "GEO_ADD_DEFAULTVALUES.Collections = new Object();"
    + "GEO_ADD_DEFAULTVALUES.Properties['ownerid'] = '" + crmForm.all.ownerid.DataValue[0].id + "';"
    + "GEO_ADD_DEFAULTVALUES.Properties['owneridname'] = \"" + crmForm.all.ownerid.DataValue[0].name + "\";"
    + "GEO_ADD_DEFAULTVALUES.Properties['owneridtype'] = 'systemuser';"
    var SADoc = SAFrame.contentWindow.document;
    IncludeScript(SADoc, SAScript);
    }
    }
    SAFrame.attachEvent("onreadystatechange", SAOnReadyStateFrame);
    }
    }
    SANav.attachEvent("onclick", SAOnReadyState);

    Advantage of this is that you do not have to make use of IFrames in CRM.

    Geert

    ReplyDelete
  59. Hey Dave,
    could you please help me, i´ve some Problems to implement your solution into my German enviroment?! I want the script to work for Accounts.

    I´ve changed the LCID from 1033 to 1031 and set the GEO_ENTITYNAME to "account" . What else do i have to do ?

    Regards,
    Georg

    ReplyDelete
  60. I will no longer be accepting support requests via comments to my blog. If you require assistance, please contact me directly through the information available on the blog profile page. All further comments to blog posts pertaining to support requests will be rejected for publishing.

    ReplyDelete

Unrelated comments to posts may be summarily disposed at the author's discretion.