I am trying to disable the ability to resolve a case in CRM unless a couple fields have data. I would like to gray out the case resolution action and was wondering if anyone knew how to do this on the form Load.
Thanks!
Try with this code on the OnLoad event of the Case form:
var menuItem = document.getElementById('_MIresolve');
if (menuItem)
menuItem.disabled = 1;
You can Ctrl+N any CRM page in order to be able to view its source code and figure out ids of controls.
Related
I have 2 select controls. One change event updates the other. Also, it updates a grid inside update panel.
On page load, I call an ajax method to get the drop down values for both select. I populate the control and trigger a button click event which then updates the grid inside the update panel.
Everything works fine in all browsers, except in Firefox. Any idea as to why this might be happening?
Upon using break point i discovered that in other browsers the server side method is called first and then the ajax method while in Firefox its the other way around.
I narrowed down the issue to when using EndRequestHandler. I use EndRequestHandler event to change the class for a control. I remove that functionality and its perfect. The code for it is below:
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler); function EndRequestHandler()
{
var type = $('[id$=ddlType]').val();
$('a[data-categoryid="' + type + '"').parent().addClass('selected');
}
Finally, there was a typo in my code. I forgot the closing square bracket in the EndRequestHandler. Surprisingly, the other browsers didn't care about it!
Updated code.
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler); function EndRequestHandler()
{
var type = $('[id$=ddlType]').val();
$('a[data-categoryid="' + type + '"]').parent().addClass('selected');
}
I'm requesting an ASP.net MVC view into a live box and the view contains form fields that have been marked up with attributes to be used by JQuery's unobtrusive validators plug-in.
The client script is not however working and my theory is that its because the validation framework is only being triggered on page load which has long since passed by the time the MVC view has been loaded into the live box.
Thus how can I let the validation framework know that it has new form fields to fix up?
Cheers, Ian.
var $form = $("form");
$form.unbind();
$form.data("validator", null);
$.validator.unobtrusive.parse(document);
// Re add validation with changes
$form.validate($form.data("unobtrusiveValidation").options);
You may take a look at the following blog post. And here's another one.
Another option, rather trick, which worked for me. Just add following line in the beginning of the partial view which is being returned by ajax call
this.ViewContext.FormContext = new FormContext();
Reference
For some reason I had to combine bjan and dfortun's answers...
So I put this in my view:
#{
this.ViewContext.FormContext = new FormContext();
}
And this execute this after the ajax call finishes:
var form = $("#EnrollmentForm");
form.unbind();
form.data("validator", null);
$.validator.unobtrusive.parse(document);
form.validate(form.data("unobtrusiveValidation").options);
I had a similar issue. I had a form that was using Ajax requests to re-display a part of the form with different form fields. I used unobtrusive validation by manually doing it on the client side using the
#Html.TextBoxFor
for my text boxes. For some reason the validation works when attempting to submit with invalid fields (i.e., the text boxes get outlined in red and the appropriate error messages display with the content I put in the
data_val_required
attribute, for example.
However, after I click a button that makes an Ajax request to modify the form with different fields and then submit again, only the red outline on the invalid fields display, but no error messages are rendered.
bjan's trick worked for me, but I still can't see what was causing the issue. All the HTML necessary to carry out the client-side validation was there I just can't figure out why the error message attribute values wouldn't display.
All I can think of is that the jQuery validation code doesn't make a second attempt to check the form fields after a submit was made.
I have an app that has several different types of form elements which all post data to the server with jQuery AJAX.
What I want to do is:
Show a loader during AJAX transmission
Prevent the user from submitting twice+ (clicking a lot)
This is easy to do on a one off basis for every type of form on the site (comments, file upload, etc). But I'm curious to learn if that is a more global way to handle this?
Something that's smart enough to say:
If a form is submitting to the server and waiting for a response, ignore all submits
Show a DISABLED class on the submitted / clicked item
Show a loading class on the class="spinner" which is closest to the submit item clicked
What do you think? Good idea? Done before?
Take a look at the jQuery Global Ajax Event Handlers.
In a nutshell, you can set events which occur on each and every AJAX request, hence the name Global Event Handlers. There are a few different events, I'll use ajaxStart() and ajaxComplete() in my code sample below.
The idea is that we show the loading, disable the form & button on the ajaxStart() event, then reenable the form and hide the loading element inside the ajaxComplete() event.
var $form = $("form");
$form.ajaxStart(function() {
// show loading
$("#loading", this).show();
// Add class of disabled to form element
$(this).addClass("disabled");
// Disable button
$("input[type=submit]", this).attr("disabled", true);
});
And the AJAX complete event
$form.ajaxComplete(function() {
// hide loading
$("#loading", this).hide();
// Remove disabled class
$(this).removeClass("disabled");
// Re-enable button
$("input[type=submit]", this).removeAttr("disabled");
});
You might need to attach to the ajaxError event as well in case an AJAX call fails since you might need to clean up some of the elements. Test it out and see what happens on a failed AJAX request.
P.S. If you're calling $.ajax or similar ($.getJSON), you can still set these events via $.ajaxStart and $.ajaxComplete since the AJAX isn't attached to any element. You'll need to rearrange the code a little though since you won't have access to $(this).
I believe you have to do 2 for sure and 3 to improve usability of your app. It is better to keep backend dumb but if you have a security issue you should handle that too.
I have a task to change envelope icons on the main Activities view page (Work Place, My Work -> Activities) for every row in the grid, depending on the custom status of the row in crm 4.0. I need to do it using JavaScript. Does anybody know if there is a way to do that and where should the JavaScript code be placed? I am assuming that I need to intercept grid onLoad event, go through the grid, check the condition and flip the url of the icon. But I cannot figure out how to hook into that event...
Thanks very much!
I got several very useful advices and here is what I got so far.
1. I added SiteMap to load a custom page, instead of default one (/workplace/home_activities.aspx)
2. Here is the code of the custom page, placing onreadystatechange in the html was the only way I could get this function to run. Do not know why.
HTML>
HEAD>
TITLE>
script language="javascript" type="text/javascript">
function Run()
{
var objIframe = getIframe();
if(objIframe.readyState == "complete")
{
var docFrame = objIframe.contentWindow.document;
var grid = docFrame.getElementById("crmGrid");
var allRecords = grid.InnerGrid.AllRecords;
for(var i=0; i
function getIframe()
{
return document.getElementById("wraperActivitiesFrame");
}
/script>
/HEAD>
body >
iframe id="wraperActivitiesFrame" src="/workplace/home_activities.aspx" WIDTH="100%" HEIGHT="100%" onreadystatechange="Run()">
/HTML>
The issue I am having now is that the function does not run again when I try to page the grid. I have 2 pages of Activities; when the page loads for the first time - I have my alert boxes, but when I click on "page 2" arrow - nothing happens. Why??? What I am doing wrong?
You kinda can hook into that event. You create a "wrapper" HTML page that you load in CRM instead of the default activities grid via Sitemap. This wrapper contains a full-size IFrame in which you load the actual grid, and in the IFrame's onreadystatechange handler (for readyState == 4), you traverse the grid's DOM (jQuery might make this a little easier, but I haven't used jQuery much myself) and do whatever changes you need to do (that means the JavaScript goes within the wrapper HTML page). If you call this via setInterval and put a try-catch around it, this will even be safe against grid refreshes and browsing through the pages.
I've been working on Chrome Extension for a website for the past couple of days. It's coming along really nicely but I've encountered a problem that you might be able to help with.
Here's an outline of what the extension does (this functionality is complete):
A user can enter their username and password into the extensions popup - and verify their user account for the particular website
When a user browses http://twitter.com a content script is dynamically included that manipulates the DOM to include an extra button next to each tweet displayed.
When a user clicks this button they are presented with a dialog box
I've made a lot of progress but here is my problem:
When a user visits Twitter the content script is activated and all tweets on the page get my new button - but if the user then clicks 'More...' and dynamically loads the next 20 tweets... these new additions to the page DOM do not get affected by the content script (because it is already loaded).
I could add an event listener to the 'More...' button so it then triggers the original content script again (and adds the new button) but i would have to predict the length of twitter's ajax request response.
I can't tap into their Ajax request that pulls in more tweets and call my addCurateButton() function once the request is complete.
What do you think is the best solution? (if there is one)
What you want to do is to re-execute your content-script every time the DOM is changed. Luckily there is an event for that. Have a look at the mutation event called DOMNodeInserted.
Rewrite your content script so that it attaches an event listener to the body of the DOM for the DOMNodeInserted event. See the example below:
var isActive = false;
/* Your function that injects your buttons */
var inject = function() {
if (isActive) {
console.log('INFO: Injection already active');
return;
}
try {
isActive = true;
//inject your buttons here
//for the sake of the example I just put an alert here.
alert("Hello. The DOM just changed.");
} catch(e) {
console.error("ERROR: " + e.toString());
} finally {
isActive = false;
}
};
document.body.addEventListener("DOMNodeInserted", inject, false);
The last line will add the event listener. When a page loads the event is triggered quite often so you should define a boolean (e.g. var isActive), that you initialize to false. Whenever the inject function is run check whether isActive == true and then abort the injection to not execute it too often at the same time.
Interacting with Ajax is probably the hardest thing to coax a content script to do, but I think you’re on the right track. There are a couple different approaches I’ve taken to solving this problem. In your case, though, I think a combination of the two approaches (which I’ll explain last) would be best.
Attach event listeners to the DOM to detect relevant changes. This solution is what you’ve suggested and introduces the race condition.
Continuously inspect the DOM for changes from inside a loop (preferably one executed with setInterval). This solution would be effective, but relatively inefficient.
The best-of-both-worlds approach would be to initiate the inspection loop only after the more button is pressed. This solution would both avoid the timing issue and be efficient.
You can attach an event-handler on the button, or link that is used for fetching more results. Then attach a function to it such that whenever the button is clicked, your extension removes all the buttons from DOM and starts over inserting them, or check weather your button exists in that particular class of DOM element or not and attach a button if it doesn't.