Create an array from input field values with Flex 4.5 - arrays

I have not been able to find any documentation and searches return useless docs not involving what I want to do.
I want to take the text entered by the user, and when they click Add Record it adds the text to the array. The list box at the bottom displays each item in the array in the order it was entered.
I am just a beginner with a basic understanding of how the code is written, but I have no idea which things to use in order to take the text, make it into a string, add it to the array, and display the array in the list.

The trick here is to just use the buttons click event to add an item to the ArrayCollection you use to provide the data to your list. Here's the sample I just came up with which does what I think you are asking:
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="HomeView">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var _records:ArrayCollection = new ArrayCollection();
protected function addRecord(event:MouseEvent):void
{
if(textInput.text != "") {
_records.addItem(textInput.text);
}
}
]]>
</fx:Script>
<s:TextInput id="textInput" left="10" right="10" top="5" prompt="Enter Text" />
<s:Button top="64" label="Add Record" horizontalCenter="0" click="addRecord(event)" />
<s:List left="10" right="10" top="132" bottom="5" dataProvider="{_records}" />
</s:View>

Related

Xpages File Download Control sort column

I would like to have a File Download control display the attachments with the newest (latest) Created On date at the top. The default is to display the newest last.
<xp:fileDownload rows="30" id="FD"
displayLastModified="false" value="#{document1.files}"
style="width:98%" hideWhen="false"
displayType="true" allowDelete="false" displayCreated="true">
</xp:fileDownload>
As there's currently no better answer, I'll post one here.
Actually, the <xp:fileDownload> component lists file attachments in order they appear in document's Rich Text field, not the newest last:
You can't change this behavior with any of the properties, so the one possible way is to obtain the list of attachments, sort it like you need, and then feed the sorted list to <xp:repeat> component, where you can draw the attachment table that will just slightly or even not differ from that displayed by <xp:fileDownload>. It's not that hard, just look at created HTML markup in your browser debug tool and recreate that inside your <xp:repeat>.
Suppose you have dominoData declared on your page:
<xp:this.data>
<xp:dominoDocument var="document1"
documentId="9CAA72D47AEA7C8D462582FB005AB525"
action="openDocument" />
</xp:this.data>
Then create the <xp:panel> where your <xp:repeat> will reside. Create the dataContext for your panel:
<xp:panel>
<xp:this.dataContexts>
<xp:dataContext var="attachments">
<xp:this.value><![CDATA[
#{javascript:
var sourceList:java.util.List = document1.getAttachmentList('files');
if (sourceList.size() == 0) {
return sourceList;
}
java.util.Collections.sort(sourceList, createdComparator);
return sourceList;
}
]]></xp:this.value>
</xp:dataContext>
</xp:this.dataContexts>
</xp:panel>
There you get a list of com.ibm.xsp.model.domino.wrapped.DominoDocument.AttachmentValueHolder objects, then sort the list with declared Comparator (see update below) using the created file attribute, and return the sorted list as attachments variable.
Then you create <xp:repeat> and nest it inside your <xp:panel> after <xp:dataContexts>. Give it the dataContext's variable name as a value:
<xp:repeat value="#{attachments}" var="attachment">
<xp:text value="#{attachment.type}" />
<xp:label value=" - " />
<xp:text>
<xp:this.value><![CDATA[
#{javascript:
var rawSize = attachment.getLength();
return (rawSize < 1024 ? 1 : (rawSize / 1024).toFixed(0)) + " KB";
}
]]></xp:this.value>
</xp:text>
<xp:label value = " - " />
<xp:link text="#{attachment.name}" value="#{attachment.href}" />
<xp:label value = " - " />
<xp:text>
<xp:this.value>
#{javascript:
return new java.util.Date(attachment.getCreated());
}
</xp:this.value>
<xp:this.converter>
<xp:convertDateTime type="both" timeStyle="short" />
</xp:this.converter>
</xp:text>
<xp:br />
</xp:repeat>
Here's the result of <xp:repeat> output compared to <xp:fileDownload>:
Just create the markup that looks like fileDownload's table, and you're done.
Update
It's worth the effort to create a request scoped Managed Bean that will serve as the Comparator instead of implementing some good sorting algorithm right inside SSJS code block.
Create a Java class inside Code/Java folder under some existing or new package. If the package name is e.g. com.benway.util and the class name is CreatedComparator:
package com.benway.util;
import java.util.Comparator;
import com.ibm.xsp.model.FileRowData;
public class CreatedComparator implements Comparator<FileRowData> {
public int compare(FileRowData file1, FileRowData file2) {
if (file1 == null || file2 == null) return 0;
return (int)(file2.getCreated() - file1.getCreated());
}
}
Register your new class as a managed bean in your faces-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config>
<managed-bean>
<managed-bean-name>createdComparator</managed-bean-name>
<managed-bean-class>
com.benway.util.CreatedComparator
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
...etc...
</faces-config>
Now you're really done :)

