Show popup/alert if account has related entity records - javascript

I have created a custom entity called Alert. I have associated this with the out of the box Account entity.
What I want to do now is to customise the Account form so that when a user opens it, it checks if the current account has any active alerts. If it does, it should show a message informing them of this (a javascript alert?) and then navigate to the alerts view for the account.
I've done some basic javascript in CRM but I'm not sure how to query related entities.
Note Active alert is defined by the Display From and Display Until dates in the Alert being active dates (Display From <= Today AND Display Until >= Today).
Update
Thanks for pointing me in the direction of oData. I now have the following function which is looking up the account set but expanding the relationship with the alerts. I'm trying to figure out how to check if there are any alerts, currently my code always triggers the javascript alert.
function CheckForAlerts(accountId)
{
var odataSelect = "http://mscrmdev/Test/xrmservices/2011/OrganizationData.svc/AccountSet?$expand=new_account_new_alert_Account&$filter=AccountNumber eq '" + accountId + "'";
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
datatype: "json",
url: odataSelect,
beforeSend: function (XMLHttpRequest) { XMLHttpRequest.setRequestHeader("Accept", "application/json"); },
success: function (data, textStatus, XmlHttpRequest)
{
// Use only one of these two methods
// Use for a selection that may return multiple entities
ProcessReturnedEntities(data.d.results);
},
error: function (XmlHttpRequest, textStatus, errorThrown) { alert('OData Select Failed: ' + odataSelect); }
});
}
function ProcessReturnedEntities(ManyEntities)
{
var oneEntity = ManyEntities[0];
if (oneEntity != null)
{
alert('There are active alerts associated with this account.');
}
}

The best way to do this will be via an oData query from the javascript. The CRM 2011 SDK comes with some helper functions for oData calls like this. You will want to use the 'retrieveMultiple' method which will allow you to retrieve all 'alerts' with a lookup to the 'account' in question.
First add the 'RESTJQueryEditor.js' file from the SDK to your form and then you can add your own custom script to perform the retrieve. I then suggest creating the message which you wish to show the user in the callback success function, something like the following:-
retrieveMultiple('nameOfYourAlertEntitySet', '?$filter=myAccountLookupName eq ' + accountId, function(alerts){
if(alerts.length > 0)
{
var message = '';
for(var index = 0; index<alerts.length; index++)
{
message += 'alert: ' + alerts[index].name;
}
alert('Found associated alerts: ' + message);
}
else
{
alert('No associated alerts found for this account');
}
},
function(){
// Log an exception
});
You will want to make the alert message a little nicer of course and adjust your attribute names accordingly, but this is the flavour of what you want to do I believe. Additionally, you can add any further criteria on the alert entity in the filter by use of the 'and' keyword.
Let me know if you have any issues.

Related

Calling multiple Ajax functions in conjunction with SetInterval

I have a set of printers associated with different devices. Every 20 seconds I check the status of the printers and display their status (offline, online, out of paper, etc.). User can select a device from a "Devices" dropdown and get status of printers associated with that device; the default on page load is "all devices".
So, there are two parts to getting status: get list of printers for selected device; get status for that list of printers.
To do this I use setInterval function within which I call an Ajax function to get the status.
I am having trouble getting two ajax functions (get device's printers and get printers' status) working in conjunction with setInterval. Getting the list of printers needs to be done once (or until device is changed), getting status needs to be done every 20 seconds.
I think using promise is the way to do it (I could be wrong) but it doesn't work properly. I need some expert assistance.
This is what I have tried but it seems both ajax functions are executed every 20 seconds.
var statusParameters;
var printers = [];
var mpeName;
var v;
var pm;
function printer(idn, hostName, ipAddress) {
this.IDN = idn;
this.HostName = hostName;
this.IPAddress = ipAddress;
}
$(document).ready(function () {
statusParameters = {
interval: 20000,
interval_id: 0,
intervalDetail_id: 0,
};
...
mpeName = ''; // denotes all printers; when user selects a device this value changes
fetchStatusData();
statusParameters.interval_id = setInterval(function () {
fetchStatusData()
}, statusParameters.interval);
// Get list of printers for selected device
pm =
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
url: 'Services/ps.asmx/GetPrinterMappingCfg',
cache: false,
data: JSON.stringify({ MPEName: mpeName }),
}).done(function (result) {
jResult = JSON.parse(result.d);
$.each(jResult, function (index, value) {
var p = new printer(value.IDN, value.Hostname, value.IPAddress);
printers.push(p);
});
}).fail(function (jqXHR, textStatus, errorThrown) {
alert(textStatus + ' - ' + errorThrown + '\n' + jqXHR.responseText);
});
})
function fetchStatusData() {
// I tried to put the above "pm" right here too
$.when(pm)
.done(function (r1) {
$.each(printers, function (index, value) {
var currPrinter = value;
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
url: "Services/ps.asmx/GetPrinterStatus",
cache: false,
//data: "",
data: JSON.stringify({ PrinterIPAddress: currPrinter.IPAddress }),
}).done(function (result) {
// initial display or updating of status info
}).fail(function (jqXHR, textStatus, errorThrown) {debugger
...
});
});
printers.length = 0; // because every 20 sec. it retrieves printer list!
}).fail(function (jqXHR, textStatus, errorThrown) {debugger
...
});
The problem I am trying to solve is I want the retrieving of list of printers to be done once, or until user selects a different device not every 20 seconds. It is a waste to keep getting the same printer list every 20 seconds.
Also, the way it is now, on initial page load it does not display printers and their status but will after 20 seconds. It will print on initial load if I move "pm" inside of "fetchStatusData" function.
Update
I think I might not have explained what I am trying to do properly. Basically, this is what I am after:
Given list of devices in a dropdown list, with "All Devices" selected on page load
Get list of printers for selected device from dropdown
Repeat the following every 20 seconds
Get status of each printer in list of printers
When user selects a new device, get list of printers again
I was thinking another way might be to create a array of "device" objects, each having an array of printer objects in addition to other properties like DeviceID, etc.
This is done only once on document.ready(). Then when a new device is selected, I already have the list of printers and can get it that way. Still would get stuck in setInterval portion of it.

