summaryrefslogtreecommitdiffstats
path: root/web/widget/abstract/base.js
blob: dd74cca32cca63ea4bdeaf6a3a293f27dc08d9e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
 * Copyright (c) 2012-2014 Kaarle Ritvanen
 * See LICENSE file for license details
 */

define(["acf2/dom", "jquery", "underscore"], function(dom, $, _) {
    return {
	extend: function(spec) {
	    var res = Object.create(this);
	    for (key in spec) res[key] = spec[key];
	    return res;
	},

	new: function(data, name, meta, level, editable, removable) {
	    return Object.create(this).init(
		data, name, meta, level, editable, removable
	    );
	},

	init: function(data, name, meta, level, editable, removable) {
	    this.data = data;
	    this.name = name;
	    this.meta = meta;
	    this.level = level;

	    var value = data.get(name);
	    var status = data.status(name);

	    if (!editable || !meta.editable) {
		var el = this.staticRender(value, meta);
		if (el) {
		    dom.setStatus(el, status);
		    return el;
		}
	    }

	    this.makeEl();
	    this.dynamic = meta.dynamic;

	    var self = this;

	    var request;
	    function handleRequest(req) {
		request = req;
		req.done(function(value, meta) {
		    if (req != request) return;
		    self.render(value, meta);
		    self.setStatus(status);
		});
	    }

	    this.wrapped = this.wrap();
	    this.visible = true;

	    if (removable) {
		var link = dom.href().click(function() {
		    data.delete(name).done(function(txnValid) {
			$("#content").trigger("reload", [txnValid]);
		    })
		}).text("Delete");
		this.wrapped = dom.makeRow(this.wrapped);
		if (this.wrapped.is("tr")) link = $("<td>").html(link);
		this.wrapped.append(link);
	    }

	    handleRequest(this.requestData(value, meta));

	    function validate() {
		request.done(function(value) {
		    self.validate(value);
		});
	    }

	    this.wrapped.on("start", function(event) {
		if (data.status(name) == "invalid") validate();
		else self.setVisible();
		event.stopPropagation();
	    });

	    this.wrapped.on("updated", function(event, field) {
		if (self.dynamic) handleRequest(self.refreshData());
		if (!field ||
		    self.dynamic ||
		    (meta.condition && field in meta.condition))
		    validate();
		event.stopPropagation();
	    });

	    return this.wrapped;
	},

	makeEl: function() { this.el = this.createEl();	},

	requestData: function(value, meta) {
	    return $.Deferred().resolve(value, meta);
	},

	refreshData: function() {
	    var def = $.Deferred();
	    var self = this;
	    this.data.metaRequest(this.name).done(function(data) {
		def.resolve(self.get(), data);
	    });
	    return def;
	},

	wrap: function() { return this.el; },

	showStatus: true,

	setStatus: function(status) {
	    if (this.el && this.showStatus)
		dom.setStatus(this.statusEl(), status);
	},

	statusEl: function() { return this.el; },

	setVisible: function() {
	    this.visible = this.data.match(this.meta.condition);
	    if (this.wrapped)
		this.wrapped.trigger("setVisible", [this.visible]);
	},

	validate: function(value) { this.setVisible(); }
    };
});