I followed the step by step guide to implement the module event calendar feature. This is the link to the module:
http://drupal.org/project/events_calendar_feature
I then created a custom modulethat downloads information from an external website every day (by implementing hook_cron). This module automatically creates nodes programmatically of type "data_event" that i created (following the guide mentioned above) with all the new events on the site every day. These are all the fields in the new content type "data_event" created:
LABEL: Title MACHINE NAME: title FIELD TYPE: Node module element
LABEL: Body MACHINE NAME: body FIELD TYPE: Node module element
LABEL: Date(s) MACHINE NAME: field_event_dates FIELD TYPE: Date WIDGET: Text field
The problem is set up properly the various fields of the node. How do I know the names of the fields for the date to be set?
This is my current implementation in my module. Commented lines are some tests without success.
Date format: dd/mm/yyyy Time format: hh:mm (24h)
function create_data_event_node($title, $id, $data_event_body, $startDate, $startDateTime, $endDate, $endDateTime) {
watchdog("Indico Downloader", "Creating new data event node.");
$node = new stdClass();
$node->type = "data_event";
$node->title = $title;
$node->language = LANGUAGE_NONE;
$node->id = $id;
node_object_prepare($node);
$node->body[$node->language][0]['value'] = $data_event_body;
$node->body[$node->language][0]['format'] = 'full_html';
// $node->field_event_dates[$node->language][0]['value']['date'] = $startDate." - ".$startDateTime;
// $node->field_event_dates = array(
// 0 => array(
// 'value' => format_date($om__result->date, 'short'),
// ),
// );
// $node->field_event_dates[$node->language][0]['value']['time'] = $startDateTime;
// $node->field_event_dates[$node->language][0]['value2']['date'] = $endDate;
// $node->field_event_dates[$node->language][0]['value2']['time'] = $endDateTime;
$node = node_submit($node);
node_save($node);
}
Thanks in advance for your answers.
Let's first make sure that you have configured your field to contain multiple values?
-- click "edit" behind your field.
-- Verify that "number Of Values" is configured to have more than 1.
Once that is done, you should be able to set the first value by assigning a value to:
$node->field_event_dates[$node->language][0]['value'] = "whatever you want it to be".
and a second date:
$node->field_event_dates[$node->language][1]['value'] = "This is a second value".
etc...
Up until:
$node->field_event_dates[$node->language][9]['value'] = "This is the last possible" (assuming you've set max values to 10).
I hope this helps?
Related
I have an two tables:-
Countries
Customers [have a number of column- ike name, address, city, zipcode, email, etc]
Customer table have an column country [Pointer of Countries].
Now what I want: I have a search form and if some put "aus" in a search box and click on "Search" button I want to display all matching records, I want to apply search on "Name, email, address, city, and the Country name [pointer]"
So if someone has name Austin or Country name "Australia" will be the output of search, currently, I'm using "contains" on the name, email and it is working fine.
I tried to apply search on country but not successes, could someone please help to apply this.
Here is my current code that is working [Without Country search], I am using cloud functions.
`var customerName = new Parse.Query("customer");
var customerEmail = new Parse.Query("customer");
var customerAddress = new Parse.Query("customer");
customerName.contains('name','aus');
customerEmail.contains('email','aus');
customerAddress.contains('address','aus');
var serviceQuery = new Parse.Query.or(
customerName,
customerEmail,
customerAddress
// country
);
.............`
Thanks
Try something like this:
var customerName = new Parse.Query('customer');
var customerEmail = new Parse.Query('customer');
var customerAddress = new Parse.Query('customer');
customerName.contains('name','aus');
customerEmail.contains('email','aus');
customerAddress.contains('address','aus');
var countryQuery = new Parse.Query('country');
countryQuery.contains('name','aus');
var customerCountry = new Parse.Query('customer');
customerCountry.matchesQuery('country', countryQuery);
var serviceQuery = new Parse.Query.or(
customerName,
customerEmail,
customerAddress,
customerCountry
);
Instead of searching for each of customers' fields, you can use full text search:
https://docs.parseplatform.org/js/guide/#full-text-search
A solution would be to compute a fullTextSearch field on cloud beforeSave of your objects. The best way is to store this string in lowercase and without diacritics. It will give better results if you do the same when searching (so that André will match andre or AnDrÉ).
Here is the helper I used to do so:
/**
* Generates fulltextsearch for any Parse.Object. It's the concatenation of the value
* of all fields in propertiesToAdd, separated by a whitespace and lowercased.
* Often used in beforeSave :)
* #param propertiesToAdd the list of the object properties names that we want to handle in fulltextsearch
* #param newObject the new version of the object
*/
static generateFulltextSearch(propertiesToAdd, newObject): string {
let result = '';
propertiesToAdd.forEach(property => {
let value = newObject.get(property);
if (value) {
result += DiacriticRemove(value) + ' ';
}
});
return result.trim().toLocaleLowerCase();
}
DiacriticRemove is simply a call to Diacritics package.
In your beforeSave (in cloud code), you just have to call:
myCustomer("myFullTextField", generateFulltextSearch(["name", "email", "address", "country", "anyotherField"], myCustomer))
Then, when you're searching:
var customer = new Parse.Query("customer");
// Don't forget to lowercase and remove diacritics from your searched string.
customer.contains('myFullTextField','aus');
And voilà :)
I am currently working on a dialog (BotFramework 3.x), that asks the user a span of two numbers. The user should have the option to say "indifferent" if he does not care or it is open end.
So my approach is to have a variety of suggested actions plus an "indifferent" value. The ActionButton should show and write "indifferent" in the chat window but pass a specific int value to the backend:
if (actions != null)
message.SuggestedActions = new SuggestedActions()
{
Actions = new List<CardAction>(actions)
};
message.AttachmentLayout = AttachmentLayoutTypes.Carousel;
And this is how I build together the actions:
CardActions = new List<CardAction>();
for (int i = fromTo.from ?? MinValue; i <= MaxValue; i++)
{
CardActions.Add(new CardAction()
{
Title = i.ToString(),
Value = complexObject,
Text = i.ToString(),
DisplayText = i.ToString(),
Type = ActionTypes.PostBack
});
}
cardActions.Add(new CardAction()
{
Title = "indifferent",
Value = indifferentValue,
Text = "indifferent",
DisplayText = "indifferent"
Type = ActionTypes.PostBack,
});
I am able to get the value in the backend - that is not the problem. What is a problem though is, that the user is not shown hin answer. I want him to see, that he tapped "5" or "indifferent" in the chat history. With ActionTypes.PostBack this does not work. If I use ActionTypes.ImBack I am not able to use a complex JSON object as value - I simply don't get a response in the backend when tapping the suggestedAction. It only works with ActionTypes.ImBack if I use a plain value. But then the chat history shows the value of the action and not the text or displayText, which would make much more sense.
What am I overseeing here??
If I use ActionTypes.ImBack I am not able to use a complex JSON object as value - I simply don't get a response in the backend when tapping the suggestedAction.
To achieve your requirement: display user selection in chat window, you can specify ActionTypes.ImBack and serialize the specified object to a JSON string, like below.
CardActions.Add(new CardAction()
{
Title = i.ToString(),
//serializes to a JSON string
Value = JsonConvert.SerializeObject(complexObject),
Text = i.ToString(),
DisplayText = i.ToString(),
Type = ActionTypes.ImBack
});
Besides, to present buttons/options that the user can tap to provide input, you can also use rich cards or PromptDialog.Choice.
PromptDialog.Choice(
context: context,
resume: ChoiceReceivedAsync,
options: myoptions,
prompt: "Hi. Please Select an option:",
retry: "Selected option not avilabel . Please try again.",
promptStyle: PromptStyle.Auto,
descriptions: desforchoices
);
Test result:
I am not able to display records on my report.
Report Source: Group Approval(sysapproval_group) table
Condition:Sys Id - is one of - javascript: new GetMyGroupApprovals().getSysIds();
Script Include : MyGroupApproval
Note : Active is checked, Accesible is all application score & Client callable unchecked
var GetMyGroupApprovals = Class.create();
GetMyGroupApprovals.prototype = {
initialize: function() {
},
getSysIds : function getMyGroupMembers(){
var ga = new GlideRecord('sysapproval_group');
ga.addQuery('parent.sys_class_name', '=', 'change_request');
ga.query();
gs.log("TotalRecords1 Before:: " + ga.getRowCount());
var sysIdArray = [];
while(ga.next()){
sysIdArray.push(ga.sys_id);
}
return sysIdArray;
},
type: 'GetMyGroupApprovals'
};
Kindly note that I have to achieve with script approach. I am not able to get records on my report.
This line is probably causing unexpected behavior:
sysIdArray.push(ga.sys_id);
ga.sys_id returns a GlideElement object, which changes for each of the iterations in the GlideRecord, so the contents of sysIdArray will just be an instance of the same object for each row in the result set, but the value will just be the last row in the set.
You need to make sure you push a string to the array by using one of the following methods:
sysIdArray.push(ga.sys_id+''); // implicitly call toString
sysIdArray.push(ga.getValue('sys_id')); // return string value
Quick suggestion, you can use the following to get sys_ids as well:
sysIdArray.push(ga.getUniqueValue());
Well the title says it all, details following.
I have two related models, User & Role.
User has roles defined as:
Ext.define('App.model.security.User', {
extend: 'App.model.Base',
entityName: 'User',
fields: [
{ name: 'id' },
{ name: 'email'},
{ name: 'name'},
{ name: 'enabled', type: 'bool'}
],
manyToMany: 'Role'
});
Then I have a grid of users and a form to edit user's data including his roles.
The thing is, when I try to add or delete a role from the user a later call to session.getSaveBatch() returns undefined and then I cannot start the batch to send the modifications to the server.
How can I solve this?
Well after reading a lot I found that Ext won't save the changed relationships between two models at least on 5.1.1.
I've had to workaround this by placing an aditional field on the left model (I named it isDirty) with a default value of false and set it true to force the session to send the update to the server with getSaveBatch.
Later I'll dig into the code to write an override to BatchVisitor or a custom BatchVisitor class that allow to save just associations automatically.
Note that this only occurs when you want to save just the association between the two models and if you also modify one of the involved entities then the association will be sent on the save batch.
Well this was interesting, I've learned a lot about Ext by solving this simple problem.
The solution I came across is to override the BatchVisitor class to make use of an event handler for the event onCleanRecord raised from the private method visitData of the Session class.
So for each record I look for left side entities in the matrix and if there is a change then I call the handler for onDirtyRecord which is defined on the BatchVisitor original class.
The code:
Ext.define('Ext.overrides.data.session.BatchVisitor', {
override: 'Ext.data.session.BatchVisitor',
onCleanRecord: function (record) {
var matrices = record.session.matrices
bucket = null,
ops = [],
recordId = record.id,
className = record.$className;
// Before anything I check that the record does not exists in the bucket
// If it exists then any change on matrices will be considered (so leave)
try {
bucket = this.map[record.$className];
ops.concat(bucket.create || [], bucket.destroy || [], bucket.update || []);
var found = ops.findIndex(function (element, index, array) {
if (element.id === recordId) {
return true;
}
});
if (found != -1) {
return;
}
}
catch (e) {
// Do nothing
}
// Now I look for changes on matrices
for (name in matrices) {
matrix = matrices[name].left;
if (className === matrix.role.cls.$className) {
slices = matrix.slices;
for (id in slices) {
slice = slices[id];
members = slice.members;
for (id2 in members) {
id1 = members[id2][0]; // This is left side id, right side is index 1
state = members[id2][2];
if (id1 !== recordId) { // Not left side => leave
break;
}
if (state) { // Association changed
this.onDirtyRecord(record);
// Same case as above now it exists in the bucket (so leave)
return;
}
}
}
}
}
}
});
It works very well for my needs, probably it wont be the best solution for others but can be a starting point anyways.
Finally, if it's not clear yet, what this does is give the method getSaveBatch the ability to detect changes on relationships.
I have created a template Location Chart Template having two fields given below:
Field 1-->
Name: Value
DataType: Integer
Field 2-->
Name: CP_Value
DataType: Integer
Now I have created a folder Location Chart List under sitecore content node and under this folder I have added 5 items with it's values(i.e. values showns below entered in Value field NOT in CP_Value field ):
East-5
Midwest-11
South-13
West-2
International-9
Now I want to fetch these location items collection on Sample.aspx page via ajax call and write down the following code in code behind file:
List<Item> locationChartsDesc = new List<Item>();
var valueFieldName = "Value" //Value OR CP_Value
var parentItem = SampleSitecoreHelper.GetItemByPath("/sitecore/content/Global Items/Location Chart List");
List<Item> locChild = new List<Item>();
if (valueFieldName != string.Empty)
{
locationChartsDesc = parentItem.GetChildren().OrderByDescending(x => x.Fields[valueFieldName].Value).ToList();
}
The sequence of Item at this step I'm getting is:
International-9
East-5
West-2
South-13
Midwest-11
Which is wrong
The sequence of Item at this step must be:
South-13
Midwest-11
International-9
East-5
West-2
Is there anything wrong in this code?
Thanks
I got the answer.I have to do the following:
Convert.ToInt16(x.Fields[valueFieldName].Value)