Why am I getting a '$' is not defined when running an AJAX query?

Possibly a dumb question, but I have a page where I'm trying to load list data into a customer table to display as a front-end. I'm retrieving this list from a SharePoint list using an AJAX call in a Javascript function, however when I'm using this function my console returns a SCRIPT5009: '$' is not defined error. Previously, I've used an AJAX call successfully using very similar code, but to return a single item from the list using the list ID to search for a specific item, and I've run the query successfully directly from the URL that returns the data I'm after - I'm just not sure what's happening with this one.
function getIncidents(){
$.ajax({
url: "SharepointURL/_api/web/lists/getbytitle('Incident List')/items?$select=Title,Id,Priority,IncidentStart,IncidentStatus,IncidentTitle,UpdateResolution",
type: "GET",
headers: {"accept": "application/json;odata=verbose"},
success: function (data) {
var dResponse = data.d.results;
var results = document.getElementById('Results');
results.innerHTML += "<tr><td>Incident<br>Reference</td><td style='width:20px'></td><td>Priority</td><td style='width:20px;'></td><td>Start Time</td><td style='width:20px'></td><td style='width:170px'>Issue</td><td style='width:20px'></td><td style='width:170px'>Latest Update</td><td style='width:20px'></td></tr>";
for(var obj in dResponse){
results.innerHTML += "<tr style='font-size:10pt'><td>"+dResponse[obj].Title + "</td><td></td><td>" + dResponse[obj].Priority + "</td><td></td><td>" + dResponse[obj].IncidentStart + "</td><td></td><td>" + dResponse[obj].IncidentTitle + "</td><td></td><td>" + dResponse[obj].UpdateResolution + "</td></tr>";
}
}
});
}
Previous example where I have this call working:
function getIncident() {
var listName="Incident List";
var incidentID = $("#incidentReference").val();
if(incidentID!=""){
$.ajax({
url: "SharepointURL/_api/web/lists/getbytitle('Incident List')/items?$filter=Title eq '" + incidentID + "'&$select=Title,Id,SystemOrService,Priority,IncidentStatus,IncidentTitle,UpdateResolution,IncidentStart,ImpactedArea,IncidentEnd",
type: "GET",
headers: {"accept": "application/json;odata=verbose"},
success: function (data) {
if(data.d.results.length>0){
var item=data.d.results[0];
$("#systemImpacted").val(item.SystemOrService);
$("#incidentPriority").val(item.Priority);
$("#incidentState").val(item.IncidentStatus);
$("#incidentTitle").val(item.IncidentTitle);
$("#incidentUpdate").val(item.UpdateResolution);
$("#startTime").val(item.IncidentStart);
$("#impactedAreas").val(item.ImpactedArea.results);
$("#endTime").val(item.IncidentEnd);
updateImpact();
getStartTime();
getEndTime();
actionsFormat();
}
},
error: function (data) {
alert("Incident Reference incorrect or not found");
}
});
}
}
The issue is that jQuery ($) is not yet loaded to the page. If you used it before, this means that loading is already setup, so you don't need to add more references to the jQuery.
In most of the cases, when you working with jQuery, you will subscribe on DOM event ready event and do your code there.
So, all you need is to find the
$(document).ready( ...
statement and insert your code there.
If you want to separate your code from already existed, you may write your own $(document).ready subscription.
If you will not find this $(document).ready function, you can search in html for the reference to the jQuery, and insert your script after it. But, than you need to be sure, that reference doesn't include async or defer attribute.
As mentioned in comments, if you decide to add your own subscription, you also need to place it after jQuery reference, because it will not work, if $ isn't available.

Export users sharepoint group

I am looking for a way how to export sharepoint groups via javascript of specific user(filled via input box). Can someone advise please? I managed to export all groups on sharepoint as well as currently logged in but not specific one. I also found the basics on microsoft web but there is nothing about specific user.
Is it somehow possible via REST?
Thank you
So I managed to do it with this functions if anyone is interested.
function GetMembersOfGroup(grpName){
$.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/sitegroups/getByName('"+ grpName +"')/users",
type: "GET",
headers: {"accept": "application/json;odata=verbose"},
success: function (data){
if (data.d.results)
{
for (var i = 0; i < data.d.results.length; i++) {
//Loop through all users and binding in dropdown
if (data.d.results[i] != null && data.d.results[i] != undefined) {
if (data.d.results[i].LoginName == "i:0#.w|ad\\" + document.getElementById("userCkToRemove").value.toLowerCase()) {
if ($("#groupNameToRemove option[value='" + data.d.results[i] + "‘]").length == 0) {
$('#groupNameToRemove').append($("<option/>", {
value: data.d.results[i].Email,
text: grpName
}));
}
}
}
}
}
},
error: function (error) {
alert(JSON.stringify(error));
}
});
}
This functions exports all members and checks whether the login name of export "file" equals the login name that we want to search (coming from input box in html). If yes then we add the name of the group in the drop-down tag based on id #groupNameToRemove which is select tag and I create and option tag within it per each group that the user is member

