dataSource unable to save richText Item - event-handling

I am using eventhandler on my Xpage to save my datasource (frmData):
<xp:eventHandler
id="saveEventHandler"
submit="true"
save="true"
event="calledbyid"
refreshMode="complete"
>
<xp:this.action><![CDATA[#{javascript:frmData.save();
context.redirectToPage("index.xsp")}]]></xp:this.action>
</xp:eventHandler>
This is called by custom properites:
<xe:basicLeafNode
onClick="XSP.executeOnServer('#{id:saveEventHandler}')"
label="Save"
rendered="#{javascript:currentDocument.isEditable()}"
>
</xe:basicLeafNode>
That is Mr. Jeremy Hodge code for client to server site trigger:
XSP.executeOnServer = function () {
// must supply event handler id or we're outta here....
if (!arguments[0])
return false;
// the ID of the event handler we want to execute
var functionName = arguments[0];
// OPTIONAL - The Client Side ID that you want to partial refresh after executing the event handler
var refreshId = (arguments[1]) ? arguments[1] : "#none";
var form = (arguments[1]) ? this.findForm(arguments[1]) : dojo.query('form')[0];
// catch all in case dojo element has moved object outside of form...
if (!form)
form = dojo.query('form')[0];
// OPTIONAL - Options object contianing onStart, onComplete and onError functions for the call to the
// handler and subsequent partial refresh
var options = (arguments[2]) ? arguments[2] : {};
// OPTIONAL - Value to submit in $$xspsubmitvalue. can be retrieved using context.getSubmittedValue()
var submitValue = (arguments[3]) ? arguments[3] : '';
// Set the ID in $$xspsubmitid of the event handler to execute
dojo.query('[name="$$xspsubmitid"]')[0].value = functionName;
dojo.query('[name="$$xspsubmitvalue"]')[0].value = submitValue;
this._partialRefresh("post", form, refreshId, options);
}
All fields value on the form has been save except one which is Rich text Item.
When I use simple button onclick event Instead of using above even handler, that Rich text Item saved!!
<xp:button
value="Label"
id="button1"
xp:key="facet_3"
>
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="complete"
>
<xp:this.action>
<xp:saveDocument
var="frmData"
>
</xp:saveDocument>
</xp:this.action>
</xp:eventHandler>
</xp:button>
Please let me know how to handle this event handler?
-mak

I don't know if the issue is with the Rich Text Item or the method of submitting. One thing I notice is that you're only passing one parameter to XSP.executeOnServer(), so it's going to infer the submit ID and the submit value.
Can you use Firebug or something similar to check what content is being submitted back to the server, both when you click the button and during the rest of the XPage's life cycle? It's hard to troubleshoot the page lifecycle processes from a question.
If no submit ID or submit value is being passed back to the server, no datasources or components on the page will be updated when you click the button. It will just save the datasource with whatever values were stored against the datasource from previous partial refreshes.
Whenever a partial refresh is triggered, some content will be updated in the server-side map of the XPage. So any previous partial refreshes may update the datasource with values before the XSP.executeOnServer() is triggered. If values have been passed back to the datasource by a partial refresh, those will be saved because they're already in the datasource, not because they are passed again by the XSP.executeOnServer().
If Firebug shows a submit id or submit value that includes the datasource being passed back to the server, the values will be passed back to the datasource, in which case there could be an issue specific to Rich Text Items.

Related

Mark an order as "Full Payment" on Sage 200

