Open popup before or after clicking the Workflow button in Netsuite - suitescript

I have this code (Userevent script) which is working fine with my custom button,
function beforeLoad_addButton(type, form) {
var url = nlapiResolveURL('SUITELET', '543', 'customdeploy1')+'&entity=' + nlapiGetRecordId() + '&recordType=' + nlapiGetRecordType();
var script = "win = window.open('" + url + "', 'win', 'resizable=0,scrollbars=0,width=450,height=300');";
form.addButton('custpage_buttonalert', 'Add Memo', script);
}
but now I want to open this popup (Suitelet) from another button created with the Workflow. How I can hook onclick action on button created with the Workflow without interrupting the workflow.

I managed to do it like this:
function beforeLoad_addButton(type, form) {
var url = nlapiResolveURL('SUITELET', '424', 'customdeploy1')+'&entity=' + nlapiGetRecordId() + '&recordType=' + nlapiGetRecordType();
var script = "win = window.open('" + url + "', 'win', 'resizable=0,scrollbars=0,width=450,height=300');";
form.addButton('custpage_buttonalert', 'Add Memo', script);
var ids = ['custpageworkflow105', 'custpageworkflow128', 'custpageworkflow148', 'custpageworkflow106', 'custpageworkflow129', 'custpageworkflow149', 'custpageworkflow107', 'custpageworkflow130', 'custpageworkflow150'];
var script1 = '';
script1 += '<script>';
ids.forEach(function(entry) {
script1 += 'jQuery("#' + entry + '").click(function() {'+ script +'});';
});
script1 += '</script>'
var newInlineHtmlField = form.addField('custpage_myinline','inlinehtml','',null,null);
newInlineHtmlField.setDefaultValue(script1);
}
I'm injecting the Javascript in the form. Here, the "ids" array is containing the workflow button ID's. When one of the button is clicked the code in script1 variable is executed, after that the workflow is performed.

Related

Restricting email notification for private site in alfresco

I have added a script to send mail whenever a site is created. How to restrict the email notification if the site created is a private site. Here is my java script
var mail = actions.create("mail");
var node = people.getGroup("GROUP_EMAIL_CONTRIBUTORS");
if(node){
var members = people.getMembers(node);
}
mail.parameters.from = "Administrator#community.com"
mail.parameters.subject=" A new site called " + document.properties.name+" is created";
mail.parameters.text="Click http://sameer_w7:8080/share/page/site/" + document.properties.name + "/dashboard" + " to join the site";
for(var i=0;i<members.length;i++)
{
mail.parameters.to = members[i].properties.email;
//execute action against a document
mail.execute(document);
}
You can get the siteVisibility state of a site.
Take a look at the SiteService Wiki page.
Something like this should work:
if (document.properties["st:siteVisibility"] != "PRIVATE"){
<your email action here>
}
Be sure you have selected type is st:site in your rule, otherwise add an extra check on that.

How to revert the changes in text file, if "Save & Close" on a page is not clicked?