prompt text won't disappear after selecting one of the suggested options

I have implemented react-select to allow entering tags based on auto-complete suggestions and/or inserting new ones.
My implementation is as follows:
import Select from 'react-select';
...
<Select.AsyncCreatable
className='add-tags'
clearable={!!selectionTags}
placeholder={'add more'}
name="form-field-name"
value={selectionTags}
onChange={setSelectionTags}
loadOptions={loadOptions}
promptTextCreator={(label)=>`add new tag: ${label}`}
inputProps={inputProps}
multi
/>
When selectionTags is the list of tags that have already been selected, setSelectionTags is a function that adds a new selected item to that list, and loadOptions holds the list of autocomplete suggestions.
Problem is that if I type "ta" and I have "tag1" as one of the available completions, then choosing it will empty the list of suggestions but leave the "add new tag: ta" entry displayed.
Any idea why it's not being removed as well?
Thanks!
Following this thread on React-Select github:
https://github.com/JedWatson/react-select/issues/1663
I ended up working round it by adding the following options:
ref={s => (selectRef = s)} // store a reference to the select instance
onChange={tags => {
selectRef.select.closeMenu(); // close the entire menu
selectRef.select.setState({
isFocused: false, // remove focus from new tag option
});
setSelectionTags(tags); // call the add tags method with the new set of tags
}}

ZK ComboBox onchange changes all comboboxes in the listbox

I have an issue with a listbox and the combobox behaviour. I have a listbox with a group of rows and I try to edit inline and change the value of a field based on the values of a combobox. But when I select one value in the combo of one row then all the values of the comboboxes of the other rows change to the same value. Please, let me know what I am doing wrong. Thanks for your help!
Here is my code:
<template name="model" var="item">
<listitem >
<listcell label="#load(item.id)"/>
<listcell label="#load(item.descCodigoTrafico)"/>
<listcell label="#load(item.descAmbitoDeTrafico)"/>
<listcell>
<combobox
model="#load(vm.listaPrecioEspecial)"
onChange="#command('addToUpdate', entry=item)"
selectedItem="#load(item.precioEspecial) #save(item.precioEspecial, before='updateItems')">
<template name="model" var="el">
<comboitem label="#load(el)"/>
</template>
</combobox>
</listcell>
<listcell label="#load(item.tipoDescuento)" />
<listcell>
<decimalbox inplace="true"
value="#load(item.ppm) #save(item.ppm, before='updateItems')"
onChange="#command('addToUpdate', entry=item)"
format="#.0000"/>
</listcell>
</listitem>
</template>
And the code of the two methods in de VM:
#Command
public void addToUpdate(#BindingParam("entry") TblEscenarioCondTrafico item){
itemsToUpdate.add(item);
LOGGER.info(item.toString());
for(TblEscenarioCondTrafico i : itemsToUpdate){
LOGGER.info("Item a guardar " + i.toString());
//LOGGER.info("Elemento...");
}
}
#NotifyChange("listaTraficos")
#Command
public void updateItems() throws Exception{
EscenarioCondTraficoService ects = new EscenarioCondTraficoService(em);
for (TblEscenarioCondTrafico i : itemsToUpdate){
LOGGER.info("Guardando " + i.toString());
ects.save(i);
}
itemsToUpdate.clear();
listaTraficos = getListaTraficos();
}
The problem should be that
model="#load(vm.listaPrecioEspecial)"
sets the same Collection to every Combobox as its model and so it is bound to all Combobox instances.
I had the same problem, like Nabil A. said the problem was the model, the same for all the items. I solved creating a new model for every item.
Instead of:
model="#load(vm.listaPrecioEspecial)"
I put something like:
model="#load(vm.getNewListaPrecioEspecial())
And in the VM class you have to create a method named getNewListaPrecioEspecial that returns a new list. (In my case a new SortingPagingListModel)

