1+ /*
2+ * Copyright 2015 brutusin.org
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ *
16+ * @author Ignacio del Valle Alles idelvall@brutusin.org
17+ */
18+ if ( "undefined" === typeof brutusin || "undefined" === typeof brutusin [ "json-forms" ] ) {
19+ throw new Error ( "brutusin-json-forms-bootstrap.js requires brutusin-json-forms.js" ) ;
20+ }
21+ if ( "undefined" === typeof markdown && window . console ) {
22+ console . warn ( "Include markdown.js (https://github.com/evilstreak/markdown-js) to add markdown support in property description popups" ) ;
23+ }
24+
25+ if ( ( "undefined" === typeof $ || "undefined" === typeof $ . fn || "undefined" === typeof $ . fn . selectpicker ) && window . console ) {
26+ console . warn ( "Include bootstrap-select.js (https://github.com/silviomoreto/bootstrap-select) to turn native selects into bootstrap components" ) ;
27+ }
28+
29+ ( function ( ) {
30+ var BrutusinForms = brutusin [ "json-forms" ] ;
31+
32+ // Basic bootstrap css
33+ BrutusinForms . addDecorator ( function ( element , schema ) {
34+ if ( element . tagName ) {
35+ var tagName = element . tagName . toLowerCase ( ) ;
36+ if ( tagName === "input" && element . type !== "checkbox" || tagName === "textarea" ) {
37+ element . className += " form-control" ;
38+ } else if ( tagName === "select" ) {
39+ element . className += " chosen-select form-control" ;
40+ } else if ( tagName === "button" ) {
41+ if ( element . className === "remove" ) {
42+ element . className += " glyphicon glyphicon-remove" ;
43+ while ( element . firstChild ) {
44+ element . removeChild ( element . firstChild ) ;
45+ }
46+ }
47+ element . className += " btn btn-primary btn-xs" ;
48+ } else if ( tagName === "form" ) {
49+ element . className += " form-inline" ;
50+ }
51+ }
52+ } ) ;
53+
54+
55+ // Description help icon
56+ BrutusinForms . addDecorator ( function ( element , schema ) {
57+ if ( element . tagName ) {
58+ var tagName = element . tagName . toLowerCase ( ) ;
59+ if ( tagName === "label" || tagName === "button" ) {
60+ if ( element . title ) {
61+ var helpLink = document . createElement ( "a" ) ;
62+ helpLink . setAttribute ( "style" , "outline: 0; text-decoration: none; margin-left: 2px;" ) ;
63+ helpLink . setAttribute ( "tabIndex" , - 1 ) ;
64+ helpLink . className = "glyphicon glyphicon-info-sign"
65+ helpLink . setAttribute ( "data-toggle" , "popover" ) ;
66+ helpLink . setAttribute ( "data-trigger" , "focus" ) ;
67+ if ( "undefined" === typeof markdown ) {
68+ helpLink . setAttribute ( "data-content" , element . title ) ;
69+ } else {
70+ helpLink . setAttribute ( "data-content" , markdown . toHTML ( element . title ) ) ;
71+ }
72+ if ( schema . title ) {
73+ helpLink . title = schema . title ;
74+ } else {
75+ helpLink . title = "Help" ;
76+ }
77+ $ ( helpLink ) . popover ( {
78+ placement : 'top' ,
79+ container : 'body' ,
80+ html : ! ( "undefined" === typeof markdown )
81+ } ) ;
82+ element . parentNode . appendChild ( helpLink ) ;
83+ }
84+ }
85+ }
86+ } ) ;
87+
88+ // Popover over inputs
89+ //BrutusinForms.addDecorator(function (element, schema) {
90+ //if (element.tagName) {
91+ // if (element.title && (tagName === "input" || tagName === "textarea" || tagName === "select")) {
92+ // element.setAttribute("data-toggle", "tooltip");
93+ // element.setAttribute("data-trigger", "focus");
94+ // if ("undefined" === typeof markdown) {
95+ // element.setAttribute("data-content", element.title);
96+ // } else {
97+ // element.setAttribute("data-content", markdown.toHTML(element.title));
98+ // }
99+ // if (schema.title) {
100+ // element.title = schema.title;
101+ // } else {
102+ // element.title = "Help";
103+ // }
104+ // $(element).popover({
105+ // placement: 'top',
106+ // container: 'body',
107+ // html: !("undefined" === typeof markdown)
108+ // });
109+ // }input
110+ // }
111+ //});
112+ // Bootstrap select
113+ BrutusinForms . addDecorator ( function ( element , schema ) {
114+ if ( element . tagName ) {
115+ var tagName = element . tagName . toLowerCase ( ) ;
116+ // https://github.com/silviomoreto/bootstrap-select
117+ if ( ! ( "undefined" === typeof $ || "undefined" === typeof $ . fn || "undefined" === typeof $ . fn . selectpicker ) && tagName === "select" ) {
118+ element . title = "" ;
119+ element . className += " selectpicker" ;
120+ element . setAttribute ( "data-live-search" , true ) ;
121+ $ ( element ) . selectpicker ( ) ;
122+ }
123+ }
124+ } ) ;
125+ BrutusinForms . bootstrap = new Object ( ) ;
126+ // helper button for string (with format) fields
127+ BrutusinForms . bootstrap . addFormatDecorator = function ( format , inputType , glyphicon , cb ) {
128+ BrutusinForms . addDecorator ( function ( element , schema ) {
129+ if ( element . tagName ) {
130+ var tagName = element . tagName . toLowerCase ( ) ;
131+ if ( tagName === "input" && schema . type === "string" && schema . format === format ) {
132+ if ( inputType ) {
133+ element . type = inputType ;
134+ }
135+ if ( glyphicon ) {
136+ var parent = element . parentNode ;
137+ var table = document . createElement ( "table" ) ;
138+ var tr = document . createElement ( "tr" ) ;
139+ var td1 = document . createElement ( "td" ) ;
140+ td1 . setAttribute ( "style" , "width:100%;border:none;margin:0" ) ;
141+ table . appendChild ( tr ) ;
142+ tr . appendChild ( td1 ) ;
143+ parent . removeChild ( element ) ;
144+ td1 . appendChild ( element ) ;
145+ parent . appendChild ( table ) ;
146+ var td = document . createElement ( "td" ) ;
147+ tr . appendChild ( td ) ;
148+ var searchButton = document . createElement ( "button" ) ;
149+ searchButton . className = "btn btn-default glyphicon " + glyphicon ;
150+ searchButton . onclick = function ( ) {
151+ cb ( element ) ;
152+ } ;
153+ td . appendChild ( searchButton ) ;
154+ }
155+ }
156+ }
157+ } ) ;
158+ } ;
159+ BrutusinForms . bootstrap . showLoading = function ( element ) {
160+ if ( element && element . parentNode ) {
161+ var loadingId = element . id + "_loading" ;
162+ var loadingLayerId = element . id + "_loading-layer" ;
163+ var loading = document . getElementById ( loadingId ) ;
164+ var loadingLayer = document . getElementById ( loadingLayerId ) ;
165+ if ( ! loading ) {
166+ var tagName = element . tagName . toLowerCase ( ) ;
167+ element . parentNode . style . position = "relative" ;
168+ loading = document . createElement ( "span" ) ;
169+ loading . id = loadingId ;
170+ loading . className = "glyphicon glyphicon-refresh glyphicon-refresh-animate" ;
171+ if ( tagName === "select" ) {
172+ loading . className += " loading-icon-select" ;
173+ } else if ( element . type === "checkbox" ) {
174+ loading . className += " loading-icon-checkbox" ;
175+ } else {
176+ loading . className += " loading-icon" ;
177+ }
178+ element . parentNode . appendChild ( loading ) ;
179+ loadingLayer = document . createElement ( "div" ) ;
180+ loadingLayer . className = "loading-layer" ;
181+ loadingLayer . appendChild ( document . createTextNode ( "" ) ) ;
182+ loadingLayer . id = loadingLayerId ;
183+ element . parentNode . appendChild ( loadingLayer ) ;
184+ }
185+ loading . style . visibility = "visible" ;
186+ loadingLayer . style . visibility = "visible" ;
187+ }
188+ }
189+ BrutusinForms . bootstrap . hideLoading = function ( element ) {
190+ if ( element ) {
191+ var loadingId = element . id + "_loading" ;
192+ var loadingLayerId = element . id + "_loading-layer" ;
193+ var loading = document . getElementById ( loadingId ) ;
194+ var loadingLayer = document . getElementById ( loadingLayerId ) ;
195+ if ( loading ) {
196+ loading . style . visibility = "hidden" ;
197+ }
198+ if ( loadingLayer ) {
199+ loadingLayer . style . visibility = "hidden" ;
200+ }
201+ }
202+ }
203+
204+ BrutusinForms . onResolutionStarted = BrutusinForms . bootstrap . showLoading ;
205+ BrutusinForms . onResolutionFinished = BrutusinForms . bootstrap . hideLoading ;
206+
207+ BrutusinForms . onValidationSuccess = function ( element ) {
208+ element . parentNode . className = element . parentNode . className . replace ( " has-error" , "" ) ;
209+ }
210+ BrutusinForms . onValidationError = function ( element , message ) {
211+
212+ setTimeout ( function ( ) {
213+ var dataToggle = element . getAttribute ( "data-toggle" ) ;
214+ var dataTrigger = element . getAttribute ( "data-trigger" ) ;
215+ var dataContent = element . getAttribute ( "data-content" ) ;
216+ var title = element . title ;
217+ element . setAttribute ( "data-toggle" , "popover" ) ;
218+ element . setAttribute ( "data-trigger" , "manual" ) ;
219+ if ( "undefined" === typeof markdown ) {
220+ element . setAttribute ( "data-content" , message ) ;
221+ } else {
222+ element . setAttribute ( "data-content" , markdown . toHTML ( message ) ) ;
223+ }
224+
225+ element . title = BrutusinForms . messages [ "validationError" ] ;
226+ if ( ! element . parentNode . className . includes ( "has-error" ) ) {
227+ element . parentNode . className += " has-error" ;
228+ }
229+ element . focus ( ) ;
230+ $ ( element ) . popover ( {
231+ placement : 'top' ,
232+ container : 'body' ,
233+ html : true
234+ } ) ;
235+ $ ( element ) . popover ( "show" ) ;
236+ var onblur = element . onblur ;
237+ element . onblur = function ( e ) {
238+ if ( dataToggle ) {
239+ $ ( element ) . popover ( 'hide' ) ;
240+ element . setAttribute ( "data-toggle" , dataToggle ) ;
241+ element . setAttribute ( "data-trigger" , dataTrigger ) ;
242+ element . setAttribute ( "data-content" , dataContent ) ;
243+ } else {
244+ $ ( element ) . popover ( 'destroy' ) ;
245+ element . removeAttribute ( "data-toggle" ) ;
246+ element . removeAttribute ( "data-trigger" ) ;
247+ element . removeAttribute ( "data-content" ) ;
248+ }
249+
250+ element . onblur = onblur ;
251+ element . title = title ;
252+ if ( onblur ) {
253+ onblur ( ) ;
254+ }
255+ }
256+ } ,
257+ 200 ) ;
258+ }
259+ } ( ) ) ;
0 commit comments