Bulk edit for Dynamics CRM Entities

blog 10 September 2008 | 1 Comment

You probably already know about a feature calledbulk edit on Microsoft Dynamics CRM that lets you modify several records at once, this is definitely a great feature that enables end users to change in bulk some values for several records. The problem is that this feature is not available for all the records in Microsoft Dynamics CRM, but as usual with some dirty and UNSUPPORTED tricks this can be done.

Recently, I was playing with this feature trying to find how it works and see if it could be possible to enable it for the Sales Order entity. My first idea as usual was to dig on the internals of the CRM’s JavaScript to see what dialogue or URL is this “Bulk Edit” option calling.

With my brand new Internet Explorer 8 Beta 2, I will dedicate a post to it in another moment but just let me say it is worth to give it a try, I started the new integrated Developer Toolbar. This toolbar basically lets you do the same things as the older plug-in IE Developer Toolbar available for IE 6 and 7, so you get sort of HTML inspector/debugger that let you dig onto the HTML, CSS and all the JavaScript code that is included on the web page that you are browsing. Looking into the on click event of the menu item for Bulk Edit on the contacts grid I found a very simple call to a function called doAction(…), and it did not take too longer to find the function definition on the JavaScript included files.

This function seems to be utilised in all the Microsoft Dynamics CRM grids to manage the typical options that you have in the grid buttons and menus. Basically, this function gets some parameters to indicate the grid that is calling the function, the entity type code and what operation to execute.

In this case, we want to get this function to fire a Bulk Edit dialogue for the Sales Order entity so the call to the function would be like this doAction(‘crmGrid’,’1088′,’bulkedit’).Where crmGrid is the name of the object that represents the Grid, we will go through this object another day as it quite useful to handy multi selection buttons on the grid, the second parameter is the entity type code for the Sales Order entity and the final parameter is the command that we want to execute.

Finally, if we edit the ISV.config file (by exporting it and re-importing it) and add a new button definition for the Sales using JavaScript to execute this function call we get the Bulk Edit functionality working!

Here is the chunk of code that we need to add on the ISV.config file under the tag.

<Entity name="salesorder">
  <Grid>
    <MenuBar>
      <Buttons>
      <Button Icon="/_imgs/ico_18_debug.gif" JavaScript="doAction('crmGrid', '1088', 'bulkedit');" Client="Web">
        <Titles>
          <Title LCID="1033" Text="Bulk Edit" />
        Titles>
        <ToolTips>
          <ToolTip LCID="1033" Text="Bulk Edit." />
        ToolTips>
      Button>
      Buttons>
    MenuBar>
  Grid>
Entity>

Hope you find this useful but remember that this is a NOT SUPPORTED customisation and you should carefully test it to avoid any problem.

I didn’t try to add this functionality to other CRM Entities that don’t support

