# j-Editable

> Este componente puede editar todos los elementos con clase editable. Funciona con valores dinámicos o de enlace de datos. Obtenga más información con el ejemplo.

Framework: jcomponent20
Product: jComponent 20 (jcomponent@20)
Language: es
Content-SHA256: a131fc2081459743a70ccf08a3c4ce1d011a6daea2cfa23318cb2dcf343e3270
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: components@910ed1a86f6e72b4f031d3ad0dc7844f9fc5cb8e
Review: not-recorded

Este componente puede editar todos los elementos con la clase `editable`. Funciona con `data-bind` o valores dinámicos. Obtenga más información con el ejemplo.

__Configuración__:

- `autofocus` {Booleano} enfoca el primer elemento (predeterminado: `false`)
- `validate` {Booleano} puede deshabilitar la validación (predeterminado: `true`)
- `disabled` {Booleano} puede deshabilitar la edición (agrega las clases `ui-editable-disabled` y `ui-editable-enabled`), predeterminado: `false`
- `changed` {String} opcional, un enlace a un método o ruta --> contendrá el objeto solo con valores modificados
- `enter` {String} opcional, un enlace a un método `method(path, value, el)`, el método se ejecuta si el usuario presiona `ENTER`
- `escape` {String} opcional, un enlace a un método `method(path, value, el)`, el método se ejecuta si el usuario presiona `ESC`
- `can` {String} opcional, un enlace al método `method(opt, el)` debe devolver `boolean`, significa `can edit?`
- `error` {String} opcional, se evalúa un enlace al método `method(el, isInvalid, meta)` cuando el elemento no es válido y viceversa
- __NEW__ `class {String}` opcional, agrega un nombre de clase con el formato `ui-editable-CLASS` (predeterminado: `default`)

---

El atributo `data-editable` describe el comportamiento:

- `path` {String} una __ruta relativa__ a la propiedad (se puede heredar de `data-bind` automáticamente)
- `required` {Booleano} opcional, habilita "obligatorio" (predeterminado: `false`)
- `type` {Cadena} opcional, puede ser `string` (predeterminado), `date`, `number`, `boolean`, `email` o `html` __NEW__ `tags`
- `can` {String} opcional, una ruta a `function(opt, el)` debe devolver `boolean`, significa `can edit?`
- `save` {String} opcional, se debe evaluar una ruta a la función `function(opt, accepted(boolean))`, `accepted`
- `format` {String} opcional, un formato para `date`, predeterminado: `yyyy-MM-dd`
- `dirsource` {String} opcional, ruta a una fuente de datos
- `dircustom` {Cadena/Booleano} opcional, puede contener una ruta a `function(val, next(new_val))` o puede ser `Boolean`. Esta opción puede permitir agregar un valor personalizado (valor no definido en la fuente de datos)
- `dirrender` {String} opcional, una ruta a `function(item, text)` (debe devolver HTML para `j-Directory`), esta función puede afectar la lista de elementos en `j-Directory`
- `dirminwidth` {Número} opcional, un ancho mínimo para `j-Directory`, predeterminado: `200`
- `dirmaxwidth` {Número} opcional, un ancho máximo para `j-Directory`
- `dirplaceholder` {String} opcional, un marcador de posición para `j-Directory`
- `dirempty` {String} opcional, agrega un campo vacío para `j-Directory`
- `dirkey` {String} opcional, un nombre clave para leer `text` en `dirsource` (predeterminado: `name`)
- `dirvalue` {String} opcional, un nombre clave para leer `value` en `dirsource` (predeterminado: `id`)
- `dirsearch` {Booleano} opcional, puede desactivar la búsqueda de `j-Directory`
- `autosource` {String} una ruta a la función `search` en `autocomplete`, `function(search, render(arr))`
- `autovalue` {String} una ruta de propiedad para el valor en `autosource`
- `maxlength` {Número} una longitud máxima
- `minvalue` {Número} por min. valor para el tipo de número (predeterminado: `undefined`)
- `maxvalue` {Número} un máx. valor para el tipo de número (predeterminado: `undefined`)
- `rebind` {Booleano} si `true` vuelve a vincular `data-bind` solo en este elemento (predeterminado: `0`)
- `validate` {String} opcional, una condición para validar el valor, puede contener un enlace a `function(value)` o `!!value.match(/[a-z]+/)`
- `multiline` {Booleano} opcional, habilita multilínea + agrega la clase `editable-multiline` (`inline-block` + `width:100%`) cuando se está editando (predeterminado: `false`)
- `raw` {Booleano} opcional, cuando `true` entonces el contenido HTML actual será un marcador de posición si el valor es `nullable` (predeterminado: `true`)
- `accept` {String} opcional, una condición para aceptar un valor, puede contener un enlace a `function(value)` o `!!value.match(/[a-z]+/)` es similar a `validate`
- `empty` {String} opcional, habilita un valor vacío y puede contener una etiqueta vacía o `1` o `true` para `rebind` automático de la carpeta
- `invalid` {String} opcional, se evalúa un enlace al método `method(el, isInvalid, meta)` cuando el elemento no es válido y viceversa

