Sitefinity get current dynamiccontent item from code - api

I'm currently writing a site using Sitefinity CMS. Can someone please explain how to get the current dynamic content item from server side code on page_load?
I have written a user control to display a custom gallery of sliding images. There are multiple content types in my dynamic module. The user control will sit as part of the masterpage template rather than on every page. On each page load I would like to fetch the current dynamiccontent item that is associated with the page and examine whether it has a property with the name 'Gallery'. If so I would then extract the images and render them via the usercontrol.
Thanks,
Brian.

I'm assuming your images are related content. This gets every published content item of your type.
var dynamicModuleManager = DynamicModuleManager.GetManager();
var moduleType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.YOURTYPEHERE");
var dcItems = dynamicModuleManager.GetDataItems(moduleType)
.Where(l => l.Status == ContentLifecycleStatus.Master);
foreach (var dcItem in dcItems)
{
//pass the dynamic content item to a model constructor or populate here, then
// get your image this way:
var image = dcItem.GetRelatedItems<Image>("Images").SingleOrDefault();
if (image != null)
{
ImageUrl = image.MediaUrl;
}
}

Related

how to access elements not read by FlaUI using UIA2 or UIA3?

How to access/Find elements not read by FLAUI using UIA2 or UIA3?
since FLAUIInspect does not show up any of the available element under the window (while inspect.exe shows all available elements) FindAll (Children/Descendants) will not give any element.
is there a wat to get these elements using FLAUI??
First, you have to access the element you need to see. On your case, the ""pane it's a Control Type Panel inside the main window, so you gonna have to do something like this:
var automation = new UIA3Automation();
var app = FlaUI.Core.Application.Attach(application.Process.Id); //Here you can attach or start a application by path
var window = app.GetMainWindow(automation); //Get hold of the window
var allObj = window.FindAllChildren();
var panel = allObj.Where(x => x.AutomationId == "16386096").FirstOrDefault().FindAllChildren(); //Here you can use other property unique to the panel, I used the AutomationId for example
After you get hold of the panel, you can now find all the children objects.emphasized text
You need to expose the AutomationPeer for that element which is not being found by FlaUI

Remove "MIME type" column from Filent Content List

I am Using a Script Adapter by passing payload to get contend for a Content List from "Search with values" event
When Contend get loaded to content list , i have a custom view to preview them. But if i clicked on MIME type column , It opens a separate view with the mapped viewer
So I need to remove this column or make it un-clickable
1) I am passing search values to content list's "Search with values" event , from where can i handle Content List's contend loading ,any Dojo Event i can use ?
2) With Script Adapter can i do this without going for a "response filter"
Edit :
As Nicely explained by "Ivo Jonker" (in his answer - "or try to specifically locate the widgets on your page" and with his example code)
responsed = page.ContentList8.ecmContentList.getResultSet();
var cols = responsed.structure.cells[0];
for (i=cols.length-1; i>0; i--){
var col = cols[i];
if (col.field=="mimeTypeIcon")
cols.splice(i,1);
}
page.ContentList78.ecmContentList.setResultSet(responsed);
I simply remove this row. Thanks Again and lovely blog , hope you keep posting more great articles.
The values passed through the Search With Values event will eventually be handled by the icm.pgwidget.contentlist.dijit.DocumentSearchHandler
that in turn creates a SearchTemplate to execute the search (ecm.model.SearchTemplate.prototype.search). One option would be to aspect/before/around the DocumentSearchHandler#query to manipulat the searchresults and by that way to remove the column.
The wiring however does not provide any handles to achieve this for a specific query-resultset combination leaving you to either fix this on a global scale (icm.pgwidget.contentlist.dijit.DocumentSearchHandler.prototype#query), or try to specifically locate the widgets on your page.
Personally, taking into account #2, i'd go for the responsefilter-option if you feel the global solution wouldn't be a problem, or alternatively i'd personally prefer to create a simple ICM widget that instantiates/implements a "plain" ecm.widget.listView.ContentList and exposes a wire to set the ecm.model.Resultset.
You'd then be able to create your own Searchquery in a scriptadapter, remove the column, and pass the resultset.
The script adapter could be something like:
var scriptadapter=this;
var queryParams={};
queryParams.query = "SELECT * FROM Document where id in /*your list*/";
queryParams.retrieveAllVersions = false;
queryParams.retrieveLatestVersion = true;
queryParams.repository = ecm.model.desktop.repositories[0];
queryParams.resultsDisplay = {
"sortBy": "{NAME}",
"sortAsc": true,
"columns": ["{NAME}"],
"honorNameProperty": true};
var searchQuery = new ecm.model.SearchQuery(queryParams);
searchQuery.search(function(response/*ecm.model.Resultset*/){
//remove the mimeTypeIcon
var cols = response.structure.cells[0];
for (i=cols.length-1; i>0; i--){
var col = cols[i];
if (col.field=="mimeTypeIcon")
cols.splice(i,1);
}
//emit the resultset to your new contentlist, be sure to block the regular synchrounous output of the scriptadapter
scriptadapter.onPublishEvent("icm.SendEventPayload",response);
//The contentlist wire would simply do contentlist.setResultSet(response);
});

Get SelectedItem in Dropdownlist without FormMethod.Post

I have a dropdownlist that is bound to a list in my model. Model.list_IDs
The current page is an "editing" page where a user would inherently change a property of the model by using the dropdownlist.
#Html.DropDownListFor(model => Model.ID, Model.list_IDs, new { style = "width:250px" })
The items within the dropdownlist are not intuitive, so I would like to provide a button, that when clicked, retrieves additional information via a stored procedure (called from the controller via a method called GetDetails)
The button is created through an action link, and I plan to display a partial view (like a focused pop up window) that shows the additional information once the button is clicked.
#Html.ActionLink(" ", "GetDetails", new { id = Model.ID.ToString() }, new { #class = "lnkMagnify16", title = "View Details" })
Obviously Model.ID.ToString() is incorrect, because it will only send the model's current ID, rather than the ID currently selected in the dropdownlist.
How can I change Model.ID.ToString() to represent the dropdownlist's current selected item?
I know there is a way to do this using FormMethod.Post (Get selected item in DropDownList ASP.NET MVC) but I do not want to reload the page with a submit button. I'd also like to avoid "third party" approaches like JavaScript if possible.
JavaScript is not a "third party" approach, and it's also the only way to accomplish what you want here. Whether by a standard form post or via AJAX (JavaScript), you must make a new request to the server to get the new information you want.
Now, since all you're specifically after is a way to dynamically update the the Model.ID value in the link, you can do that without AJAX or a form post, but you still must use JavaScript, since all dynamic behavior client-side originates from JavaScript. Basically, you'd need to bind to the change event of the dropdown and alter the href property of your link.
document.getElementById('ID').addEventListener('change', function () {
var selectedId = this.options[this.selectedIndex].value;
document.getElementById('AwesomeLink').href = // alter `href` with `selectedId`
});
However, that link is still going to change the whole view if the user clicks it. If you truly want the user to stay on the page, then you'll need to fetch the response of that link using AJAX and then either add it to the page somehow, whether that be directly or via a modal popup (which will required yet even further JavaScript to achieve). Also, it's not clear how the Model.ID value ends up in the URL, i.e. whether it's part of the path (/some/url/{id}/) or as a query string param (/some/url/?id={id}). If it's the former, I'd recommend switching to the latter, as it will make it much easier to build your URL client-side.
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", function (response) {
// add response.responseText to the DOM
});
xhr.open("GET", "/some/url/?id=" + selectedId);
xhr.send();

