Error in Dynamics CRM Custom form Event Javascript - javascript

I am trying to make a button on a form in Dynamics CRM, so that onClick the button show a dialog. The JS code I am using is as follows:
function addButton(attributename) {
if (document.getElementById(attributename) != null) {
var sFieldID = "field" + attributename;
var elementID = document.getElementById(attributename + "_d");
var div = document.createElement("div");
div.style.width = "19%";
div.style.textAlign = "right";
div.style.display = "inline";
elementID.appendChild(div, elementID);
div.innerHTML = '<button id="' + sFieldID + '" type="button" style="margin-left: 4px; width: 100%;" ><img src="/_imgs/ico_16_4210.gif" border="0" alt="Dial this number"/></button>';
document.getElementById(attributename).style.width = "80%";
document.getElementById(sFieldID).onclick = function () {onbuttonclick(); };
}
}
function onbuttonclick() { alert('Hi');}
This function is written in a JS Web Resource which gets triggered with form onload event of contact entity. Whenever the form load event is triggered I get the following error in a dialog box:
There was an error with this field's customized event.
Field:window
Event:onload
Error:undefined
kindly guide me towards the resolution.
The code is taken from a sample example.

This simply means that you have an error somewhere in your JavaScript.
A much better solution would be to use a ribbon button, and have that ribbon button call javascript, instead of messing with the DOM (which is unsupported). drop the following code into your ribbondiffxml:
<Actions>
<JavaScriptFunction Library="$[js library name]" FunctionName="[js function name]" />
</Actions>
Specifically, this should go into the CommandDefinitionNode.
Here is an example of what I do to open a dialog via javascript:
Ribbon.openDialogProcess = function (dialogId, EntityName, objectId) {
var url = Xrm.Page.context.getClientUrl() +
"/cs/dialog/rundialog.aspx?DialogId=" +
dialogId + "&EntityName=" +
EntityName + "&ObjectId=" +
objectId;
var width = 400;
var height = 400;
var left = (screen.width - width) / 2;
var top = (screen.height - height) / 2;
window.open(url, '', 'location=0,menubar=1,resizable=0,width=' + width + ',height=' + height + ',top=' + top + ',left=' + left + '');
}
so simply call that method in the RibbonDiffXML.

Related

What's causing Intersection Observer API to respond differently when replacing synchronous logic with asynchronous logic?