C# send table cell data from one page to another

I have two pages customer.aspx and customer_detail.aspc, each with their corresponding code behind files. The objective is being able to send a particular table cells's value from customer to customer_detail. For example, the following javascript renders the table dynamically onto customer.aspx based on the BindTable method in customer.aspx.cs file.
customer.aspx:
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "customer.aspx/BindCustomer",
data: "{}",
dataType: "json",
success: function(data) {
for (var i = 0; i < data.d.length; i++) {
$("#customer_table").append("<tr><td>"+'<a id = "anchor" href="customer_individual.aspx">' + data.d[i].customer_name +'</a>'+ "</td><td>" + data.d[i].customer_id +"</td><td>" + data.d[i].total_value + "</td><td>" + data.d[i].created_date + "</td></tr>");
}
},
error: function(result) {
alert("Error");
}
});
});
The BindCustomer function above is a WebMethod written in customer.aspx.cs, which returns a customer array object, customer[], which is bound to the customer_table. Notice that, in the above I have a href within the first td element of the table, which redirects the page to the customer_detail.aspx.
The objective is to be able to send say a customer_name value upon clicking the link to the customer_detail.aspx.cs, so that I can query the customer object which I store separately, with the name and populate the page accordingly. What would be the best method to accomplish this? Any suggestions as to how to proceed will be greatly helpful!
The easiest way is to format a link to customer_detail.aspx with the data you want to pass in the querystring like this (it looks very similar to what you're already doing.)
Link
When customer_detail.aspx loads, you retrieve the value from the querystring.
In your Page_Load event in customer_detail.aspx
var customerName = Request["customerName"];
You could be more particular and say Request.Querystring["customerName"] but on this page you probably don't care whether the value was passed in the querystring or a form field. Request["customerName"] covers both.

Google Recaptcha Ajax response strange checking order

I am making my registration page for my service. I need to check either Google's Recaptcha successfully verified or not. I decided to use an jquery.ajax.
I have created a function "checkCaptcha()" which sets isCAPT (if captcha valid or not) either true (FLD_VALID) or not (FLD_EMPTY):
function checkCaptcha() {
alert("1");
var captcha_response_text = grecaptcha.getResponse();
var request = $.ajax({
url: "ajax/registrationA.php",
type: "post",
data: { captcha: true, captcha_response: captcha_response_text }
});
request.done(function (response, textStatus, jqXHR) {
alert("2");
if(response) {
isCAPT = FLD_VALID;
}
else {
isCAPT = FLD_EMPTY;
}
});
}
I have to say that "registrationA.php" works fine. No problems there.
After this function, I am checking my submit button handling "onclick" event:
apply_button.onclick = function () {
checkCaptcha();
alert("3");
//alert("Капча " + isCAPT + " Логин " + isLOGIN + " Почта " + isMAIL + " Пароль " + isPASS + " Соответствие " + isPAS2);
return false;
};
You can see three "alert(...)" operators. The problem is that when I press submit button (apply_button) I get three alerts: 1, 3, 2. How can I fix this problem. I need to wait until "requiest.done" executes and only than go to "alert("3")". It is essential because now this function checks fields before checking captcha state which leads to an error because in this case isCAPT equals false.
Please help me with this problem. Maybe there is a better way to check if captcha verified or not (maybe there is a function like "grecaptcha.isVerified").
You need to check deferred.promise() method to work with asynchronous data. Check JQ documentation for that. In a few words it does exactly what you need. It allows to wait until the 2nd asynchronous request is finished and starts the 3d function.

Categories