I am inserting orders on Sage 200 through an application using the client side, C# and APIs.
I would like to check the "Full payment" checkbox on the "Payment with order" tab.
Currently, I am setting the PaymentType property, which is not working.
order.PaymentType = Sage.Accounting.SOP.SOPOrderPaymentTypeEnum.EnumSOPOrderPaymentTypeFull;
order is an instance of Sage.Accounting.SOP.SOPOrder.
Do you know how I can check that property?
The following method should supply the required results.
private static void SetPaymentWithOrder(Sage.Accounting.SOP.SOPOrder sopOrder)
{
// Indicate that order has payment
sopOrder.PaymentWithOrder = true;
// This is full payment order
sopOrder.PaymentType = Sage.Accounting.SOP.SOPOrderPaymentTypeEnum.EnumSOPOrderPaymentTypeFull;
// Fetch the the Payment Methods. SOPPaymentMethods contructor accepts the boolean flag whether to fetch payment methods including card processing method or not.
Sage.Accounting.SOP.SOPPaymentMethods paymentMethodsCollection = new Sage.Accounting.SOP.SOPPaymentMethods(false);
// Set the first payment method of the collection to the order
sopOrder.PaymentMethod = paymentMethodsCollection.First;
}
dont know if you ever managed to figure this one out or not.
Not sure if you knew this, but you cannot modify the Sales Order on the view form, or at least shouldn't be trying to do so.
Using either of the Enter/Amend Sales Order forms will allow you to do so.
What is potentially happening, is that the properties that the controls are bound to are not updating the UI after your code has run.
You can simply force this to happen using the following
Fetching the underlying bound object
public Sage.Accounting.SOP.SOPOrderReturn SOPOrderReturn
{
get
{
//Loop over the boundobjects collection
//check if the bound object is of the type we want - e.g. SOPOrderReturn
//if correct type, return this object
Sage.Common.Collections.BoundObjectCollection boundObjects = this.form.BoundObjects;
if (boundObjects != null)
{
foreach (object boundObject in boundObjects)
{
if (boundObject is Sage.Accounting.SOP.SOPOrderReturn)
{
this._sopOrderReturn = boundObject as Sage.Accounting.SOP.SOPOrderReturn;
break;
}
}
}
return this._sopOrderReturn;
}
}
Fetch the correct underlying form type that the amendable form is, suspending the databinding,
perform your changes,
resuming the databinding
Sage.MMS.SOP.MaintainOrderForm maintainOrderForm = this.form.UnderlyingControl as Sage.MMS.SOP.MaintainOrderForm;
maintainOrderForm.BindingContext[this.SOPOrderReturn].SuspendBinding();
this.SOPOrderReturn.PaymentWithOrder = true;
this.SOPOrderReturn.PaymentType = Sage.Accounting.SOP.SOPOrderPaymentTypeEnum.EnumSOPOrderPaymentTypeFull;
maintainOrderForm.BindingContext[this.SOPOrderReturn].ResumeBinding();
should do the trick.

Custom form field (date field) validation-handler

I'm trying to create my custom validation handler for some custom fields on workflow form. A have two fields: project begin date and project end date.
For those two field i need two types of validation:
project begin date can not be less then today's date
project end date must be equal or grater then project begin date
However i'm still on beginning of creation custom validation-handlers. For start i just tried some simple validation handler for text field with numbers only but this isn't functioning. I did the following:
In my share-config-custom.xml i add
<config>
<forms>
<dependencies>
<js src="/custom-form-validation.js" />
</dependencies>
</forms>
and connect to my field
<field id="mcwm:shortProjectNumber" set="general" mandatory="true">
<constraint-handlers>
<constraint type="MANDATORY" validation-handler="Alfresco.forms.validation.checkNumber" event="keyup" />
</constraint-handlers>
</field>
custom-form-validation.js file is
Alfresco.forms.validation.checkNumber = function checkNumber(field, args, event, form, silent, message) {
var ok = (field.value=="") || field.value.match("^\\d{4}\\/\\d{4}$");
var valid = ok != null && ok;
if (!valid) {
YAHOO.util.Dom.setStyle(field.id, "border", "2px solid red");
}
else {
YAHOO.util.Dom.setStyle(field.id, "border", "");
}
// Inform the user if invalid
if (!valid && !silent && form)
{
var msg = "The number must match the pattern 1234/5678.";
form.addError(form.getFieldLabel(field.id) + " " + msg, field);
}
return valid;
};
I put custom-form-validation.js file in my opt\tomcat\shared\classes\alfresco\web-extension folder, but there is no field validation at all? Any suggestion on this?
Regards,
Aleksadnar
Field validation in Share is implemented as client-side JavaScript. So your JavaScript file goes in the root of your web app (preferably a directory structure below that), not under WEB-INF. For example, you might want to put it under $TOMCAT_HOME/webapps/share/extension/js. You may have to adjust your dependencies reference accordingly.
Next, don't put custom code in Alfresco's namespace. Create your own. You can create your own namespace by placing something like this in the beginning of your JavaScript file:
if (typeof SomeCo == "undefined" || !SomeCo)
{
var SomeCo = {};
}
You may also want to minify your JavaScript. Then, turn on Share debug. You do that by placing the following in share-config-custom.xml (which lives under $TOMCAT_HOME/webapps/share/WEB-INF/classes/alfresco/web-extension):
<alfresco-config>
<!-- Put Share Client in debug mode -->
<config replace="true">
<flags>
<client-debug>false</client-debug>
<client-debug-autologging>false</client-debug-autologging>
</flags>
</config>
</alfresco-config>
With that in place you can use your browser's developer console to step through the client side JavaScript and figure out why your validator isn't working.
You can use an alternative way to implement the form field validation handler, using javascript directly. I mean, you can add a listener to control when the form is submitted, and add a condition to cancel the submition. So, you could use a code like this when the form is loaded:
//Add a listener to control when the form is submitted
document.body.addEventListener("submit", function (event) {
//If there are wrong values
if(wrongValues()){
//Cancel the event
event.stopPropagation();
event.preventDefault();
}
}, true);
If you want more details about this solution, you can visit this post