Context
I've used the "Intersection Observer API" to build an infinite scroll image gallery. Basically this API allows me to load more items when a certain dummy DOM element enters the viewport.
Prototype
Currently the prototype is implemented for an “iPhone X” (375x812) mobile device only. See: http://urbexco-acceptance.droppages.com/min_rep_ex_working (use Chrome DevTools 'inspect' device toolbar to select the right resolution). The image gallery is generated based on 57 items in the "database". When scrolling down, first 15 elements are loaded, then 15 more elements are loaded, then another 15 elements are loaded into the DOM, then another 10 elements are loaded, and finally 2 elements are loaded. When there are still more than 15 items left to be loaded, they are added using the following logic:
function addItems(n){
// Append new items to .items-wrapper
var items = document.querySelector('.items-wrapper');
for (var i = 0; i < n; i++) {
var url = 'https://img01.ztat.net/article/spp-media-p1/09742e38c25b3e1d9716e02f8e76e87d/89fc0bda6a2c446a8e9e0d8adbc9a4fe.jpg';
width = 170.5;
height = 246;
var newDiv = document.createElement('div');
newDiv.classList.add('item');
items.appendChild(newDiv);
newDiv.innerHTML = "<img src=" + '"' + url + '"' + "width=" + '"' + width + '"' + "height=" + height + "/>";
}
}
Minimal Working Example (no mobile view possible)
https://jsfiddle.net/9jqgzymo/
Objective
Since image width and height are currently hardcoded, I am now trying to assign width and height dynamically based on the image url. I try to achieve this using the getMeta() function:
function addItems(n){
// Append new items to .items-wrapper
var items = document.querySelector('.items-wrapper');
for (var i = 0; i < n; i++) {
var url = 'https://img01.ztat.net/article/spp-media-p1/09742e38c25b3e1d9716e02f8e76e87d/89fc0bda6a2c446a8e9e0d8adbc9a4fe.jpg';
getMeta(url);
}
}
function getMeta(url){
var img = new Image();
img.onload = function(){
res = calculateAspectRatioFit(this.width, this.height, 170.5, 246)
var newDiv = document.createElement('div');
newDiv.classList.add('item');
var items = document.querySelector('.items-wrapper');
items.appendChild(newDiv);
newDiv.innerHTML = "<img src=" + '"' + url + '"' + "width=" + '"' + res.width + '"' + "height=" + res.height + "/>";
};
img.src = url;
}
function calculateAspectRatioFit(srcWidth, srcHeight, maxWidth, maxHeight) {
var ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight);
return { width: srcWidth*ratio, height: srcHeight*ratio };
}
Challenge
When implementing it this way, I see that - on initiation - already 30 items from the "database" where added to the DOM. Sometimes even all of them? Currently the non-working prototype is implemented for an “iPhone X” (375x812) mobile device only. See: http://urbexco-acceptance.droppages.com/min_rep_ex_not_working (use Chrome DevTools 'inspect' device toolbar to select the right resolution). For a minimal working example, see: https://jsfiddle.net/k3p20qno/
Key question
What is the reason that with my new implementation, on initiation, already 30 or more items are added to the DOM? How can I fix it?
Well the problem lies in here :
function getMeta(url){
var img = new Image();
img.onload = function(){
res = calculateAspectRatioFit(this.width, this.height, 170.5, 246)
var newDiv = document.createElement('div');
newDiv.classList.add('item');
var items = document.querySelector('.items-wrapper');
items.appendChild(newDiv);
newDiv.innerHTML = "<img src=" + '"' + url + '"' + "width=" + '"' + res.width + '"' + "height=" + res.height + "/>";
};
img.src = url;
}
Above code does an async operation with onload event. So it doesn't wait to image to be loaded.
If you turn this into a function that returns a promise you will get the result that you expect. And you should await where you call the function. That way when you add the intersection element it will add it as the last element of the items wrapper. If you don't await it will be added as the first element because the loading of the images will be async and will happen later.
function getMeta(url){
var img = new Image();
const p = new Promise(resolve =>{
img.onload = function(){
console.log( this.width+' '+ this.height );
res = calculateAspectRatioFit(this.width, this.height, 170.5, 246)
var newDiv = document.createElement('div');
newDiv.classList.add('item');
var items = document.querySelector('.items-wrapper');
items.appendChild(newDiv);
newDiv.innerHTML = "<img src=" + '"' + url + '"' + "width=" + '"' + res.width + '"' + "height=" + res.height + "/>";
resolve()
};
})
img.src = url;
return p;
}
Fiddle
Edit: Put the resolve() in the right position which is inside the load function

Materialize modal dynamically