One Response on “Bulk edit for Dynamics CRM Entities”

  1. Anonymous says:

    Please help, I tried creating a Bulk Update button on the ACtivities grid but have had no luck.

    This is the code in ISV.Config

    </p> </p> <p> <tooltips></tooltips></p> <p> <tooltip LCID="1033" Text="Bulk Edit." /></p> </p> </p> </p> <p>crmGrid = My Activities ?</p> <p>Many thanks</p> <div class="reply"> <a rel='nofollow' class='comment-reply-link' href='/blog/bulk-edit-for-dynamics-crm-entities/?replytocom=2#respond' onclick='return addComment.moveForm("div-comment-2", "2", "respond", "16")'>Reply</a> </div> </div> </li> </ol> </div> <!-- end #comments_wrap --> <div id="respond"> <h3>Leave a Reply</h3> <div class="cancel-comment-reply"> <p><small><a rel="nofollow" id="cancel-comment-reply-link" href="/blog/bulk-edit-for-dynamics-crm-entities/#respond" style="display:none;">Click here to cancel reply.</a></small></p> </div> <form action="http://marcoamoedo.com/wp-comments-post.php" method="post" id="commentform" name="commentform"> <p><input type="text" name="author" id="author" value="" size="22" tabindex="1" /> <label for="author"><small>Name (required)</small></label></p> <p><input type="text" name="email" id="email" value="" size="22" tabindex="2" /> <label for="email"><small>Mail (will not be published) (required)</small></label></p> <p><input type="text" name="url" id="url" value="" size="22" tabindex="3" /> <label for="url"><small>Website</small></label></p> <!--<p><small><strong>XHTML:</strong> You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> </small></p>--> <p><textarea name="comment" id="comment" rows="8" tabindex="4" style="width:440px"></textarea></p> <p><input name="submit" type="submit" id="submit" tabindex="5" value="Submit Comment" /> <input type="hidden" name="comment_post_ID" value="16" /> </p> <input type='hidden' name='comment_post_ID' value='16' id='comment_post_ID' /> <input type='hidden' name='comment_parent' id='comment_parent' value='0' /> <div style="display:block;" id="captchaImgDiv"> <div style="display:block; padding-top:5px;" id="captchaInputDiv"><input type="text" value="" name="captcha_code" id="captcha_code" tabindex="4" style="width:65px;" /> <label for="captcha_code"><small>CAPTCHA Code</small></label> </div> <div style="width: 250px; height: 40px; padding-top:10px;"><img class="si-captcha" id="si_image_com" style="border-style:none; margin:0; padding-right:5px; float:left;" src="http://marcoamoedo.com/wp-content/plugins/si-captcha-for-wordpress/captcha-secureimage/securimage_show.php?si_form_id=com&prefix=9P19mspnntEDVtTt" alt="CAPTCHA Image" title="CAPTCHA Image" /> <input id="si_code_com" type="hidden" name="si_code_com" value="9P19mspnntEDVtTt" /> <div id="si_audio_com"> <a id="si_aud_com" href="http://marcoamoedo.com/wp-content/plugins/si-captcha-for-wordpress/captcha-secureimage/securimage_play.php?si_form_id=com&prefix=9P19mspnntEDVtTt" rel="nofollow" title="CAPTCHA Audio"> <img src="http://marcoamoedo.com/wp-content/plugins/si-captcha-for-wordpress/captcha-secureimage/images/audio_icon.png" alt="CAPTCHA Audio" style="border-style:none; margin:0; vertical-align:top;" onclick="this.blur();" /></a> </div> <div id="si_refresh_com"> <a href="#" rel="nofollow" title="Refresh Image" onclick="si_captcha_refresh('si_image_com','com','mp3','/wp-content/plugins/si-captcha-for-wordpress/captcha-secureimage','http://marcoamoedo.com/wp-content/plugins/si-captcha-for-wordpress/captcha-secureimage/securimage_show.php?si_form_id=com&prefix='); return false;"> <img src="http://marcoamoedo.com/wp-content/plugins/si-captcha-for-wordpress/captcha-secureimage/images/refresh.png" alt="Refresh Image" style="border-style:none; margin:0; vertical-align:bottom;" onclick="this.blur();" /></a> </div> </div> </div> <p style="display: none;"><input type="hidden" id="akismet_comment_nonce" name="akismet_comment_nonce" value="80286d2725" /></p><p id="sfc_comm_send"></p> </form> <div class="fix"></div> </div> <!-- end #respond --> </div><!--comments--> </div><!--content--> <div id="sidebar"> <div id="text-4" class="widget widget_text"><h3>Sponsors<span class="fold"> </span></h3> <div class="textwidget"><div style="float: left; padding:10px;"> <iframe src="http://affiliate.godaddy.com/ad/8FBA7BBAAFFE44DB9434DFD20B525CD417C5E0173C6A31B419F563B7FF82985E" width="125" height="125" frameborder="0" scrolling="no" marginwidth="0" marginheight="0" hspace="0" allowtransparency="true"></iframe> </div> <div style="float: left; padding:10px;"> <A href="https://community.dynamics.com/product/crm/default.aspx"><IMG alt="Ad" src="http://marcoamoedo.com/wp-content/uploads/2011/01/Dynamics_Community.png" /> </A> </div> <div style="float: left; padding:10px;"> <A href="http://www.woothemes.com/"><IMG alt="Ad" src="http://marcoamoedo.com/wp-content/uploads/2011/01/your_ad_here.jpg"" /></A> </div> <div style="float: left; padding:10px;"> <iframe src="http://affiliate.godaddy.com/ad/F285CF87B34533AD6362D511C323820A28D564BA50504BC49E8BB2B50EA81763" width="125" height="125" frameborder="0" scrolling="no" marginwidth="0" marginheight="0" hspace="0" allowtransparency="true"></iframe> </div> </div> <div class="fix"></div></div><div id="text-3" class="widget widget_text"><h3>Follow Me!<span class="fold"> </span></h3> <div class="textwidget"><a href='http://feeds.feedburner.com/marcoamoedo'><img src='/wp-content/uploads/2011/01/feed-icon.png'/></a> <a href='http://www.twitter.com/marcoamoedo '><img src='/wp-content/uploads/2011/01/Twitter-icon.png'/></a> <a href='http://www.linkedin.com/in/amoedo'><img src='/wp-content/uploads/2011/01/linkedin-icon.png'/></a> <a href=' '><img src='/wp-content/uploads/2011/01/facebook-icon.png'/></a> <a href='http://www.flickr.com/photos/marcoamoedo/'> <img src='/wp-content/uploads/2011/01/flikr-icon.png'/></a> </div> <div class="fix"></div></div><div id="ezadssearch-3" class="widget ezAdsSearch"><h3>Search<span class="fold"> </span></h3><div class="ezAdsense adsense adsense-search"><div style="margin:0px; "> <form action="http://www.google.co.uk/cse" id="cse-search-box"> <div> <input type="hidden" name="cx" value="partner-pub-9444034820705407:25djktb0jh8" /> <input type="hidden" name="ie" value="ISO-8859-1" /> <input type="text" name="q" size="31" /> <input type="submit" name="sa" value="Search" /> </div> </form> <script type="text/javascript" src="http://www.google.co.uk/cse/brand?form=cse-search-box&lang=en"></script> </div></div><div class="fix"></div></div> <div id="flickr" class="widget"> <h3>Flickr Photos</h3> <div class="wrap"> <div class="fix"></div> <script type="text/javascript" src="http://www.flickr.com/badge_code_v2.gne?count=6&display=latest&size=s&layout=x&source=user&user=43488505@N06"></script> <div class="fix"></div> </div> </div> <div id="woo-twitter" class="widget widget_Twidget"><div id="twitter" class="widget"><h3>Twitter Updates</h3><ul id="twitter_update_list"><li></li></ul><div class="fix"></div></div><div class="fix"></div></div><div class="clear"></div><div id="nav_menu-3" class="widget widget_nav_menu"><h3>Navigation<span class="fold"> </span></h3><div class="menu-main-menu-container"><ul id="menu-main-menu" class="menu"><li id="menu-item-38" class="menu-item menu-item-type-post_type menu-item-38"><a href="http://marcoamoedo.com/about/">About</a></li> <li id="menu-item-39" class="menu-item menu-item-type-taxonomy current-post-ancestor current-menu-parent current-post-parent menu-item-39"><a href="http://marcoamoedo.com/category/blog/">blog</a></li> </ul></div><div class="fix"></div></div><div id="text-5" class="widget widget_text"><h3>Interesting Links<span class="fold"> </span></h3> <div class="textwidget"><script type="text/javascript"> ch_client = "amoedo"; ch_width = 300; ch_height = 250; ch_type = "mpu"; ch_sid = "Chitika Default"; ch_color_site_link = "#0000CC"; ch_color_title = "#0000CC"; ch_color_border = "#FFFFFF"; ch_color_text = "#000000"; ch_color_bg = "#FFFFFF"; </script> <script src="http://scripts.chitika.net/eminimalls/amm.js" type="text/javascript"> </script></div> <div class="fix"></div></div><div id="recent-comments-3" class="widget widget_recent_comments"><h3>Recent Comments<span class="fold"> </span></h3><ul id="recentcomments"><li class="recentcomments">Anonymous on <a href="http://marcoamoedo.com/blog/adding-linkedin-to-dynamics-crm/#comment-34">Adding LinkedIn to Dynamics CRM</a></li><li class="recentcomments">Anonymous on <a href="http://marcoamoedo.com/blog/adding-linkedin-to-dynamics-crm/#comment-33">Adding LinkedIn to Dynamics CRM</a></li><li class="recentcomments">Anonymous on <a href="http://marcoamoedo.com/blog/adding-linkedin-to-dynamics-crm/#comment-32">Adding LinkedIn to Dynamics CRM</a></li><li class="recentcomments">Anonymous on <a href="http://marcoamoedo.com/blog/adding-linkedin-to-dynamics-crm/#comment-31">Adding LinkedIn to Dynamics CRM</a></li><li class="recentcomments">Anonymous on <a href="http://marcoamoedo.com/blog/summary-of-xrm-and-crm-5-at-pdc09/#comment-30">Summary of xRM and CRM 5 at PDC09</a></li></ul><div class="fix"></div></div><div id="tag_cloud-3" class="widget widget_tag_cloud"><h3>Tags<span class="fold"> </span></h3><div></div> <div class="fix"></div></div> </div><!--sidebar--> <div class="fix"></div> </div><!--wrapper--> <script type="text/javascript"> var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-4711888-1']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); </script> <script type="text/javascript"> FB_RequireFeatures(["XFBML"], function() { FB.init("3c6f9e54cbc149b844fe7c53a15701a4", "http://marcoamoedo.com/?xd_receiver=1", {"permsToRequestOnConnect":"email"}); }); </script> <style type="text/css"> #fb-user { border: 1px dotted #C0C0C0; padding: 5px; display: block; height: 96px; } #fb-user .fb_profile_pic_rendered { margin-right: 5px; } #fb-user a.FB_Link img { float: left; } </style> <script type="text/javascript"> var fb_connect_user = false; function sfc_update_user_details() { fb_connect_user = true; // Show their FB details TODO this should be configurable, or at least prettier... if (!jQuery('#fb-user').length) { jQuery('#comment-user-details').hide().after("<span id='fb-user'>" + "<fb:profile-pic uid='loggedinuser' facebook-logo='true' size='normal' height='96'></fb:profile-pic>" + "<span id='fb-msg'><strong><fb:intl>Hi</fb:intl> <fb:name uid='loggedinuser' useyou='false'></fb:name>!</strong><br /><fb:intl>You are connected with your Facebook account.</fb:intl>" + "<a href='#' onclick='FB.Connect.logoutAndRedirect(\"http://marcoamoedo.com/blog/bulk-edit-for-dynamics-crm-entities/\"); return false;'> Logout</a>" + "</span></span>"); jQuery('#sfc_comm_send').html('<input style="width: auto;" type="checkbox" id="sfc_comm_share" /><label for="sfc_comm_send"><fb:intl>Share Comment on Facebook</fb:intl></label>'); } // Refresh the DOM FB.XFBML.Host.parseDomTree(); } jQuery("#commentform").bind('submit',sfc_handle_submit_share); function sfc_handle_submit_share() { if (jQuery('#sfc_comm_share:checked').val() == 'on') { sfc_setCookie('sfc_share', 'yes'); } return true; } // first, check if we already have email permission var sfc_comm_email_perm = false; FB.ensureInit ( function () { FB.Facebook.apiClient.users_hasAppPermission('email',function(res,ex){ if (res == 0) { // no permission, ask for it on submit jQuery("#commentform").bind('submit',sfc_get_email_perms); } else { // we have permission, no special handler needed sfc_comm_email_perm = true; } }); }); // ask for email permission function sfc_get_email_perms() { if (sfc_comm_email_perm) return true; if (fb_connect_user) { FB.Facebook.apiClient.users_hasAppPermission('email',function(res,ex){ if (res == 0) { FB.Connect.showPermissionDialog("email", function(perms) { if (perms.match("email")) { sfc_commentform_submit(); } else { var dialog = FB.UI.FBMLPopupDialog('Email required', ''); var fbml='\ <div id="fb_dialog_content" class="fb_dialog_content">\ <div class="fb_confirmation_stripes"></div>\ <div class="fb_confirmation_content"><p>This site requires permission to get your email address for you to leave a comment. You can not leave a comment without granting that permission.</p></div>\ </div>'; dialog.setFBMLContent(fbml); dialog.setContentWidth(540); dialog.setContentHeight(65); dialog.set_placement(FB.UI.PopupPlacement.topCenter); dialog.show(); setTimeout ( function() { dialog.close(); }, 5000 ); } }); } else { sfc_commentform_submit(); } }); return false; } else { return true; } } // submit the form function sfc_commentform_submit() { jQuery("#commentform").unbind('submit',sfc_get_email_perms); jQuery("#commentform :submit").click(); } function sfc_setCookie(c_name,value,expiredays) { var exdate=new Date(); exdate.setDate(exdate.getDate()+expiredays); document.cookie=c_name+ "=" +escape(value)+((expiredays==null) ? "" : ";expires="+exdate.toGMTString()); } function sfc_getCookie(c_name) { if (document.cookie.length>0) { c_start=document.cookie.indexOf(c_name + "="); if (c_start!=-1) { c_start=c_start + c_name.length+1; c_end=document.cookie.indexOf(";",c_start); if (c_end==-1) c_end=document.cookie.length; return unescape(document.cookie.substring(c_start,c_end)); } } return ""; } FB.ensureInit ( function () { FB.Connect.ifUserConnected(sfc_update_user_details); if (sfc_getCookie('sfc_share') == 'yes') { sfc_setCookie('sfc_share', null); FB.Connect.streamPublish(null, {"name":"Bulk edit for Dynamics CRM Entities","href":"http:\/\/marcoamoedo.com\/blog\/bulk-edit-for-dynamics-crm-entities\/","description":"You probably already know about a feature calledbulk edit on Microsoft Dynamics CRM that lets you modify several records at once, this is definitely a great feature that enables end users to change in bulk some values for several records. The problem is that this feature is not available for all the records in Microsoft [...]","caption":"{*actor*} left a comment on Bulk edit for Dynamics CRM Entities","comments_xid":"http%3A%2F%2Fmarcoamoedo.com%2Fblog%2Fbulk-edit-for-dynamics-crm-entities%2F"}, [{"text":"Read Post","href":"http:\/\/marcoamoedo.com\/blog\/bulk-edit-for-dynamics-crm-entities\/"}] ); } }); </script> <script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></script> <script type="text/javascript" src="http://twitter.com/statuses/user_timeline/marcoamoedo.json?callback=twitterCallback2&count=4"></script> </body> </html>