I am passing the page id component id and template id to a aspx page as querystring with this java script:
var masterTabControl = $controls.getControl($("#MasterTabControl"),
"Tridion.Controls.TabControl");
p.compPresTab = masterTabControl.getPage("ComponentPresentationsTab");
p.selectedComponentPresentation = p.compPresTab.getSelectedComponentPresentation();
p.selectedComp = p.selectedComponentPresentation.getComponentId();
window.open("http://" + location.hostname + ":path/test.aspx?pgId=" + pageId +
"&comId=" + p.selectedComponentPresentation.getComponentId() +
"&comTmpId=" +
p.selectedComponentPresentation.getComponentTemplateId(),
"myWindow", "status = 1,
toolbar=no,width=300,height=200,resizable=no,scrollbars=yes");
Now on the test.aspx page i am reading the id and with some additional information from the user i am saving it into a text file.
On a button click on popup test.aspx page i am saving it in text file:
sLogDetails = PageId + "| " + ComponentId + "|" + ComponentTemplateId +
"|" + text ;
//Move the contents to the temp file other than the existing one.
using (var sr = new StreamReader(permanentFile))
{
using (var sw = new StreamWriter(#"" + tempFile , true))
{
string line;
while ((line = sr.ReadLine()) != null)
{
string[] parts = line.Split('|');
PageId = parts[0].Trim();
ComponentId = parts[1].Trim();
ComponentTemplateId = parts[2].Trim();
//Check there exist same record already
if (SPageId != PageId.Trim() || SComponentId != ComponentId.Trim()
|| SComponentTemplateId != ComponentTemplateId.Trim())
sw.WriteLine(line);
}
//Delete the Permanent file & create permanent file from temporary file
File.Delete(permanentFile);
File.Move(tempFile, permanentFile);
// Insert changes to the Permanent file
using (StreamWriter w = File.AppendText(permanentFile))
{
// Close the writer and underlying file.
w.WriteLine(sLogDetails);
w.Flush();
w.Close();
}
If the id is already present in the text file then i am populating it in the text field on popup test.aspx page like :
using (StreamReader r = File.OpenText(strPath + "Log.txt"))
{
string line;
while ((line = r.ReadLine()) != null)
{
// Console.WriteLine(line);
string[] parts = line.Split('|');
PageId=parts[0].Trim();
ComponentId = parts[1].Trim();
ComponentTemplateId = parts[2].Trim();
//If there exist a record populate the data fields
if (SPageId == PageId.Trim() && SComponentId == ComponentId.Trim()
&& SComponentTemplateId == ComponentTemplateId.Trim())
{
txtRuleName.Text = (string)parts[3];
}
}
r.Close();
}
Now I am getting stuck here. When it's populating in the text field, user can edit the text area in popup test.aspx page and on click of ok it will get saved in text file. And if user is closing the page window without "save & Close", then the changes made by him in text field should not get saved in text file. It should revert back to old one.
Any idea how can i make it?
It is fairly difficult to respond to "something that didn't happen".
So is there any way you can create a list of other ways that the user can exit that Window? With that list you can register the relevant event handlers (or override the relevant commands) and implement your roll back there.
Alternatively you can consider making the change to the file in a temporary location from your popup. And then only commit it to your text file when the user clicks Save and Close.
Note that his file-based approach will start failing when you scale out your Tridion GUI and Content Manager to run on multiple machines. In general you should be wary of storing things in files on a server, when you are working on enterprise level software. What is a single server now (and will always be a single server in your development environment) will turn into multiple servers at some point in the future at which time your solution will cause problems.

Adobe AIR/Flex file upload to a server that requires basic authentication

Adobe reference specifically points this out as a limitation.
Here's the note in the file.upload functionality in adobe reference.
Note: If your server requires user authentication, only SWF files running in a browser — that is, using the browser plug-in or ActiveX control — can provide a dialog box to prompt the user for a username and password for authentication, and only for downloads. For uploads using the plug-in or ActiveX control, or for uploads and downloads using the stand-alone or external player, the file transfer fails.
click here for the full reference page for File
Has anyone been able to work around this limitation. One thought I had was to use the native support in AIR for Javascript and see that works. Anyone tried that? Anyone have other ideas?
I've also tried the solution proposed here and it didn't work. According to the questioner in the forum it didn't seem to work for him either. Probably hitting the issue/limitation mentioned above.
I understand how to include basic authentication on a URLRequest and that works fine for me if I'm posting key/value pairs. But when I attempt to upload a file it does not work. It just sits there and does not fire any of the file.upload events. No errors no progress. Any help is much appreciated.
Here's my sample code:
var sendVars:URLVariables = new URLVariables();
sendVars.prop1 = "filename" ;
var urlRequest:URLRequest = new URLRequest();
urlRequest.method = URLRequestMethod.POST ;
urlRequest.data = sendVars ;
var encoder:Base64Encoder = new Base64Encoder();
encoder.encode("user:pass");
var credsHeader:URLRequestHeader = new URLRequestHeader("Authorization", "Basic " + encoder.toString());
urlRequest.requestHeaders.push(credsHeader);
file = new File(url);
file.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA , file_UploadCompleteDataHandler );
file.addEventListener( Event.OPEN, fileOpenHandler);
file.addEventListener(ProgressEvent.PROGRESS, fileProgressHandler);
file.addEventListener(Event.COMPLETE, file_CompleteHandler);
file.addEventListener(IOErrorEvent.IO_ERROR, file_IOErrorHandler);
file.addEventListener(HTTPStatusEvent.HTTP_STATUS , file_HTTPStatusHandler);
file.addEventListener(SecurityErrorEvent.SECURITY_ERROR, file_SecurityErrorHandler);
try {
// Start the file upload
file.upload(urlRequest, "primaryFile", false);
}
catch (error:Error) {
trace( "Unable to upload file." + file.name);
}
Do exactly what you are doing except get the file.data and pass it into this....
public static function prepareWithFormData(vars:MetadataList, bytes:ByteArray, fieldName:String, filename:String, request:URLRequest):void {
bytes.position = 0;
var boundary: String = '---------------------------' + UIDUtil.createUID();
var header1: String = "";
var varsArray:Array = vars.asArray();
for each(var item:Metadata in varsArray) {
header1 += "\r\n--" + boundary + "\r\n";
header1 += 'Content-Disposition: form-data; name="' + item.name + '"\r\n\r\n';
header1 += item.value;
}
header1 += '\r\n--'+boundary + '\r\n'
+'Content-Disposition: form-data; name="' + fieldName + '"; filename="'+filename+'"\r\n'
+'Content-Type: application/octet-stream\r\n\r\n'
//In a normal POST header, you'd find the image data here
var header2:String = '\r\n--'+boundary + '--';
//Encoding the two string parts of the header
var headerBytes1: ByteArray = new ByteArray();
headerBytes1.writeMultiByte(header1, "ascii");
var headerBytes2: ByteArray = new ByteArray();
headerBytes2.writeMultiByte(header2, "ascii");
//Creating one final ByteArray
var sendBytes: ByteArray = new ByteArray();
sendBytes.writeBytes(headerBytes1, 0, headerBytes1.length);
sendBytes.writeBytes(bytes, 0, bytes.length);
sendBytes.writeBytes(headerBytes2, 0, headerBytes2.length);
request.data = sendBytes;
request.method = URLRequestMethod.POST;
request.contentType = "multipart/form-data; boundary=" + boundary;
}

Updating ValidatorCallOut Error Message from Javascript

I am trying to update the error message for a CustomValidator that uses a ValidatorCallOut via javascript. Basically its checking to see if a number entered is an increment of a specified number. I have some code that will update the error message the first time it is run, but after that it will no longer update the error message, although through javascript alerts I see the values are actually being updated. Here is the client side javascript validation function I'm using:
function checkIncrement(sender, args) {
var incrementValue = parseInt(sender.orderIncrement); // Custom attribute registered with RegisterExpandoAttribute
var remainder = args.Value % incrementValue;
if ((remainder) != 0) {
var remainder, lowRange, highRange;
lowRange = parseInt(args.Value - remainder);
highRange = parseInt(lowRange + incrementValue);
sender.errormessage = "Closest possible values are <b>" + lowRange + "</b> or <b>" + highRange + "</b>"; // Gets updated once, but not after that
alert("Low Range: " + lowRange); // always updated with current value
args.IsValid = false;
return;
}
args.IsValid = true;
}
Any idea on how to keep the error message updated every time this is run to validate?
Try the following:
sender.errormessage = "Your message here";
var cell = sender.ValidatorCalloutBehavior._errorMessageCell;
// cell is going to be null first time.
if (cell != null) {
cell.innerHTML = "Your message here";
}
The reason why the message sticks once it has been initialized is because Callout is not created initially. Once it has been created, Callout is just hidden and is not recreated on subsequent showing. Thus, message that it was initialized with when it was created will stick and persist. The above code is a hack and there really should be a method along the lines of set_ErrorMessage, but there isn't one.

Problem Registering onsubmit statement for Extended button control

Hi I recently fell in love with an extended upload button control I found here that when used together with an aspnet file upload control, can perform uploads in a gmail-like manner. The only problem is that when the control is placed on a page any button on that page will trigger the click event of the extended control.
I had no idea why this was happening until I looked at the source code.
/// Basic registration of events
protected override void OnInit(EventArgs e)
{
this.Page.LoadComplete += new EventHandler(Page_LoadComplete);
base.OnInit(e);
this.Page.ClientScript.RegisterClientScriptInclude(this.GetType(), "ScriptBlock", this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "WebControls.JScripts.AIMScript.js"));
string cid = this.ClientID;
string onsubmitstatement = "return AIM.submit( document.forms[0], {'onStart' : " + OnStartScript + ", 'onComplete' : " + OnCompleteScript + "})";
this.Page.ClientScript.RegisterOnSubmitStatement(this.GetType(), "OnSubmitScript", onsubmitstatement);
}
From what I can gather the problem lies in the control registering the 'onsubmitstatement' for all controls
on pages form i.e 'document.forms[0]'. Now I have very limited experience in authoring custom controls so all my efforts to register the 'onsubmitstatement' for only the upload control has failed e.g
string ctrlid = this.ClientID
string onsubmitstatement = "return AIM.submit( document.getElementById('" + ctrlid + "'), {'onStart' : " + OnStartScript + ", 'onComplete' : " + OnCompleteScript + "})";
can any one help me? Is there a way to register the onsubmit function for only this control ?
We'd need to know what exactly AIMScript.js is actually doing to really answer the question.
The basic idea though is that you need to change the javascript so it does it's thing on the click event for a particular button, rather than intercepting the submit event for the entire form. But it could be that this particular javascript might be dependent on a form element in some other ways too.
It could be as simple as changing the registrations to just register a javascript DoClick function like this:
string onsubmitstatement = "function DoClick() {return AIM.submit( document.forms[0], {'onStart' : " + OnStartScript + ", 'onComplete' : " + OnCompleteScript + "})}";
this.Page.ClientScript. RegisterClientScriptBlock(this.GetType(), "OnSubmitScript", onsubmitstatement);
Then in on the actual button control, wire it up to call the new DoClick() javascript function you registered above --like this:
<input type="button" value="ClickMe" onclick="DoClick()" />

Resources