I attempt to create a custom field for AEM form (AEM6.0 SP3) following how text field does it: /libs/fd/af/components/guidetextbox
I created init.jsp and widget.jsp with same content.
On widget.jsp, I then add some jQuery to autopopulate text field on focus out.
<script>
var thisField = '${guideid}${'_widget'}';
$(thisField).focusout(function() {
$(this).val('date ' + new Date());
});
</script>
On focus in, I type text 'ABC' then when focus-out I get text 'date ' however when submitting the data, text 'ABC' gets submitted.
Is there any AEM API I need to invoke (instead of just jQuery .val() function) in order for the changes to be recorded ?
Not the best solution, but we managed to get it work by first calling focus(), eg.
$(this).focus().val('date ' + new Date());
Better solution:
create a custom function eg
function initDatePicker(thisObj) { $(this).focusout(function() {thisObj.value = $(this).val();});}
Update .content.xml to call this within initScript eg.
<cq:template guideNodeClass="guideTextBox" jcr:primaryType="nt:unstructured" jcr:title="Datepicker input field" initScript="initDatePicker(this)"/>
the function will be immediately included when the widget is added to canvas.
In AEM Forms a Javascript model is maintained that stores the value and that model is used to submit the data. Now to pass on the value from the ui to the model XFA_EXIT_EVENT[1] has to be triggered. So after setting the value you must add this line of code to persist the value
$(this).trigger(xfalib.ut.XfaUtil.prototype.XFA_EXIT_EVENT)
Also a better way would be to create your own widget for this specific scenario. See [2] for more details. The article is for AEM Form 6.1 but it will work for AEM 6.0 as well.
[1] https://helpx.adobe.com/aem-forms/6/html5-forms/introduction-widgets.html
[2] https://helpx.adobe.com/aem-forms/6-1/custom-appearance-widget-adaptive-form.html
Related
I created a Entity in Content-Types and Data and this entity have a field that is a datetime
When I click in the Plus button (+) I want to hide the field from user (this I got) and that default value be the current date (to be filled behind the scene)
Is there a way to achieve this ?
I read about prefill but I dont got how to do that with the default "Manage Content / Data"
I´m using 2sxc 10.24.0
Welcome to StackOverflow, #Alexandre ;)
The special buttons can only be done in the view. The internal manage-data doesn't provide options to customize. You can set default texts, but there is currently no mechanism to provide tokens, JS or something to get dynamic values as an initial value from the normal Admin-dialogs.
I got if I create a view and then use
#Edit.Toolbar(toolbar: new object[] { new { command = new { action = "new", contentType = "Articles", prefill = new { CreationDate = DateTime.Now } }}}
I believe that to do that in Manage Content / Data will be need to modify the "view" from the 2sxc
I am trying to set the initial value in a Wijimo Autocomplete control which has been loaded from an external data source. The scenario being a form is used to create some new data and then is saved. Subsequently the data needs to be edited so it is reloaded into the form.
I can successfully use the Autocomplete on the initial form - the source list is a JSON Array of objects which is loaded into the controller. The app is using UI Router so I resolve this first.
When I save the data I serialise the selected Object from the Autocomplete control and is then saved to a Mongo DB store. When loading this data back in it is converted back to an object.
This is what the control looks like:
<wj-auto-complete
selected-index="selectedIndexCombo"
selected-item="selectedAirline"
items-source="airlineCodes"
display-member-path="Title"
placeholder="Airline Code"
max-items="50"/>
An example of the source list looks like this:
{
"#href":"\/airline.nsf\/api\/data\/collections\/name\/(LUAirlines)\/unid\/8DCD734E7BCDA24D80257C99003770C4",
"#link":
{
"rel":"document",
"href":"\/airline.nsf\/api\/data\/documents\/unid\/8DCD734E7BCDA24D80257C99003770C4"
},
"#entryid":"98-8DCD734E7BCDA24D80257C99003770C4",
"#unid":"8DCD734E7BCDA24D80257C99003770C4",
"#noteid":"FB2",
"#position":"98",
"#siblings":100,
"#form":"Airline",
"AirlineCode":"WN",
"Airline":"Southwest Airlines",
"Title":"WN - Southwest Airlines"
}
So when the form is initially created the controller property selectedAirline is correctly set with the selected Object.
So this works fine in the save function:
$scope.formData.selectedAirline = JSON.stringify($scope.selectedAirline);
But when reloading in the data:
AirlineInfoFactory.loadAirlineInfo($scope.reference).then(function success(response) {
$scope.selectedAirline = eval('(' + response.data.selectedAirline + ')');
$scope.information = response.data.information;
$scope.dataLoaded = true;
console.log($scope.selectedAirline)
$scope.selectedIndexCombo=11;
})
The autocomplete control does not bind to the selectedAirline property.
I tried using the selected-index attribute on the directive so see if I could just change it to something when the data loads but it doesnt work either. I suspect its to do with the digest loop but I am not sure.
Any ideas?
Thanks
I tried to replicate the scenario by reloading the data and setting the selectedAirline property and it works well withe latest version 32. Here is the fiddle:
http://jsfiddle.net/n1kpkcud/2/
` $scope.countries = initialList;
$scope.selectedAirline = '';
$scope.setItem = function () {
$scope.countries = reloading;
$scope.selectedAirline = 'Yemen';
}`
I would suggest you to update this fiddle so that it replicates the issue and I can suggest you accordingly.
I'm writing a GUI extension and using the Anquilla framework to get a list of Keywords within a Category. I'm obtaining an XML document for the list of keywords then working with that document within my extension.
My problem is that the returned XML doesn't contain the Keyword's 'Description' value. I have the Title and Key etc.
My original code looks like this:
var category = $models.getItem("CATEGORYTCMID:);
var list = category.getListKeywords();
list.getXml();
A typical node returned is this:
<tcm:Item ID="tcm:4-1749-1024"
Type="1024" Title="rate_one" Lock="0" IsRoot="true"
Modified="2012-12-17T23:01:59" FromPub="010 Schema"
Key="rate_one_value" IsAbstract="false"
CategoryTitle="TagSelector"
CategoryID="tcm:4-469-512" Icon="T1024L0P0"
Allow="268560384" Deny="96" IsNew="false"
Managed="1024"/></tcm:ListKeywords>
So I've tried using a Filter to give me additional column information:
var filter = new Tridion.ContentManager.ListFilter();
filter.columns = Tridion.Constants.ColumnFilter.EXTENDED;
var list = category.getListKeywords(filter);
Unfortunately this only gives the additional XML attributes:
IsShared="true" IsLocalized="false"
I'd really like the description value to be part of this XML without having to create a Keyword object from the XML. Is such a thing possible?
cough any ideas? cough
I'm afraid you'll have to load the Keyword itself to get the Description.
It's not used in any lists, so it's not returned in the XML.
You could always create a List Extender to add this information to the list, but try to be smart about it since this extender will execute everytime a GetList is called.
Won't save you from having to open every keyword in the list, but you'll be doing it server-side (with Core Service/NetTcp for instance) which will probably be easier and faster than opening each keyword with Anguilla.
In this instance I only need the one keyword, so I simply get it from the CMS. Getting an object in Anguilla is a bit weird, here's the code:
In your main code area:
var selectedKy = $models.getItem("TcmUriOfKeywordHere");
if (selectedKy.isLoaded()) {
p.selectedKy = selectedKy;
this.onselectedKyLoaded();
} else {
$evt.addEventHandler(selectedKy, "load", this.onselectedKyLoaded);
selectedKy.load();
}
It's worth noting how I store the keyword in the properties of the item, so I can obtain it in the onselectedKyLoaded function
The function called once the item is loaded
ContentBloom.ExampleGuiExtension.prototype.onselectedKyLoaded = function (event) {
var p = this.properties;
var selectedDescription = p.selectedKy.getDescription();
// do what you need to do with the description :)
};
I resolved this, thanks to the answer here: https://stackoverflow.com/a/12805939/1221032 - Cheers Nuno :)
I am working on the Event Handler for saving a component.
My objective is to perform some validations when the user creates and component based on a schema.
I have a schema with the name "Employee".
Employee has an embedded schema with the name "Experience" and it is multivalued.
Experience has 3 fields.
Role : Drop down with the values Manager, Lead.
Company: Text field
Years: Text field
When the user enters some data in these fields, I want to do some validations before save.
The high level design would look like this.
Load the instance of the Component
Navigate to embedded field "Experience"
For every "Experience". I need to get the value of the "Role", and check that appropriate value is entered in other two fields(By writing Component Save event)
For( all the repeated "Experience")
{
If (Role=="Manager")
check the values in the other two fields and do some validation
If (Role=="Lead")
check the values in the other two fields and do some validation
}
I am stuck at extracting the value and Names of subfields at the embeddded field.
I have tried:
Tridion.ContentManager.Session mySession = sourcecomp.Session;
Schema schema= sourcecomp.Schema;
if(schema.Title.Equals("Employee"))
{
var compFields = new ItemFields(sourcecomp.Content, sourcecomp.Schema);
var embeddefield = (EmbeddedSchemaField)compFields["Experience"];
var embeddedfields = (IList<EmbeddedSchemaField>)embeddefield.Values;
foreach(var a in embeddedfields)
{
if(a.Name.Equals("Role"))
{
string value=a.Value.ToString();
}
}
}
Actually I am stuck how to retrieve the values in the other fields at the same time.
Can any one explain how it can be done?
What you need to understand on a EmbeddedSchemaField class is that it represents both a schema and a field (as the name implies...)
I always find it helpful to look at the source XML of the component when writing code that targets its fields, you get a good visual representation of what your classes must do. If you look at a component XML like this:
<Content>
<Title>Some Title</Title>
<Body>
<ParagraphTitle>Title 1</ParagraphTitle>
<ParagraphContent>Some Content</ParagraphContent>
</Body>
<Body>
<ParagraphTitle>Title 2</ParagraphTitle>
<ParagraphContent>Some more Content</ParagraphContent>
</Body>
</Content>
Body is your embedded Schema field, which is multivalued, and contains 2 single-valued fields within it.
Addressing these fields in TOM.NET then:
// The Component
Component c = (Component)engine.GetObject(package.GetByName(Package.ComponentName));
// The collection of fields in this component
ItemFields content = new ItemFields(c.Content, c.Schema);
// The Title field:
TextField contentTitle = (TextField)content["Title"];
// contentTitle.Value = "Some Title"
// Get the Embedded Schema Field "Body"
EmbeddedSchemaField body = (EmbeddedSchemaField)content["Body"];
// body.Value is NOT a field, it's a collection of fields.
// Since this happens to be a multi-valued field, we'll use body.Values
foreach(ItemFields bodyFields in body.Values)
{
SingleLineTextField bodyParagraphTitle = (SingleLineTextField)bodyFields["ParagraphTitle"];
XhtmlField bodyParagraphContent = (XhtmlField) bodyFields["ParagraphContent"];
}
Hope this gets you started.
The following code in a cshtml file creates a dropdown with a list of Contacts, but the field it uses for the description of values, is not the one I want to display.
How do I force it to choose data from a different field in the Contact object?
#Html.DropDownList("ContactId", String.Empty)
#Html.DropDownListFor(a => a.OtherContactId,
new SelectList(Model.ContactList, "ContactId", "ContactValue",
Model.OtherContactId), "-- Select --")
where, Model.ContactList is populated in your controller action.
p.s. I'm not entirely certain whether you mean change the title of the select option text or the property that is updated, so have presented a kind of hybrid offering
You can try something like this on the server side(controller):
ViewBag.ContactList = new SelectList(iContactRepository.GetAllContacts(),
"ContactId", "Name", contactDefault.ContactId);
//Here the method GetAllContacts returns Iqueryable<Contact>.
And this on the view:
#Html.DropDownList("ContactIdSelect", ViewBag.ContactList as SelectList)
This is the SelectList documentation.
Hope it helps.