I want to create modal in materialize dynamically.
this is my javascript code:
$(document).ready(function(){
var modalContainer = $('<div id="modal_id" class="modal"></div>');
var modalContent = $('<div class="modal-content"><p>my content</p></div>');
modalContainer.append(modalContent);
modalContainer.modal(); // or modalContainer.modal('open');
});
and this is my trigger button:
<a class="waves-effect waves-light btn modal-trigger" href="#modal_id">Show Modal</a>
but, this is not working. when i click to Show Modal anchor, show me the wrapper of modal and do not show modal box.
please help me. thanks.
You can do it with this simple approach. Create and an empty div with .modal class and whatever the id you want to assign.
Then in jQuery, create a variable and save a div with class modal-content. In that div specify your message or content, you want to add dynamically. After that, append that variable to modal using $(.modal).append() and open your modal using .modal()
Take a look at Example
I've created a jsfiddle take a look at it.
Demo - jsFiddle
Example
HTML
<a class="waves-effect waves-light btn modal-trigger" href="#modal1">Modal</a>
<div id="modal1" class="modal"></div>
jQuery
$(document).ready(function(){
// Here specify your content or message, enclose between <p>
var content = '<div class="modal-content"><p>my content</p></div>';
$('.modal').append(content);
$('.modal').modal();
});
You can open the modal on 1.0.0 using pure javascript like this
const elem = document.getElementById('modalId here');
const instance = M.Modal.init(elem, {dismissible: false});
instance.open();
I wrote a small class to create modals dynamically. Note that setting the height and width is a bit buggy, I don't really know why. I only need fixed-footer modals in my application, but that class could easily be set dynamically to fit your needs. Anyways, I hope it helps:
class Modal {
constructor(opt) {
this.name = opt.name;
this.width = opt.width || '';
this.height = opt.height || '';
this.topMargin = opt.height ? Math.floor((100 - this.height) / 2) : '';
this.style = (opt.width && opt.height) ? 'width: ' + this.width + '%; height: ' + this.height + 'vh; top: ' + this.topMargin + 'vh;' : opt.width ? 'width: ' + this.width + '%;' : opt.height ? 'height: ' + this.height + 'vh; top: ' + this.topMargin + 'vh' : '';
this.footerButtons = opt.footerButtons || '';
this.openButton = opt.openButton || null;
this.title = opt.title || '';
this.onOpen = opt.onOpen;
this.fixedContent = opt.fixedContent || '';
this.template = '<div id="' + this.name + '" class="modal modal-fixed-footer" style="' + this.style + '"><div class="modal-content" style="padding-top: 17px;"><h4>' + this.title + '</h4><div class="divider"></div><br>' + this.fixedContent + '<div class="modal-content-dynamic"></div></div><div class="modal-footer">' + this.footerButtons + '</div></div>';
$('.container').append(this.template);
var self = this;
if (this.openButton) {
$(document).on('click', this.openButton, function () {
self.open();
});
}
}
open() {
$('#' + this.name).openModal({
dismissable: false,
preventScrolling: false
});
if (this.onOpen) this.onOpen(this);
}
close() {
$('#' + this.name).closeModal();
}
setContent(content) {
$('#' + this.name).find('.modal-content-dynamic').html(content);
}
addContent(content) {
$('#' + this.name).find('.modal-content-dynamic').append(content);
}
setTitle(title) {
$('#' + this.name).find('.modal-content h4').html(title);
}
setFooterButtons(buttons) {
$('#' + this.name).find('.modal-footer').html(buttons);
}
}
And then use it like this:
var testModal = new Modal({
name: 'testModal',
openButton: '#open_testModal',
title: '<b>TestModal</b>',
fixedContent: '<p>Some static content</p>',
onOpen: function (modal) {
// do something every time the modal is opened
}
});

Find the last element that has appeared DOM html

I have a code that puts images on a table(html), and I want to focus on the image that has just appeared.
I know that i have to use $(this) but i don't know how, here is my code
function positioning(year, mon) {
$('#' + year + ' .' + mon).prepend('<img class="black_point" src="./images/circle.png"/>');//that adds the image
var table = document.getElementById("table");
var images = table.getElementsByTagName("img");
//here I need the current image I had just add to send to that function
function connect(images) {
var tabBcr = table.getBoundingClientRect();
var imgBcr = image.getBoundingClientRect();
x = imgBcr.left + (imgBcr.width / 2) - tabBcr.left;
y = imgBcr.top + (imgBcr.height / 2) - tabBcr.top;
}
}
I hope I have explained well .
I think it will work, add this where you want to get that img element:
var imgelem=$('#' + year + ' .' + mon).find("img:first");

How to retrieve function input javascript

