"Function Expected" error in JsProvider.ashx after setting a lookup field - javascript

I have an HTML page that gets opened when clicking a ribbon button of a custom entity page. The JS code running in this page is does some business logic, and eventually needs to update a lookup field back on the custom entity page.
Currently, for setting the lookup value, I'm doing something like the following*:
window.opener.Xrm.Page.getAttribute("ik_reportid").setValue([{
id: "d67aa9d8-c528-e711-80f2-005056b74923",
name: "test record",
entityType: "ik_report"
}]);
*Note: The above is written hard-coded for simplifying this question. I assure you the problem is not in these values, but somewhere else.
After doing so, the HTML page continues with its existing code, and eventually calls window.opener.Page.data.refresh(true), and then closes itself with window.close().
The problem is that when the opener page is refreshing, I get an error "function expected", and opening the debugger get me to the following line in JsProvider.ashx:
Mscrm.FormInputControl.LookupUIBehavior.$2I=function($p0,$p1){if(!parseInt($p0.type)&&!parseInt($p1.type)||parseInt($p0.category)===LookupItemCategories.UNKNOWN_EMAIL&&parseInt($p1.category)===LookupItemCategories.UNKNOWN_EMAIL)
I watched the values of p0 and p1, and I noticed they don't have a category property. However, when I tried using the same code for setting the value of the same lookup field when I'm on the page itself (i.e., omitting the window.opener', and even calling arefresh`), I get no error.
In addition, I commented-out the refresh call inside the HTML page code. That didn't help, too: when I clicked the save button on the entity page, I again got the "function expected" error, now in Global.ashx (b was expected to be a function, apparently) :
Sys._isInstanceOfType=function(c,b){if(typeof b==="undefined"||b===null)return false; if(b instanceof c) return true;
No idea what's the cause for it. Any help is welcomed.

Posting messages between windows should meet your requirements here. You can find more information here
Basically in your parent window do something like this:
window.onmessage = function (e) {
//e.data will contain some payload
Xrm.Page.getAttributes("xxx").setValue(e.data);
};
Or to be compatible with all browsers:
if (window.addEventListener) {
window.addEventListener('message', function (e) {
//e.data will contain some payload
Xrm.Page.getAttributes("xxx").setValue(e.data);
});
}
else { // IE8 or earlier
window.attachEvent('onmessage', function (e) {
//e.data will contain some payload
Xrm.Page.getAttributes("xxx").setValue(e.data);
});
}
Now in your child window only send the result using postMessage
window.opener.postMessage("I'm the result", '*');
I usually handle the scenarios that you described this way. The other solution would be to create a callback on parent window
window.callback = function() {
//do your stuff here
}
and from child window calling this callback:
childWindow.opener.callback();
But personally I prefer the postMessage approach, I had some problems with the callbacks sometimes.

Related

my onload function sequence is wrong

What I'm trying to do is getting data from a database and when the page loads they will show on the screen. when a user is logged in it has an database url that is saved in a variable db and I use db.allDocs to get all data from that user.
Now. I've got it working on a button <button onclick="showInfoItems()">
But when I try it onload, it does work, but not with the correct database. This is because the user is unknown for some reason.
my code:
<body>
<ul id="info-lijst"></ul>
<script src="js/showinfo.js"></script>
<script>onload = showInfoItems();</script>
the user info is known in the showinfo.js, but for some reason the user is undefined, until I press the onclick button.
I thought that, when I first load in the js file (as I do) and then do the onload, it will work, but no. the username is undefined.
Does someone know what I'm doing wrong or how I can fix this?
EDIT:
showInfoItems.js:
function showInfoItems() {
console.log(dbrp);
dbrp.allDocs({
include_docs: true,
attachments: true,
descending: true
}).then(function (doc) {
console.log(doc);
buildInfoItem(doc.rows);
}).catch(function (err) {
console.log(err);
});
}
What the dbrp variable is:
localhost:5984/userdb-undefined
and when i do the onclick it's:
localhost:5984/userdb-1234567890 (username is known)
You defined onload wrong. It expects a callable function. What you do is calling your function immediately.
window.onload = function() {
showInfoItems()
});
EDIT
Since this seems to be more an PouchDB issue a expand my answer.
The problem is, that you need to wait for an asynchronous function call. This function is not done when your document is ready. So either you add a callback to this function to trigger another function when it is done or you add dispatch a CustomEvent
document.dispatchEvent(new CustomEvent('databaseReady'));
Then you can listen for this event and bind multiple function to it.
document.addEventListener('databaseReady', function() {
showInfoItems()
});
http://codepen.io/anon/pen/vgeyzV?editors=1010

Can I trigger my Html.ValidationMessageFor with jquery and have it display some string I define in JQuery?

If I have a validation tag in my asp.net mvc application for a text field called search, can I plug into it using jquery/javascript to get it to trigger if certain logic is performed? How would I do that?
It looks something like this
#Html.TextBox("SearchQuery", other stuff here, other)
#Html.ValidationMessageFor("SearchQuery")
Say I want to trigger the validation message to show if this occurs
$('form').submit( function (e) {
e.preventDefault(e);
var results = GetLocation();
if (results) {
this.submit();
} else {
// trigger validation message and display "can't find results"
}
});
Please note that I don't think I need to validate here, I just want to show a message where the validation message would be if I did validate
As far as i understand your question, for custom messages coming from server you need to send the object to server and then get the response from it.
You can perform it with an ajax call for example:
$.ajax({
url : 'example.com',
type: 'POST',
data : results,
success:function(datafromserver)
{
$('.resultState').html(datafromserver);
}
});
Another thing if do validation first in the client and then send (and check again in server), in this case remember var result can always be true if the getLocation functions returns anything (such as string , object etc...) so in this case print it with console.log and take a look if is it an object (f example: data.x === none or 'no coordinates' just evaluate it correctly and you can avoid ajax.
Hope helped!
Regards

When quick navigate from one page to another script alert shown, why? [duplicate]

This question already has answers here:
handle ajax error when a user clicks refresh
(5 answers)
Closed 8 years ago.
I have a Web app (MVC 5), and when I move fast from index page to different page i get a javascript alert tell me : "The page at localhost:4332 says: " (its says nothing).
and when i press the OK button, evertything is back to normal its continue to the other page, i want to disable this alert from pop to the client.
I'm thinking its because i move to a different page too fast and the script cant run fully.
What i do in the script is initialize a drop down list with values i get from Ajax post request.
(in order to save time from the load the page time, i load the page and than initialize the drop down list.
this is my code :
$(document).ready(function () {
$.ajax({
type: 'POST',
url: '/Home/GetProfiles',
success: function (data) {
$.each(data, function (key, value) {
$('#filterSelect').append($("<option></option>").attr("value", value).text(key));
});
},
error: function (ts) { alert(ts.responseText) }
});
})
I do a couple things more but i don't want to complicate the code that i posted here, i think the problem is related to this lines of code.
I try to add "try" and "catch" with console.log of the exception but i didn't get nothing to the console, and the alert keep pops
Any idea why its happens ? and how can i fix it ?
You're getting a message because navigating the page cancels any AJAX requests, so they'll error. You have an onerror callback that shows the responseText, and since it errored there's no text to show.
#Andrea Faulds is correct. This is happening because the page content changes before the ajax call finishes. This can happen when you quickly navigate to another page, or reload the current page, before the ajax call finishes.
For appropriate fix, see this URL: handle ajax error when a user clicks refresh
To summarize, many people do something like this:
error: function (ts) {
if (ts.readyState == 0 || ts.status == 0) return;
alert(ts.responseText);
}
However, this can also suppress real errors. For example, if you begin the ajax request, and then disable your network connection, you may never see the alert message (because in these cases, readyState and status are also zero).
Another possible solution is for you to do something like this:
error: function (ts) {
alert(ts.responseText || 'An asynchronous request was unable to complete.');
}
In this case, by using the || operator, your user will still see the alert when the page content changes before the ajax call finishes. However the alert will not be blank, because when it is, the other message will be shown.

Fire a .js file with jquery click event

I am attempting to load a .js file hosted online after a jquery click event. First, am I doing this right? Will all the javascript be applied only after a link is clicked?
$(document).ready(function() {
var clickHandler ="file.js";
$('a').click(function() {
$.getScript(clickHandler, function(data, textStatus, jqxhr) {
console.log(data);
console.log(textStatus);
console.log(jqxhr.status);
});
});
Edit: I just checked the console and it is loading the file but giving me a 403 Forbidden message. Why is this happening? Do I need to have some text in my header to refer to?
EDIT 1:
Misread the jQuery code -- this part of the answer doesn't apply:
There are ways to add Javascript file to an existing document, but it isn't as simple as you are trying to do.
This discussion can explain that: How to dynamically insert a <script> tag via jQuery after page load?
The other solution is to put the contents of the Javascript into its own function, include that on the page normally and then run that function in your click handler.
Edit: Expanded answer
Lets say that you have some fairly simple code in your file.js like this:
var el = document.getElementById("fooz");
if (el) {
el.className += " example";
}
This code will, since it is not wrapped up in a function, will run (or try to run) as soon as it is loaded. It will only run once every time it is loaded.
However, if you wrap it up in a function, like this:
function colorFooz() {
var el = document.getElementById("fooz");
if (el) {
el.className += " example";
}
}
Then the code will not run until the function is called. It will load and be ready to be called later.
Error 403
The first thing to do is figure out why are getting the error 403.
At this stage, that has nothing to do with Javascript, jQuery or AJAX. Simply the problem by trying to load that Javascript file directly in your browser, by typing something like this utnil your URL:
http://example.com/file.js
Changing the URL to your website and path of course. At this point, you should still be getting the 403 error, but you can now check your server logs to see what error is written there.
I found a page that gives a guide to tracking down 403 errors here: http://www.checkupdown.com/status/E403.html
((PS: If I had to randomly guess at the reason why you are getting the 403 error, I'd say that you don't have the path file file.js correct. Depending on your structure and various includes, it may be calculating the relative path incorrectly.))
The function you pass to click() is a callback and is only executed when the element is clicked. So yes, you've got that part right.

How to parse string html from submitted iframe

I'm uploading a file in an iframe (with name and id=upload_target) to some server. As a response it creates a callback json style :
'result':'true'
So I'm trying the following. On onload action of my IFrame I've added an event listener, which should run function grabbing data :
function fileUploadFunction(){
(...)
$("#upload_target").onload = uploadDone;
(...)
};
function uploadDone() {
alert("uploadDone");
var ret = frames['upload_target'].document.getElementsByTagName("body")[0].innerHTML;
var data = eval("("+ret+")");
if(data.result == 'true') {
alert("GREAT SUCCESS !!");
}
else {
alert("GREAT FAILURE :(");
}
}
But as a result I'm not getting anything at all. Should I return callback status in different form, or can it be solved differently ? Because even the first alert from uploadDone is not shown problem probably lies somewhere else.
Probably the reason nothing is happening is because of the funky way you have to detect an iFrame is loaded. Check the post jQuery .ready in a dynamically inserted iframe. I am assuming you are using jQuery.

Categories

Resources