Source: widgets/SpwEditAttributes.js

Retour à la documentation
/**
 * @class spw.widgets.SpwEditAttributes
 */
define([
    'dojo/_base/declare',
    'dojo/_base/lang',
    'dojo/_base/array',

    'dojo/on',
    'dojo/dom-construct',
    'esri/request',

    'spw/api/SpwBaseTemplatedWidget',

    'dojo/text!./templates/SpwEditAttributes.html',

    'spw/widgets/SpwEditRelatedAttribute',

    'dijit/form/Select',
    'dijit/form/ValidationTextBox',
    'dijit/form/FilteringSelect',
    'dijit/form/SimpleTextarea',
    'dijit/form/DateTextBox',
    'dijit/Dialog',

    'dojo/data/ItemFileReadStore',

    'dijit/form/Button',
    'dijit/form/Form'

], function(declare, lang, array, on, domConstruct, request, _Templated, template, SpwEditRelatedAttribute, Select, ValidationTextBox,
            FilteringSelect, SimpleTextarea, DateTextBox, Dialog, ItemFileReadStore) {

    return declare([_Templated], {

        templateString: template,

        onSuccessCallback: null,
        onCancelCallback: null,
        oldAttributes: null,

        _lastLayerURI: null,

        ignoreFields: [],
        readOnlyAttributes: [],
        resetAttributes: [],

        fieldsOrder: [],

        relatedLayers: null,

        regex: null,

        orderFields: function(fields) {
            if (this.fieldsOrder == null) {
                return fields;
            }

            var fieldsSorted = fields.slice(0);

            fieldsSorted.sort(lang.hitch(this, function(f1, f2) {
                var idx1 = this.fieldsOrder.indexOf(f1.name);
                var idx2 = this.fieldsOrder.indexOf(f2.name);

                if (idx2 < 0) {
                    return -1;
                }
                else if (idx1 < 0) {
                    return 1;
                }

                return idx1 - idx2;
            }));

            return fieldsSorted;
        },

        postCreate: function() {
            this.inherited(arguments);

            this.toDeleteTr = [];

            this.own(
                on(this.formNode, 'submit', lang.hitch(this, this.onSubmit)),
                on(this.cancelNode, 'click', lang.hitch(this, this.onCancel))
            );
        },

        buildForm: function(fields) {
            array.forEach(this.toDeleteTr, lang.hitch(this, function(tr) {
                domConstruct.destroy(tr);
            }));

            array.forEach(this.widgetsToClose, lang.hitch(this, function(wgt) {
                wgt.close();
            }));

            this.widgetsToClose = [];

            this.toDeleteTr.length = 0;

            fields = this.orderFields(fields).reverse();

            array.forEach(fields, lang.hitch(this, function(info) {
                if (this.ignoreFields && this.ignoreFields.indexOf(info.name) > -1) {
                    return;
                }

                var tr = domConstruct.create('tr', null, this.tbodyNode, 'first');

                this.toDeleteTr.push(tr);

                domConstruct.create('td', {
                    innerHTML: info.alias + ' : ',
                    style: 'width: 1%; white-space: nowrap; text-align: right;'
                }, tr);

                var td = domConstruct.create('td', null, tr);

                if (this.relatedLayers && this.relatedLayers[info.name]) {
                    this[info.name] = new SpwEditRelatedAttribute(lang.mixin(this.relatedLayers[info.name], {
                        spwViewer: this.spwViewer,
                        name: info.name,
                        required: !(info.nullable === true),
                        disabled: this.isReadyOnly(info.name)
                    }), domConstruct.create('div', null, td));

                    this.widgetsToClose.push(this[info.name]);
                }
                else if (info.domain) {
                    if (info.nullable === true) {
                        var store = new ItemFileReadStore({
                            data: {
                                items: info.domain.codedValues,
                                identifier: 'code',
                                label: 'name'
                            }
                        });

                        this[info.name] = new FilteringSelect({
                            store: store,
                            searchAttr: 'name',
                            name: info.name,
                            style: 'width: 95%;',
                            required: !(info.nullable === true),
                            disabled: this.isReadyOnly(info.name)
                        });

                        this[info.name].placeAt(td).startup();
                    } else {
                        this[info.name] = new Select({
                            name: info.name,
                            options: array.map(info.domain.codedValues, function(e) {
                                return {
                                    label: e.name,
                                    value: e.code
                                };
                            }),
                            style: 'width: 95%;',
                            disabled: this.isReadyOnly(info.name)
                        });

                        this[info.name].placeAt(td).startup();
                    }
                } else if (info.type === 'esriFieldTypeString' && info.length === 1073741822) {
                    this[info.name] = new SimpleTextarea({
                        name: info.name,
                        rows: '4',
                        required: !(info.nullable === true),
                        style: 'resize: none; width: 95%;',
                        disabled: this.isReadyOnly(info.name)
                    });

                    this[info.name].placeAt(td).startup();
                } else if (info.type === 'esriFieldTypeString' || info.type === 'esriFieldTypeInteger' || info.type === 'esriFieldTypeSmallInteger') {
                    var params = {
                        required: !(info.nullable === true),
                        name: info.name,
                        style: 'width: 95%;',
                        disabled: this.isReadyOnly(info.name)
                    };

                    if (this.regex && this.regex[info.name]) { // parce que si on met regExp directement, ça foire
                        params.regExp = this.regex[info.name];
                    }

                    this[info.name] = new ValidationTextBox(params);

                    this[info.name].placeAt(td).startup();
                } else if (info.type === 'esriFieldTypeDate') {
                    var params = {
                        required: !(info.nullable === true),
                        name: info.name,
                        value: new Date(),
                        style: 'width: 95%;',
                        disabled: this.isReadyOnly(info.name)
                    };

                    this[info.name] = new DateTextBox(params);

                    this.formatValues = this.formatValues || {};
                    this.formatValues[info.name] = function(value) {
                        if (value instanceof Date) {
                            return value.getTime();
                        }

                        return value;
                    };

                    this[info.name].placeAt(td).startup();
                }

            }));
        },

        isReadyOnly: function(attribute) {
            if (this.readOnlyAttributes == null) {
                return false;
            }

            return this.readOnlyAttributes.indexOf(attribute) > -1;
        },

        fillForm: function(attributes) {
            this.formNode.reset();

            this.oldAttributes = attributes;

            array.forEach(this.resetAttributes, lang.hitch(this, function(attr) {
                if (attributes[attr]) {
                    attributes[attr] = attributes[attr].trim();
                }
            }));

            this.formNode.set('value', attributes);
        },

        onSubmit: function(evt) {
            if (evt.preventDefault) {
                evt.preventDefault();
            }

            if (!this.formNode.validate()) {
                return false;
            }

            var values = lang.mixin(lang.clone(this.oldAttributes), this.formNode.get('value'));

            if (!array.every(this.widgetsToClose, lang.hitch(this, function(wgt) {
                if (!wgt.validate()) {
                    return false;
                }

                values[wgt.name] = wgt.get('value');
                return true;
            }))) {
                return false;
            }

            array.forEach(this.ignoreFields, lang.hitch(this, function(field) {
                // pour être certain d'avoir tous les champs (ex. lors d'un copier/coller depuis une autre couche
                if (values[field] === undefined) {
                    values[field] = null;
                }
            }));

            for (var key in values) {
                if (values.hasOwnProperty(key)) {
                    if (this.oldAttributes[key] == null && values[key] === '') {
                        values[key] = null;
                    }
                }
            }

            if (this.formatValues) {
                for (var key in this.formatValues) {
                    if (this.formatValues.hasOwnProperty(key)) {
                        if (values[key] && this.formatValues[key]) {
                            values[key] = this.formatValues[key](values[key]);
                        }
                    }
                }
            }

            if (this.onSuccessCallback) {
                this.onSuccessCallback(values);
                this.onSuccessCallback = null;
            }

            this.onDeactivate();

            return false;
        },

        onDeactivate: function() {
            this.inherited(arguments);

            array.forEach(this.widgetsToClose, lang.hitch(this, function(wgt) {
                wgt.close();
            }));
        },

        onCancel: function() {
            if (this.onCancelCallback) {
                this.onCancelCallback();
                this.onCancelCallback = null;
            }

            this.onDeactivate();
        },

        edit: function(uri, attributes, success, cancel) {
            if (uri == null) {
                cancel('Il faut préciser une URL !');
                return;
            }

            if (uri === this._lastLayerURI) {
                this.attributes = attributes;
                this.onSuccessCallback = success;
                this.onCancelCallback = cancel;
                this._lastLayerURI = uri;

                this.fillForm(attributes);

                this.onActivate();
                return;
            }

            this._lastLayerURI = uri;

            request({
                url: uri + '?f=json',
                handleAs: 'json'
            }).then(lang.hitch(this, function(json) {
                if (json.fields) {
                    this.buildForm(json.fields);

                    this.attributes = attributes;
                    this.onSuccessCallback = success;
                    this.onCancelCallback = cancel;
                    this._lastLayerURI = uri;

                    this.fillForm(attributes);

                    this.onActivate();
                }
                else {
                    console.error('[SPwEditAttributes] Impossible de récupérer les infos du service');
                    cancel('Impossible de récupérer les informations de la couche');
                }
            }), lang.hitch(this, function(err) {
                console.error('[SPwEditAttributes] Impossible de récupérer les infos du service : ' + err);
                cancel('Impossible de récupérer les informations de la couche');
            }));
        }
    });

});