I'm trying to populate a subgrid with fetchXml results in CRM 2015 online. One issue in the beginning was that document.getElementById("leadUmbrellaGrid"); returns null
function filterSubGrid() {
var leadwithSameNameGrid = Xrm.Page.getControl("leadUmbrellaGrid").getGrid();//HAVE TRIED window.parent.document.getElementById("leadUmbrellaGrid"); //grid to filter
var currentleadId = Xrm.Page.data.entity.getId();;
if (leadwithSameNameGrid == null) {
setTimeout('filterSubGrid()', 500);
return;
}
//fetch xml code
var fetchXml = "<fetchxml goes here>";
leadwithSameNameGrid.control.SetParameter("fetchXml", fetchXml); //set the fetch xml to the sub grid
leadwithSameNameGrid.control.refresh(); //refresh the sub grid using the new fetch xml
}
I have gone through this and this
I tried window.parent.document.getElementById as well but in both cases, the .control is null or undefined and end up with:
TypeError: Unable to get property 'SetParameter' of undefined or null reference
Would appreciate your help/tips.
Thanks,
Here's the solution:
We need to use window.parent.document.getElementById
Wait for the control to load in the DOM.
So the code would look like this:
function filterSubGrid()
{
var leadwithSameNameGrid = window.parent.document.getElementById("leadUmbrellaGrid");
var currentleadId = Xrm.Page.data.entity.getId();;
if (leadwithSameNameGrid == null)
{
setTimeout(filterSubGrid, 500);
return;
}
//fetch xml code
var fetchXml = "<fetchxml goes here>";
if (leadwithSameNameGrid.control != null)
{
leadwithSameNameGrid.control.SetParameter("fetchXml", fetchXml); //set the fetch xml to the sub grid
leadwithSameNameGrid.control.refresh(); //refresh the sub grid using the new fetch xml
}
else
{
setTimeout(filterSubGrid, 500);
}
}
function filterSubGrid() {
var leadwithSameNameGrid = window.parent.document.getElementById("leadUmbrellaGrid");
var currentleadId = Xrm.Page.data.entity.getId();;
if (leadwithSameNameGrid == null) {
setTimeout('filterSubGrid()', 500);
return;
}
//fetch xml code
var fetchXml = "<fetchxml goes here>";
if (relatedProjectsSubGrid.control != null) {
leadwithSameNameGrid.control.SetParameter("fetchXml", fetchXml); //set the fetch xml to the sub grid
leadwithSameNameGrid.control.refresh(); //refresh the sub grid using the new fetch xml
} else {
setTimeout('filterSubGrid()', 500);
}
}
Ive tried this one but didn't quite get where did you get the "relatedProjectsSubGrid.control", also is this still working for CRM 7.1?
Thanks
Related
I have List<model> and I convert to JSON in Javascript and when I click button call controller method
and pass paramater like this :
$('#exceldownload').click(function(){
var json = #Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.ReportListModel,Newtonsoft.Json.Formatting.Indented));
json = JSON.stringify(json);
window.location = "#Url.Action("ReportExcel","Report")?model="+json+"";
});
And Controller Code :
public FileResult ReportExcel(string model)
{
var b = JsonConvert.DeserializeObject<List<ReportListModel>>(model);
if (b.Count == 0)
{
return File(Encoding.UTF8.GetBytes("empty"), "text/plain", "empty");
}
else
{
DataTable table = (DataTable)JsonConvert.DeserializeObject(JsonConvert.SerializeObject(b), (typeof(DataTable)));
using (var excelPack = new ExcelPackage())
{
var ws = excelPack.Workbook.Worksheets.Add("WriteTest");
ws.Cells.LoadFromDataTable(table, true, OfficeOpenXml.Table.TableStyles.Light8);
var FileBytesArray = excelPack.GetAsByteArray();
return File(FileBytesArray, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "test.xlsx");
}
}
}
But when I click button and getting like this :
This site can't be reached,
Localhost refused to connect,
ERR_CONNECTION_CLOSED
I want to when I click button download excel file.
It's crashing at this line:
window.location = "#Url.Action("ReportExcel","Report")?model="+json+"";
Change it to
window.location = #Url.Action("ReportExcel","Report") + "?model="+json+"";
Try debugging the ASP.NET code. Probably an internal server error occurs.
to check if page is published using server side code i should use this snippet:
PublishingPageCollection pages = PublishingWeb.GetPublishingWeb(web).GetPublishingPages();
foreach (PublishingPage page in pages)
{
if(!page.ListItem.File.Level == SPFileLevel.Published)
return;
// logic
}
How could i do the same but using Javascript in SharePoint?
According to SP.Publishing.PublishingWeb Methods the method GetPublishingPages is not supported in JSOM API.
But you could consider the following example to determine whether page is published or not using JSOM API
function getPublishingPages(success,error)
{
var ctx = SP.ClientContext.get_current();
var list = ctx.get_web().get_lists().getByTitle('Pages');
var items = list.getItems(SP.CamlQuery.createAllItemsQuery());
ctx.load(items,'Include(File)');
ctx.executeQueryAsync(function() {
success(items);
},
error);
}
SP.SOD.executeFunc('SP.js', 'SP.ClientContext', function() {
getPublishingPages(printPagesInfo,logError);
});
function printPagesInfo(pages)
{
pages.get_data().forEach(function(item){
var file = item.get_file();
var pageStatus = file.get_level() === SP.FileLevel.published ? 'published' : 'not published';
console.log(String.format('Page {0} is {1}', file.get_name(),pageStatus));
});
}
function logError(sender,args){
console.log('An error occured: ' + args.get_message());
}
Ok so the scenario is currently I am populating a drop down list from my model with the following code
ViewBag.LeaseCompanyID = new SelectList(ContractModelEntity.system_supplier.Where(x => x.Type == "Lease"), "CompanyID", "Name", data.LeaseCompanyID);
This works perfectly, however on my form I have a button located next to the drop down list which adds another option in the database, using ajax and a modal popup.
The controller code for this is here
[HttpPost]
public JsonResult AddSupplier([Bind(Include="Name,Type")] system_supplier data)
{
if (ModelState.IsValid)
{
ContractModelEntity.system_supplier.Add(data);
ContractModelEntity.SaveChanges();
return Json(0, JsonRequestBehavior.AllowGet);
}
return Json(1, JsonRequestBehavior.AllowGet);
}
When the new option is added into the database I then need to refresh my dropdownlist to get this new data (currently if I refresh the page I can see the new option). I am using minimalect plugin for the drop downs.
Does anybody know a way of updating this minimalect list, there must be a way of building the list through an ajax call which returns some JSON data.
Thanks in advance for your help
OK so after doing a bit of research here is my solution, hopefully it will help other poeple. Someone might even have a cleaner solution.
I first created a jsonresult controller method which looked like this
[HttpGet]
public JsonResult RetreiveSuppliers(string contractType)
{
var supplierData = ContractModelEntity.system_supplier.Where(x => x.Type == contractType);
var result = new List<object>();
foreach (var x in supplierData)
{
result.Add(new { Id = x.CompanyID, Name = x.Name });
}
return Json(result, JsonRequestBehavior.AllowGet);
}
That got me the data from the database. then I created a javascript on the page which looks like this
$("body").on("click", "#btn_InsertNewSupplier", function () {
var supForm = $("#addSupData");
$.ajax({
url: "#Url.Action("AddLeaseSupplier", "Contract")",
data: supForm.serialize(),
type: "POST",
success: function (result) {
if (result === 0) {
var inst = $.remodal.lookup[$('[data-remodal-id=modal_AddSupplier]').data('remodal')];
inst.close();
NotificationAlert("success", "New Supplier Created");
GetNewSupplierList();
} else {
NotificationAlert("error", "Failed Adding New Supplier");
}
}
});
});
function GetNewSupplierList() {
var actionurl = "#Url.Action("RetreiveSuppliers", "Contract", new { contractType = "Lease"})";
$.getJSON(actionurl, tempdata);
}
function tempdata(response) {
if (response != null) {
var html = "";
for (var i = 0; i < response.length; i++) {
html += '<option value="' + response[i].Id + '">' + response[i].Name + '</option>';
}
$("#LeaseCompanyID").html(html);
}
}
So once the ajax call is successful it will trigger the GetNewSupplierList function which calls my controller method and returns some JSON data. Once that is returned it calls tempdata, which builds the new HTML for my select picker, once that is built it updates the html on the selectpicker id.
Works like a charm!!!
Thanks to everyone who took a look at this post.
I have this ajax call here in a script tag at the bottom of my page. Everything works fine! I can set a breakpoint inside the 'updatestatus' action method in my controller. My server gets posted too and the method gets called great! But when I put the javascript inside a js file the ajax call doesn't hit my server. All other code inside runs though, just not the ajax post call to the studentcontroller updatestatus method.
<script>
$(document).ready(function () {
console.log("ready!");
alert("entered student profile page");
});
var statusdropdown = document.getElementById("enumstatus");
statusdropdown.addEventListener("change", function (event) {
var id = "#Model.StudentId";
var url = '#Url.Action("UpdateStatus", "Student")';
var status = $(this).val();
$.post(url, { ID: id, Status: status }, function (data) {
// do something with the returned value e.g. display a message?
// for example - if(data) { // OK } else { // Oops }
});
var e = document.getElementById("enumstatus");
if (e.selectedIndex == 0) {
document.getElementById("statusbubble").style.backgroundColor = "#3fb34f";
} else {
document.getElementById("statusbubble").style.backgroundColor = "#b23f42";
}
}, false);
</script>
Now I put this at the bottom of my page now.
#section Scripts {
#Scripts.Render("~/bundles/studentprofile")
}
and inside my bundle.config file it looks like this
bundles.Add(new ScriptBundle("~/bundles/studentprofile").Include(
"~/Scripts/submitstatus.js"));
and submitstatus.js looks like this. I know it enters and runs this code because it I see the alert message and the background color changes. So the code is running. Its just not posting back to my server.
$(document).ready(function () {
console.log("ready!");
alert("submit status entered");
var statusdropdown = document.getElementById('enumstatus');
statusdropdown.addEventListener("change", function (event) {
var id = "#Model.StudentId";
var url = '#Url.Action("UpdateStatus", "Student")';
var status = $(this).val();
$.post(url, { ID: id, Status: status }, function (data) {
// do something with the returned value e.g. display a message?
// for example - if(data) { // OK } else { // Oops }
});
var e = document.getElementById('enumstatus');
if (e.selectedIndex == 0) {
document.getElementById("statusbubble").style.backgroundColor = "#3fb34f";
} else {
document.getElementById("statusbubble").style.backgroundColor = "#b23f42";
}
}, false);
});
In the console window I'm getting this error message.
POST https://localhost:44301/Student/#Url.Action(%22UpdateStatus%22,%20%22Student%22) 404 (Not Found)
Razor code is not parsed in external files so using var id = "#Model.StudentId"; in the main view will result in (say) var id = 236;, in the external script file it will result in var id = '#Model.StudentId'; (the value is not parsed)
You can either declare the variables in the main view
var id = "#Model.StudentId";
var url = '#Url.Action("UpdateStatus", "Student")';
and the external file will be able to access the values (remove the above 2 lines fro the external script file), or add them as data- attributes of the element, for example (I'm assuming enumstatus is a dropdownlist?)
#Html.DropDownListFor(m => m.enumStatus, yourSelectList, "Please select", new { data_id = Model.StudentId, data_url = Url.Action("UpdateStatus", "Student") })
which will render something like
<select id="enumStatus" name="enumStatus" data-id="236" data-url="/Student/UpdateStatus">
Then in the external file script you can access the values
var statusbubble = $('#statusbubble'); // cache this element
$('#enumStatus').change(function() {
var id = $(this).data('id');
var url = $(this).data('url');
var status = $(this).val();
$.post(url, { ID: id, Status: status }, function (data) {
....
});
// suggest you add/remove class names instead, but if you want inline styles then
if (status == someValue) { // the value of the first option?
statusbubble.css('backgroundColor', '#3fb34f');
} else {
statusbubble.css('backgroundColor', '#b23f42');
};
});
I am using JS to submit data without loading the page and it is working fine, on response i am trying to send JSON which looks like this
{"mes":"<div class=\"alert alert-success\">Your goal has been updated.<\/div>","graph_data":"[['07\/9\/2014',500],['07\/8\/2014',900],['07\/7\/2014',1200],['07\/6\/2014',500],['07\/5\/2014',500],['07\/4\/2014',500],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000]]"}
There are two items in the JSON response mes and graph_data. Now how can i make use of graph_data and mes seperately?
If I do this alert(data); this shows the above JSON response
But if I do the following I cant get them to alert seperately.
alert(data.graph_data);
alert(data.mes);
I will really appreciate if anyone can guide me on how to separate the two.
Update
This is the JS i am using to send and retrieve data on click of a button
$('#goalgraphdatasubmit').click(function () {
$('#goalgraphupdateform').submit();
});
$('#goalgraphupdateform').submit(function (e) {
"use strict";
e.preventDefault();
document.getElementById("goalgraphdatasubmit").innerHTML = "saving..";
var post = $('#goalgraphupdateform').serialize();
var action = $('#goalgraphupdateform').attr('action');
$("#holiday_goal_message").slideUp(350, function () {
$('#holiday_goal_message').hide();
$.post(action, post, function (data) {
$('#holiday_goal_message').html(data);
document.getElementById('holiday_goal_message').innerHTML = data;
$('#holiday_goal_message').slideDown('slow');
document.getElementById("goalgraphdatasubmit").innerHTML = "Submit";
alert(data);
if (data == '<div class="alert alert-success">Your goal has been updated.</div>') {
//$('#divGoal').load('dashboard-goals.php');
$("#holiday_goal_message").hide(2000);
updatetestGraph();
}
});
});
});
Use Like
var data = JSON.parse('{"event1":{"title":"My birthday","start":"12\/27\/2011 10:20 ","end":"12\/27\/2011 00:00 "},"event2":{"title":"My birthday again","start":"12\/27\/2011 10:20 ","end":"12\/27\/2011 00:00 "}}');
arr = []
for(var event in data){
var dataCopy = data[event]
for(key in dataCopy){
if(key == "start" || key == "end"){
// needs more specific method to manipulate date to your needs
dataCopy[key] = new Date(dataCopy[key])
}
}
arr.push(dataCopy)
}
alert( JSON.stringify(arr) )
Demo1
Demo2
Sorry cannot comment so have to answer
I have taken your JSON string in a variable here and it gives me proper result
See here
var d = {"mes":"<div class=\"alert alert-success\">Your goal has been updated. <\/div>","graph_data":"[['07\/9\/2014',500],['07\/8\/2014',900],['07\/7\/2014',1200],['07\/6\/2014',500],['07\/5\/2014',500],['07\/4\/2014',500],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000],['07\/11\/2014',2000]]"};
alert(d.graph_data);
alert(d.mes);