Bootstrap 3 Multiple Accordions on one page must assign data-parent values after the fact

Due to some restrictions with a CMS I am developing for I cannot create the intended markup for a proper accordion with Bootstrap 3 on page load, however I can get it very close.
The issue I am having is that the initial
panel group id (accordion1), I cannot assign the proper data-parent="accordion1" to the data-toggle="collapse" element in the panel. I am attempting to rewrite the data-parent references to the proper accordion ID but it does not have an affect, it is like the collapse binding is already in place and I'm not sure how to get around it.
This is an example of my issue. (id's are the same on page load but I try to rewrite them with a script on dom-ready)
$(document).ready(function() {
$('.panel-group').each(function() {
var $t = $(this);
var id = "#" + $t.attr("id");
$t.find('[data-parent]').attr("data-parent", id);
});
});
This function fixes the markup as BS3 wants but the functionality is still broken.
http://plnkr.co/CTBekXVyzU0xjzlud2N1
I ended up figuring out that the error was my own. Multiple accordions is not an issue. Where I went wrong was in the markup. The error in my ways weas that the data-toggle="collapse" element's href="#collapse-0" for example was duplicated for both accordions. They must be unique. The CMS restriction still existed on the data-parent however. This caused me to redo my script (which does work now for multiple accordions)
$('.panel-group').each(function(){
//setup each panel group with individual id's appropriately
var $t = $(this);
var id = "#" + $t.attr('id');
var randomInt = $t.attr('id').split('_')[1]; //extract
$t.find('.panel').each(function(){
//set the proper collapsable targets for each
var $t = $(this);
var $dataParent = $t.find('[data-parent]');
var href = $dataParent.attr('href');
//set the collapse target
var $targetId = $dataParent.attr('href', injectRandom(href, randomInt));
var targetId = $targetId.attr('href').split('#')[1];
//set the random id's
$dataParent.attr('data-parent', id);
//set the collapse container
$dataParent.parents('.panel-heading:first').next().attr('id', targetId);
});
//open first pane
$t.find('[data-toggle]:first').trigger('click');
});
I will update the plunkr

how to open multiple windows from the controller in asp.net MVC

How to open multiple windows from the controller?
For example, I have a controller that gets all the clients and for each client I want that his info is displayed in a different window or tab.
Is that possible using asp.net MVC 4?
I've done this exact thing, it was based on a button click which would fire multiple windows based on the parameters. Here's what you could do. Your controller would be like this...
[HttpPost]
public ActionResult CopyOpportunitySave(CopyOpportunityViewModel model)
{
ViewModel model = new ViewModel();
foreach (var url in "List object that contains URLS")
{
model.ClientURLs.Add(url);
}
return View("CopyOpportunity", model);
}
So now your Model class will have a property like
public List<string> ClientURLs{get; set;}
which is populated by all the URLs you will need to do a window.Open.
and Now in your view you can say
#foreach (var u in ViewModel.ClientURLs)
{
<script>
window.open(u);
</script>
}
just as long as the script inside the foreach loop is getting executed, it will work
This won't be possible by just using native MVC 4. However, one could think of some work-arounds which might resemble your requirements. For starters, is it necessary to actually open a 'browser tab' per client, or could this also be a tab page per client in one single HTML-document. If the latter is an option, you could take a look at different 'tab' controls being available in HTML.
If your really want a new browser window per client, my hint would be to return the list of possible clients to one HTML page and then use scripting in that HTML page to open a popup window for each client. For each popup / client an additional request needs to be send to the server.
Just make the link (<a></a>) that opens the client information have a target = "_blank":
John Smith
If you are using Html helpers it could be like this:
#Html.ActionLink("John Smith", "Details", "Clients", new {id = 1}, new { target = "_blank"})
This will open a new browser tab with the page you need.