<commit_before>## enketo-core 

[![npm version](https://badge.fury.io/js/enketo-core.svg)](http://badge.fury.io/js/enketo-core) [![Build Status](https://travis-ci.org/enketo/enketo-core.svg?branch=master)](https://travis-ci.org/enketo/enketo-core) [![Dependency Status](https://david-dm.org/enketo/enketo-core/status.svg)](https://david-dm.org/enketo/enketo-core) [![devDependency Status](https://david-dm.org/enketo/enketo-core/dev-status.svg)](https://david-dm.org/enketo/enketo-core#info=devDependencies) [![Codacy Badge](https://www.codacy.com/project/badge/dc1c5aaa9267d75cbd2d6714d2b4fa32)](https://www.codacy.com/app/martijn_1548/enketo-core)

The engine that powers [Enketo Smart Paper](https://enketo.org) and [various third party tools](https://enketo.org/#tools).

This repo is meant to use as a building block for any enketo-powered application.

Follow the [Enketo blog](http://blog.enketo.org) or [Enketo on twitter](https://twitter.com/enketo) to stay up to date.

### Usage as a library

1. Install with `npm install enketo-core --save` or include as a git submodule.
2. Develop a way to perform an XSL Transformation on OpenRosa-flavoured XForms inside your app. The transformation will output an XML instance and a HTML form. See [enketo-transformer](https://github.com/enketo/enketo-transformer) for an example. For development purposes you may also use the free (and slow, not robust at all) API provided by Enketo LLC at [http://xslt-dev.enketo.org/transform](http://xslt-dev.enketo.org/transform/) (add `?xform=http://myforms.com/myform.xml` to use API).
3. Add [themes](./src/sass) to your stylesheet build system (2 stylesheets per theme, 1 is for `media="print"`).
4. Override [config.json](./config.json) and optionally [widgets.js](./src/js/widgets.js) with your app-specific versions.
5. Main methods illustrated in code below:

```javascript 
	
var Form = require('enketo-core');

// The XSL transformation result contains a HTML Form and XML instance.
// These can be obtained dynamically on the client, or at the server/
// In this example we assume the HTML was injected at the server and modelStr 
// was injected as a global variable inside a <script> tag.

// required string of the jquery selector of the HTML Form DOM element
var formSelector = 'form.or:eq(0)';

// required object containing data for the form
var data = {
	// required string of the default instance defined in the XForm
	modelStr: globalXMLInstance,
	// optional string of an existing instance to be edited
	instanceStr: null,
	// optional boolean whether this instance has ever been submitted before
	submitted: false,
	// optional array of external data objects containing: 
	// {id: 'someInstanceId', xmlStr: '<root>external instance content</root>'}
	external = []
};

// instantiate a form, with 2 parameters
var form = new Form( formSelector, data);

// initialize the form and capture any load errors
var loadErrors = form.init();

// submit button handler for validate button
$( '#submit' ).on( 'click', function() {
    form.validateForm()
    	.then(function (valid){
    		if ( !valid ) {
       			alert( 'Form contains errors. Please see fields marked in red.' );
    		} else {
        		// Record is valid! 
        		var record = form.getDataStr();

        		// reset the form view
        		form.resetView();

        		// reinstantiate a new form with the default model 
        		form = new Form( formSelector, { modelStr: modelStr } );

        		// do what you want with the record
    		}
    	});
} );

```

### How to run to develop on enketo-core

1. install [node](http://nodejs.org/) and [grunt-cli](http://gruntjs.com/getting-started)
2. install dependencies with `npm install`
3. build with `grunt`
4. start built-in auto-reloading development server with `grunt develop` 
5. browse to [http://localhost:8005/forms/index.html](http://localhost:8005/forms/index.html)

### How to create or extend widgets<commit_msg>changed: added browser support section to readme, closes #317<commit_after>## enketo-core 

[![npm version](https://badge.fury.io/js/enketo-core.svg)](http://badge.fury.io/js/enketo-core) [![Build Status](https://travis-ci.org/enketo/enketo-core.svg?branch=master)](https://travis-ci.org/enketo/enketo-core) [![Dependency Status](https://david-dm.org/enketo/enketo-core/status.svg)](https://david-dm.org/enketo/enketo-core) [![devDependency Status](https://david-dm.org/enketo/enketo-core/dev-status.svg)](https://david-dm.org/enketo/enketo-core#info=devDependencies) [![Codacy Badge](https://www.codacy.com/project/badge/dc1c5aaa9267d75cbd2d6714d2b4fa32)](https://www.codacy.com/app/martijn_1548/enketo-core)

The engine that powers [Enketo Smart Paper](https://enketo.org) and [various third party tools](https://enketo.org/#tools).

This repo is meant to use as a building block for any enketo-powered application.

Follow the [Enketo blog](http://blog.enketo.org) or [Enketo on twitter](https://twitter.com/enketo) to stay up to date.

### Usage as a library

1. Install with `npm install enketo-core --save` or include as a git submodule.
2. Develop a way to perform an XSL Transformation on OpenRosa-flavoured XForms inside your app. The transformation will output an XML instance and a HTML form. See [enketo-transformer](https://github.com/enketo/enketo-transformer) for an example. For development purposes you may also use the free (and slow, not robust at all) API provided by Enketo LLC at [http://xslt-dev.enketo.org/transform](http://xslt-dev.enketo.org/transform/) (add `?xform=http://myforms.com/myform.xml` to use API).
3. Add [themes](./src/sass) to your stylesheet build system (2 stylesheets per theme, 1 is for `media="print"`).
4. Override [config.json](./config.json) and optionally [widgets.js](./src/js/widgets.js) with your app-specific versions.
5. Main methods illustrated in code below:

```javascript 
	
var Form = require('enketo-core');

// The XSL transformation result contains a HTML Form and XML instance.
// These can be obtained dynamically on the client, or at the server/
// In this example we assume the HTML was injected at the server and modelStr 
// was injected as a global variable inside a <script> tag.

// required string of the jquery selector of the HTML Form DOM element
var formSelector = 'form.or:eq(0)';

// required object containing data for the form
var data = {
	// required string of the default instance defined in the XForm
	modelStr: globalXMLInstance,
	// optional string of an existing instance to be edited
	instanceStr: null,
	// optional boolean whether this instance has ever been submitted before
	submitted: false,
	// optional array of external data objects containing: 
	// {id: 'someInstanceId', xmlStr: '<root>external instance content</root>'}
	external = []
};

// instantiate a form, with 2 parameters
var form = new Form( formSelector, data);

// initialize the form and capture any load errors
var loadErrors = form.init();

// submit button handler for validate button
$( '#submit' ).on( 'click', function() {
    form.validateForm()
    	.then(function (valid){
    		if ( !valid ) {
       			alert( 'Form contains errors. Please see fields marked in red.' );
    		} else {
        		// Record is valid! 
        		var record = form.getDataStr();

        		// reset the form view
        		form.resetView();

        		// reinstantiate a new form with the default model 
        		form = new Form( formSelector, { modelStr: modelStr } );

        		// do what you want with the record
    		}
    	});
} );

```

### Browser support

The following browsers are officially supported:
* latest Android webview on latest Android OS
* latest WKWebView on latest iOS
* latest version of Chrome/Chromium on OS X, Linux, Windows, Android and iOS
* latest version of Firefox on OS X, Windows, Linux, Android and iOS
* latest version of Safari on OS X, Windows, and on the latest version of iOS
* latest version of Microsoft Edge

We have to admit we do not test on all of these, but are committed to fixing browser-specific bugs that are reported for these browsers. Naturally, older browsers versions will often work as well - they are just not officially supported.
Note that some applications using Enketo Core (e.g. Enketo Express) may have more limited browser support. 

### How to develop Enketo Core

1. install [node](http://nodejs.org/) and [grunt-cli](http://gruntjs.com/getting-started)
2. install dependencies with `npm install`
3. build with `grunt`
4. start built-in auto-reloading development server with `grunt develop` 
5. browse to [http://localhost:8005/forms/index.html](http://localhost:8005/forms/index.html)

### How to create or extend widgets
{'fraction_non_alphanumeric': 0.11982520699172033, 'fraction_numerical': 0.010234590616375345, 'mean_word_length': 3.7996688741721854, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 26, 'lorem ipsum': 0, 'www.': 4, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4381159', 'n_tokens_mistral': 2752, 'n_tokens_neox': 2638, 'n_words': 935}