-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathjquery-edit-block.js
166 lines (144 loc) · 6.18 KB
/
jquery-edit-block.js
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
(function ($) {
// bind listeners on a document level to catch clicks to the generated buttons
$(document)
.on('click', 'a[href="#editBlock"]', function (e) {
e.preventDefault();
$(this).parents('.edit-block').editblock('edit');
})
.on('click', 'a[href="#cancelEditBlock"]', function (e) {
e.preventDefault();
$(this).parents('.edit-block').editblock('cancel');
})
.on('click', 'a[href="#saveBlock"]', function (e) {
e.preventDefault();
$(this).parents('.edit-block').editblock('save');
});
// swap object with HTML, original is hidden
var ebSwap = function (originalObject, newHtml) {
originalObject.hide();
$(newHtml).insertAfter(originalObject);
};
// swap object with DOM element, original is removed from DOM
var ebReplace = function (originalObject, newObject) {
originalObject.remove();
newObject.show();
};
// remove form elements from parent and revert state from 'editing'
var ebClean = function (that) {
that.removeClass('editing');
// remove remnants of ui elements for editing
that.find('.ui-spinner, .redactor_box').remove();
that.find("[role=edit]").each(function () {
ebReplace($("[name=" + this.getAttribute('data-name') + "]"), $(this));
});
that.find("a[href='#cancelEditBlock'], a[href='#saveBlock']").hide();
that.find("a[href='#editBlock']").show();
};
var methods = {
init: function (options) {
var editButton = ' <a href="#editBlock" class="button"><i class="icon-edit"></i> Edit</a> ',
cancelButton = ' <a href="#cancelEditBlock" class="button" style="display:none"><i class="icon-ban-circle"></i> Cancel Edit</a> ',
saveButton = ' <a href="#saveBlock" class="button" style="display:none"><i class="icon-save"></i> Save</a> ';
return this.each(function () {
var $this = $(this);
if (!$this.hasClass('edit-block')) { $this.addClass('edit-block'); }
$this.append('<div role="edit-buttons"></div>');
var buttons = $this.find('div[role="edit-buttons"]');
buttons.append(editButton).append(saveButton).append(cancelButton);
});
},
cancel: function () {
return this.each(function () {
ebClean($(this));
});
},
edit: function () {
return this.each(function () {
var $this = $(this);
$this.addClass('editing');
$this.find("[role=edit]").each(function () {
var $item = $(this),
inputField;
switch ($item.data('edit')) {
case "textarea":
// create a textarea based on the text in the object
// if textarea predefined as <div> with rows and cols attributes
var cols = $item.attr('cols');
var rows = $item.attr('rows');
var rc = (cols == undefined ? "" : "cols='" + cols + "'") + (rows == undefined ? "" : " rows='" + rows + "'");
inputField = '<textarea role="entry" name="' + $item.data('name') + '"'+ rc + '>' + $item.text() + '</textarea>';
ebSwap($item, inputField);
break;
case "textarea-rich":
// create a textarea with redactor
inputField = '<textarea role="entry" name="' + $item.data('name') + '">' + $item.text() + '</textarea>';
ebSwap($item, inputField);
$("textarea[name=" + $item.data('name') + "]").redactor();
break;
case "toggle":
// create a checkbox
var state = $item.html() === 'Yes' ? ' checked' : '';
inputField = '<input role="entry" type="checkbox" name="' + $item.data('name') + '"' + state + '>';
ebSwap($item, inputField);
break;
case "spinner":
// create an input with jQuery UI spinner
inputField = '<input role="entry" size="3" name="' + $item.data('name') + '" value="' + $item.text().replace(/"/g, '"') + '">';
ebSwap($item, inputField);
$("input[name=" + $item.data('name') + "]").spinner();
break;
case "text":
default:
// create a text field
inputField = '<input role="entry" type="text" name="' + $item.data('name') + '" value="' + $item.text().replace(/"/g, '"') + '">';
ebSwap($item, inputField);
break;
}
});
$this.find("a[href='#cancelEditBlock'], a[href='#saveBlock']").show();
$this.find("a[href='#editBlock']").hide();
});
},
save: function () {
return this.each(function () {
var $this = $(this);
$this.find("i.icon-save").removeClass("icon-save").addClass("icon-refresh icon-spin");
// cache the form for reference later
var form = $this.find('form[role=edit-form]');
// post to the form's action url with the contents of the form
$.ajax({
url: form.attr('action'),
type: form.attr('method') || 'post',
data: form.serialize(),
success: function (res) {
$this.find("[role=edit]").each(function () {
// revert all items back to "read" state
var name = this.getAttribute('data-name');
if (this.getAttribute('data-edit') === 'toggle') {
var toggle = $("[name=" + name + "]").is(':checked') ? 'Yes' : 'No';
this.innerHTML = toggle;
} else {
this.innerHTML = $("[name=" + name + "]").val();
}
});
// remove form elements from DOM
ebClean($this);
},
error: function () { window.alert('There was an error saving that information.'); },
complete: function () {
$this.find("i.icon-refresh").removeClass("icon-refresh icon-spin").addClass("icon-save");
}
});
});
}
};
$.fn.editblock = function (method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
}
if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
}
$.error('Method ' + method + ' does not exist from SEP block edit plugin.');
};
}(jQuery));