I've got the following code that produces a dynamically created image button and panel in asp.net: -
Panel panBlocks = new Panel();
panBlocks.ID = "PanBlockQuestionID" + recordcount.ToString();
panBlocks.Width = 1300;
panBlocks.Height = 50;
panBlocks.BackColor = Color.Pink;
ImageButton cmdBlocks = new ImageButton();
cmdBlocks.ImageUrl = "~/Images/block3.png";
cmdBlocks.ID = "lblImg" + recordcount.ToString();
cmdBlocks.Attributes["class"] = "liQuestionsLabel2";
cmdBlocks.Width = 30;
cmdBlocks.Attributes.Add("OnMouseOver", "showPanel(" + "CPH_Body_" + panBlocks.ClientID.ToString() + ")");
cmdBlocks.Attributes.Add("OnMouseOut", "hidePanel();");
li.Controls.Add(cmdBlocks);
li.Controls.Add(panBlocks);
When I hover over the image I want it to display a particular panel. I've added the "CPH_Body_" + panBlocks.ClientID.ToString() as an attribute.
I've got the following javascript code:
function showPanel(PanelID)
{
document.getElementById("CPH_Body_liQuestions1").style.height = "40px";
}
How do I retrieve the PanelID in the javascript please as it looks like an array. I need to retrieve this so I know which panel to display please.
IIUC (!!):
Change this :
cmdBlocks.Attributes.Add("OnMouseOver", "showPanel(" + "CPH_Body_" + panBlocks.ClientID.ToString() + ")");
To:
cmdBlocks.Attributes.Add("OnMouseOver", "showPanel('" + panBlocks.ClientID.ToString() + "')");
And change this :
function showPanel(PanelID)
{
document.getElementById("CPH_Body_liQuestions1").style.height = "40px";
}
To
function showPanel(PanelID)
{
document.getElementById(PanelID).style.height = "40px";
}

open window on click of button as modal dialog using javascript

I have to open a window when a button is clicked, as a modal dialog using JavaScript.
I have used window.open, but it shows me two instances, the parent page and the pop-up page.
When the pop-up page is open, then do not allow the user to click on the parent page.
function openWindow() {
var w = 950;
var h = 350;
var t = 0;
var l = 0;
var scrollbars = 1;
var modal = 'yes';
var reportWindow = window.open("Search.aspx" + '', '', "width=" + w + ",height=" + h + ",left=" + l + ",top=" + t + ',scrollbars=' + scrollbars + 'modal' + modal);
reportWindow.focus();
}
Your code line,
reportWindow = window.open("Search.aspx" + '', '', "width=" + w + ",height=" + h + ",left=" + l + ",top=" + t + ',scrollbars=' + scrollbars + 'modal' + modal);
is missing an '=' symbol after modal. It should be,
reportWindow = window.open("Search.aspx" + '', '', "width=" + w + ",height=" + h + ",left=" + l + ",top=" + t + ',scrollbars=' + scrollbars + 'modal=' + modal);
To open window as dialog box,
<html>
<body>
<script language="JavaScript">
function openWindow() {
if (window.showModalDialog) {
window.showModalDialog("http://example.com","name",
"dialogWidth:255px;dialogHeight:250px");
} else {
window.open('http://example.com','name',
'height=255,width=250,toolbar=no,directories=no,status=no, linemenubar=no,scrollbars=no,resizable=no ,modal=yes');
}
}
</script>
<button onclick="openWindow();">Open window</button>
</body>
</html>
If the above code is not working, please use jQuery modal dialog. You can load any urls to dialog using an iframe.
"window.open" will not work. This command always just opens a popup wich is not "always" on top of its parent.
2 Options:
If you just want to let the user enter a search string you could use
prompt("Please enter a search string:", "");
If you have a complexe search form, you have to create a modal dialog for your own.
There are frameworks which provide this functionality (google for "jQuery") or you create it for your own. Should not be hard, tell me if you need some help!

Categories

Resources