Skip to content

Commit 386f8ae

Browse files
Multiple value control
Based in Doña Ana County one
1 parent e4573e1 commit 386f8ae

File tree

4 files changed

+340
-3
lines changed

4 files changed

+340
-3
lines changed

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
alfresco-datalist-constraints
23
=============================
34

@@ -27,4 +28,20 @@ Requires an additional property at `alfresco-global.properties`
2728
datalist.show.ordered=true
2829
```
2930

30-
If **true** values are showed ordered by value in combos, if **false** values are showed as they were introduced in combos.
31+
If **true** values are showed ordered by value in combos, if **false** values are showed as they were introduced in combos.
32+
33+
## Version 2.1.1
34+
35+
Both artifacts are versioned as 2.1.1
36+
37+
Support for multiple values control
38+
39+
```xml
40+
<field id="ks:option">
41+
<control template="/org/alfresco/components/form/controls/datalistSelectone-multiple.ftl">
42+
<control-param name="itemType">Option</control-param>
43+
</control>
44+
</field>
45+
```
46+
47+
*Based in Doña Ana County [multivalue form control](https://github.com/donaanacounty/multivalueFormControl)*

datalist-model-repo/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>es.keensoft</groupId>
66
<artifactId>datalist-model-repo</artifactId>
7-
<version>2.1.0</version>
7+
<version>2.1.1</version>
88
<name>datalist-model-repo Repository AMP project</name>
99
<packaging>amp</packaging>
1010
<description>Manages the lifecycle of the site-props-repo Repository AMP (Alfresco Module Package)</description>

datalist-model-share/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>es.keensoft</groupId>
66
<artifactId>datalist-model-share</artifactId>
7-
<version>2.0.0</version>
7+
<version>2.1.1</version>
88
<name>site-props-share AMP project</name>
99
<packaging>amp</packaging>
1010
<description>Manages the lifecycle of the site-props-share AMP (Alfresco Module Package)</description>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
<#include "/org/alfresco/components/form/controls/common/utils.inc.ftl" />
2+
3+
4+
<#assign optionSeparator=",">
5+
<#assign fieldValue=field.value>
6+
7+
<#if fieldValue?string == "" && field.control.params.defaultValueContextProperty??>
8+
<#if context.properties[field.control.params.defaultValueContextProperty]??>
9+
<#assign fieldValue = context.properties[field.control.params.defaultValueContextProperty]>
10+
<#elseif args[field.control.params.defaultValueContextProperty]??>
11+
<#assign fieldValue = args[field.control.params.defaultValueContextProperty]>
12+
</#if>
13+
</#if>
14+
15+
<#if fieldValue?string != "">
16+
<#assign values=fieldValue?split(",")>
17+
<#else>
18+
<#assign values=[]>
19+
</#if>
20+
21+
<div class="form-field">
22+
<#if form.mode == "view">
23+
<div class="viewmode-field">
24+
<#if field.mandatory && !(fieldValue?is_number) && fieldValue?string == "">
25+
<span class="incomplete-warning"><img src="${url.context}/res/components/form/images/warning-16.png" title="${msg("form.field.incomplete")}" /><span>
26+
</#if>
27+
<span class="viewmode-label">${field.label?html}:</span>
28+
<#if fieldValue?string == "">
29+
<#assign valueToShow=msg("form.control.novalue")>
30+
<#else>
31+
<#if field.control.params.options?? && field.control.params.options != "" &&
32+
field.control.params.options?index_of(labelSeparator) != -1>
33+
<#assign valueToShow="">
34+
<#assign firstLabel=true>
35+
<#list field.control.params.options?split(optionSeparator) as nameValue>
36+
<#assign choice=nameValue?split(labelSeparator)>
37+
<#if isSelected(choice[0])>
38+
<#if !firstLabel>
39+
<#assign valueToShow=valueToShow+",">
40+
<#else>
41+
<#assign firstLabel=false>
42+
</#if>
43+
<#assign valueToShow=valueToShow+choice[1]>
44+
</#if>
45+
</#list>
46+
<#else>
47+
<#assign valueToShow=fieldValue>
48+
</#if>
49+
</#if>
50+
<span class="viewmode-value">${valueToShow?html}</span>
51+
</div>
52+
<#else>
53+
<label for="${fieldHtmlId}-entry">${field.label?html}:<#if field.mandatory><span class="mandatory-indicator">${msg("form.required.fields.marker")}</span></#if></label>
54+
<input class="hidden-input-${fieldHtmlId}" id="${fieldHtmlId}" type="hidden" name="${field.name}" value="${fieldValue?string}" />
55+
<div class="field-data-${fieldHtmlId}" id="field-data-${fieldHtmlId}"></div>
56+
57+
<script language="Javascript" type="text/javascript">//<![CDATA[
58+
59+
(function() {
60+
61+
62+
var hiddenInputId = "${fieldHtmlId}";
63+
var fieldDataDivId = "field-data-${fieldHtmlId}";
64+
var firstRun = true;
65+
66+
67+
function WindowLoad() {
68+
refreshVisible(hiddenInputId, fieldDataDivId);
69+
}
70+
71+
function relocatePlus() {
72+
73+
var oldPlus = document.querySelector('#plus-${fieldHtmlId}');
74+
if (oldPlus) {
75+
oldPlus.parentNode.removeChild(oldPlus);
76+
}
77+
78+
var childDivs = document.querySelector('#field-data-${fieldHtmlId}').getElementsByTagName('div');
79+
var lastDiv = childDivs[childDivs.length-1];
80+
81+
var newPlus = document.createElement('img');
82+
newPlus.setAttribute('class', 'icon plus-icon');
83+
newPlus.setAttribute('id', 'plus-${fieldHtmlId}');
84+
newPlus.setAttribute('src', '${url.context}/res/sp/components/form/images/plus-icon.png');
85+
newPlus.setAttribute('alt', 'Add another');
86+
newPlus.setAttribute('style', 'vertical-align: middle;margin-left:5px;');
87+
88+
lastDiv.appendChild(newPlus);
89+
90+
if (newPlus.addEventListener) {
91+
newPlus.addEventListener("click", function(){addField('field-data-${fieldHtmlId}', '${fieldHtmlId}');}, false);
92+
} else {
93+
newPlus.attachEvent('onclick', function(){addField('field-data-${fieldHtmlId}', '${fieldHtmlId}');} );
94+
}
95+
96+
};
97+
98+
function getCount(divId) {
99+
var el = document.body.querySelector('#' + divId);
100+
var matches = el.querySelectorAll('div');
101+
return matches.length;
102+
};
103+
104+
function addField(divName, hiddenInputId) {
105+
var count = getCount(divName);
106+
addInput(divName, count, hiddenInputId);
107+
108+
};
109+
110+
111+
function deleteField(hiddenInputId, divName, fieldDataDivId) {
112+
var count = getCount(fieldDataDivId);
113+
var el = document.getElementById(divName);
114+
115+
el.parentNode.removeChild(el);
116+
117+
// Get removed index
118+
var index = divName.split('___');
119+
index = index[1];
120+
121+
refreshHidden(index, count, hiddenInputId);
122+
refreshVisible(hiddenInputId, fieldDataDivId);
123+
124+
relocatePlus();
125+
126+
};
127+
128+
function addInput(divName, index, hiddenInputId, value) {
129+
var newdiv = document.createElement('div');
130+
newdiv.setAttribute('id', 'div' + hiddenInputId + '___' + index);
131+
newdiv.innerHTML = "<select "
132+
+ "id='txt"
133+
+ hiddenInputId
134+
+ index
135+
+ "'"
136+
<#if field.control.params.styleClass??>+ " class='${field.control.params.styleClass}'"</#if>
137+
<#if field.control.params.style??>+ " style='${field.control.params.style}'"<#else>+ " style='margin-bottom: 4px;'"</#if>
138+
<#if field.control.params.maxLength??>+ " maxlength='${field.control.params.maxLength}'"<#else>+ " maxlength='1024'"</#if>
139+
<#if field.control.params.size??>+ " size='${field.control.params.size}'"</#if>
140+
+ "></select><img class='icon' style='vertical-align: middle;margin-left:5px;' id='minus-"+index+"-${fieldHtmlId}' src='${url.context}/res/sp/components/form/images/minus-icon.png' alt='Delete this input' "
141+
+ " />";
142+
document.getElementById(divName).appendChild(newdiv);
143+
fillOptions("txt" + hiddenInputId + index, value);
144+
145+
// find text field, attach oninput event listener
146+
var input = document.querySelector('#txt' + hiddenInputId + index);
147+
148+
if (input.addEventListener) {
149+
input.addEventListener("input", function(){refresh(hiddenInputId, divName);}, false);
150+
} else {
151+
input.attachEvent('oninput', function(){refresh(hiddenInputId, divName);} );
152+
};
153+
154+
if (input.addEventListener) {
155+
input.addEventListener("keydown", function(e){if (e.keyCode == 188){e.preventDefault();}}, false);
156+
} else {
157+
input.attachEvent('onkeydown', function(e){if (e.keyCode == 188){e.preventDefault();}} );
158+
};
159+
160+
161+
162+
// find minus button, attach onclick event listener
163+
var minus = document.querySelector('#minus-'+index+'-${fieldHtmlId}');
164+
165+
if (minus.addEventListener) {
166+
minus.addEventListener("click", function(){deleteField(hiddenInputId, "div" + hiddenInputId + '___' + index, divName);}, false);
167+
} else {
168+
minus.attachEvent('onclick', function(){deleteField(hiddenInputId, "div" + hiddenInputId + '___' + index, divName);} );
169+
};
170+
171+
relocatePlus();
172+
173+
if (!firstRun) {
174+
input.focus();
175+
}
176+
};
177+
178+
179+
function refresh(hiddenInputId, fieldDataDivId) {
180+
var count = getCount(fieldDataDivId);
181+
refreshHidden(-1, count, hiddenInputId);
182+
};
183+
184+
function refreshHidden(excludedIndex, count, hiddenInputId) {
185+
var cat = "";
186+
187+
var nonEmptyCounter = 0;
188+
for (var i = 0; i < count; i++) {
189+
if (i != excludedIndex) {
190+
var fieldval = document.getElementById("txt"
191+
+ hiddenInputId + i).value;
192+
if (fieldval != "") {
193+
if (nonEmptyCounter > 0) {
194+
cat = cat + ",";
195+
}
196+
cat = cat + fieldval;
197+
nonEmptyCounter++;
198+
}
199+
}
200+
}
201+
202+
document.getElementById(hiddenInputId).value = cat;
203+
};
204+
205+
function refreshVisible(hiddenInputId, fieldDataDivId) {
206+
207+
var cat = document.getElementById(hiddenInputId).value;
208+
209+
if (cat != "") {
210+
211+
blocks = cat.split(",");
212+
213+
var el = document.body.querySelector('#' + fieldDataDivId);
214+
var matches = el.querySelectorAll('div');
215+
for (var j = 0; j < matches.length; j++) {
216+
matches[j].parentNode.removeChild(matches[j]);
217+
}
218+
219+
for (var i = 0; i < blocks.length; i++) {
220+
addInput(fieldDataDivId, i, hiddenInputId, blocks[i]);
221+
}
222+
223+
} else {
224+
addInput(fieldDataDivId, 0, hiddenInputId);
225+
}
226+
227+
firstRun = false;
228+
};
229+
230+
var reps = 0;
231+
232+
var checkExist = setInterval(function() {
233+
if (document.getElementById(hiddenInputId)) {
234+
clearInterval(checkExist);
235+
WindowLoad();
236+
}
237+
if (reps>=40){
238+
// give up after a second
239+
clearInterval(checkExist);
240+
}
241+
reps++;
242+
}, 25);
243+
244+
} )();//]]></script>
245+
246+
247+
<@formLib.renderFieldHelp field=field />
248+
<#if field.control.params.mode?? && isValidMode(field.control.params.mode?upper_case)>
249+
<select id="${fieldHtmlId}" name="${field.name}" tabindex="0"
250+
<#if field.description??>title="${field.description}"</#if>
251+
<#if field.control.params.size??>size="${field.control.params.size}"</#if>
252+
<#if field.control.params.styleClass??>class="${field.control.params.styleClass}"</#if>
253+
<#if field.control.params.style??>style="${field.control.params.style}"</#if>
254+
<#if field.disabled && !(field.control.params.forceEditable?? && field.control.params.forceEditable == "true")>disabled="true"</#if>>
255+
</select>
256+
</#if>
257+
</#if>
258+
</div>
259+
260+
<#function isSelected optionValue>
261+
<#list values as value>
262+
<#if optionValue == value?string || (value?is_number && value?c == optionValue)>
263+
<#return true>
264+
</#if>
265+
</#list>
266+
<#return false>
267+
</#function>
268+
269+
<#function isValidMode modeValue>
270+
<#return modeValue == "OR" || modeValue == "AND">
271+
</#function>
272+
273+
<script type="text/javascript">//<![CDATA[
274+
275+
YAHOO.util.Event.onContentReady("${fieldHtmlId}", function ()
276+
{
277+
278+
var selects = document.getElementsByTagName('select');
279+
for (var i = 0; i < selects.length; i++) {
280+
if (selects[i].id.indexOf("${fieldHtmlId}") > 0) {
281+
fillOptions(selects[i].id);
282+
}
283+
}
284+
285+
286+
}, this);
287+
288+
function fillOptions(selectId, value) {
289+
290+
Alfresco.util.Ajax.jsonGet({
291+
url: encodeURI(Alfresco.constants.PROXY_URI + '/keensoft/datalist/${field.control.params.itemType}?'+ (new Date().getTime())),
292+
successCallback:
293+
{
294+
fn: function loadWebscript_successCallback(response, config)
295+
{
296+
var obj = eval('(' + response.serverResponse.responseText + ')');
297+
if (obj)
298+
{
299+
300+
var select = document.getElementById(selectId);
301+
302+
for (var j = 0; j < obj.length; j++) {
303+
var newOption = document.createElement('option');
304+
newOption.value = obj[j].code;
305+
newOption.text = obj[j].value;
306+
select.options.add(newOption);
307+
}
308+
309+
// Current value
310+
if (value) {
311+
select.value = value;
312+
}
313+
}
314+
}
315+
}
316+
});
317+
318+
}
319+
320+
//]]></script>

0 commit comments

Comments
 (0)