How to add a dynamically created DOJO DateTextBox - dojo

I'm struggling dynamically creating a dijit.form.DateTextBox and then adding it to an existing document. I've tried several things, first of which is to dynamically create the field via new dijit.form.DateTextBox and then adding it via domConstruct. With this method, I end up getting
"Uncaught TypeError: Failed to execute 'appendChild' on 'Node':
parameter 1 is not of type 'Node'."
.
When I try to dynamically create it with a string that evaluates to what I would use if I was declaratively creating it, I end up with a simple text box.
I was hopeful that the HTML 5 date would work, but it doesn't seem they've improved that a single bit since the moment they came up with the idea.
Here's the code I'm using. The commented version is the one that attempts to create it declaratively, which ends up as only a simple text field, and not a DateTextBox
var startDateField = new dijit.form.DateTextBox({ name: startDateID, class: "dateField",
value: startDate, onchange: "setstartDate(this.value)"}, startDateID);
//var startDateField = '<input id="' + startDateID + '" data-dojo-type="dijit.form.DateTextField" name="' + startDateID + '" class="dateField" ' +
// 'value="' + startDate + '" required onChange="setstartDate(this.value)"/>';
var startDateField = domConstruct.place(startDate, startDateLabel, "after");

You have to use placeAt when it comes to widgets:
var startDateField = new dijit.form.DateTextBox({ name: startDateID, class: "dateField", value: startDate, onchange: "setstartDate(this.value)"}, startDateID);
startDateField.placeAt(startDateLabel, "after");

Related

Cannot use contenteditable widget on server side paged tablesorter

I have a tablesorter project which has been working good with client side paging since some months. Now I have to turn it to server side paging but I can't get it to work with all the features I was using with client side version.
As on subject, my problem is to make the contenteditable feature to work.
What I've done to achieve that, is to write a custom function to bind to ajaxProcessing handler on the tablesorterPager config:
ajaxProcessing: function (data) {
if (data && data.hasOwnProperty('rows')) {
var str = "", d = data.rows,
// total number of rows (required)
total = data.total_rows,
// len should match pager set size (c.size)
len = d.length;
for (var i = 0; i < len; i++) {
str += '<tr>';
for (var column = 0; column < orderedFieldMapping.length; column++) {
if (orderedFieldMapping[column].toUpperCase() != 'ACTIVATIONDATE' || bReadOnly)
str += '<td class="' + orderedFieldMapping[column].toUpperCase() + '"' + ($('#' + orderedFieldMapping[column].toUpperCase()).prop('checked') ? '' : 'style="display:none;"') + '><div>' + (eval('d[i].' + orderedFieldMapping[column]) != null ? eval('d[i].' + orderedFieldMapping[column]) : '') + '</div></td>';
else
str += '<td class="' + orderedFieldMapping[column].toUpperCase() + '"' + ($('#' + orderedFieldMapping[column].toUpperCase()).prop('checked') ? '' : 'style="display:none;"') + '><div ' + (eval('d[i].' + orderedFieldMapping[column]) != null ? '' : 'class="emptyPlaceholder"') + 'onmouseup="javascript:SelectActivationDateText(this);" onblur="javascript:RestoreCellStyle(this);">' + (eval('d[i].' + orderedFieldMapping[column]) != null ? eval('d[i].' + orderedFieldMapping[column]) : emptyTextString) + '</div></td>';
}
str += '</tr>';
}
// in version 2.10, you can optionally return $(rows) a set of table rows within a jQuery object
return [total, $(str)];
}
},
Please note that I'm returning a set of table rows within a jQuery object, option allowed as stated on the docs example comment (also visible on this code sample). The reason why I do such thing is that I need to control table markup to add styles, handlers and classes. That's what I do in the inner for cycle, and it's not very important knowing exactly what I'm doing there.
What is important is that I get the expected result and markup for my table, and server side paging is working with no issue, BUT contenteditable widget is not working.
I get no warnings on js console and all is working just fine, but I can't edit columns I marked as editable. I can see that also looking at the markup because contenteditable attribute is not present at all. Of course the widget is inintialized and configured (in the same way that it was on previous version, with client side paging).
Another hint that points on some widget malfunction (maybe): I managed to manually add (inside the very same function I posted above) the contenteditable attribute on the markup just to see if it would give me some information. In this case I can edit the content as expected, but I get no handler for editComplete event, and data acceptance settings are not applying. I could still manually add handlers and custom code to get it to work as intended, but it would be bad and I don't want to use a hack to get an already implemented feature to work.
Any hint would be appreciated, thanks to everyone who will answer.
I think I see the issue. The contenteditable widget does not re-apply the contenteditable property on the elements within the table cells when the content is updated (via the pager, or whatever).
So this is definitely a bug, I just opened a ticket: https://github.com/Mottie/tablesorter/issues/732
In the mean time, you can add the contenteditable property to the div in your markup:
str += '<td><div contenteditable>...</div></td>';