Marking a field invalid

I use a custom AJAX vtype, which works and all.
However I notice the extjs docs note that
"Note: this method does not cause the Field's validate or isValid methods to return false if the value does pass validation. So simply marking a Field as invalid will not prevent submission of forms submitted with the Ext.form.action.Submit.clientValidation option set."
How does one mark a field as invalid so that form.isValid() returns false?
My vtype:
Ext.apply(Ext.form.VTypes, {
username: function(value, field){
var conn = new Ext.data.Connection();
conn.request({
url: 'test.php',
params:{email:value},
method: 'POST',
success: function(responseObject){
var resp = responseObject.responseText;
if (resp == 0) {
field.markInvalid('This email is invalid or already registered!');
} else if (resp == 1) {
field.clearInvalid();
}
},
failure: function(){
Ext.Msg.show({title: 'Error', msg: 'Connection error!',});
}
});
return true;
}
});
Well, if you look at the definition of clientValidation:
Determines whether a Form's fields are validated in a final call to
isValid prior to submission. Pass false in the Form's submit options
to prevent this. If not defined, pre-submission field validation is
performed.
This is basically saying, if its set to false then the form will be automatically validated prior to submission... at which point it will fail if you have marked any fields as invalid. If you set it to true then you need to manually check if the form is valid before submitting.
It's worth pointing out that your AJAX vtype is never going to work. When the form calls the vtype to check whether the field is valid, all it gets in response is true... so the form submits no matter what. Even if you tell it to return after the ajax request has completed, the form would submit before the vtype ajax request completes.
A better solution would be to include the call to the vtype manually in your submit button handler...then in your success of the ajax request just do
if(form.isValid()) {
form.getForm().submit();
}
This will force the submit button's click event to first validate the username field and then, and only then, will it submit the form.

Change in URL to trigger Event in GWT

I am iterating through some data and generating parameterized URL links based on some conditions like this:
finishedHTML.append("<a href=\"http://" + domain + "&service=" + allEvents[eventCounter].EventService +"&day="+ offSet+(-1 * i) +"\"><img src=\"/info.jpg\" alt=\"Info\"/>");
I had the beginning of my application checking for URL parameters when the page was loaded/refreshed, and take some action depending on if the parameters were there and what they were.
However, I added a # to the beginning of the paramters, so the page wouldn't need to be refreshed, but now it's not triggering the function that checks the URL.
My question is how can I trigger an event in GWT when a user clicks a link? Do I need to generate GWT controls, and link a click handler? Is it possible to setup an event that fires when the URL is changed???
UPDATE:
Adam answered part of the initial question, but I can't get the querystring after "#". Is there a better way than the function below:
public static String getQueryString()
{
return Window.Location.getQueryString();
}
In other words, if I enter example.com?service=1 I get service=1 as my querystring. If I enter example.com#?service=1, I get a null value for the querystring..
Use History.addValueChangeHandler( handler ), and create a handler to catch the URL changes.
There's no need for click handlers etc., any change of the "hash" part in the URL will be sufficient.
EDIT:
See this code example - it will parse URLs of the form http://mydomain/my/path#tok1&tok2&tok3
public void onValueChange(ValueChangeEvent<String> event) {
String hash = event.getValue();
if ( hash.length() == 0 ) {
return;
}
String[] historyTokens = hash.split("&",0);
// do stuff according to tokens
}
(Just responding to your Update)
Have you tried
History.getToken()
to get the value after the "#"?

