Refresh form after save and close - javascript

I have some custom script that adds the latest note value to a hidden text field, and the hidden text field is subsequently displayed in one of my views for the entity. When I click save and close after adding a new note, the view does not update with the newest note since the form was not refreshed. What can I do so that the form will be refreshed if the user clicks on save and close?
EDIT: #Arthur For some reason, I cannot add a comment to your post.
Anyhow, I tried as you have suggested. When I tried to click on "save" alone, the form refreshed and the value returned was true, so the flag was tripped. However, when I tried the same with "save and close" the form did not refresh, and consequently the flag was not tripped. This is leading me to assume that I must refresh the form in order for the view to update.
EDIT 2: Here is the code that retrieves the information.
function GetLatestNote() {
var req = new XMLHttpRequest();
req.open("GET", encodeURI(Xrm.Page.context.getClientUrl() + "/XRMServices/2011/OrganizationData.svc/AnnotationSet?" + "$select=NoteText&$filter=ObjectId/Id eq guid'" + Xrm.Page.data.entity.getId() + "'&$orderby=CreatedOn desc&$top=1"), true);
req.setRequestHeader('Accept', 'application/json');
req.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
req.onreadystatechange = function() {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var note = JSON.parse(req.responseText).d;
var results = note.results;
var NoteText = results[0].NoteText;
var newnote = Xrm.Page.getAttribute("new_lastcomment").setValue(NoteText);
}
}
};
req.send();
}
new_lastcomment is the hidden field. What I am trying to do now is that if the user clicks on save and close, to stop the save event, reload the page, and use the script to close the form. Here is the code for that function:
function save(executionObj) {
var savestate = executionObj.getEventArgs.getsavemode();
if (savestate == 2) {
executionObj.getEventArgs().preventDefault();
window.location.reload(true);
Xrm.Page.data.entity.save("saveandclose");
}
}
What happens when I test this code however is that I get the following message when I attempt to save and close :
There was an error with this field's customized event.Field: crmForm, Event: onsave, Error: Object does not support property or method 'getsavemode'
However, once I click ok, the script closes and the view is updated as I want it! But now there is a problem because I do not want this error message popping up every time I hit save and close. To add more depth here, I run both of these function as an onsave event, and for the save function, I have "Pass execution context as first parameter" checked. I tried to run it without checking this box, and got an error that the value was undefined, but once again, after I clicked ok, the form would close and the view updated. Why is this error coming up now?
EDIT: #Arthur The form is now refreshing, but I am still getting the same error message that I was getting before.

Typically a "isdirty" flag gets triggered whenever there is a change to the form.
This flag lets CRM know that there have been modifications to the form in question, and to make sure to display the "There are unsaved changes" dialog box.
My guess is that this flag is not being tripped when you update the textbox.
if you put
console.log(Xrm.Page.data.entity.getIsDirty())
in your javascript and check out the resulting code, does it say true or false?
If it's false you'll need to set the dirty flag using
Xrm.Page.data.setFormDirty()
EDIT: I don't think this is the issue any more. refer to below.
After you set the value of the text box try executing this:
Xrm.Page.data.refresh(save);
That should save it, that way the save and close button doesn't have to.

After doing some research, I have found out what the issue was.
In my function GetLatestNote(), I was retrieving the data from the note field asynchronously. This may have resulted in the control returning to the user before the code was executed and the field was populated on the form. Therefore, this resulted in the information not being brought over when I clicked save and close.
Here is the code with the JSON code being executed synchronously, for those who may need it in the future. Works like a charm :)
function GetLatestNote() {
var req = new XMLHttpRequest();
req.open("GET", encodeURI( Xrm.Page.context.getClientUrl() + "/XRMServices/2011/OrganizationData.svc/AnnotationSet?" + "$select=NoteText&$filter=ObjectId/Id eq guid'"+Xrm.Page.data.entity.getId()+"'&$orderby=CreatedOn desc&$top=1"), false);
req.setRequestHeader('Accept', 'application/json');
req.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
req.send(null);
var note = JSON.parse(req.responseText).d;
var results = note.results;
var NoteText = results[0].NoteText;
var newnote = Xrm.Page.getAttribute("new_lastcomment").setValue(NoteText);
}
#Arthur thank you very much for trying to help me out. I truly appreciated it!

Related

HTTP Request effects URL

