I have a jQuery function which monitors the 'beforeunload' status.
So therefore every time i do a refresh this method is executed.
The function is as follows:
<script type="text/javascript">
var bIsSafeRedirect = false;
$('#reload').click(function()
{
bIsSafeRedirect = true;
location.reload();
});
$(window).bind('beforeunload', function()
{
if (!bIsSafeRedirect )
{
return '>>>>>Before You Go<<<<<<<< \n Your custom message go here';
}
});
</script>
Now i have other components such as
<td onClick="window.location.replace('try.html')" id="reload" target="Content">
which onclick reloads the same page.
I this scenario where the table data is clicked i dont want the jQuery function to be invoked.I want it to be skipped as a special case.
How can i achieve it.
The entire code is shown below
<html>
<head>
<title>Refresh a page in jQuery</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript">
function load()
{
document.getElementById("first").value="hello";
}
</script>
</head>
<body>
<h1>Stop a page from exit with jQuery</h1>
<button id="reload">Refresh a Page in jQuery</button>
<script type="text/javascript">
var bIsSafeRedirect = false;
function unload(type, url){
if(type === 'noReturn'){
$(window).unbind("beforeunload");
window.location.replace(url);
} else if(!bIsSafeRedirect && type === 'return') {
var conf = confirm('do you want to quit');
if(conf){
alert("ajax");
} else {
return false;
}
}
}
$(window).bind("beforeunload", function(){
unload('return');
});
</script>
<table>
<tr>
<td onClick="window.location.replace('try.html')" id="reload" target="Content">
<td onClick="unload('noReturn','try.html')">
Usual Refresh
</td>
</tr>
</table>
<input type="text" id="first" size="15"/>
<input type="button" onclick="load()" value="load"/>
</body>
</html>
Try this:
<td onClick="replaceContent();" id="reload" target="Content">
Here is the replaceContent() function:
function replaceContent(){
$(window).unbind('beforeunload');
window.location.replace('try.html');
}
one way is to prepend this to onClick:
$(window).unbind('beforenload');
the other way is to use a global flag, exactly like the bIsSafeRedirect you're currently using. Change the beforeunload handler body like this:
if (shouldRefresh && !bIsSafeRedirect)
{
return '>>>>>Before You Go<<<<<<<< \n Your custom message go here';
}
and set shouldRefresh value to false in onClick.
Make a function that handles both of these:
function unload(type, url){
if(type === 'noReturn'){
$(window).unbind("beforeunload");
window.location.replace(url);
} else if(!bIsSafeRedirect && type === 'return') {
var conf = confirm('Confirmation message');
if(conf){
// fire ajax call here
} else {
return false;
}
}
}
And then fire this function in your bind() call:
$(window).bind("beforeunload", function(){
unload('return');
});
Since we supply the return string to the type parameter, it fires the else if part of the if statement, which doesn't unbind the beforeunload event and so returns that string.
And for your other components:
<td onClick="unload('noReturn','try.html')"></td>
So now, since we have supplied the noReturn string to the type parameter, the first part of the if statement will execute and load the page without the interference of the beforeunload handler by unbinding it.
With this method, you can use the unload function on multiple elements' inline onclick handlers and make it a more globally usable script.
Related
I have requirement on Dynamics crm 2015 online:
I have a lookup and subgrid on a custom entity.
When the user clicks on the 'search' button, which shows search box, I want that search to be pre-populated with the lookup field value, so to save the user from copy/pasting or typing the lookup value into the search box.
What I have tried so far!
I have written a JavaScript in which I tried to catch the event of '+' button on sub grid, using 'addEventListener' on 'gridname_addImageButton' id but the event was not caught. This is quite basic stuff for normal web development, but not happening on dynamics crm.
UPDATE
This the HTML of the "+" button that appears on the grid.
<a action="tec|ManyToMany|SubGridStandard|Mscrm.AddExistingRecordFromSubGridAssociated" tabindex="1340"
title="Add record." class="ms-crm-ImageStrip-addButton" style="display: block; cursor: pointer;"
onclick="return false;" id="tec_addImageButton" href="#">
<img class="ms-crm-add-button-icon" title="Add Experlogix Model record." alt="Add record."
id="Tec_addImageButtonImage" src="/_imgs/imagestrips/transparent_spacer.gif?ver=-893257913" />
</a>
And this is the javascript that I tried:
var elem = document.getElementById('tec_addImageButton');
elem.addEventListener('click',myFunc(),false);
What am I missing?
Regards,
Momi
CRM forms are not "normal web development" as the product does not support direct DOM manipulation. The only manipulation allowed is that done using CRM's Xrm.Page object. The general how-to of using Xrm.Page is documented in the SDK: https://msdn.microsoft.com/en-us/library/gg328261.aspx.
Specifically, you are looking to add a custom filter to a lookup, which can be done with the code:
Xrm.Page.getControl(arg).addCustomFilter(filter, entityLogicaName)
Where filter is a string with a valid FetchXML filter, i.e.:
<filter type="and">
<condition attribute="new_somefieldname" operator="eq" value="somevalue" />
</filter>
You can call addCustomFilter in the OnLoad event or you can use a PreSearch event handler to add your filter:
Xrm.Page.getControl(arg).addPreSearch(handler)
Credit to http://missdynamicscrm.blogspot.com/2014/08/crm-2013-using-addcustomfilter-to-get-filtered-lookup-field-based-on-linked-entity.html for this fully implemented example.
function onLoad()
{
addEventHandler();
}
function addEventHandler() {
// add the event handler for PreSearch Event
Xrm.Page.getControl("parentcontactid").addPreSearch(addFilter);
}
function addFilter() {
//find contact contains this #example.com
var email = "%#example.com%";
//create a filter xml
var filter = "<filter type='and'>" +
"<condition attribute='emailaddress1' operator='like' value='" + email + "'/>" +
"</filter>";
//add filter
Xrm.Page.getControl("parentcontactid").addCustomFilter(filter);
}
Make sure that event is attaching to the anchor and add the function without brackets () while adding the event listener like in the following example.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript">
window.onload = function () {
document.getElementById('tec_addImageButton').addEventListener('click', myFunc, false)
}
function myFunc() {
alert("testing");
}
</script>
</head>
<body>
<a id="tec_addImageButton" href="#">test button</a>
</body>
</html>
You have to put the html script as a web resource in your solution.
Insert HTML inside your Form
You have to put the js script as a web resource in your solution.
You have to event the frame on Form Libraries : web resource
You have to event the frame on Event Handler -> Form -> onload Add: myObj.init()
if (typeof (myObj) == "undefined") {
myObj = {};
}
(function () {
myObj.init = function () {
Xrm.Page.ui.controls.get('id_iframe').getObject().onload= function() {
var el = Xrm.Page.ui.controls.get('id_iframe').getObject().contentWindow.document.getElementById('myLabel');
addEvent(el, 'click', function () { alert('Evento'); });
};
}
function addEvent(element, evnt, funct) {
if (element.attachEvent)
return element.attachEvent('on' + evnt, funct);
else
return element.addEventListener(evnt, funct, false);
}
})();
<HTML>
<BODY onload="SetupEvents()">
<label id="myLabel" >Click me</label>
</HTML>
So, I've found this JSFiddle example. In JSFiddle works well, the problem is that, even if I search any != from "advogados" (just testing), the browser goes to: http://www.site.com/index.html?procura=teste
No jQuery conflict, no html issue.
Here's JS
$("#procura").on("submit", function(event){
// prevent form from being truely submitted
event.preventDefault();
// get value of text box
name = $("#procura_texto").val();
// compare lower case, as you don't know what they will enter into the field.
if (name.toLowerCase() == "advogados")
{
//redirect the user..
window.location.href = "http://jornalexemplo.com.br/lista%20online/advogados.html";
}
else
{
alert("no redirect..(entered: " + name + ")");
}
});
If your javascript is somewhere in your HTML before your <form> your $("#procura") will be an empty set, so the submit-action won't be bound to anything. Try following code:
<html>
<head>
<script type="text/javascript" src="/path/to/your/jquery.js"></script>
<script type="text/javascript">
$(function() {
// This code will be run if your document is completely
// parsed by the browser, thus all below elements are
// accessible
$('#procura').on('submit', ....);
});
</script>
</head>
<body>
<form id="procura">...</form>
</body>
</html>
$(function() {}) is also known as $(document).ready(function() {}), (documentation)
You aren't defining the variable name. http://jsfiddle.net/zwbRa/59/
var name = $("#procura_texto").val();
Lets say I have a string like this
var methodString = "<script>
var a;
var b;
function func1(v1, v2)
{
..///DO random stuff
}
</script>";
I then attach this code to the end of the body after a button click somewhere on the page
$(body).append(methodString);
How do I call this new function that i just appended
$("button1").click(function() { func1(a,b); }); //This doesn't seem to recognize the new method.
simple HTML
<button onclick="func1(a,b);">Click me</button>
With jQuery
<script type="text/javascript">
$('#myButton').click(function(){
func1(a,b);
});
</script>
<button id="myButton">Click me</button>
I have an application that needs to retrieve a value out of a hidden input form field. However, this application has a base page which calls another page that is in an iFrame and then it also can call itself inside another iFrame:
default.asp -> screen.asp (in iFrame)
screen.asp -> a new instance of screen.asp (in iFrame)
document.getElementById('focusValue').value
window.frames[0].document.getElementById('focusValue').value
parent.frames[arrVal].document.getElementById('focusValue').value
When I reference the hidden input form field from default -> screen I can use the standard document.getElementById('focusValue').value;. Then when I'm in the 1st level iFrame I have to use window.frames[0].document.getElementById('focusValue').value;. Then when I'm in the 2+ levels in an iFrame I have to use the parent.frames[arrVal].document.getElementById('focusValue').value;.
A common structure that I'm starting to see is this:
if(document.getElementById('focusValue') == undefined){
window.frames[0].document.getElementById('focusValue').value = focusValue;
console.log('1');
}else if((parent.frames.length -1) == arrVal){
console.log('2');
if (arrVal > 0) {
parent.frames[arrVal].document.getElementById('focusValue').value = focusValue;
}
}else{
document.getElementById('focusValue').value = focusValue;
console.log('3');
}
Now I can certainly do this but outside of writing a novel worth of comments I'm concerned with other programmers(or me 1 month from now) looking at this code and wondering what I was doing.
My question is there a way to achieve what I'm looking to do in a standard form? I'm really hoping that there is a better way to achieve this.
I would suggest you have each page do the work of finding the value you want by calling a method. Basically exposing a lookup interface. Then you only need to call a method on the target page from the parent page. Proper naming will help developers understand what is going on and using methods will simplify the logic.
Or if you only need to get the value from the parent page, then you could register a hook with each page in an iframe using a common interface. Each page can just call that hook to get the value. This prevents your complex logic of determining what level the page is. Something like
iframe1.GetValueHook = this.GetValue;
iframe2.GetValueHook = this.GetValue;
Then each page can just call
var x = this.GetValueHook();
If you have nested pages, you could make this recursive. If you need communication between all pages then use the same approach but with a registration process. Each page registers itself (and it's children) with it's parent. But if you need to do this then you should reevaluate your architecture.
Example:
register.js
var __FRAMENAME = "Frame1";
var __FIELDID = "fieldId";
var __frames = [];
function RegisterFrame(frame) {
__frames.push(frame);
for (var i = 0; i < frame.children.length; i++) {
__frames.push(frame.children[i]);
}
RegisterWithParent();
}
function RegisterWithParent() {
var reg = {
name: __FRAMENAME,
getvalue: GetFieldValue,
children: __frames
};
if(parent != undefined && parent != this) {
parent.RegisterFrame(reg);
}
}
function SetupFrame(name, fieldId) {
__FRAMENAME = name;
__FIELDID = fieldId;
RegisterWithParent();
}
function GetFieldValue() {
return document.getElementById(__FIELDID).value;
}
function GetValueFrom(name) {
for (var i = 0; i < __frames.length; i++) {
if (__frames[i].name == name) {
return __frames[i].getvalue();
}
}
}
index.html
<html>
<head>
<script language="javascript" type="text/javascript" src="register.js"></script>
</head>
<body>
PAGE
<input type="hidden" id="hid123" value="123" />
<iframe id="frame1" src="frame1.html"></iframe>
<iframe id="frame2" src="frame2.html"></iframe>
<script type="text/javascript">
SetupFrame("Index", "hid123");
setTimeout(function () { //Only here for demonstration. Make sure the pages are registred
alert(GetValueFrom("frame3"));
}, 2000);
</script>
</body></html>
frame1.html
<html>
<head>
<script language="javascript" type="text/javascript" src="register.js"></script>
</head>
<body>
<input type="hidden" id="hid" value="eterert" />
<script type="text/javascript">
SetupFrame("frame1", "hid");
</script>
</body></html>
frame2.html
<html>
<head>
<script language="javascript" type="text/javascript" src="register.js"></script>
</head>
<body>
<input type="hidden" id="hid456" value="sdfsdf" />
<iframe id="frame2" src="frame3.html"></iframe>
<script type="text/javascript">
SetupFrame("frame2", "hid456");
</script>
</body></html>
frame3.html
<html>
<head>
<script language="javascript" type="text/javascript" src="register.js"></script>
</head>
<body>
<input type="hidden" id="hid999" value="bnmbnmbnm" />
<script type="text/javascript">
SetupFrame("frame3", "hid999");
</script>
</body></html>
This would be better if you can change it up to use a dictionary/hash tbale instead of loops.
Your best bet will be to set varables named correctly so it's self documenting. Something like this...
var screenFrame = window.frames[0];
var screenFrame2 = parent.frames[arrVal];
var value = screenFrame2.document.getElementById('focusValue').value
This will make it easier to read.
If you really must search frames for a given element, then you should just make your own function to do that and use that function everywhere. Put a lot of comments in the function explaining why/what you're doing and give the function a meaningful name so it will be more obvious to future programmers looking at your code what you are doing or where they can look to find what you are doing.
function setValueByIdFrames(name) {
if(document.getElementById(name) == undefined){
window.frames[0].document.getElementById(name).value = name;
console.log('1');
} else if((parent.frames.length -1) == arrVal){
console.log('2');
if (arrVal > 0) {
parent.frames[arrVal].document.getElementById(name).value = name;
}
} else {
document.getElementById(name).value = name;
console.log('3');
}
}
Is there an error in the way i use the __doPostBack?
function displaymessage() {
var scl = "aaaaaa";
var pageId = '<%= Page.ClientID %>';
__doPostBack(pageId, 'OtherInformation');
alert(scl);
}
<input type="button" value="Click me!" id="Button2" onclick="displaymessage()" />
When i press the button it should call the RaisePostBackEvent in the code file, but it doesn't. If i comment the doPostBack it reaches the alert but when it is uncommented it does not. So it must be an error in the usage of the doPostBack.
I followed this post: Call ASP.NET function from JavaScript?
Place the following script on the header section of your html file:
<script>
function __doPostBack(eventTarget, eventArgument) {
document.Form1.__EVENTTARGET.value = eventTarget;
document.Form1.__EVENTARGUMENT.value = eventArgument;
document.Form1.submit();
}
</script>
for me the _dopostback() was not firing only on IE and chrome browser. I have resolved by adding "return false;" statement in the javascript function. for example:-
function test()
{
_dopostback("logout","");
return false;
}
now its working fine.
Change you code to this:
setTimeout(function () { __doPostBack('btnSave', '') }, 500);
Use btnSave Id. It will work in all browsers.
Drop your second argument of __doPostBack ('OtherInformation'), and replace with an empty string, ''. You could put that data in a hidden input field if you need it, and retrieve it using Request.Form.
I also followed the same post you mentioned and got an error, I tried to use the other answers here but it still didn't work.
Until I've found this post:
http://forums.asp.net/t/1197643.aspx
(look in the 8th reply made by NC01).
1.basically the idea is that your aspx should have something like this:
<script type="text/javascript" language="javascript">
function myfunction() {
if ('<%=Page.IsPostBack%>' == 'False') {
var pageId = '<%= this.UniqueID %>';
__doPostBack(pageId, 'do_something_good');
}
}
</script>
2.then in your .cs you should add interface IPostBackEventHandler (for example:)
public partial class _default : System.Web.UI.Page, IPostBackEventHandler
3.and in your .cs in page_load add this line:
this.ClientScript.GetPostBackEventReference(this, string.Empty);
4.don't forget to implement the interface:
public void RaisePostBackEvent(string eventArgument)
{
if (eventArgument == "do_something_good")
{
//bla
}
}
And guess what - it even works!
#Subhash Dike - The PageMethods works only for static methods, AFAIK.
Add EnableEventValidation="false" into your <%Page tag to solve __doPostBack problem