I am not much of a JavaScript expert and trying to figure out here how can I extend an existing object.
HTML:
<li data-brandtarget="Netherlands"><img src="images/netherlands.png" alt="Netherlands">Netherlands</li>
<li data-brandtarget="Netherlands"><img src="images/netherlands.png" alt="Netherlands">Netherlands</li>
JS:
MedicareDataSource.prototype.FEATURES_ = new storeLocator.FeatureSet(
// Brand Fetures
new storeLocator.Feature('Aquafleur-YES', 'Aquafleur'),
new storeLocator.Feature('Aquafarm-YES', 'Aquafarm'),
new storeLocator.Feature('Bm_Web-YES', 'Blue Marine'),
// The below mentioned features I want to be added based on a loop
//new storeLocator.Feature('Naamlandnat-Netherlands', 'Netherlands'),
//new storeLocator.Feature('Naamlandnat-Great Britain', 'Great Britain'),
//new storeLocator.Feature('Naamlandnat-France', 'France'),
//new storeLocator.Feature('Naamlandnat-Germany', 'Germany')
);
I am trying to make the country features dynamic. So I am looping through all the lists and getting the attribute. Now while looping how can I extend and add new feature to the existing object? Below is my approach.
jQuery('.country-options li').each(function(){
var countryName = jQuery(this).attr('data-brandtarget');
MedicareDataSource.prototype.FEATURES_ = new storeLocator.FeatureSet(
// Country Features
new storeLocator.Feature('Naamlandnat-'+ countryName, countryName)
);
});
I know it is wrong because I guess: I am creating the new object again and again with each loop which overwrites the existing object and thus only the last feature stays in the object.
So what is the right way to extend the features without overwriting the existing feature set here?
I also tried:
by removing the new and keeping it just storeLocator.FeatureSet(...); inside the loop but didn't work.
According to the reference I found, you can call add() on the existing FeatureSet:
MedicareDataSource.prototype.FEATURES_ = new storeLocator.FeatureSet();
jQuery('.country-options li').each(function(){
var countryName = jQuery(this).attr('data-brandtarget');
MedicareDataSource.prototype.FEATURES_.add(
new storeLocator.Feature('Naamlandnat-'+ countryName, countryName)
);
});
Related
I have a constructor like this
function Employee(name, rank, mf)={
this.name=name;
this.rank=rank;
this.mf=mf;
}
How can I create a new employee and storing the name, rank, and mf in an object with the ability to change it later on? Keep in mind i'm creating the new employee through a function so i can't just create a new var manually. THx.
This is how i create a new employee
function employee(){
var name=prompt("Last, First");
var rank=prompt("Rank");
var mf=prompt("M/F");
var ID=prompt("ID");
var confirming=confirm("ID: "+ID+"Name: "+name+"Rank: "+rank+", "+mf);
if(confirming){
new Employee(name, rank, mf);
}else{
console.log("Employee addition cancled")
}
}
You have a typo in your constructor code which can cause you compilation (syntax) error. Note the equal = sign. Should be
function Employee(name, rank, mf) {
Q: How can I create a new employee and storing the name, rank, and mf in an object with the ability to change it later on?
A: You'll need to maintain a reference to that new object by storing it into a variable. You can achieve it by doing
var myEmployee1 = new Employee(...);
So from there you could access that same object through calling the variable like myEmployee.name
If you are having a function to take on the create employee object role then you can either modify that function to, return the newly created object or populate straight into a global variable. My preference would be the former as it is much cleaner.
Also, tracking the employee objects in an array is 1 strategy you can use but depending on how many objects you are expected. Finding an object in an array may not be as efficient as storing them in a {} dictionary data structure. As you are required to loop through individual objects from an array before finding the right one, whereas dictionary you access objects straight from the key, essentially transversing a tree which is quicker in most scenario.
Obviously storing an employee object through using the name as the key can be dangerous because names are never unique. Instead you should be using the unique identifier Id.
Example:
function employee(){
...
return new Employee(name, rank, mf);
}
var myDictionary = {};
var emp = employee();
myDictionary[emp.id] = emp; // Store the employee object by its key with value = the object itself.
// To access the very same employee object next time. Let say the id is 10 then you would do...
console.log(myDictionary[10].name)
You need to maintain global array for object reference this check my sample code :
var objRef=[];
function employee(){
var name=prompt("Last, First");
var rank=prompt("Rank");
var mf=prompt("M/F");
var ID=prompt("ID");
var confirming=confirm("ID: "+ID+"Name: "+name+"Rank: "+rank+", "+mf);
if(confirming){
objRef[name]=new Employee(name, rank, mf); //access using objRef['alen']
}else{
console.log("Employee addition cancelled.")
}
}
//Your constructor.
function Employee(name, rank, mf)
{
this.name=name;
this.rank=rank;
this.mf=mf;
}
and you can access your object by simply objRef[name]. you can make id as key .
I have data being sent to a custom data list from the following code:
// Get the site name and dataLists
var site = siteService.getSite("Testing");
var dataLists = site.getContainer("dataLists");
// Check for data list existence
if (!dataLists) {
var dataLists = site.createNode("dataLists", "cm:folder");
var dataListProps = new Array(1);
dataListProps["st:componentId"] = "dataLists";
dataLists.addAspect("st:siteContainer", dataListProps);
dataLists.save();
}
// Create new data list variable
var orpList = dataLists.childByNamePath("orplist1");
// If the data list hasn't been created yet, create it
if (!orpList) {
var orpList = dataLists.createNode("orplist1","dl:dataList");
// Tells Alfresco share which type of items to create
orpList.properties["dl:dataListItemType"] = "orpdl:orpList";
orpList.save();
var orpListProps = [];
orpListProps["cm:title"] = "Opportunity Registrations: In Progress";
orpListProps["cm:description"] = "Opportunity registrations that are out for review.";
orpList.addAspect("cm:titled", orpListProps);
}
// Create new item in the data list and populate it
var opportunity = orpList.createNode(execution.getVariable("orpWorkflow_nodeName"), "orpdl:orpList");
opportunity.properties["orpdl:nodeName"] = orpWorkflow_nodeName;
opportunity.properties["orpdl:dateSubmitted"] = Date().toString();
opportunity.properties["orpdl:submissionStatus"] = "Requires Revisions";
opportunity.save();
This correctly creates data list items, however, at other steps of the workflow require these items to be updated. I have thought of the following options:
Remove the data list item and add another with the updated information
Simply update the data list item
Unfortunately I have not found adequate solutions elsewhere to either of these options. I attempted to use orpWorkflow_nodeName, which is a unique identifier generated at another step, to identify a node to find it. This does not seem to work. I am also aware that nodes have unique identifiers generated by Alfresco itself, but documentation doesn't give adequate information on how to obtain and use this.
My question:
Instead of var opportunity = orpList.createNode(), what must I use in
place of createNode() to identify an existing node so I can update its
properties?
You can use this to check existing datalist item.
var opportunity = orpList .childByNamePath(execution.getVariable("orpWorkflow_nodeName"));
// If the data list Item is not been created yet, create it
if (!opportunity ) {
var orpList = orpList .createNode(execution.getVariable("orpWorkflow_nodeName"),"dl:dataList");}
Im trying (desperately) to access the content of a dataset by script in the beforeFactory.
The task at hand is to create design elements from a linked library and place them in a certain cell of a grid. Everything works fine except for the "place them in a certain cell of a grid"-part.
The information about which element is to be created and where it is to be placed is available in a dataset (dsDesignInformation), which contains three columns: targetRow, targetColumn, targetContent. targetContent contains a string, which is used to find an element in the library.
For example: There is a grid placed on the body (grdMasterGrid), with two rows and two columns. If the dsDesignInformation would contain a row like (1,1,"testObjectName"), I want to create the element "testObject" from a linked library and place it in the intersection of row 1 and column 1 of my grdMasterGrid.
The code for creating and placing the element:
importPackage(org.eclipse.birt.report.model.api);
var myLibraryHandle = reportContext.getDesignHandle().getLibrary("myLibraryName");
var myElementFactory = reportContext.getDesignHandle().getElementFactory();
// should be the objectname as defined in the dsDesignInformation
var myTargetElementHandle = myLibraryHandle.findElement("testObjectName");
var myCreatedElementHandle = myElementFactory.newElementFrom(myTargetElementHandle , "someUniqueElementName");
var myMasterGridHandle = reportContext.getDesignHandle().findElement("grdMasterGrid");
// should be target coordinates as defined in dsDesignInformation
var myTargetCellHandle= myMasterGridHandle.getCell(1,1);
myTargeCellHandle.getContent().add(myCreatedElementHandle);
This works like a charm when used with hard coded target-information and placed in the beforeFactory of the report design.
I do however need to access the contents of dsDesignInformation and pass them on to the script above. So far (4 days in) I had zero (as in null) success.
I would be glad for any help or ideas on the topic.
Regards,
maggutz
It is possible to do this, but with some severe restrictions.
The main restriction is: You cannot use your DataSource and your DataSet directly.
Instead, you'll have to copy them and work with the copy.
Don't ask my why this is, because I don't know. But I learned it the hard way during hours and days of trying...
The next restriction is: You cannot access report parameter values, unfortunately. This is not a problem if your query works without parameters.
Otherwise, you'll have to find a way to access the parameter value anyhow. Depending on how your report is integrated into the app, you could try writing the value into the appContext before calling BIRT, for example.
Here is a fragment of working code (in the beforeFactory event) to show you how to workaround this limitation:
importPackage( Packages.org.eclipse.birt.report.model.api );
importPackage(Packages.org.eclipse.birt.data.engine.api);
importPackage(Packages.org.eclipse.birt.report.model.api);
importPackage(Packages.org.eclipse.birt.data.engine.api.querydefn);
importPackage(Packages.org.eclipse.birt.data.engine.core);
importPackage( Packages.org.eclipse.birt.report.model.api );
var myconfig = reportContext.getReportRunnable().getReportEngine().getConfig();
var de = DataEngine.newDataEngine( myconfig, null );
var dsrc = reportContext.getDesignHandle().findDataSource("lisa");
// This is the existing data source.
var odaDataSource = new OdaDataSourceDesign( "Test Data Source" );
// We create a new DataSource which is only to be used in this event
// Now we copy the relevant properties from the existing DataSource to the new one.
var dbUrl = dsrc.getProperty("odaURL").toString();
var dbUsr = dsrc.getProperty("odaUser").toString();
var dbPwd = dsrc.getProperty("odaPassword").toString();
var dbDrv = dsrc.getProperty("odaDriverClass").toString();
odaDataSource.setExtensionID( "org.eclipse.birt.report.data.oda.jdbc" );
odaDataSource.addPublicProperty( "odaURL", dbUrl );
odaDataSource.addPublicProperty( "odaDriverClass", dbDrv);
odaDataSource.addPublicProperty( "odaUser", dbUsr );
odaDataSource.addPublicProperty( "odaPassword", dbPwd );
// log.info("odaURL=" + dbUrl); // Only if you have a logging framework at hand
// Now create a new DataSet and set its query etc.
// I suppose that it is possible to copy the properties from an existing DataSet instead.
// However, I didn't try that.
var odaDataSet = new OdaDataSetDesign( "Test Data Set" );
odaDataSet.setDataSource( odaDataSource.getName() );
odaDataSet.setExtensionID( "org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet" );
// This is the SQL query (in my application).
// You'll have to modify this as needed.
odaDataSet.setQueryText( " select STEDA.TEDA_ID, STBST.LANGTEXT" +
" from STEDA, STBST" +
" where STEDA.ZUSATZ_1 = 'MATRIX'" +
" and STBST.TBST_ID = STEDA.TEDA_ID");
// Tell the DataEngine about the new objects.
de.defineDataSource( odaDataSource );
de.defineDataSet( odaDataSet );
// Now execute the query:
// This seems overly complicated, but hey: it works.
var queryDefinition = new QueryDefinition( );
queryDefinition.setDataSetName( odaDataSet.getName() );
queryDefinition.setAutoBinding(true);
var pq = de.prepare( queryDefinition );
var qr = pq.execute( null );
rowcount=0;
var elementFactory = reportContext.getDesignHandle().getElementFactory()
var ri = qr.getResultIterator( );
// Our application is using the query to generate a layout structure
// into an (already existing) placeholder element "Layout MATRIX".
var containerGrid = reportContext.getDesignHandle().findElement("Layout MATRIX");
// Iterate through the query results
while ( ri.next( ) )
{
// get the actual values of the query output columns
var tedaId = ri.getString("TEDA_ID");
var langtext = ri.getString("LANGTEXT");
// log.info("langtext: " + langtext);
rowcount++;
// Do something with the current result row.
... myModifyLayout(containerGrid, tedaId, langtext); ...
}
// Cleanup
ri.close( );
qr.close( );
de.shutdown( );
// You may want to save the modified design file while developing.
// That way you can check the mresults in the Report Designer.
if (false) {
reportContext.getDesignHandle().saveAs("c:/temp/modified.rptdesign");
}
I am building JavaScript code to make a custom push function. My new function should act exactly like the original push function.
Here is the code. Please check it.
<script type="text/javascript">
function MyArray(){
this.add=function(x){
return this[this.length]=x;
}
}
MyArray.prototype=Array.prototype;
var collection = new MyArray();
collection.push(44);
collection.add(56); // this is not working.
collection.push(77);
collection.push(88);
console.log(collection);
</script>
Because you're not using a native array, the length property doesn't automatically adjust itself. You need to increment it manually, otherwise the next push will just overwrite it:
function MyArray(){
this.add=function(x){
return this[this.length++]=x;
}
}
If you want to use add instead of push (so, use add as push-alias), just refer to the original Array.prototype.push. See snippet. The snippet also contains a custom addMulti method, derived from Array.prototype.push.
function MyArray(){ }
MyArray.prototype = Array.prototype;
MyArray.prototype.add = Array.prototype.push;
// custom addMulti method, derived from Array.prototype.push
MyArray.prototype.addMulti = function addMulti(arrayOfValues){
[].push.apply(this, arrayOfValues);
};
var foo = new MyArray;
// add and push both work
foo.add(13);
foo.push(17);
foo.add(15,16,18);
foo.push(112);
// push an array of values
foo.addMulti([200,300,400,500]);
var report = new MyArray;
report.add('<code>foo.length: ',foo.length, ', foo: [', foo, ']</code>');
document.querySelector('#result').innerHTML = report.join('');
<div id="result"><div>
I want to store objects in jquery. The objects are 'events' each event has a date, title and some text. They need to be stored like and array (maybe thats what they will be a multi-dimensional array) so I can iterate through them with a counter.
Edit,
I like the stores var as a way to group the info but how do I add multiple items and how do I index them?
var dates = new Array('12th Dec', '14th Jan', '6th May');
var event_title = new Array('My Birthday', 'Going to Beach', 'Holiday');
var event_text = new Array('One Year Older', 'Remember the suntan lotion', 'on the plane to spain');
I need to return by index alert(dates[2], event_title[2], event_text[2]);
you can try:
var store = {};
store = {
dates : dates,
titles: titles,
infotxt: infotxt
};
Then access:
store.dates or store.title or so..
You probably don't want to store separate related info in arrays as you're doing, and then attempt to access those groups by index.
JavaScript has a perfect, native object that allows you to group similar properties. Just use an object literal:
var events = [];
events.push({
data: someData,
title: someTitle,
text: someText
});
Now you have what's referred to oftentimes as a "collection".
You could take it a step further and make each event a "class":
function MyAwesomeEvent(data, title, text) {
this.data = data;
this.title = title;
this.text = text;
}
events.push(new MyAwesomeEvent(someData, someTitle, someText));
That approach is potentially heavy-handed depending on what your specific use-case is, but it's another option.