PDF Acro javascript dialog box issue - javascript

I am working on creating a custom PDF dialog box and am having an issue getting the values that were entered. I have checked the code and cant find the issue. When I press accept and display the value that was entered into field1 it says "undefined". Any pointers on where the bug is would be helpful Thanks in advance.
[// Dialog Definition]
var oDlg = {
field1: "",
field2: "",
field3: "",
field4: "",
// [* initialize: Method that runs when the dialog is created*]
initialize: function(dialog) {
var dlgInit = {
"firstLine":this.field1,
"secondLine":this.field2,
"thirdLine":this.field3,
"forthLine":this.field4,};
dialog.load(dlgInit);
},
// [* commit: Method called when OK button is selected*]
commit: function(dialog) {
var data = dialog.store();
this.field1 = data["firstLine"];
this.field2 = data["secondLine"];
this.field3 = data["thirdLine"];
this.field4 = data["forthLine"];
},
// [* description: Actual dialog box fields *]
description: {
name: "Test Dialog",
elements: [ {
type: "view",
elements: [ {
name: "Additional Information",
type: "static_text",
},
{
name: "(For Further Credit, Reference of other Information)",
type: "static_text",
},
{
item_id: "firstLine",
type: "edit_text",
char_width: 35
},
{
item_id: "secondLine",
type: "edit_text",
char_width: 35
},
{
item_id: "thirdLine",
type: "edit_text",
char_width: 35
},
{
item_id: "forthLine",
type: "edit_text",
char_width: 35
},
{
type: "ok_cancel",
},
] },
] }
};
[// Dialog Activation]
if( "ok" == app.execDialog(oDlg)) { // [* ok_cancel button was pressed with ok *]
app.alert("The value is: "+oDlg.field1,3);
}

http://www.aiim.org/documents/standards/pdf/AcroJS.pdf
Page 99 - Description of item_id:
"An ItemID for this dialog, which is a unique 4- character string."
Your question is kind of old now, but maybe my answer can help someone else. ;)

Related

A filter to delete object with a specific variable in array

I want to show every task that does not have a propery of type: "delete"
tasks: [
{ title: "test" , type: "delete"},
{ title: "test" , type: "insert"},
{ title: "test" },
],
Something like code below.
this.apiTask.filter(x => !x.type : "delete"))
I would appreciate if someone can help
you have to check the properties in this way:
tasks: [
{ title: "test" , type: "delete"},
{ title: "test" , type: "insert"},
{ title: "test" },
]
console.log(this.apiTasks.flter(task => task.type !== 'delete'))
// OUTPUT: [
// { title: "test" , type: "insert"},
// { title: "test" },
// ]
There are two cases of above:
if you want that property "type" should be present and type!="delete"
then use this.apiTasks.filter(a=>a.type && a.type!=="delete")
# There will be 1 items #
if property existence does not matter
then use this.apiTasks.filter(a=>a.type!=="delete")
# there will be 2 items #
some extra things-
you can use lodash library
existence of a propery can be checked using a.hasOwnProperty("type")

react TypeError: Cannot read property 'type1' of undefined

