Skip to content
Niko edited this page May 15, 2024 · 8 revisions

Some formatting patterns that occur fairly often:

boolean handling

You can always use a checkbox, but it is often nices to use a combo box:

    <label><span>Enabled</span>
    	<select name="data.enabled" class="bool">
    		<option value="true">yes</option><option value="false">no</option>
    	</select>
    </label>

default value for collections

When adding a new collection using the collection controls, you might want to set some default values. This is best accomblished by using the "addCollection" event.

For example we have a colleciton named "tasks" with a select box that shows some values (open/closed) we simply add a handler to it:

	<tbody class="collection" id="taskList" data-field="data.tasks">
		<tr><td>
			<select name="tasks.state">
				<option value="open">Open</option>
				<option value="closed">Closed</option>
			</select>
		</td></tr>
	</tbody>

And based on this we can add the following code:

$("#taskList").on("addCollection", function(ev, line, pojo) {
	$("select[name='tasks.state']").val("open");
});

Collection of strings

You sometimes just want a simple list of keywords or similar in a collection. In this case you can use the "insert" and "insertAction" for editing without any extra javascript:

<div class="input-group">
	<input data-field="data.keywords" class="form-control insert string" />
	<span class="input-group-text"><i class="action fa fa-plus insertAction" data-field="data.keywords"></i></span>
</div>
<ul class="collection" data-field="data.keywords">
	<li><span class="field">keywords.</span> <i class="action remove fa fa-trash"></i>
</ul>

This will allow editing of a list of keywords.

Collection with autocomplete

Quite often you do not simply want to create a new element within a collection, but rather have an autocomplete control that allows to select an element from the database which you want to add.

This can be accomplished by using the "insert" control and events:

<table>
<tbody class="collection" data-field="data.users">
	<tr>
		<td><span class="ui-icon ui-icon-minusthick delete"></span></td>
		<td>
			<span class="field">users.userName</span>
		</td>
	</tr>
</tbody>
</table>
<div class="button insertAction" data-field="data.users" style="float:right"><span class="ui-icon ui-icon-pencil"></span></div>
Add: <input id="userSelectionAutcomplete" class="insert" data-field="data.users"/>

The logic behind this control is similar to the normal collection. In this case the collection template (the "tr") will be filled with the data object returned by the autocomplete. The autocomplete itself is just the standard jquery ui autocomplete which will trigger a predefined event:

$("#userSelectionAutcomplete").autocomplete({
	source: function( request, response ) {
		$.ajax({
			url: "../ajax/findUser" ,
			dataType: "json",
			type: "POST",
			contentType: "application/x-www-form-urlencoded; charset=UTF-8",
			data: "q=" + encodeURIComponent(request.term),
			success: function( data ) {
				// set a custom response object based on the json array
				response( $.map( data, function( item ) {
					return !item?null:{
						label: item.userName,
						value: item
					};
				}));
			}
		});
	},
	minLength: 2,
	select: function( event, ui ) {
		// trigger the form insert functionality
		$(this).trigger("insert", [ui.item.value]);
		// reset value
		$(this).val("");
		return false;
	}	
});

The rest is handled by the form framework. It will create a new duplicate of the template (in this case a new 'tr'), fill it with data from the selected object and make sure it is serialized with all data in the final object. You can even use input fields to modify fields on the selected element.

Single field with autocomplete

This is very similar to a collection (see above). The only change is in the "select" trigger:

...
	select: function( event, ui ) {
		// set the new value
		$(this).data().pojo = ui.item.value;
                // render the new text
		$(this).change();
		return false;
	}	
...

Array of String <-> Comma Separated Input

also see: Objects

If you have a list of strings, which do not need any special handling (like autocomplete), but just simple inserting, you can use the event methods to fill and structure it again when editing:

   <input name="data.types" class="object commajoined"/>
	// join the string with a comma between each entry 
	$(".commajoined").on("fill",function(){
		$(this).val($(this).data("pojo").join(","));
	});

	// when editing write the pojo-array by splitting the val
	$(".commajoined").keyup(function(){
                $(this).data().pojo = $(this).val().split(",");
	});

TagIt and arrays

Using Tag-It you can have a pretty nice control for categories. These are normally saved as either comma separated values or an array.

Working with an array is a little tricky, but not so hard in the end.

In this example the data is stored in an array of strings which is in the "pojo" data of the field.

// enable tag-control
$("input[name='data.categories']", $detail).each(function() {
	$(this).on("fill",function(){
		// remove all tags (from a previous fill)
		$(this).tagit("removeAll");
		// check if we have data on this field
		if($(this).data().pojo) {
			$(this).val($(this).data("pojo").join(","));
			var $cats = $(this);
			// the data is on the pojo, call tagit for each
			$.each($(this).data().pojo, function(el) {
				$cats.tagit("createTag", this);
			});
		} else {
			$(this).val("");
		}
		// set "orig" value to avoid triggering changed event
		$(this).data().orig = $(this).val()
	});
 	// split the value to create the array of strings
	$(this).on("change",function(){
		$(this).data().pojo = $(this).val().split(","); 
	});

	// add tagit
	$(this).tagit({
		allowSpaces: true,
		placeholderText: $(this).attr("title"),
		});
});

# Adding a datetime picker to fields in a collection

$(".collection", $detail).on("postAddCollection", function(ev, line, data){ $(".datetime", line).datetimepicker({ lang: "de", step: 15 }); });