List checked nodes in Dynatree

I have tree created with Dynatree, with checkboxes in it.
Can you help me how can I get a list (or array) of checked checkboxes in it, so I can manipulate with them (move them into another tree)?
Tnx in adv!
Ok, here it is:
var selNodes = node1.tree.getSelectedNodes();
// convert to title/key array
var selKeys = $.map(selNodes, function(node1){
alert("[" + node1.data.key + "]: '" + node1.data.title + "'");
});

Conditionally adjust visible columns in Rally Cardboard UI

So I want to allow the user to conditionally turn columns on/off in a Cardboard app I built. I have two problems.
I tried using the 'columns' attribute in the config but I can't seem to find a default value for it that would allow ALL columns to display(All check boxes checked) based on the attribute, ie. the default behavior if I don't include 'columns' in the config object at all (tried null, [] but that displays NO columns).
So that gets to my second problem, if there is no default value is there a simple way to only change that value in the config object or do I have to encapsulate the entire variable in 'if-else' statements?
Finally if I have to manually build the string I need to parse the values of an existing custom attribute (a drop list) we have on the portfolio object. I can't seem to get the rally.forEach loop syntax right. Does someone have a simple example?
Thanks
Dax - Autodesk
I found a example in the online SDK from Rally that I could modify to answer the second part (This assumes a custom attribute on Portfolio item called "ADSK Kanban State" and will output values to console) :
var showAttributeValues = function(results) {
for (var property in results) {
for (var i=0 ; i < results[property].length ; i++) {
console.log("Attribute Value : " + results[property][i]);
}
}
};
var queryConfig = [];
queryConfig[0] = {
type: 'Portfolio Item',
key : 'eKanbanState',
attribute: 'ADSK Kanban State'
};
rallyDataSource.findAll(queryConfig, showAttributeValues);
rally.forEach loops over each key in the first argument and will execute the function passed as the second argument each time.
It will work with either objects or arrays.
For an array:
var array = [1];
rally.forEach(array, function(value, i) {
//value = 1
//i = 0
});
For an object:
var obj = {
foo: 'bar'
};
rally.forEach(obj, function(value, key) {
//value = 'bar'
//key = 'foo'
});
I think that the code to dynamically build a config using the "results" collection created by your query above and passed to your sample showAttributeValues callback, is going to look a lot like the example of dynamically building a set of Table columns as shown in:
Rally App SDK: Is there a way to have variable columns for table?
I'm envisioning something like the following:
// Dynamically build column config array for cardboard config
var columnsArray = new Array();
for (var property in results) {
for (var i=0 ; i < results[property].length ; i++) {
columnsArray.push("'" + results[property][i] + "'");
}
}
var cardboardConfig = {
{
attribute: 'eKanbanState',
columns: columnsArray,
// .. rest of config here
}
// .. (re)-construct cardboard...
Sounds like you're building a neat board. You'll have to provide the board with the list of columns to show each time (destroying the old board and creating a new one).
Example config:
{
attribute: 'ScheduleState'
columns: [
'In-Progress',
'Completed'
]
}

Dashcode - how do you combine two values from one datasource

In Dashcode, if I have a dataSource that has, for example, 2 fields called 'FirstName' and 'Last Name', how do I concatenate the 2 fields into one text field in a list view?
I'm fairly sure it must be to use a value transformer, so say that I assign the 'FirstName' field to the textfield, and add a value transformer... how do I then add the 'LastName' value to the 'value' variable in the transformer.
I'm sure it's to do with dashcode.getDataSource and valueForKeyPath and I think I'm close to the solution but it all seems a bit ungainly so any help would be much appreciated.
Correct - you need to use a Value Transformer.
In the Transformer, you would code as follows:
itemDescription = Class.create(DC.ValueTransformer,{
transformedValue: function(value){
var itemDataSource = dashcode.getDataSource('itemsList'); // The Data Source Name here
var lastName = itemDataSource.selection().valueForKey('lastName'); // Presumes you have a field called lastName
return value + " " + lastName;
}
});
Hope this helps - I battled with this for a day!!!
For future googlers, since there is absolutely no documentation anywhere about this :
When in detailed view to concatenate two fields from same the datasource :
XML
<?xml version="1.0" encoding="utf-8"?>
<immobilier>
<bien>
<ID>1453</ID>
<Titre>Maison / Villa F4</Titre>
<Ville>Sainte Clotilde</Ville>
<Quartier>BRETAGNE</Quartier>
</bien>
</immobilier>
To combine the fields Ville and Quartier create a value transformer like so :
mapAdresse = Class.create(DC.ValueTransformer,{
transformedValue: function(value){
if (value.trim() != "") {
//Replace immoListe with your source name
var itemDataSource = dashcode.getDataSource('immoListe');
//THIS IS THE MOST IMPORTANT : HOW TO FIND THE CURRENTLY SELECTED ITEM INDEX
var selectedIndex = document.getElementById('list').selectedIndex;
//Use the selectedIndex to find the record in the datasource
var quartier = itemDataSource.selection().valueForKey("bien")[selectedIndex].valueForKey("Quartier");
//Concatenate to your liking
if (quartier.trim() != "") value = value + ", "+ quartier;
}
return value;
}
});
Why is this not documented anywhere ?? Beats me !!

Setting a property list with Titanium Appcelerator

I'm working with the latest Mobile SDK (1.6) on OS X.
I have this piece of code:
var globalArray = [
{title:'foo',value:'yes'},
{title:'bar',value:'no'}
];
Titanium.App.Properties.setList('globalArrayProperty',globalArray);
Titanium.App.Properties.getList('globalArrayProperty')[0].value = 'it works!';
Titanium.API.info('first value : ' + Titanium.App.Properties.getList('globalArrayProperty')[0].value);
I simplified it so that I can explain you where the problem stands.
So, I create an array with a couple of objects.
Then, I'm setting a property depending on this array and then affecting a new value to the first object.
But when I call the display the property, instead of showing the 'it works!' string, it shows the initial one 'yes'.
I tried by adding a couple of lines:
Titanium.App.Properties.setList('globalArrayProperty',globalArray);
var arr = Titanium.App.Properties.getList('globalArrayProperty');
arr[0].value = 'it works!';
// This works
Titanium.API.info('first value with arr: ' + arr[0].value);
// This doesn't work
Titanium.API.info('first value : ' + Titanium.App.Properties.getList('globalArrayProperty')[0].value);
So the intermediate var 'arr' get the property, set it but cannot apply the modification on the property.
Am I missing something?
Thanks,
Regards.
i think you need to set the property list again after updating the array
Titanium.App.Properties.setList('globalArrayProperty',globalArray);
var arr = Titanium.App.Properties.getList('globalArrayProperty');
arr[0].value = 'it works!';
// This works
Titanium.API.info('first value with arr: ' + arr[0].value);
// save changes to property list
Titanium.App.Properties.setList('globalArrayProperty',arr);
// This doesn't work
Titanium.API.info('first value : ' + Titanium.App.Properties.getList('globalArrayProperty')[0].value);