I'm studying the react-beautiful-dnd example, and I want to add a conditional repulsion of an element, but I get an error that the field cannot be read.
This data
const initialData = {
tasks: {
'task-1': { id: 'task-1', content: 'Take out the garbage',type1: 'w' },
'task-2': { id: 'task-2', content: 'Watch my favorite show',type1: 'a' },
'task-3': { id: 'task-3', content: 'Charge my phone',type1: 'h' },
'task-4': { id: 'task-4', content: 'Cook dinner',type1: 'w' }
},
columns: {
'column-1': {
id: 'column-1',
title: 'To do',
type2: 'all',
taskIds: ['task-1', 'task-2', 'task-3', 'task-4']
},
'column-2': {
id: 'column-2',
title: 'In progress',
type2: 'w',
taskIds: []
},
'column-3': {
id: 'column-3',
title: 'Done',
type2: 'a',
taskIds: []
}
},
// Facilitate reordering of the columns
columnOrder: ['column-1', 'column-2', 'column-3'] }export default initialData
so they are connected
import initialData from './initial-data'
so it is assigned in state
state = initialData
this is how it is used and everything that I described it works and this is the code from the example
const start = this.state.columns[source.droppableId]
const finish = this.state.columns[destination.droppableId]
if (start === finish) {
const newTaskIds = Array.from(start.taskIds)
now below i want to add my condition and it throws an error
const typeDrag = this.state.tasks[source.draggableId]
const typeDrop = this.state.columns[destination.droppableId]
if(typeDrag.type1!==typeDrop.type2)
{return}
and I don't understand why start.taskIds works, but typeDrag.type1 reports that there is no such field
similarly executable codesandbox example
example
Solution:
instead of: const typeDrag = this.state.tasks[source.draggableId]
use: const typeDrag = this.state.tasks[draggableId]
Explanation:
In your code source doesn't have property draggableId.
So typeDrag is undefined because source.draggableId is undefined.
Argument of your onDragEnd hook looks like that:
{
"draggableId": "task-2",
"type": "TASK",
"source": {
"index": 1,
"droppableId": "column-1"
},
"destination": {
"droppableId": "column-2",
"index": 0
},
"reason": "DROP"
}
By checking your sandbox sample I see that you've already extracted draggableId property to a constant from the method argument ("result"):
const { destination, source, draggableId } = result; // line:28
So using draggableId instead of source.draggableId resolves TypeError: Cannot read property 'type1' of undefined.

Information isn't being passed to an array via Mongoose, can't work out why

Apologies if this has been answered before, I have checked other answers and can't work it out from those.
I have a set of information that I would like placed into an array named "teamDetails". Here is the relevant /post item from server.js:
app.post('/create', (req, res) => {
console.log('Post command received');
console.log(req.body);
console.log(req.body.data.teamDetails[0]);
//We need to push the variable below, 'teamDetails', as an object into an array of the same name
var teamDetailsObj = {
// Modified for Postman
"teamName": req.body.data.teamDetails[0].teamName,
"teamNameShort": req.body.data.teamDetails[0].teamNameShort,
"teamfounded": req.body.data.teamDetails[0].teamFounded,
"teamHome": req.body.data.teamDetails[0].teamHome
};
console.log(teamDetails);
var newTeam = new Team({
"data.added": new Date(),
"data.entry": req.body.data.entry
});
newTeam.save().then((doc) => {
console.log("This is newTeam.data: " + newTeam.data);
console.log("This is teamDetailsObj: " + teamDetailsObj);
newTeam.data.teamDetails.push(teamDetailsObj);
var teamId = doc.id;
res.render('success.hbs', {teamId});
console.log("Team Added - " + teamId);
}, (e) => {
res.status(400).send(e);
});
});
Here is my team.js model:
var mongoose = require('mongoose');
var ObjectID = mongoose.Schema.Types.ObjectId;
var Mixed = mongoose.Schema.Types.Mixed;
var Schema = mongoose.Schema;
var Team = mongoose.model('Team', {
data: {
entry: {
type: String,
default: "USER.INPUT"
},
added: {
type: Date,
default: Date.Now
},
teamDetails: [
{
teamName: {
type: String,
trim: true,
required: true,
default: "First Team"
},
teamNameShort: {
type: String,
trim: true,
uppercase: true,
maxlength: 3,
required: true
},
teamFounded: {
type: Number,
maxlength: 4
},
teamHomeCity: {
type: String
}
}
]
}
});
module.exports = {Team};
Lastly, the sample data I'm trying to inject via Postman:
{
"data": {
"entry": "Postman.Entry",
"teamDetails": [
{
"teamName": "Test Teamname",
"teamNameShort": "TTN",
"teamFounded": "1986",
"teamHome": "London",
"players": [
{
"player1Name": "Test Player 1",
"player1Position": "Forward",
"player1Nationality": "GBR"
},
{
"player2Name": "Test Player 2",
"player2Position": "Defender",
"player2Nationality": "UKR"
},
{
"player3Name": "Test Player 3",
"player3Position": "Goaltender",
"player3Nationality": "IRL",
"captain": true
}
],
"coachingStaff": {
"headCoach": "Derp McHerpson",
"teamManager": "Plarp McFlarplarp"
}
}
]
}
}
(Disregard the players section, it's another kettle of fish)
As a result of using my code above, the resulting entry for teamDetails is just an empty array. I just can't get my code to push the teamDetailsObj into it.
Any help anyone can provide is appreciated.
It looks like you add teamObjDetails AFTER saving it with newTeam.save().then( ... )
I'm not a lot familiar with Mongoose but I don't see how could the team details could be present if not added before saving.
Let me know if it changes something !
A. G

JavaScript - Using eval() for a condition - is it correct?

I have JSON data that I am searching through using filter:
myJsonData.filter(function (entry) { return (entry.type === 'model' || entry.type === 'photographer' ); });
Now instead of specifying those conditions after return, I've created a similar string (because I want to have a list of pre-created search conditions) then using eval() so:
myJsonData.filter(function () { return eval(stringToSearch) ; });
This appears to work. However, I just want to confirm, is this its correct usage? Are there any risks/issues in doing this?
I want to have the flexibility to do, any kind of search e.g.:
myJsonData.filter(function (entry) {
return (entry.type === 'model' || entry.type === 'photographer')
&& entry.level.indexOf('advanced') > -1 ;
});
That's why I made a separate class to create that string.
To avoid eval you could translate user input (through buttons, or whatever) to filters. Those filters would have one filter per data property (i.e. per location, type, level, ...). One of those filters could either be a list of values, or a free-text single value.
Here is an example implementation with a sample data set, without any sexy input/output widgets,... just the bare minimum to demo the algorithm of filtering:
// The sample data to work with:
var data = [
{ location: "ny", type: "model", level: "advanced", name: "Jack" },
{ location: "ny", type: "model", level: "beginner", name: "Fred" },
{ location: "sf", type: "model", level: "experienced", name: "Helen" },
{ location: "sf", type: "photographer", level: "is advanced", name: "Stacy" },
{ location: "sf", type: "photographer", level: "advanced experience", name: "Joy" },
{ location: "ny", type: "photographer", level: "beginner++", name: "John" },
{ location: "sf", type: "model", level: "no experience", name: "Jim" },
{ location: "ny", type: "photographer", level: "professional", name: "Kay" },
];
// A global variable to maintain the currently applied filters
var filters = { type: [], location: [], level: "" };
// Capture user selections and translate them to filters
// Type 1: multiple selections from a closed list of values:
document.querySelector("#seltypes").addEventListener("change", function() {
filters.type = [...this.options].filter(option => option.selected).map(option => option.value);
refresh();
});
document.querySelector("#sellocations").addEventListener("change", function() {
filters.location = [...this.options].filter(option => option.selected).map(option => option.value);
refresh();
});
// Type 2: free text filter:
document.querySelector("#inplevel").addEventListener("input", function() {
filters.level = this.value;
refresh();
});
function refresh() {
// This is the actual filtering mechanism, making use of the filters variable
let result = data;
for (let prop in filters) {
let value = filters[prop];
if (!value.length) continue; // If this filter is empty: don't filter
result = Array.isArray(value)
? result.filter(entry => value.some(type => entry[prop] === type))
: result.filter(entry => entry[prop].includes(value));
}
// No effort done here on the output format: just JSON :-)
document.querySelector("#output").textContent = JSON.stringify(result, null, 2);
}
// Start
refresh();
td { vertical-align: top }
<b>Filters (Ctrl to multi select):</b>
<table>
<tr><th>Types</th><th>Locations</th><th>Level</th></tr>
<tr><td>
<select multiple id="seltypes" size="2">
<option value="model">Model</option>
<option value="photographer">Photographer</option>
</select>
</td><td>
<select multiple id="sellocations" size="2">
<option value="ny">New York</option>
<option value="sf">San Francisco</option>
</select>
</td><td>
<input id="inplevel">
</td></tr></table>
<pre id="output"></pre>
You can create an object with the values you want in the output and then filter.
In an if condition I check whether the advanced filter is applied or not. If applied with check for the && condition too. If not, then I will just check the normal condition.
let data = [{type: 'model', level:'advanced'}, {type:'photographer',level:'advanced'},{type:'random', level:'random'}, {type:'model', value:'without level'}]
let checks = {'model':true, 'photographer':true, advanced:['advanced']}
let output = data.filter(( {type,level} ) => {
if(checks.advanced && checks.advanced ){
return checks[type] && checks.advanced.includes(level)
} else {
return checks[type]
}
} )
console.log(output)
There is nothing wrong in using eval. Here are three ways you could have done it.
There is of course other ways to do it, but this is a much more dynamic approach.
// The sample data to work with:
var data = [
{ location: "ny", type: "model", level: "advanced", name: "Jack" },
{ location: "ny", type: "model", level: "beginner", name: "Fred" },
{ location: "sf", type: "model", level: "experienced", name: "Helen" },
{ location: "sf", type: "photographer", level: "is advanced", name: "Stacy" },
{ location: "sf", type: "photographer", level: "advanced experience", name: "Joy" },
{ location: "ny", type: "photographer", level: "beginner++", name: "John" },
{ location: "sf", type: "model", level: "no experience", name: "Jim" },
{ location: "ny", type: "photographer", level: "professional", name: "Kay" },
];
// Example 1
var searchOne = function(a ){
return a.location == "ny";
}
// Example two: an attribute
var searchTwo = new Function("a", test.getAttribute("condition"));
// Example three: filter list, need much work.... to handle operator // And, OR
var searchThree = [
{ field: "location", key: "=", value:"ny" }]
console.log("example 1")
console.log(data.filter(searchOne))
console.log("example 2")
console.log(data.filter(searchTwo))
console.log("example 3")
console.log(data.filter((a)=> {
var result = true;
searchThree.forEach((x)=> {
var v = a[x.field];
if (x.key == "=")
result = (v == x.value);
else if (x.key == "!=")
result = (v != x.value);
//.....
});
return result;
}))
<p id="test" condition="return a.location=='sf';"</p>

CRM 2016 AutoComplete

I'm currently trying to implement the new CRM's Autocomplete in a CRM online 2016 environment.
I've used the code from Sample: Auto-complete in CRM controls and have verified that it works on the Account form and another custom entity that already exists. However, when I use it one 1 specific custom entity and any of its string fields, the autocomplete box does not appear.
Attempts:
Creating a new form
Creating a brand new text field for the autocomplete to run on
Validated that it's hitting ext.getEventSource().showAutoComplete(resultSet);
Validated that no errors are being thrown from my JS
Anyone have any ideas of what might possibly be wrong? I'm thinking it has something to do with my entity or the entity form instead of the code or the text field.
/** Sample JavaScript code to demonstrate the auto-completion feature.
This sample configures the auto-complete feature for the "Account Name"
field in the account form. */
function suggestAccounts() {
// List of sample account names to suggest
accounts = [
{ name: 'A. Datum Corporation', code: 'A01' },
{ name: 'Adventure Works Cycles', code: 'A02' },
{ name: 'Alpine Ski House', code: 'A03' },
{ name: 'Bellows College', code: 'A04' },
{ name: 'Best For You Organics Company', code: 'A05' },
{ name: 'Blue Yonder Airlines', code: 'A06' },
{ name: 'City Power & Light', code: 'A07' },
{ name: 'Coho Vineyard', code: 'A08' },
{ name: 'Coho Winery', code: 'A09' },
{ name: 'Coho Vineyard & Winery', code: 'A10' },
{ name: 'Contoso, Ltd.', code: 'A11' },
{ name: 'Contoso Pharmaceuticals', code: 'A12' },
{ name: 'Contoso Suites', code: 'A13' },
{ name: 'Consolidated Messenger', code: 'A14' },
{ name: '​Fabrikam, Inc.', code: 'A15' },
{ name: 'Fabrikam Residences', code: 'A16' },
{ name: '​First Up Consultants', code: 'A17' },
{ name: 'Fourth Coffee', code: 'A18' },
{ name: 'Graphic Design Institute', code: 'A19' },
{ name: 'Humongous Insurance', code: 'A20' },
{ name: 'Lamna Healthcare Company', code: 'A21' },
{ name: 'Litware, Inc.', code: 'A22' },
{ name: 'Liberty Delightful Sinful Bakery & Cafe', code: 'A23' },
{ name: 'Lucerne Publishing', code: 'A24' },
{ name: 'Margie Travel', code: 'A25' },
{ name: '​Munson Pickles and Preserves Farm', code: 'A26' },
{ name: 'Nod Publishers', code: 'A27' },
{ name: 'Northwind Electric Cars', code: 'A28' },
{ name: 'Northwind Traders', code: 'A29' },
{ name: 'Proseware, Inc.', code: 'A30' },
{ name: 'Relecloud', code: 'A31' },
{ name: 'School of Fine Art', code: 'A32' },
{ name: 'Southridge Video', code: 'A33' },
{ name: 'Tailspin Toys', code: 'A34' },
{ name: 'Trey Research', code: 'A35' },
{ name: 'The Phone Company', code: 'A36' },
{ name: 'VanArsdel, Ltd.', code: 'A37' },
{ name: 'Wide World Importers', code: 'A38' },
{ name: '​Wingtip Toys', code: 'A39' },
{ name: 'Woodgrove Bank', code: 'A40' }
];
var keyPressFcn = function (ext) {
try {
var userInput = Xrm.Page.getControl("name").getValue();
resultSet = {
results: new Array(),
commands: {
id: "sp_commands",
label: "Learn More",
action: function () {
// Specify what you want to do when the user
// clicks the "Learn More" link at the bottom
// of the auto-completion list.
// For this sample, we are just opening a page
// that provides information on working with
// accounts in CRM.
window.open("http://www.microsoft.com/en-us/dynamics/crm-customer-center/create-or-edit-an-account.aspx");
}
}
};
var userInputLowerCase = userInput.toLowerCase();
for (i = 0; i < accounts.length; i++) {
if (userInputLowerCase === accounts[i].name.substring(0, userInputLowerCase.length).toLowerCase()) {
resultSet.results.push({
id: i,
fields: [accounts[i].name]
});
}
if (resultSet.results.length >= 10) break;
}
if (resultSet.results.length > 0) {
ext.getEventSource().showAutoComplete(resultSet);
} else {
ext.getEventSource().hideAutoComplete();
}
} catch (e) {
// Handle any exceptions. In the sample code,
// we are just displaying the exception, if any.
console.log(e);
}
};
Xrm.Page.getControl("name").addOnKeyPress(keyPressFcn);
}
You must have a lookup control on the form in order for the autocomplete to render. It sounds weird but this is currently the best workaround. I set mine to not be visible. Note: this is any lookup field it does not matter the relationship you choose. Having the lookup field sets something on the form to load the missing libraries.
I spend most of my weekend trying to figure out a similar situation. I could describe at great lengths the events that led to this discovery, but I will spare you.
I assume that Microsoft is trying to not include resources where they do not see a configured need and that is why the back-end autocomplete files are missing (until you add in a requirement for them).

Categories

Resources