__Métodos__:

- __NUEVO__: `component.changed()` devuelve un objeto con datos modificados

__Es bueno saberlo__:

- si el usuario presiona algo de `key` entonces el elemento editable contendrá la clase `keypressed` siempre y cuando no haya abandonado el control
- cada elemento modificado contendrá la clase `changed`
- si el componente cambia algunos valores, el elemento principal contendrá la clase `ui-editable-changed`
- si el elemento tiene `data-bind` con `empty`, se borrará después del enfoque
- __NEW__ ahora admite el tipo `tags`. Por ahora solo es compatible con `rebind` y `data-bind`. (el enlace de datos `template` con `{jQuery selector}` funciona desde `+v18`)
- __NEW__ si el elemento (__o padre, o padre de padre__) contiene el atributo `data-disabled="1"`, el control estará deshabilitado
- __NEW__ elementos ocultos y deshabilitados no serán validados

Úselo con `<ui-component name="editable">`. Cuando el componente aún no está cargado, jComponent lo descarga en el primer uso desde la dirección en `DEF.fallback` (la CDN Componentator de forma predeterminada). Autor: Peter Širka. Fuente: repositorio de componentes Componentator, licencia MIT.

```html example.html
<style>
	.changed {}
	.changed::after { float: right; content: '+'; margin-left: 5px; font-weight: normal; color: orange; }
</style>

<ui-component name="LAZY datepicker"></ui-component>
<ui-component name="LAZY directory"></ui-component>

<ui-component name="editable" path="form">
	<div style="width:500px;padding:10px;border:1px solid #E0E0E0">

		<div class="row">
			<div class="col-xs-3">
				Name:
			</div>
			<div class="col-xs-9">
				<ui-bind path="form.name" config="html" class="editable block" data-editable="required:true"></ui-bind>
			</div>
		</div>
		<div class="row">
			<div class="col-xs-3">
				Email:
			</div>
			<div class="col-xs-9">
				<ui-bind path="form.email" config="html" class="editable block" data-editable="required:1;type:email"></ui-bind>
			</div>
		</div>
		<div class="row">
			<div class="col-xs-3">
				Nickname:
			</div>
			<div class="col-xs-9">
				<ui-bind path="form.nickname" config="empty:Nickname;html" class="editable block" data-editable="required:true"></ui-bind>
			</div>
		</div>
		<div class="row">
			<div class="col-xs-3">
				Framework:
			</div>
			<div class="col-xs-9">
				<ui-bind class="editable block" config="html;empty:Choose a framework;change:renderframework" path="form.frameworkid" data-editable="dirsource:frameworks;"></ui-bind>
			</div>
		</div>
		<div class="row">
			<div class="col-xs-3">
				Country:
			</div>
			<div class="col-xs-9">
				<ui-bind path="form.countries" config="template:{#countrytags}" class="editable block" data-editable="rebind:1;dirsource:countries;type:tags"></ui-bind>
			</div>
		</div>
		<div class="row">
			<div class="col-xs-3">
				Date:
			</div>
			<div class="col-xs-9">
				<ui-bind path="form.date" config="html:(new Date() || value).format('yyyy-MM-dd')" class="editable block" data-editable="type:date"></ui-bind>
			</div>
		</div>
	</div>
	<pre><ui-bind path="form" config="html:JSON.stringify(value, null, '  ')"></ui-bind></pre>
</ui-component>

<script type="text/html" id="countrytags">
	{{ foreach m in value }}<span class="editable-tag"><i class="ti ti-times"></i>{{ m }}</span>{{ end }}
</script>


<script>

	// Alternative to tags (ui-bind path="path" config="change:myfunc")
	function myfunc(data, path, el) {
		if (!data)
			return el.html('');
		var template = '<span class="tag"><i class="ti ti-times"></i>{0}</span>';
		var html = '';
		for (var i = 0; i < data.length; i++)
			html += template.format(data[i]);
		el.html(html);
	}

	var frameworks = [{ id: 0, name: 'Nothing', template: '<b>{{ name }}</b>' }, { id: 1, name: 'jComponent' }, { id: 2, name: 'Angular.js' }, { id: 3, name: 'React' }];
	var countries = ['Slovakia', 'Poland', 'Hungary', 'Germany', 'USA', 'Austria', 'Poland', 'Czechia'];
	var form = {};
	form.date = new Date();
	form.name = 'Peter Širka';
	form.countries = ['Slovakia', 'Hungary'];
	form.frameworkid = 0;

	function renderframework(value, path, el) {
		return value ? frameworks.findValue('id', value, 'name', DEF.empty) : DEF.empty;
	}

</script>
```
