Javascript's setTimeout function is a method of the window object. This object doesn't exist in ExtendScript and is therefore not available to scripts made for Adobe InDesign or Illustrator. What can I use instead to acheive the same results?
It's part of the extendscript's $ object.
$.sleep(1000) //tell extendscript to sleep 1000 milliseconds
Not the same as setTimeout() but you should be able to make it work for you.
EDIT: Here is setTimeout extension for extendscript:
$.setTimeout = function(func, time) {
$.sleep(time);
func();
};
$.setTimeout(function () {alert("hello world")}, 3000);
There is a setTimeout ExtendScript implementation here (German site, with code commented in english), but since it relies on app.idleTasks, it works in InDesign only (no Photoshop).
I paste here the downloadable code found in the link above (© Andreas Imhof):
/**
* setTimeout
* Version 1.0
* A setTimeout function implementation for InDesign ExtendScript like known from a Browser's Javascript.
* Uses InDesign's idleTask stuff.
* Timeout milliseconds are not accurate, but it allows to call a heavy load script,
* split it up into small junks for InDesign is not blocked too long and has time to breath.
*
* The script MUST run in its dedicated target engine:
* #target "InDesign"
* #targetengine "myOwnEngineName"
*
* DISCLAIMER:
* No warranty - use as is or modify but retain the originator's coordinates:
* CopyRight Andreas Imhof, www.aiedv.ch, ai#aiedv.ch
*/
//
var setTimeout_Task_curfile = new File($.fileName),
setTimeout_Task_curfullname = decodeURI(setTimeout_Task_curfile.name),
// setTimeout_Taskname must be a UNIQUE name, so we take it from the current running script!!
// May be set to any String like
// setTimeout_Taskname = 'myOwnTask';
setTimeout_Taskname = setTimeout_Task_curfullname.lastIndexOf(".") > 0 ? (setTimeout_Task_curfullname.substr(0,setTimeout_Task_curfullname.lastIndexOf("."))) : setTimeout_Task_curfullname,
setTimeout_Tasks = {}, // all defined tasks prepared to run
/**
* setTimeout_hasIdleTask
* Utility function
* #param {Number} the timeout task id
* #return {Boolean} true if a given timeout id also has his attached idleTask
*/
setTimeout_hasIdleTask = function(id) {
var has = false, i;
for (i = 0; i < app.idleTasks.length; i++) {
//alert("id: " + id + " tid: " + app.idleTasks[i].label);
if (app.idleTasks[i].isValid && (app.idleTasks[i].id === id)) {
has = true;
break;
}
}
return has;
},
/**
* setTimeoutList
* Utility function
* #return {String} a list of all currently active setTimeout_Tasks
*/
setTimeoutList = function() {
var list = "", cb,
k;
for (k in setTimeout_Tasks) {
if (list !== "") list += ",";
cb = setTimeout_Tasks[k]["cb"].toString();
cb = cb.replace(/\s/g,"");
list += setTimeout_Tasks[k]["taskid"] + ":" + cb;
}
return list;
},
/**
* idleTasksList
* Utility function
* #return {String} a list of all currently active idleTasks
*/
idleTasksList = function() {
var list = "",
k;
for (k = 0; k < app.idleTasks.length; k++) {
if (list !== "") list += ",";
list += app.idleTasks[k].id + ":" + setTimeout_hasIdleTask(app.idleTasks[k].id) + ":" + app.idleTasks[k].label;
}
return list;
},
/**
* setTimeoutInit
* Init/clean the timeout system
*/
setTimeoutInit = function() {
var it;
// remove all (erroneous) idleTasks
//alert("set idleTasks: " + app.idleTasks.length);
//NA: logmess("setTimeoutInit set idleTasks: " + app.idleTasks.length + "\n");
for (it = 0; it < app.idleTasks.length; it++) {
if (app.idleTasks[it].label == setTimeout_Taskname) {
//alert("removing idleTask id " + app.idleTasks[it].id + " label: " + app.idleTasks[it].label);
clearTimeout(app.idleTasks[it].id);
}
}
setTimeout_Tasks = {};
},
/**
* Tasks Handler
* Check if a task can be called now
* #param {Number} taskid
* #return {Boolean} always false
*/
setTimeoutHandler = function(taskid) {
var now_Ticks = new Date().getTime(),
cb, cb_retval = undefined;
try {
//alert("taskid: " + taskid + "\nnumcalls: " + setTimeout_Tasks[taskid]["numcalls"]);
// we look for well timed call only!!! CS6 calls at start AND after the timeout
if (setTimeout_Tasks[taskid]["end_ticks"] > now_Ticks) { // we have not reached timeout
//NA: logmess("setTimeoutHandler id " + taskid + " too early by ms: " + (setTimeout_Tasks[taskid]["end_ticks"] - now_Ticks) + "\n");
//alert("setTimeoutHandler id " + taskid + " too early by ms: " + (setTimeout_Tasks[taskid]["end_ticks"] - now_Ticks));
setTimeout_Tasks[taskid]["numcalls"] += 1;
return false; // wait for next call
}
}
catch(ex) {
alert("Exception (1) in function 'setTimeoutHandler()', taskid " + taskid + ":\n" + ex);
}
try {
cb = setTimeout_Tasks[taskid]["cb"]; // store the callback
clearTimeout(taskid); // remove the timeout
}
catch(ex) {
alert("Exception (2) in function 'setTimeoutHandler()', taskid " + taskid + ":\n" + ex);
}
try {
//NA: logmess("setTimeoutHandler call " + cb + "\n");
cb_retval = cb(); // call the cb
//if (cb_retval) alert("cb_retval:\n" + cb_retval);
} catch(ex) {
alert("Exception in function '" + cb() + ":\n" + ex);
}
return false;
},
/**
* setTimeout
* Set a function to called after the given timeout
* #param {function} callback the function to call
* #param {Number} timeout in ms
* #return {Boolean} null on error, otherwise the id (can be used with clearTimeout
*/
setTimeout = function(callback,timeout) {
try {
var idle_Task,
now_Ticks = new Date().getTime();
idle_Task = app.idleTasks.add({sleep:timeout});
idle_Task.label = setTimeout_Taskname;
setTimeout_Tasks[idle_Task.id] = {
"label": setTimeout_Taskname,
"start_ticks": now_Ticks,
"sleep": timeout,
"end_ticks": now_Ticks + timeout,
"cb": callback,
"taskid": idle_Task.id,
"numcalls": 0
};
setTimeout_Tasks[idle_Task.id].handler = function(ev){setTimeoutHandler(setTimeout_Tasks[idle_Task.id]["taskid"]);};
idle_Task.addEventListener(IdleEvent.ON_IDLE, setTimeout_Tasks[idle_Task.id].handler,false);
//NA: logmess("setTimeout idle_Task.id: " + idle_Task.id + ", timeout: " + timeout + "\ncallback: " + callback + "\n");
return idle_Task.id;
}
catch(ex) {
alert("Exception in function 'setTimeout()':\n" + ex);
}
return null;
},
/**
* clearTimeout
* Clear the timeout given by the setTimeout return value
* #param {Number} id the timeout id to clear
*/
clearTimeout = function (id){
var i, task = null;
for (i = 0; i < app.idleTasks.length; i++) {
//alert("id: " + id + " tid: " + app.idleTasks[i].label);
if ((app.idleTasks[i].id == id) && app.idleTasks[i].isValid) {
task = app.idleTasks[i];
break;
}
}
if (task !== null) {
try {
if (setTimeout_Tasks[id] && setTimeout_Tasks[id].handler) {
// this kills any!!! app.idleTasks.itemByID(id).removeEventListener(IdleEvent.ON_IDLE, setTimeout_Tasks[id].handler,false);
task.removeEventListener(IdleEvent.ON_IDLE, setTimeout_Tasks[id].handler,false);
}
// this kills any!!! app.idleTasks.itemByID(id).remove();
//task.remove();
task.sleep = 0;
}
catch(ex) {
alert("Exception in function 'clearTimeout() idleTasks':\n" + ex);
}
try {
delete setTimeout_Tasks[id];
}
catch(ex) {
alert("Exception in function 'clearTimeout() delete setTimeout_Tasks':\n" + ex);
}
}
};
/**
* Init/clean the timeout system
*/
setTimeoutInit();
// alert(setTimeout_Taskname); // Just to check if the 'setTimeout_Taskname' was set correctly
In Adobe After Effects using the $.sleep(time) will cause the script to stall.
Instead use the native app.scheduleTask(stringToExecute, delay, repeat) in ExtendScript:
Example:
var taskId = app.scheduleTask(function () {alert("hello world")}, 1500, false);
To cancel:
app.cancelTask(taskId);
Related
Short Version:
I am using the code from the Project Tracker Template to send out emails showing the change in a status for a field (Contact Name changed from: Billy -> Susan).
Everything works perfectly expect when I have a field that is a Date instead of a String. If I have a Date field in the code I get the following error:
'string' value is expected for 'NewValue' field in model 'SystemOrdersHistory', but found object. Error: 'string' value is expected for 'NewValue' field in model 'SystemOrdersHistory', but found object. at onSystemOrdersSave_ (Datasources:218) at models.SystemOrders.onSaveEvent:1
Modifying records: (Error) : 'string' value is expected for 'NewValue' field in model 'SystemOrdersHistory', but found object.
(Error) : 'string' value is expected for 'NewValue' field in model 'SystemOrdersHistory', but found object.
Any help would be greatly appreciated!
Long Version
I am using the code below (adjusted to fit the names of my models and fields).
Whenever I add a Date field (ex: DeliveryDate) to the function "notifyAboutItemChanges_" function and the "onSystemOrdersSave_" function I get the error about "expecting a string, but found an object".
Note: The OldValue and NewValue fields in the "History" model are both Strings.
Notifications Server Script:
/**
* Sends email.
* #param {!string} to - email address of a recipient.
* #param {!string} subject - subject of email message.
* #param {!string} body - body of email message.
*/
function sendEmail_(to, subject, body) {
try {
MailApp.sendEmail({
to: to,
subject: subject,
htmlBody: body,
noReply: true
});
} catch (e) {
// Suppressing errors in email sending because email notifications
// are not critical for the functioning of the app.
console.error(JSON.stringify(e));
}
}
/**
* Sends email notification about recent project item changes to item owner
* and assignee.
* #param {!Array<ItemHistory>} changes - list of recent project item changes.
*/
function notifyAboutItemChanges_(changes) {
if (!changes || changes.length < 2) {
return;
}
var settings = getAppSettingsRecord_()[0];
if (!settings.EnableEmailNotifications) {
return;
}
var data = {
appUrl: settings.AppUrl,
itemShowName: changes[0].ShowName,
itemUsersPosition: changes[0].UsersPosition,
itemDeliveryInfo: changes[0].DeliveryInfo,
itemDeliveryDate: changes[0].DeliveryDate,
itemKey: changes[0]._key,
itemName: changes[0].Name,
modifiedBy: changes[0].ModifiedBy,
changes: changes
};
// Email subject.
var subjectTemplate =
HtmlService.createTemplate(settings.NotificationEmailSubject);
subjectTemplate.data = data;
var subject = subjectTemplate.evaluate().getContent();
// Email body.
var emailTemplate =
HtmlService.createTemplate(settings.NotificationEmailBody);
emailTemplate.data = data;
var htmlBody = emailTemplate.evaluate().getContent();
sendEmail_('user#gmail.com', subject, htmlBody);
Datasources Server Script:
/**
* Item key URL parameter.
*/
var ITEM_KEY = 'itemKey';
/**
* Checks that Application Settings record already exists.
* Otherwise creates a new one.
* #return {!Array<AppSettings>} app settings record as an array.
*/
function getAppSettingsRecord_() {
var newQuery = app.models.AppSettings.newQuery();
var settingsRecords = newQuery.run();
if (settingsRecords.length > 1) {
console.warn('There is more than one(%s) App Settings entries' +
'in the database', settingsRecords.length);
}
if (settingsRecords.length === 0) {
var settingsRecord = app.models.AppSettings.newRecord();
settingsRecord.AppUrl = ScriptApp.getService().getUrl();
settingsRecord.NotificationEmailSubject =
'A change has been made to <?= data.itemShowName?>: <?= data.itemUsersPosition?>';
settingsRecord.NotificationEmailBody =
'Hello!\n<br/>\n<p><b><?= data.modifiedBy ?></b> ' +
'made the following changes: </p>\n' +
'<? for (var i = 1; i < data.changes.length; i++) {\n' +
'\tvar change = data.changes[i]; ?>\n' +
'\t<b><?= change.FieldName ?>: </b>\n' +
'\t<? if (change.FieldName === "Comment") { ?>\n' +
'\t\t<div style="white-space: pre-line;"><?= change.NewValue ?></div>' +
'\n\t<? } else { ?>\n ' +
'\t\t<?= change.OldValue ?> → <?= change.NewValue ?>' +
'\n\t<? } ?>\n\t<br/>\n' +
'<? } ?>\n<br/>\n' +
'<a href="<?= data.appUrl ?>?' + ITEM_KEY + '=<?= data.itemKey ?>' +
'#EditItem" target="_blank">Go to the project item</a>';
app.saveRecords([settingsRecord]);
return [settingsRecord];
} else {
return settingsRecords;
}
}
/**
* Populates project record with required data on project create event.
* #param {!Project} project - project being created.
*/
function onProjectCreate_(project) {
var date = new Date();
project.CreatedDate = date;
project.ModifiedDate = date;
project.ModifiedBy = currentUserEmail_();
}
/**
* Audits project on changes.
* #param {!Project} project - project being modified.
*/
function onProjectSave_(project) {
project.ModifiedDate = new Date();
project.ModifiedBy = currentUserEmail_();
}
/**
* Populates project item with required data on item create event, adds
* comment entry to the project item history.
* #param {!SystemOrders} SystemOrders - project item being created.
*/
function onSystemOrdersCreate_(SystemOrders) {
var date = new Date();
var editor = currentUserEmail_();
if (SystemOrders.Comment) {
SystemOrders.Comment = SystemOrders.Comment.trim();
}
SystemOrders.CreatedDate = date;
SystemOrders.Owner = editor;
SystemOrders.ModifiedDate = date;
SystemOrders.ModifiedBy = editor;
if (SystemOrders.Comment) {
var history = app.models.SystemOrdersHistory.newRecord();
history.CreatedBy = currentUserEmail_();
history.CreatedDate = new Date();
history.FieldName = 'Comment';
history.NewValue = SystemOrders.Comment;
app.saveRecords([history]);
SystemOrders.History.push(history);
}
}
/**
* Calculates history entries sum for {Array<SystemOrders>}.
* #param {!number} historySum - the accumulated number of history entries
* previously returned in the last invocation of the callback, or
* initialValue, if supplied.
* #param {!SystemOrders} SystemOrders - the current {SystemOrders} being
* processed in the array.
* #return {!number} history entries sum.
*/
function sumHistory_(historySum, SystemOrders) {
return historySum + SystemOrders.History.length;
}
/**
* Calculates potential project deletion impact.
* Throws an error if there is no project with the key provided.
* #param {!string} projectKey - project key to calculate deletion impact.
*/
function getDeleteProjectImpact(projectKey) {
var projectQuery = app.models.Project.newQuery();
projectQuery.prefetch.Items._add();
projectQuery.prefetch.Items.History._add();
projectQuery.filters._key._equals = projectKey;
var projects = projectQuery.run();
if (projects.length === 0) {
throw new Error('Project with key ' + projectKey + ' was not found.');
}
var SystemOrderss = projects[0].Items;
return {
affectedItems: SystemOrderss.length,
affectedHistory: SystemOrderss.reduce(sumHistory_, 0)
};
}
/**
* Checks that project item readonly fields were not modified.
* Throws an error if user attempts to modify read only fields.
* #param {!SystemOrders} record - modified project item.
* #param {!SystemOrders} oldRecord - project item before modification.
*/
function validateItemChange_(record, oldRecord) {
var readonlyFields = [
'CreatedDate',
'ModifiedBy',
'ModifiedDate',
'Owner'
];
for (var i = 0; i < readonlyFields.length; i++) {
var field = readonlyFields[i];
var newValue = record[field];
var oldValue = oldRecord[field];
var isDate = newValue instanceof Date && oldValue instanceof Date;
if (isDate === true) {
newValue = record[field].getDate();
oldValue = oldRecord[field].getDate();
}
if (newValue === oldValue) {
continue;
}
throw new Error(field + ' field is read only');
}
}
/**
* Handles project item change event, creates history entries for each changed
* field.
* #param {!SystemOrders} record - modified project item.
* #param {!SystemOrders} oldRecord - project item before modification.
*/
function onSystemOrdersSave_(record, oldRecord) {
validateItemChange_(record, oldRecord);
var editableFields = [
'ShowName',
'UsersPosition',
'DeliveryInfo',
'DeliveryDate'
];
var editor = currentUserEmail_();
var date = new Date();
var changes = [record];
record.ModifiedBy = editor;
record.ModifiedDate = date;
for (var i = 0; i < editableFields.length; i++) {
var field = editableFields[i];
var newValue = record[field];
var oldValue = oldRecord[field];
if (newValue !== oldValue) {
var history = app.models.SystemOrdersHistory.newRecord();
history.Item = record;
history.CreatedBy = editor;
history.CreatedDate = date;
history.FieldName = field;
history.NewValue = newValue;
history.OldValue = oldValue;
changes.push(history);
}
}
app.saveRecords(changes);
notifyAboutItemChanges_(changes);
}
/**
* Counts project items by some grouping criteria(field).
* #param {!string} projectKey - project key to calculate stats.
* #param {!string} grouping - project item field to group items by.
* #param {!Array<string>} groupingValues - possible field values.
* #return {!Array<SystemOrderssBreakdown>} grouped project items counts.
*/
function getSystemOrderssBreakdown_(projectKey, grouping, groupingValues) {
if (!grouping || !groupingValues || groupingValues.length === 0) {
return [];
}
var itemsQuery = app.models.SystemOrders.newQuery();
itemsQuery.prefetch.Project._add();
itemsQuery.filters.Project._key._equals = projectKey;
var items = itemsQuery.run();
if (items.length === 0) {
return [];
}
var records = [];
var map = {};
for (var i = 0; i < items.length; i++) {
var itemGrouping = items[i][grouping];
if (!map[itemGrouping]) {
map[itemGrouping] = 0;
}
map[itemGrouping]++;
}
for (i = 0; i < groupingValues.length; i++) {
var breakdownRecord = app.models.SystemOrderssBreakdown.newRecord();
var groupingValue = groupingValues[i];
breakdownRecord.Grouping = groupingValue;
breakdownRecord.ItemsCount = map[groupingValue] || 0;
records.push(breakdownRecord);
}
return records;
}
It fails here:
// history.NewValue and history.OldValue are strings
// newValue and oldValue can be of any type (Boolean, Number, Date,
// but not a relation as of now)
// You are getting an exception because you are not casting types
history.NewValue = newValue;
history.OldValue = oldValue;
You can fix it by adding fields of each possible type to your history model (NewStringValue, NewDateValue, NewBoolValue, NewNumberValue, OldStringValue...). With that approach you'll get benefits of strong typing, but your code and UI will become significantly more complex...
You can store all your fields' history as strings(like you are doing now), but in this case you'll need to think about formatting and localization in advance:
function fieldToString(field, fieldValue) {
// TODO: pass field metadata to individually handle
// different data types.
return fieldValue !== null ? fieldValue.toString() : null;
}
...
history.NewValue = fieldToString(field, newValue);
history.OldValue = fieldToString(field, oldValue);
...
I'm Having some trouble making an POST Http Request to my firebase cloud-functions project from Unity3D game engine.
I keep getting a code 400 response, and in the firebase console I can see the following error:
Error: invalid json at parse
I don't really have a lot of knowledge about Http requests, and after quite some time of trying to find out a solution I'd like to ask for help.
Here is the client code:
public void RateLevel(string guid, int rating)
{
RateLevelRequest rlr = new RateLevelRequest (guid, rating.ToString());
string body = rlr.ToJson ();
UnityWebRequest www = UnityWebRequest.Post("myurl", body);
www.SetRequestHeader ("Content-Type", "application/json");
StartCoroutine (MakeRequest (www));
}
/* * * * * * * * * * * * * * * * * * *
* AUXILIAR CLASS FOR HTTP REQUESTS *
* * * * * * * * * * * * * * * * * * */
[System.Serializable]
public class RateLevelRequest
{
public string guid;
public string rating;
public RateLevelRequest(string _guid, string _rating)
{
guid = _guid;
rating = _rating;
}
public string ToJson()
{
string json = JsonUtility.ToJson (this);
Debug.Log ("RateLevelRequest Json: " + json);
return json;
}
}
I can guarantee that the json is well formed, with values like this.
{"guid":"fake-guid","rating":"-1"}
And here is my current deployed function in firebase-functions.
exports.rate_level = functions.https.onRequest((req, res) => {
if(req.method === 'POST')
{
console.log('guid: ' + req.body.guid);
console.log('rating: ' + req.body.rating);
console.log('invented var: ' + req.body.myinvention);
if(req.body.guid && req.body.rating &&
(req.body.rating == 1 || req.body.rating == -1))
{
res.status(200).send('You are doing a post request with the right fields and values');
}
else
{
res.status(403).send('Required Fields are not Defined!')
}
}
else
{
res.status(403).send('Wrong Request Method!');
}
});
Has anyone tried this and succeeded before?
Thanks in advance!
Ok I found the answer in an excellent blog entry.
I really don't know what was wrong, but I instead replaced my code to the one indicated in the article mentioned above, which works. I'll post it for the rest of you having issues.
public void RateLevel(string guid, int rating)
{
RateLevelRequest rlr = new RateLevelRequest (guid, rating.ToString());
string body = rlr.ToJson ();
byte[] bodyRaw = new System.Text.UTF8Encoding ().GetBytes (body);
UnityWebRequest www = new UnityWebRequest("myurl", UnityWebRequest.kHttpVerbPOST);
www.uploadHandler = (UploadHandler)new UploadHandlerRaw (bodyRaw);
www.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
www.SetRequestHeader ("Content-Type", "application/json");
StartCoroutine (MakeRequest (www));
}
Best!
I am using external interface to store cookies in client side of application. Like I have created a cookie in html and i am using those methods in flex using External Interface. I am saving a username in cookie when I re use cookie is displaying, I have deployed in server and i ran like http://localhost/[Path]/index.html.in this html I am embedded swf file and I have saved cookie in html JavaScript, now if I open this url cookie is saving if I open a new window what ever the cookies are a raised and it is loading from start. for cookies saving i am using this code in flex:`package Name{
import flash.external.ExternalInterface;
/**
* The Cookie class provides a simple way to create or access
* cookies in the embedding HTML document of the application.
*
*/
public class Cookies {
/**
* Flag if the class was properly initialized.
*/
private static var _initialized:Boolean = false;
/**
* Name of the cookie.
*/
private var _name:String;
/**
* Contents of the cookie.
*/
private var _value:String;
/**
* Flag indicating if a cookie was just created. It is <code>true</code>
* when the cookie did not exist before and <code>false</code> otherwise.
*/
private var _isNew:Boolean;
/**
* Name of the external javascript function used for getting
* cookie information.
*/
private static const GET_COOKIE:String = "cookieGetCookie";
/**
* Name of the external javascript function used for setting
* cookie information.
*/
private static const SET_COOKIE:String = "cookieSetCookie";
/**
* Javascript code to define the GET_COOKIE function.
*/
private static var FUNCTION_GET_COOKIE:String =
"function () { " +
"if (document." + GET_COOKIE + " == null) {" +
GET_COOKIE + " = function (name) { " +
"if (document.cookie) {" +
"cookies = document.cookie.split('; ');" +
"for (i = 0; i < cookies.length; i++) {" +
"param = cookies[i].split('=', 2);" +
"if (decodeURIComponent(param[0]) == name) {" +
"value = decodeURIComponent(param[1]);" +
"return value;" +
"}" +
"}" +
"}" +
"return null;" +
"};" +
"}" +
"}";
/**
* Javascript code to define the SET_COOKIE function.
*/
private static var FUNCTION_SET_COOKIE:String =
"function () { " +
"if (document." + SET_COOKIE + " == null) {" +
SET_COOKIE + " = function (name, value) { " +
"document.cookie = name + '=' + value;" +
"};" +
"}" +
"}";
/**
* Initializes the class by injecting javascript code into
* the embedding document. If the class was already initialized
* before, this method does nothing.
*/
private static function initialize():void {
if (Cookies._initialized) {
return;
}
if (!ExternalInterface.available) {
throw new Error("ExternalInterface is not available in this container. Internet Explorer ActiveX, Firefox, Mozilla 1.7.5 and greater, or other browsers that support NPRuntime are required.");
}
// Add functions to DOM if they aren't already there
ExternalInterface.call(FUNCTION_GET_COOKIE);
ExternalInterface.call(FUNCTION_SET_COOKIE);
Cookies._initialized = true;
}
/**
* Creates a new Cookie object. If a cookie with the specified
* name already exists, the existing value is used. Otherwise
* a new cookie is created as soon as a value is assigned to it.
*
* #param name The name of the cookie
*/
public function Cookies(name:String) {
Cookies.initialize();
this._name = name;
this._value = ExternalInterface.call(GET_COOKIE, name) as String;
this._isNew = this._value == null;
}
/**
* The name of the cookie.
*/
public function get name():String {
return this._name;
}
/**
* The value of the cookie. If it is a new cookie, it is not
* made persistent until a value is assigned to it.
*/
public function get value():String {
return this._value;
}
/**
* #private
*/
public function set value(value:String):void {
this._value = value;
ExternalInterface.call(SET_COOKIE, this._name, this._value);
}
/**
* The <code>isNew</code> property indicates if the cookie
* already exists or not.
*/
public function get isNew():Boolean {
return this._isNew;
}
}
}
I am using cookie like this var anotherCookie:Cookies = new Cookies("username");
anotherCookie.value=[Textinput].text;.is there any code i need to use save cookie in new window also? Please help me Thanks in Advance.
By default browsers will delete cookies at the end of the current session, e.g. when they close the browser. You can set an "expires" date to some far future date in order for it to stick around for a while. Note that if they have certain types of anti-virus programs it might delete the cookie as well.
Hi I need to save email-id in my login form through the cookies. if I use shared object I am able to save but my requirement is need to save in cookies. How can I save? I got sample code from net. Attaching that code `package com {
import flash.external.ExternalInterface;
/**
* The Cookie class provides a simple way to create or access
* cookies in the embedding HTML document of the application.
*
*/
public class Cookie {
/**
* Flag if the class was properly initialized.
*/
private static var _initialized:Boolean = false;
/**
* Name of the cookie.
*/
private var _name:String;
/**
* Contents of the cookie.
*/
private var _value:String;
/**
* Flag indicating if a cookie was just created. It is <code>true</code>
* when the cookie did not exist before and <code>false</code> otherwise.
*/
private var _isNew:Boolean;
/**
* Name of the external javascript function used for getting
* cookie information.
*/
private static const GET_COOKIE:String = "cookieGetCookie";
/**
* Name of the external javascript function used for setting
* cookie information.
*/
private static const SET_COOKIE:String = "cookieSetCookie";
/**
* Javascript code to define the GET_COOKIE function.
*/
private static var FUNCTION_GET_COOKIE:String =
"function () { " +
"if (document." + GET_COOKIE + " == null) {" +
GET_COOKIE + " = function (name) { " +
"if (document.cookie) {" +
"cookies = document.cookie.split('; ');" +
"for (i = 0; i < cookies.length; i++) {" +
"param = cookies[i].split('=', 2);" +
"if (decodeURIComponent(param[0]) == name) {" +
"value = decodeURIComponent(param[1]);" +
"return value;" +
"}" +
"}" +
"}" +
"return null;" +
"};" +
"}" +
"}";
/**
* Javascript code to define the SET_COOKIE function.
*/
private static var FUNCTION_SET_COOKIE:String =
"function () { " +
"if (document." + SET_COOKIE + " == null) {" +
SET_COOKIE + " = function (name, value) { " +
"document.cookie = name + '=' + value;" +
"};" +
"}" +
"}";
/**
* Initializes the class by injecting javascript code into
* the embedding document. If the class was already initialized
* before, this method does nothing.
*/
private static function initialize():void {
if (Cookie._initialized) {
return;
}
if (!ExternalInterface.available) {
throw new Error("ExternalInterface is not available in this container. Internet Explorer ActiveX, Firefox, Mozilla 1.7.5 and greater, or other browsers that support NPRuntime are required.");
}
// Add functions to DOM if they aren't already there
ExternalInterface.call(FUNCTION_GET_COOKIE);
ExternalInterface.call(FUNCTION_SET_COOKIE);
Cookie._initialized = true;
}
/**
* Creates a new Cookie object. If a cookie with the specified
* name already exists, the existing value is used. Otherwise
* a new cookie is created as soon as a value is assigned to it.
*
* #param name The name of the cookie
*/
public function Cookie(name:String) {
Cookie.initialize();
this._name = name;
this._value = ExternalInterface.call(GET_COOKIE, name) as String;
this._isNew = this._value == null;
}
/**
* The name of the cookie.
*/
public function get name():String {
return this._name;
}
/**
* The value of the cookie. If it is a new cookie, it is not
* made persistent until a value is assigned to it.
*/
public function get value():String {
return this._value;
}
/**
* #private
*/
public function set value(value:String):void {
this._value = value;
ExternalInterface.call(SET_COOKIE, this._name, this._value);
}
/**
* The <code>isNew</code> property indicates if the cookie
* already exists or not.
*/
public function get isNew():Boolean {
return this._isNew;
}
}
}
`How can I use this? I need to integrate this with jsp by default swf file is embedded in jsp.
How can I save only username (email-id)? If user reenters again it should show in dropdown. how can I pass text input text into the cookie? Please help me in these Thanks in advance.
The posted code uses the ExternalInterface class to access the browsers cookies through JavaScript. I guess your question is about how to use that class. Here you go:
// Initialize the object:
var cookie:Cookie = new Cookie("NAME OF THE COOKIE");
// Retrieve and trace the value of the cookie:
trace(cookie.value());
// Set new value for the cookie:
cookie.value = "NEW VALUE";
I cannot answer the remaining questions about the drop down. You'll need to be more specific what your actual question is.
I am a little stuck and need some advice/help.
I have a progress bar:
<mx:ProgressBar id="appProgress" mode="manual" width="300" label="{appProgressMsg}" minimum="0" maximum="100"/>
I have two listener functions, one sets the progress, and one sets the appProgressMsg:
public function incProgress(e:TEvent):void {
var p:uint = Math.floor(e.data.number / e.data.total * 100);
trace("Setting Perc." + p);
appProgress.setProgress(p, 100);
}
public function setApplicationProgressStep(e:TEvent):void {
trace("Setting step:" + e.data);
appProgressMsg = e.data;
}
I want to reuse this progress bar alot. And not necessarily for ProgressEvents, but when going through steps.
For instance, I loop over a bunch of database inserts, and want to undate the progress etc.
Here is a sample:
public function updateDatabase(result:Object):void {
var total:int = 0;
var i:int = 0;
var r:SQLResult;
trace("updateDatabase called.");
for each (var table:XML in this.queries.elements("table")) {
var key:String = table.attribute("name");
if (result[key]) {
send(TEvent.UpdateApplicationProgressStep, "Updating " + key);
i = 1;
total = result[key].length;
for each (var row:Object in result[key]) {
//now, we need to see if we already have this record.
send(TEvent.UpdateApplicationProgress, { number:i, total: total } );
r = this.query("select * from " + key + " where server_id = '" + row.id + "'");
if (r.data == null) {
//there is no entry with this id, make one.
this.query(table.insert, row);
} else {
//it exists, so let's update.
this.update(key, row);
}
i++;
}
}
}
}
Everything works fine.
That is, the listener functions are called and I get trace output like:
updateDatabase called.
Setting step:Updating project
Setting Perc 25
Setting Perc 50
Setting Perc 75
Setting Perc 100
The issue is, only the very last percent and step is shown. that is, when it's all done, the progress bar jumps to 100% and shows the last step label.
Does anyone know why this is?
Thanks in advance for any help,
Jason
The new code, which works awesomely I might add:
public function updateDatabase(result:Object, eindex:int = 0, sindex:int = 0 ):void {
var total:int = 0;
var i:int = 0;
var j:int;
var r:SQLResult;
var table:XML;
var key:String;
var elems:XMLList = this.queries.elements("table");
var startTime:int = getTimer();
var row:Object;
for (i = eindex; i < elems.length(); i++) {
table = elems[i];
key = table.attribute("name");
if (!result[key])
continue;
total = result[key].length;
send(TEvent.UpdateApplicationProgressStep, "Updating " + key);
for (j = sindex; j < result[key].length; j++) {
if (getTimer() - startTime > 100) {
setTimeout(updateDatabase, 100, result, i, j);
send(TEvent.UpdateApplicationProgress, { number:j, total: total } );
return;
}
row = result[key][j];
r = this.query("select * from " + key + " where server_id = '" + row.id + "'");
if (r.data == null) {
//there is no entry with this id, make one.
this.query(table.insert, row,false);
} else {
//it exists, so let's update.
this.update(key, row,false);
}
}
send(TEvent.UpdateApplicationProgress, { number:1, total: 1 } );
}
}
Flash is single threaded. The display will not update until your function returns. For this reason, you should never have any code that runs for longer than about 100ms (1/10th of a second), otherwise the UI (or even the entire browser) will appear to be locked up.
The general solution is to split up your work over multiple frames, here is some pseudo-code:
function doWork(arg1:Obj, arg2:Obj, start:int=0) {
var startTime = getTimer(); // store starting time
for(i=start; i<length; i++) {
if(getTimer() - startTime > 100) { // see if we've been working too long
trace("Current progress: "+(i/length * 100)+"%");
updateProgress( i / length );
setTimeout(doWork, 100, arg1, arg2, i); // schedule more work to be done
return; // stop current loop
}
trace("Working on item "+i);
// processing here
}
trace("All work done");
}
doWork(data1, data2); // start the work
Your pseudo-code works for updating the progress bar however in my case my "work" was copying of files from DVD to the appStorageDirectory which seem to reintroduce the same issue that your work around resolved - the progress bar now does not update
Here is my hack of your solution
function doWork(arg1:int, arg2:int, start:int=0) {
var startTime = getTimer(); // store starting time
for(var i:int=start; i<arg2; i++) {
if(getTimer() - startTime > 100 ) { // see if we've been working too long
trace("Current progress: "+(i/arg2 * 100)+"%");
setTimeout(doWork, 100, i, arg2, i); // schedule more work to be done
return; // stop current loop
}
trace("Working on item "+i);
dispatchEvent(new progressMadeEvent("incrementChange",i,arg2))
var dir:String = copyRes[i].nativePath.toString().split(OSSep).pop()
copyRes[i].copyTo(appStore.resolvePath(dir)) // copies dir from DVD to appStorageDir
}
trace("All work done");
}