I am trying to disable view picker on account lookup in 2016.
The code works fine I mean I am not getting any error but the code not able to find the particular DIV of "parentaccountid".
Where as I can see it in Elements:
But it's returns {null} when the code try to get the elements of DIV - document.getElementByid("parentaccountid");
My code runs on load of opportunity page.
Even at this step I can see the particular DIV element- id: parentaccountid
Where as I still get {null} value:
Where as in 2013 I have seen it working pretty fine.
Sorry I don't have data to share here but it works fine.
Here is the code below:
function DisablePick()
{
VULoader();
//call this function from OnLoad handler
function VULoader(){
var myLookup1;
alert("Hello..I am Here");
var fetch = "<fetch mapping='logical'>"
+"<entity name='account'>"
+"<attribute name='name'/>"
+"<filter type='and'>"
+"<condition attribute='name' operator='eq' value='Blue Yonder Airlines (sample)' />"
+"</filter>"
+"</link-entity>"
+"</entity>"
+"</fetch>";
myLookup1 = new XrmLookupField("parentaccountid");
myLookup1.AddLockedView(
//sViewId
myLookup1.NewGuid() ,
//sEntityName
"account",
//sViewDisplayName
"My Locked Custom View",
//sFilterXml
fetch,
//sFilterLayout
layout(1, "name", "accountid")
.column("name", 200)
.toString()
);
}
function XrmLookupField(sId) {
var xlf = this;
//control instance
xlf.Ctl = Xrm.Page.getControl(sId);
//dom instance
xlf.Dom = document.getElementById(sId);
//jquery instance
xlf.$ = $(xlf.Dom);
/* 2013 addition --- Inline Control instance --- */
xlf.$i = $("#" + sId + "_i");
//use that to disable the view picker
xlf.DisableViewPicker = function () {
/* 2013 addition --- The attribute capitalization changed */
xlf.SetParameter("disableviewpicker", "1");
}
//use that to enable the view picker
xlf.EnableViewPicker = function () {
/* 2013 addition --- The attribute capitalization changed */
xlf.SetParameter("disableviewpicker", "0");
}
//set undocumented attributes
xlf.SetParameter = function (sName, vValue) {
xlf.$.attr(sName, vValue);
/* 2013 addition --- Also change the inline contorl value */
xlf.$i.attr(sName, vValue);
}
//add locked view
xlf.AddLockedView = function (sViewId, sEntityName, sViewDisplayName, sFilterXml, sFilterLayout) {
//first enable the view picker
xlf.EnableViewPicker();
//add the custom view (last parameter set the view as default)
xlf.Ctl.addCustomView(sViewId, sEntityName, sViewDisplayName, sFilterXml, sFilterLayout, true);
//lock the view picker
xlf.DisableViewPicker();
}
//create new guid
xlf.NewGuid = function () {
var d = new Date().getTime();
var guid = '{xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx}'.replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16);
});
return guid;
}
}
}
Few points to mention:
I am calling DisablePicker method on load of an opportunity page.
Yes, I have already checked whether any duplicate id is there or not but I didn't find any.
I tried to run this method on load of Account field as well but nope no response.
If I change the property disableviewpicker value from 0 to 1 in DIV itself manually from browser after page gets loaded & open the lookup then it will take the effect of the changed value.
Really I am getting no clue why it's behaving this manner, I just need to know where exactly I am going wrong or it's a product bug but I don't think it is. As its a very basic behavior.
PS: For my non MS CRM friends I cannot change the DIV or anything except my JavaScript code.
Your form code executes in a frame that is separate from the actual CRM form; it runs in the ClientApiWrapper.aspx page. Therefore, to access the form element you want to modify from your form script, you form code should do parent.document.getElementById instead of document.getElementById.
When you use your browser's dev tools, the default frame that the console executes against is also not the frame that has your form elements, and it's also not the frame that has your form's code. The simplest way to execute against the correct frame is to use the function in your dev tools to switch frames. In Firefox, that button looks like this:
It's easiest to set your frame to the ClientApiWrapper.aspx one, as it provides access to both the libraries loaded on your form as well as the CRM client-side API.
Related
I created an action using Action wizard in Acrobat Pro X.
A JavaScript is running when action started.
What this Javascript Do? suppose 100 page in opened pdf, this javascript extract all as seperate pages and rename it as user defined style.
e.g. Hello_001.pdf,Hello_002.pdf,Hello_003.pdf,Hello_004.pdf,... and so on,
i want a Custom Menu which target this action to execute.
It seems to me that you can find your answer in the link you gave. Important is that your script/function works correctly. So test it before in the js console. However here an example, where you can replace the script with yours. Regards, Reinhard
EDIT: (25.11.) Thought can use it by myself, but then I want to have it sortable. So I introduced leading zeros in the extract filename -> function changed.
//Save this in the ....\Acrobat\Javascripts\ program or user directory
// as whatever.js to load as Add-In
//-> create a submenu as first position under "Edit"
app.addSubMenu({ cName: "Specials", cParent: "Edit", nPos: 0 });
//-> now create a Menuitem for the function you will execute
app.addMenuItem({ cName: "Extract all Pages to file", cParent: "Specials", cExec: "extractAll()"});
//-> state your function (extract all Pages with leading zeros)
extractAll = app.trustedFunction(function (){
var re = /.*\/|\.pdf$/ig;
var filename = this.path.replace(re,"");
var lastPage = this.numPages;
var lz = Math.pow(10, (lastPage).toString().length); //calc full decimals (10,100,..)
app.beginPriv(); // Explicitly raise privilege
for ( var i = 0; i < lastPage; i++ ) {
var zPgNo = (lz + i+1).toString().slice(1); //calc actual, cut leading 1 = zerofilled PgNo
this.extractPages({
nStart: i,
nEnd: lastPage -1,
cPath : filename + "_page_" + zPgNo + ".pdf"
});
};
app.endPriv();
app.alert("Done!");
})
You can't trigger an Action to run from a menu item. However, you can create an application level JavaScript that contains a function that does what you want and then call that function from either an Acrobat Action or a custom Menu Item or both. The answer from ReFran shows how to add the custom menu item.
I have a div part in my HTML(erb), whose display is "none" at first. Then I change its style to "block" detecting the input values of datetimepicker.
I have succeeded to change the style, but the style reverses to "none" if the form gets flash error message shown after validation.
Is there any way to keep the style changed even after error message shows up.
Here is my code of javascript.
$('.datetimepicker').on('dp.change', function(e) {
var x = document.getElementById("from").value;
var y = document.getElementById("to").value;
var date_y = Date.parse(y);
var date_x_day = Date.parse(x) + (1 * 86400000);
if (date_y > date_x_day) {
$('#hotel').fadeIn(500);
} else {
$('#hotel').fadeOut(500);
}
});
I tried to put the line below after "$('#hotel').fadeIn(500); " but it doesn't work.
document.getElementById('hotel').style.display="block";
Could anyone tells me the best way??
So you want to show the hotels after selecting the date, but after the form submission the page will render with a date value and dp.change never get's triggered.
You can extract that anonymous function and call it right after the page renders.
function handleHotelVisibility(){
// method body;
}
$(function(){
handleHotelVisibility();
$('.datetimepicker').on('dp.change', handleHotelVisibility);
});
I am trying to achieve an effect like this on mobile (ios + android):
http://i.imgur.com/6zaTdRd.png
Where the currently selected textfield has a blue tinted icon + underlining
So my framework lacks any support for grey scaling a bitmap image of any sort so I need to swap between two images to achieve this effect.
My current implementation looks like this:
Please note this for the Titanium Alloy MVC framework but I'm guessing the basic logic should be similar.
I listen for blur/focus events to toggle current image
$.firstNameField.addEventListener('focus', function(e){
swapImages($.firstNameField.getParent());
});
$.lastNameField.addEventListener('focus', function(e){
swapImages($.lastNameField.getParent());
});
and then I swap images like so:
/**
* Swaps between the images (..._0 and ..._1) of an ImageView nested in a
TableRow
* ..._0 Greyscale image
* ..._0 Colour image
* #param e current TableViewRow
*/
function swapImages(e){
var imagePathSplit = (e.children[0].image).split('_');
var newImagePath = null;
if(imagePathSplit[1] == "0.png")
newImagePath = imagePathSplit[0] + "_1.png";
else
newImagePath = imagePathSplit[0] + "_0.png";
e.children[0].image = newImagePath;
return;
}
This doesn't look that great especially since I need a lot more fields with this functionality, I also want to implement tabbing (using Return key = NEXT) between the fields which will further balloon to increase 1 more event listener per field.
How would something like this be done ideally? I can think of one way of just creating the fields in code in array form which should help simplify matters (no more looking too far for Parent/Children, but that would still end up using quite a bit of listeners for switching right?
EDIT: Forgot to add how I have the textFields setup:
<TableView id="paypalTable">
<TableViewSection>
<TableViewRow id="firstNameView" class="tableRow">
<ImageView id="firstNameIcon" class="textFieldIcon"/>
<TextField id="firstNameField" class="textField"/>
</TableViewRow>
I tried something similar in one of my projects. Although I had an Alloy project I had to use a classic approach to get my desired behaviour.
In my controller:
var textFields = [];
var yourTextFieldsArray = [];
for (var i = 0; i < yourTextFieldsArray; i++) {
//Set the selected state to false initially. Maybe you need another command for it.
textFieldIsSelected[i] = false;
//create your new view
textFields[i] = Ti.UI.createView({
top : topValues[i],
width : Titanium.UI.FILL,
height : height,
id : i + 1,
touchEnabled : true
});
textFields[i].addEventListener('click', function(e) {
//Check the source id
if (e.source.id - 1 > -1) {
//use your function swapImages(e.source.id). Notice the slightly different parameter since you do not need the complete event.
swapImages(e.source.id);
}
}
function swapImages(id){
//Check the the path variable as you did
var imagePathSplit = (textFields[i-1].image).split('_');
var newImagePath = null;
if(imagePathSplit[1] == "0.png")
newImagePath = imagePathSplit[0] + "_1.png";
else
newImagePath = imagePathSplit[0] + "_0.png";
textFields[i-1].image = newImagePath;
}
This approach lets you use the same event listener for every property.
Please notice that my ids start at 1 and not at 0. This is because I had to implement such a behaviour for images and ImageViews do not accept id=0. My guess is that TextViews don't do it either so you should stick with it. Further notice that you need to decrement the id to get the corresponding object in the textFields Array. Otherwise you would get an out of bounds error.
You should create one more event listener for your NEXT event. Implement it in the same way as the first eventListener. Maybe the code is not perfect because I wrote it from my memory. If there are any questions left feel free to ask in the comments.
i have a subgrid on a custom entity form where i am showing related records for Case Entity. I want to restrict user to select only one record. How can i achieve this using javascript in crm 2011
Sometimes unsupported should be supported!!! Especially when one needs to go the whole distance to implement such trivial UI requests.
The Subgird has all these nice methods that you can use that for some reason Microsoft insist on not exposing as SDK. That’s silly.
I would also look for a javascript solution. Here is some pseudo code that can help you with the task. (not tested but it should put you on the right track)
The code creates a simple wrapper on the internal crm grid control and utilizes its methods.
function xGrid(sId) {
var o = this;
o.Dom = document.getElementById(sId);
if (!o.Dom)
return alret("this subgrid: " + sId + " is not on the form!");
o.Grid = o.Dom.contorl;
o.GetSelectedIds = function () {
return o.Grid && o.Grid.get_selectedIds();
}
o.AddOnSelectionChange = function (fCallback) {
o.Grid && o.Grid.add_onSelectionChange(fCallback);
return o;
}
}
You can create the xGrid when the page loads i.e.
function OnCrmPageLoad() {
window.MyGrid = new xGrid("SubGrid_Test");
MyGrid.AddOnSelectionChange(SubGridTestChanged);
}
And call the function bellow then the selection changes
function SubGridTestChanged() {
if (MyGrid.GetSelectedIds().length > 1)
alert("You’re only allowed to pick 1 record at a time");
}
A supported way to implement this check is to create a synchrnous plugin on the associate/disassociate message that will check if more than one record is associated and throw and exception, in order to display a warning to the user to select only one record.
I recently installed Tridion 2011 SP1 with SDL module Translation Manager enabled.
Everything was working fine. Then I installed the Tridion 2011 Powertools, following the installation procedure.
When trying to reload the GUI (browser cache emptied and modification parameter instanciated for server element in WebRoot\Configuration\System.Config) I'm getting the following Javascript error :
SCRIPT5007: Unable to get value of the property 'getItemType': object is null or undefined
Dashboard_v6.1.0.55920.18_.aspx?mode=js, line 528 character 851
And here is the concerned JS line:
Tridion.TranslationManager.Commands.Save.prototype._isAvailable=function(c,a){var
e=c.getItem(0),f=$models.getItem(e),b=f.getItemType(),d=$models.getItem(this.getTmUri ())
The preceding Javascript lines are dealing with other TranslationManager commands, so I suppose it is a kind of TranslationManager commands registration or somehting.
Trying to browse my Tridion publications by selecting any folder/strucutreGroup will also give the same error and the right frame (content frame) will not display any Tridion items but simply display:
Loading ...
Has anyone already experienced similar issue ?
For now I have no other choice than commenting out the Powertools sections file
Tridion_Home\web\WebUI\WebRoot\Configuration\System.Config
Thank you,
François
Strange thing here is that it refers to Save command which is not intended to be called or used from Dashboard.
I`d suggest to disable JS minification (JScriptMinifier filter in System.config), as it will probably show more correct details.
Another useful thing would be this error call stack.
--
I was not able to reproduce an issue from initial question, but had following error when I installed PT:
PowerTools is not defined
which appears in
*\PowerTools\Editor\PowerTools\Client\Shared\Scripts\ProgressDialog\ProgressDialog.js where it tries to register PowerToolsBase namespace, instead of PowerTools.
I`ll be surprised if adding
Type.registerNamespace("PowerTools");
at the top of the file will fix a problem, as in my case it was breaking entire GUI no matter if TM included or no.
I did check *\PowerTools\Editor\PowerTools\Client\Shared\Scripts\ProgressDialog\ProgressDialog.js, but the line
Type.registerNamespace("PowerTools");
was already there, so not the problem here.
Also, I disabled the JS minification. Here are the main methods the UI is loading before getting the error:
...
PowerTools.Commands.ItemCommenting.prototype.isValidSelection = function (selection) {
//Use the existing Save command from the CME
return $cme.getCommand("Save")._isEnabled(selection);
}
...
/**
* Executes this command on the selection.
* Override this method to implement the actual functionality.
* #param {Tridion.Core.Selection} selection The current selection.
*/
Tridion.TranslationManager.Commands.SendForTranslation.prototype._execute = function SendForTranslation$_execute(selection)
{
var selectedItems = selection.getItems();
if (selectedItems.length == 1)
{
var job = $models.getItem(selectedItems[0]);
if (job)
{
if (job.isLoaded())
{
job.saveAndSend();
}
else
{
$log.warn("Unable to send an unloaded job?! {0}".format(job.getId()));
}
}
else
{
$log.warn("Unable to execute save-and-send-for-translation for this selection: {0}".format(selectedItems));
}
}
else
{
$log.warn("Unable to save-and-send-for-translation multiple items at a time.");
}
};
...
Tridion.TranslationManager.Commands.Save.prototype._isAvailable = function Save$_isAvailable(selection, pipeline)
{
var itemUri = selection.getItem(0);
var item = $models.getItem(itemUri);
var itemType = item.getItemType(); !!!!!!!!! fails on this line !!!!!! item is null or not an object
var config = $models.getItem(this.getTmUri());
if (pipeline)
{
pipeline.stop = false;
}
if (config && config.hasChanged() && (itemType == $const.ItemType.CATEGORY || itemType == $const.ItemType.FOLDER || itemType == $const.ItemType.STRUCTURE_GROUP || itemType == $const.ItemType.PUBLICATION))
{
if (pipeline)
{
pipeline.stop = true;
}
return true;
}
return this.callBase("Tridion.Cme.Command", "_isAvailable", [selection, pipeline]);
};
Ok. It`s clear now.
PowerTools.Commands.ItemCommenting is used in Dashboard Toolbar.
This command uses Save to check its availability.
In the same time TM thinks that "Save" will only be used on an ItemToolbar.
The difference between this toolbars which cause an issue is that Dashboard view could have any-length selection, when Item view will always have selection having one item (currently opened).
Opening empty dashboard selection is not yet made, ItemCommenting tries to check its availability, by calling Save, which calls all its extensions. And so far as selection is empty
var itemUri = selection.getItem(0);
will return null, as well as
$models.getItem(null)
What you can do, is to remove ItemCommenting extension command as it is done in tridion powertool trunk editor.config.
http://code.google.com/p/tridion-2011-power-tools/source/browse/trunk/PowerTools.Editor/Configuration/editor.config?spec=svn942&r=903 [592]