I have a subgrid on a form, that I am trying to refresh with dynamic fetchXML depending on the form data. The fetch is refreshing the subGrid appropiately, however the link-entity columns are either not pulling the data, or the subGrid is not displaying it. Here is my javascript that is running.
function UpdateContactSubGrid() {
//If this method is called from the Onload, make sure the grid is loaded before proceeding
if (document.getElementById('new_Opportunity_Contacts_SubGrid') == null) {
//The subgrid hasn't loaded, wait 1 second and then try again
setTimeout(UpdateContactSubGrid, 1000);
return;
}
// To get the Id of the 'Contacts' subgrid
var grid = document.getElementById('new_Opportunity_Contacts_SubGrid').control;
var fetchXML = "";
// To get contract lookup from 'CustomerId' field
var accountLookup = getAttributeValue("customerid");
if (accountLookup != null)
{
fetchXML = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>" +
"<entity name='new_affiliation'>" +
"<attribute name='new_role' />" +
"<attribute name='new_contactid' />" +
"<attribute name='new_affiliationid' />" +
"<order attribute='new_contactid' descending='false' />" +
"<filter type='and'>" +
"<condition attribute='statecode' operator='eq' value='0' /> " +
"<condition attribute='new_clientid' operator='eq' value='" + accountLookup[0].id + "' />" +
"</filter>" +
"<link-entity name='contact' from='contactid' to='new_contactid' alias='a_adbe31a68306e2118bc478e3b5100e8d'>" +
"<attribute name='emailaddress1' />" +
"<attribute name='telephone1' />" +
"<attribute name='mobilephone' />" +
"</link-entity>" +
"</entity>" +
"</fetch>";
}
else
{
fetchXML = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>" +
"<entity name='new_affiliation'>" +
"<attribute name='new_role' />" +
"<attribute name='new_contactid' />" +
"<attribute name='new_affiliationid' />" +
"<order attribute='new_contactid' descending='false' />" +
"<filter type='and'>" +
"<condition attribute='statecode' operator='eq' value='0' /> " +
"</filter>" +
"<link-entity name='contact' from='contactid' to='new_contactid' alias='a_adbe31a68306e2118bc478e3b5100e8d'>" +
"<attribute name='emailaddress1' />" +
"<attribute name='telephone1' />" +
"<attribute name='mobilephone' />" +
"</link-entity>" +
"</entity>" +
"</fetch>";
}
if (grid.SetParameter)
//Inject the new fetchXml
grid.SetParameter("fetchXml", fetchXML);
else
grid.get_innerControl().setParameter("fetchXml", fetchXML);
//Force the subgrid to refresh
grid.refresh();
}
// parametrs:
// attributeName: the name of the attribute
//purpose:
//It checks the existance of the attribute on the form and then get the value of the attriute.It applies null checks.
function getAttributeValue(attributeName) {
try {
var returnValue = null;
var attrb = Xrm.Page.getAttribute(attributeName);
if (attrb != null) {
{
var attrbValue = attrb.getValue();
if (attrbValue != null)
returnValue = attrbValue;
}
}
return returnValue;
}
catch (ex) {
alert(ex.message + ' ' + ex.name);
}
}
What’s the relationship type between the entities ?
With N:N you’ll need to indicate intersect="true" in your link-entity node.
With N:1 you can add link-type="outer" attribute to your link-entity node.
As a side note, consider writing FetchXml dynamically i.e.
var fetchXML =
fetch()
.entity("new_affiliation")
.attributes("new_role", "new_contactid", "new_affiliationid")
.order("new_contactid", fetch.order.Asc)
.filter()
.condition("statecode", fetch.op.Equal, 0);
if (accountLookup != null) {
fetchXML = fetchXML
.condition("new_clientid", fetch.op.Equal, accountLookup[0].id);
}
fetchXML = fetchXML
.link({
entityName: "contact",
to: "new_contactid",
from: "contactid",
alias : "a_adbe31a68306e2118bc478e3b5100e8d",
type: fetch.link.outer //added outer join
})
.attributes("emailaddress1", "telephone1", "mobilephone")
return fetchXML.toString();
you can find more about using Dynamic FetchXMl builder on my blog
http://totbcrm.blogspot.com/2014/08/building-fetchxml-dynamically.html
HTH
Related
This loop generate buttons in my HTML inside an AJAX function.
for( var i = 0; i<len; i++){
var d = new Date(response[i]['date']);
dformat = [d.getDate() + '/' +
(d.getMonth()+1) + '/' +
d.getFullYear() + ' ' +
d.getHours() + ':' +
d.getMinutes()];
console.log(response[i])
var bons = "<tbody>" +
"<th>" + response[i]['id'] + "</th>" +
"<td>" + dformat + "</td>" +
"<td>" + response[i]['poids'] + "</td>" +
"<td>" + response[i]['origine'] + "</td>" +
"<td>" + response[i]['type'] + "</td>" +
"<td>" + response[i]['famille'] + "</td>"
if(response[i]['localisation'] != "Expédié"){
bons = bons + "<td> <input class='evacuate' id='" + response[i]['id'] + "' type='button'" + "value='Evacuer'> </td>"
}else{
bons = bons + "<td>" + response[i]['localisation'] + "</td>"
}
bons = bons + "</tr>" +
"</tbody>"
$("#index").append(
bons
);
}
Then I have another AJAX function which makes every buttons previously generated clickable like :
$(".evacuate").on('click', function(){
console.log("test des boutons")
});
Problem is, the console.log isn't displayed, as if the function is never called. What am I doing wrong here ?
Try this:
$(document).on('click','.evacuate', function(){
console.log("test des boutons")
});
You should define the click event on elements that already exist on the page. So for your situation, select the parent element and then add click event. For example if the element with evacuate class is inside an element with someclass class, this will work:
$(".someclass").on('click', '.evacuate', function(){
console.log("test des boutons")
});
According to your code, you can use tbody tag as parent:
$("tbody").on('click', '.evacuate', function(){
console.log("test des boutons")
});
I don't really understand how this works but thanks to the answers given above I managed to display my console.log.
$(document.getElementsByName).on('click', '.evacuate', function(){
console.log("Test des boutons")
});
Button should visible Based on the team.Example If logged-in user part of the "Test Team","Test Button" should be enable.If not disable.I am using webapi .But it is giving null values.Any suggestions??
function GetUserTeam() {
var clientUrl1 = Xrm.Page.context.getClientUrl();
var oDataPath1 = clientUrl1 + "/api/data/v8.0/";
var req1 = new XMLHttpRequest();
try {
var strTest = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>" +
" <entity name='team'>" +
" <attribute name='name' />" +
" <attribute name='businessunitid' />" +
" <attribute name='teamid' />" +
" <attribute name='teamtype' />" +
" <order attribute='name' descending='false' />" +
" <filter type='and'>" +
" <condition attribute='teamtype' operator='eq' value='0' />" +
" </filter>" +
" <link-entity name='teammembership' from='teamid' to='teamid' visible='false' intersect='true'>" +
" <link-entity name='systemuser' from='systemuserid' to='systemuserid' alias='ab'>" +
" <filter type='and'>" +
" <condition attribute='systemuserid' operator='eq-userid' />" +
" </filter>" +
" </link-entity>" +
" </link-entity>" +
" </entity>" +
"</fetch>";
req1.open("GET", oDataPath1 + "teams?fetchXml=" + encodeURI(strTest), true);
req1.setRequestHeader("Accept", "application/json");
req1.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req1.setRequestHeader("OData-MaxVersion", "4.0");
req1.setRequestHeader("OData-Version", "4.0");
req1.onreadystatechange = function () {
if (this.readyState == 4) {
// debugger;
req1.onreadystatechange = null;
if (this.status == 200) {
var reqResults = JSON.parse(this.response).value;
if (reqResults != null && reqResults.length > 0) {
if ("TestTeam"==reqResults.length[i].name){return true;}
else{return false;}
}
}//End of for
}//En of IF
}
else {
var error = JSON.parse(this.response).error;
alert(error.message);
}
}
};
req1.send();
}
catch (e) {
alert(e);
}
}
Thanks for posting your sample code. It had some syntax errors, but I assume this is because you edited it for the post. For example, the for loop wasn't present and brackets were missing.
The request is asynchronous. Undefined was returned from your method. You either want to change the XMLHttpRequest to run synchronously (generally not recommended for user experience reasons) or pass in callbacks to call when you have a result. Here I added onSuccess and onError. onSuccess would take true/false as an argument which is whether or not TestTeam was found.
In your for loop you had reqResults.length[i] where you maybe meant reqResults[i]. Again, that could be just an issue with editing for posting.
So this code will call onSuccess with a value of true if TestTeam is one of the user's teams. With false if not. Or it will call onError if an error occurs. You might edit to build an array of teams to pass back, etc. Or you can edit the .open() call so it runs synchronously and doesn't use callbacks.
function GetUserTeam(onSuccess, onError) {
var clientUrl1 = Xrm.Page.context.getClientUrl();
var oDataPath1 = clientUrl1 + "/api/data/v8.0/";
var req1 = new XMLHttpRequest();
try {
var strTest = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>" +
" <entity name='team'>" +
" <attribute name='name' />" +
" <attribute name='businessunitid' />" +
" <attribute name='teamid' />" +
" <attribute name='teamtype' />" +
" <order attribute='name' descending='false' />" +
" <filter type='and'>" +
" <condition attribute='teamtype' operator='eq' value='0' />" +
" </filter>" +
" <link-entity name='teammembership' from='teamid' to='teamid' visible='false' intersect='true'>" +
" <link-entity name='systemuser' from='systemuserid' to='systemuserid' alias='ab'>" +
" <filter type='and'>" +
" <condition attribute='systemuserid' operator='eq-userid' />" +
" </filter>" +
" </link-entity>" +
" </link-entity>" +
" </entity>" +
"</fetch>";
req1.open("GET", oDataPath1 + "teams?fetchXml=" + encodeURI(strTest), true);
req1.setRequestHeader("Accept", "application/json");
req1.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req1.setRequestHeader("OData-MaxVersion", "4.0");
req1.setRequestHeader("OData-Version", "4.0");
req1.onreadystatechange = function () {
if (this.readyState == 4) {
// debugger;
req1.onreadystatechange = null;
if (this.status == 200) {
var returnValue = false;
var reqResults = JSON.parse(this.response).value;
if (reqResults != null && reqResults.length > 0) {
for(var i = 0, j = reqResults.length; i < j; i++){
if ("TestTeam" == reqResults[i].name){
returnValue = true;
break;
}
}
}
// Call the handler
onSuccess && onSuccess(returnValue);
}
else {
var error = JSON.parse(this.response).error;
alert(error.message);
onError && onError(error);
}
}
};
req1.send();
}
catch (e) {
alert(e);
onError && onError(e);
}
}
I am learner in javaScript
How to write required on selectpicker based on
var typeSelectBox = "<select id='depprojsDevice' class='selectpicker'>";
typeSelectBox += "<option value=''> -- SELECT --</option>";
if (arr) {
for (var i in arr) {
typeSelectBox += "<option value='" + arr[i][2] + "'>" + arr[i][0] + " " + arr[i][1] + "</option>";
}
}
typeSelectBox + "</select>";
$('#depprojsDevice_Div').html(typeSelectBox);
$("div#depprojsDevice_Div select[id = 'depprojsDevice']").attr('required','required');
$(function(){
$("#depprojsDevice").prop('required',true);
});
Try This Code
I have used jquery datatable plugin.
And I have the following problem.
Fiddle
Html:
<input type="button" value="click" id ="button" />
<table id="testTable">
<thead>
<td>
col1
</td>
<td>
col2
</td>
</thead>
</table>
JS:
(function(){
var firstData = "<tr>" +
"<td>" +
"cell11" +
"</td>" +
"<td>" +
"cell12" +
"</td>" +
"</tr>" +
"<tr>" +
"<td>" +
"cell21" +
"</td>" +
"<td>" +
"cell22" +
"</td>" +
"</tr>";
debugger;
$(firstData).appendTo($('#testTable'));
$('#testTable').dataTable();
})();
$('#button').click(function(){
var secondData = "<tr>" +
"<td>" +
"cell31" +
"</td>" +
"<td>" +
"cell32" +
"</td>" +
"</tr>" +
"<tr>" +
"<td>" +
"cell41" +
"</td>" +
"<td>" +
"cell42" +
"</td>" +
"</tr>";
$('#testTable tbody').empty().append($(secondData));
});
I initialized table as datatable with firstdata. sorting , searching etc are working perfect as expected. But I later altered the body with secondData. Now also sorting and searching is done on first data. How to resolve this?
You must go through the dataTables API. You can manipulate the content of a <table> through javascript or jQuery, but without using the API, jQuery dataTables has no chance of knowing what manipulations you have done. Thats why the old rows still appears after deletion.
You are using dataTables 1.10.x, and in that version the API has been dramatically simplified. Simply use
<dataTables instance>.row.add(..)
You have a chunk of HTML with <tr>'s you want to inject :
dataTable.clear();
$secondData = $(secondData);
for (var tr=0;tr<$secondData.length;tr++) {
var tds = $($secondData[tr]).find('td');
var cols = [];
for (var td=0;td<tds.length;td++) {
cols.push($(tds[td]).html());
}
dataTable.row.add(cols);
}
dataTable.draw();
It seems like a lot of code, but only because we here parse a piece of HTML in the process. Normally you would insert a row like this
dataTable.row.add(['cell31', 'cell32']);
forked fiddle -> http://jsfiddle.net/QgGKD/
I have a loop in which I'm making Ajax xmlhttp requests. This occurs within a function triggered by a window.onload event.
The Ajax calls are being made with async=false, because they need to occur in a specific order that relies on each step completing before the next can occur.
With each successive request in the loop, I'm updating a div with the xmlhttp.responseText.
Firefox is refreshing between calls as desired.
IE is not. When the loop begins, the div is populated with the pre-loop content. When the loop finishes, the div is populated with the first refresh that occurs outside of the loop.
Can someone please help?
Two attempted solutions:
1. Adding a random string to the end of the GET query string to ensure a unique url
2. Submitting with the POST method
No luck with either.
Thanks.
Code...
<script type="text/javascript">
function order_process() {
var err;
var queue_id = "<?= implode(':',$plans[$_REQUEST['order_queue_id']]); ?>".split(':'); // Queue ID
var queue_ax = "<?= implode(':',array_keys($plans[$_REQUEST['order_queue_id']])); ?>".split(':'); // Queue Action
i = 0;
for (step in queue_id) {
// The DIV contents that display during each loop iteration
document.getElementById("barber_pole").innerHTML='\
<center>\
<table style="align:left" border="0" cellpacing="1" cellpadding="1">\
<tr><td><B>Processing Order</B><span style="float:right;">Step ' + (i + 1) + '/' + queue_id.length + '</span></td></tr>\
<tr><td style="background-color:#FFFFFF;height:1.5px"></td></tr>\
<tr><td height="20" style="text-align:center">' + queue_ax[i] + '...</td></tr>\
<tr><td height="20"><IMG SRC="../../_include/images/barber_pole.gif" style="vertical-align: middle;"></td></tr>\
</table>\
</center>';
xmlhttp = ajax_request(); // Create request object
xmlhttp.onreadystatechange=function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
1;
}
}
var url = '../../../api/order_process.php?api_login=' + "<?=$api_login?>" + '&api_pass=' + "<?=$api_pass?>" + "&order_id=<?= $_REQUEST['order_id']?>" + '&order_action_id=' + queue_id[step] + '&timeid=' + Math.random();
xmlhttp.open("GET",url,false);
xmlhttp.send();
// If the response includes the string 'failed' exit the loop and render error error message
if (xmlhttp.responseText.split(',')[0] == 'failed') {
err = queue_ax[i] == 'Registering Domain'
? "<h1 class=\"landing-title\">" + fname + ', ' + "<?=$feedback[domain_register][title]?>" + "</h1><DIV class='landing-body'><?=$feedback[domain_register][body]?></DIV>"
: queue_ax[i] == 'Provisioning cPanel Account'
? "<h1 class=\"landing-title\">" + fname + ', ' + "<?=$feedback[cpanel_provision][title]?>" + "</h1><DIV class='landing-body'><?=$feedback[cpanel_provision][body]?></DIV>"
: queue_ax[i] == 'Credit Card Fraud Protection'
? "<h1 class=\"landing-title\">" + fname + ', ' + "<?=$feedback[maxmind_minfraud][title]?>" + "</h1><DIV class='landing-body'><?=$feedback[maxmind_minfraud][body]?>\"" + xmlhttp.responseText + '"</DIV>'
: queue_ax[i] == 'Verifying Payment'
? "<h1 class=\"landing-title\">" + fname + ', ' + "<?=$feedback[verify_payment][title]?>" + "</h1><DIV class='landing-body'><?=$feedback[verify_payment][body]?>\"" + xmlhttp.responseText + '"</DIV>'
: xmlhttp.responseText == 'failed,'
? "<h1 class=\"landing-title\">" + fname + ', ' + "<?=$feedback[gen_err][title]?>" + "</h1><DIV class='landing-body'><?=$feedback[gen_err][body]?></DIV>"
: "<h1 class=\"landing-title\">" + fname + ', ' + "<?=$feedback[gen_err][title]?>" + "</h1><DIV class='landing-body'><?=$feedback[gen_err][body]?>\"" + xmlhttp.responseText + '"</DIV>';
break;
}
i++;
}
if (err) {
document.getElementById("landing-pres").innerHTML = err;
Cufon.replace('.landing-title');
} else {
document.getElementById("barber_pole").innerHTML = "<?= $thank[$_REQUEST['order_queue_id']][1] ?>";
}
}
window.onload=order_process;
</script>
async=false is not recommended [third parameter in xmlhttp.open("GET",url,false);], and we should not write onreadystatechange function if we are using async=false [Also, you are doing nothing in that function]. Please refer http://www.w3schools.com/ajax/ajax_xmlhttprequest_send.asp
Here is the good way that collecting / preparing all HTML once and update your "barber_pole" div like this..
<script type="text/javascript">
function order_process()
{
var err;
var queue_ids = "<?php echo implode(':',$plans[$_REQUEST['order_queue_id']]); ?>"; // Queue IDs separated by ':'
var queue_axns = "<?php echo implode(':',array_keys($plans[$_REQUEST['order_queue_id']])); ?>"; // Queue Actions separated by ':'
var xmlhttp = ajax_request(); // Create request object
var url = '../../../api/order_process.php?api_login=' + "<?=$api_login?>" + '&api_pass=' + "<?=$api_pass?>" + "&order_id=<?= $_REQUEST['order_id']?>" + '&order_action_ids=' + encodeURIComponent(queue_ids) + '&order_actions=' + encodeURIComponent(queue_axns) + '&timeid=' + Math.random();
xmlhttp.onreadystatechange = function ()
{
if (xmlhttp.readyState == 4)
{
document.getElementById("barber_pole").innerHTML = xmlhttp.responseText;;
}
else
{
document.getElementById("barber_pole").innerHTML = "Processing..";
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
window.onload=order_process;
</script>
in order_process.php file...
<?php
//Checking whether logged in or not blah blah..
$action_ids = $_REQUEST['order_action_ids'];
$order_actions = $_REQUEST['order_actions'];
$actions_ids_array = explode(":", $action_ids);
$order_actions_array = explode(":", $order_actions);
$strHTML = '';
for($cnt=0; $cnt < count($actions_ids_array); $cnt++ )
{
$each_action_id = $actions_ids_array[$cnt];
$each_action = $order_actions[$cnt];
//Process each action collect $fname and $status value and generate HTML
//blah blah..
$strHTML .= "<h1 class=\"landing-title\">" . $fname . $status . "</h1>";
}
echo $strHTML;
exit;