Everything works fine, it submits the data to the url, and the data gets put into the database just fine. The only problem I am having is the below code is on my index.php page, it submits the data to the submitusername.php page and everything works however after it submits the data to the submitusername page the url turns into "/index.php?username=blahblahblah" this isn't a major issue but it is something I would like to learn how to fix/what is causing it.
function submitUsername(){
var submitData = new XMLHttpRequest();
var username = document.getElementById('username').value;
submitData.onreadystatechange = function() {
if(submitData.readyState == 4 && submitData.status == 200) {
callback(submitData.responseText);
}
},
submitData.open("GET", "submitusername.php?username="+encodeURIComponent(username), true);
submitData.send();
}
Nothing in the code you've provided would have the effect you describe.
It sounds like you are trying to trigger the JavaScript when a form is submitted, but the form is submitting normally and loading a new page.
You need to prevent the default behaviour of the form submission.
Change your event handler function to capture the Event object and prevent the default behaviour, then make sure you are binding the event handler appropriately.
function submitUsername(evt){
evt.preventDefault
var submitData = new XMLHttpRequest();
and
document.getElementById('myform').addEventListener('submit', submitUsername);

JQuery validation resetForm is not working

I have a very simple issue: There is a form with a clear form button. When I click on it, all fields reset. But I also have an extra validation rule: at least one additional field should be filled. After clearing, they all are empty, of course, but I don't want to see these validation messages. I want it to clear the entire form, hide all validation messages and so on. Here is my code:
$("a[data-clear]").click(function (event) {
var now = new Date();
$("#report_search section:gt(0) input").val("");
$("#includeDerived").prop("checked", true);
$("#includeApp").prop("checked", true);
$("#includeOrg").prop("checked", false);
$("input[name='FromDate']").datepicker().datepicker("setDate", now.dateAdd("year", -1));
$("input[name='ToDate']").datepicker().datepicker("setDate", now);
$("form").validate().resetForm();
event.preventDefault();
});
I have only one form on the page so multiple forms is not an issue.
Desired result: form is cleared, validation messages are not shown.
Actual result: form is cleared, validation messages persist.
Sample rule which is checking if fields are filled:
jQuery.validator.addMethod("isSufficientInfo",
function (value, element, params) {
var hasPersonInfo = $("input[name='LastName']").val() && $("input[name='FirstName']").val();
if (hasPersonInfo) {
return true;
}
var hasDocInfo = $("select[name='D']").val() && $("input[name='C']").val() && $("input[name='E']").val();
if (hasDocInfo) {
return true;
}
return $("input[name='A']").val() || $("input[name='B']").val();
}, "File some fields");
$("#IsEnoughInfo").rules("add", { isSufficientInfo: "" });
If you're still looking for the answer,
I suspect that $("form").validate() creates a new validator instance.
What you need is the previously created instance:
$("form").data("validator").resetForm()
Or store the validator in a variable:
var v = $("form").validate()
v.resetForm()
Reason for error
Your event for click event is getting propagated from button to window (inside-out). This is causing your form to trigger validation and thus you are getting the same error message, even after you call the resetForm. If you debug the validation library step by step and get to this.hideErrors then you will see that when this.hideErrors gets executed, the error messages are gone. Since the validation script hasn't finished yet, it continues with other statements, and at the end the event that got propagated is handled by the window from inside-out. The error messages are again shown as this event triggers the request on the form.
Solution
The solution is to move your call to event.preventDefault() to the top, like as shown below:
$("a[data-clear]").click(function (event) {
event.preventDefault(); // Move to top
var now = new Date();
$("#report_search section:gt(0) input").val("");
$("#includeDerived").prop("checked", true);
$("#includeApp").prop("checked", true);
$("#includeOrg").prop("checked", false);
$("input[name='FromDate']").datepicker().datepicker("setDate", now.dateAdd("year", -1));
$("input[name='ToDate']").datepicker().datepicker("setDate", now);
$("form").validate().resetForm(); // this should work now
});
Also see the updated jsfiddle sample
Give it a try and let me know if this works for you or not. I did the step-by-step debug and got to this conclusion.

websockets do not work when assigned to global var

I use websockets along with javascript and html5
I have the following code.
<input type="text" onFocus=" so = new websocket('ws://localhost:1234');" onBlur="so.close();" onKeyUp="keyup();" >
<script type='text/javascript'>
var so; //this is global...
//wait a little (user stops typing)
function keyup(){
if (timeout) {clearTimeout(timeout);}
timeout = setTimeout(lookup, 250);
}
function lookup(){
//it's global, so use it right away
so.onopen = function(){
//send data to server to get responce...
So, websockets open/close if user clicks/or not a textfield. User types something on textfield. The value of textfield is sended to the server, a query is executed and if there are matching results, they render on the screen of the user.
If I click on the text field I see in the console "connected" and if I click anyware else I see "closed normally", as I should. That's ok.
But when I type letteres to the textfield, to send data to server, nothing is sended. I see nothing in the console. I see no errors.
What am I missing? It's like so.onopen never get executed.
Any advice?
Thanks in advance
The problem is that you recreate the socket but don't bind the onopen event handler.
On focus, you should call a function doing both : create the websocket and bind the onopen event handler :
<input id=someid type="text" onBlur="so.close();" >
<script type='text/javascript'>
var so, field = document.getElementById('someid');
field.onfocus = function(){
so = new websocket('ws://localhost:1234');
so.onopen = function(){
// do things
}
}

Why do my functions keep reading input from my input text field?

The input on my html form has a problem. Curently I am taking the input which is a twitter name into an Ajax function that calls tweets via php from the twitter api.
As I have a setInterval function to keep checking for updates, the input is passed again and again into the function to get tweets.
The problem is that the function seems to be reading the input directly from what is in the text input box. So if the user changes the text without pressing enter or hitting the button, the function keeps reading that text as the input. So the input entered initially is not fixed after pressing enter or hitting the button to submit.
Here is the html form taking in the input:
<div id="topdiv">Input Twitter ID: <input type="text" id="userid" onkeydown="if(event.keyCode===13) {document.getElementById('tweet-button').click();}">
<input type="submit" id="tweet-button" onclick="getStatusesX();" value="Get recent tweets">
<p id="tweetbox"></p>
</div>
Here are the functions:
function getStatusesX() {
var userID = document.getElementById("userid").value;
getStatuses(userID);
var intervalstop = setInterval(function() {getStatuses(userID);}, 20000);
clearInterval(intervalstop);}
//Create a cross-browser XMLHttp Request object
function getXMLHttp() {
var xmlhttp;
if (window.ActiveXObject) {
XMLHttp = new ActiveXObject("Microsoft.XMLHTTP");
} else if (window.XMLHttpRequest) {
XMLHttp = new XMLHttpRequest();
} else {
alert("Your browser does not support XMLHTTP!");
}
return XMLHttp;
}
//function that searches for the tweets via php
function getStatuses(userID){
XMLHttp1 = getXMLHttp();
//ajax call to a php file that will extract the tweets
XMLHttp1.open( 'GET', 'TwitterGlimpsePHP.php?userid='userID, true);
// Process the data when the ajax object changes its state
XMLHttp1.onreadystatechange = function() {
if( XMLHttp1.readyState == 4 ) {
if( XMLHttp1.status ==200 ) { //no problem has been detected
document.getElementById("tweetbox").innerHTML=XMLHttp1.responseText;
}
}
}
XMLHttp1.send(null);
}
I want the input to be taken as the text after enter is pressed. I have tried assigning it to variables but cannot work out why it keeps reading from the input field. Any help appreciated.
This is not an official answer - just trying to clear up my comments
This is what I mean by declaring outside the function...
var intervalstop;
function getStatusesX() {
clearInterval(intervalstop);
var userID = document.getElementById("userid").value;
getStatuses(userID);
intervalstop = setInterval(function() {getStatuses(userID);}, 20000);
}
that way you initialize the var and inside the function you clear first to ensure it's not compounding. Then you set the var to a new interval to begin again.
You said twitter doesn't like something about this code if the user clicks many times - Makes perfect sense. They will want to throttle the API to prevent someone from making 50,000 requests per minute cause of improper coding. You should check the API specs to make sure you're within a realistic zone and consider caching the results locally if you are pushing boundaries.
The issue is that you are re-reading the value of the textbox every time getStatuses is called.
Try capturing the value of the textbox first, and passing it into your getStatuses function:
So your new getStatusesX is:
function getStatusesX() {
var userID = document.getElementById("userid").value;
getStatuses(userID);
setInterval(function() {
getStatuses(userID);
}, 20000);
}
Update getStatuses to take a userID parameter and delete the line where you're reading the textbox's value inside of getStatuses.
That having been said, it might be an issue if this is possible to begin with - what if the user clicks the button to automatically refresh statuses multiple times? You might want to disable the button/textbox after it's been clicked, or have it clearInterval the old interval first.

How to avoid automatic page reload after XMLHttpRequest call?

I know this is a bit paradoxal because XMLHttpRequest shouldn't be reloading the page, and it's the whole point of it.
Tried in Chrome latest version, Safari on iOS and on an Android. All same result.
I am sending a form through it, with files. Works great, the destination site receive correctly the data, and displays it. Sends back a 200, "OK". (It's facebook)
But then my page reloads automatically. Just like if I submitted the form using HTML form and a submit button. (Which was my original problem)
Here is how I do it, from Javascript
// Get the form element
var formData = new FormData(document.getElementById("photosubmitform"));
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://graph.facebook.com/' + facebookWallId + '/photos', false);
xhr.onload = function(event)
{
var json = xhr.responseText; // Response, yay!
}
xhr.send(formData); // Sending it, will reload the page on success...
Any chance you're triggering this by submitting a form? If you don't return false in the onsubmit handler, the form will still be submitted.
Use event.preventDefault() when observing button click in your form.

Categories

Resources