ajaxcontroltoolkit setting hidden value after asyncfileupload has completed

I have an asyncfileupload control that I'm using from the ajaxcontroltoolkit. On the file complete in the code behind I process the file and write the information in the file to a database. I get the id of the record from the database, and this needs to be written to an asp hidden field. I've tried just setting the value:
fldImageID.Value = pimg.IdImageGroup.ToString();
I've tried Registering a script like I've seen in an example on a website:
ScriptManager.RegisterClientScriptBlock(
ImageFileUploader,
ImageFileUploader.GetType(),
"script1",
"alert('hi'); top.document.getElementById('"
+ fldImageID.ClientID
+ "').value='"
+ pimg.IdImageGroup.ToString()
+ "'; top.document.getElementById('"
+ lblError.ClientID
+ "').innerHTML = 'image uploaded'",
true);
I've just tried embedding javascript in a response.Write call from the method I've set to process the uploaded file. Nothing I've done has worked so far. After I've done everything the hidden field still does not contain the required value.
This is pretty easy with jQuery. Have an html hidden input control placed in your page, not the asp:hidden input control. Add a class lets say "hiddenPhoto" to your html hidden control.
so lets say our control html is like this
<input type="hidden" class="hiddenPhoto" runat="server" id="hdPhotoName" />
Now access it using class selector in your OnClientUploadComplete js method and set its value. Have it declared runat="server" in order to access its value on the server side.
Regards
I found an acceptable solution back when I was working on this. And since then I've received emails from people who have had the same problem and have been asking if I found a solution. So I'm presenting it here, stripping out any extraineous code:
From the user control that has the FileUpload control I first set the session variable on the back side in the FileUploadComplete handler:
*in the ascx file (upload_chart.ascx) I have the AsyncFileUpload, what is important is the OnUploadComplete and the OnClientUploadComplete:*
<ajaxToolkit:AsyncFileUpload
OnUploadedComplete="FileUploadComplete1"
OnClientUploadComplete="UploadComplete1"
ID="ImageFileUploader"
runat="server" />
*in the code behind of the ascx file (upload_chart.ascx.cs) I handle the FileUploadComplete:*
public void FileUploadComplete1(object sender, EventArgs e)
{
try
{
if (ImageFileUploader.FileBytes.Length > 0)
{
// File data is in ImageFileUploaded.FileBytes
// Save it however you need to
// I saved it to a database, in a DBImage Object class I created
// DBImage is specific to my application
ODS.Entity.DBImage pimg =
ODS.Data.DataRepository.SaveImageBytes(ImageFileUploaded.FileBytes);
// Set the ImageID1 in the session
Session["ImageID1"] = pimg.IdImageGroup.ToString();
}
else
{
// error handling for an empty file, however you want to handle it
}
}
catch (Exception Ex)
{
// error handling for an unhandled exception, whatever you want to do here
}
}
Javascript and script methods are used to set the value on the page, here is my codebehind for the script method:
// on the aspx page code behind (chartofthedayadmin.aspx.cs) I have the webmethod:
[System.Web.Services.WebMethod]
public static string GetImageID1()
{
System.Web.SessionState.HttpSessionState Session = System.Web.HttpContext.Current.Session;
String retval = Session["ImageID1"].ToString();
Session["ImageID1"] = null;
return retval;
}
Here is the javascript:
// on the aspx front end (chartofthedayadmin.aspx) I have the javascript
// to call the Web method and the javascript failed message:
function UploadComplete1() {
var str = PageMethods.GetImageID1(uploadSuccess1, uploadFailed);
}
function uploadFailed() {
alert('error occurred or some meaningfull error stuff');
}
*// javascript on the user control (upload_chart.ascx) to set the value of the hidden field*
function uploadSuccess1(result) {
document.getElementById('<%= fldImageID.ClientID %>').value = result;
}
note: Make sure your scriptmanager has EnablePageMethods="true".
The better and more simple solution is in code behind:
string script = String.Format("top.document.getElementById('hdnFilename').value='{0}';", safeFilename);
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "hdnFilenameFromCodeBehind", script, true);
In my case, safeFilename is the unique filename, after handling duplicate filename, i.e. sample_5.png in the 5th upload of sample.png.
See http://forums.asp.net/t/1503989.aspx