Adding a teaser image to Composite.News

Is it possible to add a teaser image to the default Composite.News package? Out of the box the news ext. brings all I need but a teaser image for the list view is missing in my case.
Yes, but this require modifications with package.
Edit News data type: go to Data -> Page Datafolders -> locate Composite.News.NewsItem -> right click -> Edit -> on the Fields tab add new field for example named "TeaserImage", Field Type = Data Reference, Reference Type = C1 Image File, Optional = Yes -> Save data type.
Modify the News Form Markup:
The News data item contains custom Form Markup, so the new added field will be not automatically appear there, so you should manually add the markup for the new field: go to Data -> Page Datafolders -> locate Composite.News.NewsItem -> right click -> Edit Form Markup -> add markup for the new TeaserImage field:
<cms:binding name="TeaserImage" type="System.String" optional="true" />
</cms:bindings>
<cms:layout>
<cms:layout.label>
<cms:read source="Title" />
</cms:layout.label>
<TabPanels>
<PlaceHolder Label="Settings">
<FieldGroup>
...
<TextArea Label="Teaser" Help="The short description of the news item">
<TextArea.Text>
<cms:bind source="Teaser" />
</TextArea.Text>
</TextArea>
<DataReferenceTreeSelector Label="TeaserImage" Help="" Handle="Composite.Management.ImageSelectorDialog" SearchToken="Composite.Plugins.Elements.ElementProviders.MediaFileProviderElementProvider.MediaFileSearchToken,Composite|MimeTypes=',\ \'image/gif\',\ \'image/jpeg\',\ \'image/png\',\ \'image/bmp\'', Extensions=null, Folder=null, HideSubfolders='False', Keyword=null" DataType="Composite.Data.Types.IImageFile,Composite" NullValueAllowed="true">
<DataReferenceTreeSelector.Selected>
<cms:bind source="TeaserImage" />
</DataReferenceTreeSelector.Selected>
</DataReferenceTreeSelector>
</FieldGroup>
</PlaceHolder>
<XhtmlEditor Label="News Story" Help="News Story" ClassConfigurationName="common">
...
</XhtmlEditor>
</TabPanels>
</cms:layout>
Modify the XSLT function Composite.News.NewsList -> edit the function call "GetNewsItemXml" -> modify Selected fields (select the new TeaserImage field), -> edit function Template and add the code where you want to render the Tease Image.

Combobox in a DataItemTemplate

In the AspxGridView there are two comboboxes in DataItemTemplate, manually loaded. So when user selects one field of the first combo second will be disabled, i wrote this:
<dxe:ASPxComboBox ID="cmbEqualNotEqual" runat="server"
ClientInstanceName="cmbCEqualNotEqual" EnableClientSideAPI="true">
<Items>
<dxe:ListEditItem Text=" " Value="0" />
<dxe:ListEditItem Text="Eşittir" Value="1" />
<dxe:ListEditItem Text="Eşit Değildir" Value="0" />
</Items>
<ClientSideEvents SelectedIndexChanged="function(s,e){
alert(s.GetEnabled());
var selectedIndex = s.GetSelectedIndex();
if(selectedIndex == 2)
{
cmbCBiggerSmaller.SetEnabled(false);
}
}" />
</dxe:ASPxComboBox>
But this code disables the combo at the last row, not the row user works on. How can i disable the row user works on?
Thanks
I answer it for myself:
for (int i = 0; i < grid.VisibleRowCount; i++)
{
ASPxComboBox combito = grid.FindRowCellTemplateControl(i, grid.Columns[2] as GridViewDataColumn, "combito") as ASPxComboBox;
//combito.Value
}
The problem appears because the ClientInstanceName property is set for all editors in the same column to the same value. A possible solution is to handle the HtmlRowCreated event of the ASPxGridView and set the ClientInstanceName for both editors to a unique value. Also, in this event handler you should write the client side SelectedIndexChanged event handler. Finally, to obtain an editor instance, use the ASPxGridView's FindRowCellTemplateControl method.
Also, the following article can be helpful to you:
http://www.devexpress.com/Support/Center/ViewKBIssue.aspx?kbid=K18282

Resources