bootstrap_builders 0.0.45 → 0.0.46
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +61 -43
- data/app/assets/javascripts/bootstrap_builders.js +5 -0
- data/app/assets/javascripts/bootstrap_builders/bb-btn-responsive.js +12 -0
- data/app/assets/javascripts/bootstrap_builders/date-picker-input.js +87 -0
- data/app/assets/javascripts/bootstrap_builders/tabs.js +65 -0
- data/app/assets/javascripts/bootstrap_builders/url-builder/lib/url-builder.js +143 -0
- data/app/assets/javascripts/bootstrap_builders/view-port-detection.js +102 -0
- data/lib/bootstrap_builders/version.rb +1 -1
- metadata +8 -8
- data/app/assets/javascripts/bootstrap_builders.coffee +0 -5
- data/app/assets/javascripts/bootstrap_builders/bb-btn-responsive.coffee +0 -9
- data/app/assets/javascripts/bootstrap_builders/date-picker-input.coffee +0 -74
- data/app/assets/javascripts/bootstrap_builders/tabs.js.coffee +0 -48
- data/app/assets/javascripts/bootstrap_builders/url-builder/lib/url-builder.coffee +0 -99
- data/app/assets/javascripts/bootstrap_builders/view-port-detection.coffee +0 -71
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd89dcad0a76bb86f423577ee2c84653236773d2
|
4
|
+
data.tar.gz: d8bb1af2fbe8de6add3d9f05a9cff885789365b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b07a1621f558a7e6dce1005e1bc5deb9c02948264d61f7981c35550a99b7200d164b962e1f78e48c14f49b659c4be175d336e3c8f870af132d938e5242df6606
|
7
|
+
data.tar.gz: 88c1cb48cdcd704e39f9f4d6a3b19f6c8d441c2717123f50a85af9ab26ac8ee8ccf4ddaf475d049113b0486f0d42529f44d95e197224a4d09c28a39014712286
|
data/README.md
CHANGED
@@ -30,9 +30,9 @@ Then add to your `application.css`:
|
|
30
30
|
|
31
31
|
### Date picker input for SimpleForm
|
32
32
|
|
33
|
-
```
|
34
|
-
|
35
|
-
|
33
|
+
```erb
|
34
|
+
<%= f.input :activation_at, as: :bb_date_picker %>
|
35
|
+
<%= f.input :something_at, as: :bb_date_time_picker %>
|
36
36
|
```
|
37
37
|
|
38
38
|
You might encounter some trouble with specs. Use the helpers:
|
@@ -51,57 +51,71 @@ set_bb_date_input ".subscription_start_date", 2.days.from_now.to_date
|
|
51
51
|
2. Controls if `:right` argument is given
|
52
52
|
3. Table if `:table` argument is given
|
53
53
|
|
54
|
-
```
|
55
|
-
|
54
|
+
```erb
|
55
|
+
<%= bb_panel "Title of panel", controls: button_content do %>
|
56
56
|
Content of panel
|
57
|
+
<% end %>
|
57
58
|
```
|
58
59
|
|
59
|
-
```
|
60
|
-
|
61
|
-
|
60
|
+
```erb
|
61
|
+
<%= bb_panel "Title of panel", controls: button_content do |panel| %>
|
62
|
+
<% panel.controls << bb_btn("#", "Another button", :mini) %>
|
62
63
|
Content of panel
|
64
|
+
<% end %>
|
63
65
|
```
|
64
66
|
|
65
67
|
### Panel with a table
|
66
68
|
|
67
|
-
```
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
```erb
|
70
|
+
<%= bb_panel "Title of panel", table: true do %>
|
71
|
+
<tbody>
|
72
|
+
<tr>
|
73
|
+
<td>Test</td>
|
74
|
+
</tr>
|
75
|
+
</tbody>
|
76
|
+
<% end %>
|
72
77
|
```
|
73
78
|
|
74
79
|
You can add custom classes like this:
|
75
|
-
```
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
+
```erb
|
81
|
+
<%= bb_panel "Title of panel", table: {bs_classes: [:striped]} do %>
|
82
|
+
<tbody>
|
83
|
+
<tr>
|
84
|
+
<td>Test</td>
|
85
|
+
</tr>
|
86
|
+
</tbody>
|
87
|
+
<% end %>
|
80
88
|
```
|
81
89
|
|
82
90
|
You can make the panel collapsed with the title functioning as the open toggle like this:
|
83
|
-
```
|
84
|
-
|
91
|
+
```erb
|
92
|
+
<%= bb_panel "Title", :collapsable, :collapsed do %>
|
85
93
|
Content
|
94
|
+
<% end %>
|
86
95
|
```
|
87
96
|
|
88
97
|
### Table
|
89
98
|
|
90
99
|
1. Adds Bootstrap classes: "table", "table-hover", "table-striped"
|
91
100
|
|
92
|
-
```
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
101
|
+
```erb
|
102
|
+
<%= bb_table do %>
|
103
|
+
<tbody>
|
104
|
+
<tr>
|
105
|
+
<td>Test</td>
|
106
|
+
</tr>
|
107
|
+
</tbody>
|
108
|
+
<% end %>
|
97
109
|
```
|
98
110
|
|
99
111
|
2. A table showing a models attributes:
|
100
112
|
|
101
|
-
```
|
102
|
-
|
103
|
-
|
104
|
-
|
113
|
+
```erb
|
114
|
+
<%= bb_table do %>
|
115
|
+
<tbody>
|
116
|
+
<%= bb_attribute_rows @model, [:id, :created_at, :updated_at] %>
|
117
|
+
</tbody>
|
118
|
+
<% end %>
|
105
119
|
```
|
106
120
|
|
107
121
|
You can change the default classes like this:
|
@@ -117,11 +131,11 @@ The classes "bb-table" and "table" are always added.
|
|
117
131
|
2. Adds labels automatically
|
118
132
|
3. Doesn't show button if CanCan doesn't allow it
|
119
133
|
|
120
|
-
```
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
134
|
+
```erb
|
135
|
+
<%= bb_new_btn url: [:admin, User] %>
|
136
|
+
<%= bb_edit_btn url: [:admin, user], :mini %>
|
137
|
+
<%= bb_destroy_btn url: [:admin, user], label: false %>
|
138
|
+
<%= bb_btn "/url", "My label", :block, :lg, :confirm, :disabled %>
|
125
139
|
```
|
126
140
|
|
127
141
|
### Responsive mixins
|
@@ -161,25 +175,29 @@ And so on...
|
|
161
175
|
|
162
176
|
### Tabs
|
163
177
|
|
164
|
-
```
|
165
|
-
|
166
|
-
|
178
|
+
```erb
|
179
|
+
<%= bb_tabs do |tabs| %>
|
180
|
+
<%= tabs.tab "Title" do %>
|
167
181
|
Content of tab
|
182
|
+
<% end %>
|
183
|
+
<% end %>
|
168
184
|
```
|
169
185
|
|
170
|
-
```
|
171
|
-
|
172
|
-
|
186
|
+
```erb
|
187
|
+
<%= bb_tabs :pills, :stacked do |tabs| %>
|
188
|
+
<%= tabs.tab "Title", "id-of-content-container" do %>
|
173
189
|
Content of tab
|
174
|
-
|
190
|
+
<% end %>
|
191
|
+
<%= tabs.tab "Load on demand", ajax_url: some_path %>
|
192
|
+
<% end %>
|
175
193
|
```
|
176
194
|
|
177
195
|
Pre-select a tab by using the query parameter called "bb_selected_tab" like so: "?bb_selected_tab=id-of-content-container". This will also work with ajax tabs.
|
178
196
|
|
179
197
|
### Flash
|
180
198
|
|
181
|
-
```
|
182
|
-
|
199
|
+
```erb
|
200
|
+
<%= bb_flash %>
|
183
201
|
```
|
184
202
|
|
185
203
|
## Contributing to bootstrap_builders
|
@@ -0,0 +1,12 @@
|
|
1
|
+
$(document).ready(function() {
|
2
|
+
$.bbUpdateResponsiveButtons = function() {
|
3
|
+
if ($.bbViewPortOrBelow("md")) {
|
4
|
+
$(".bb-btn-responsive").addClass("btn-xs")
|
5
|
+
} else {
|
6
|
+
$(".bb-btn-responsive").removeClass("btn-xs")
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
$.bbViewPortChange(function() { $.bbUpdateResponsiveButtons() })
|
11
|
+
$.bbUpdateResponsiveButtons()
|
12
|
+
})
|
@@ -0,0 +1,87 @@
|
|
1
|
+
class DatePickerInput {
|
2
|
+
constructor(options) {
|
3
|
+
var current_input = this
|
4
|
+
|
5
|
+
this.element = options.element
|
6
|
+
this.text_ele = $("input.bb_date_picker, input.bb_date_time_picker", this.element)
|
7
|
+
this.form = this.text_ele.parents("form").first()
|
8
|
+
|
9
|
+
// The hidden Rails-inputs that will get the actual values like year, month, date, hour and minute.
|
10
|
+
this.text_ele = $("input.bb_date_picker, input.bb_date_time_picker", this.element)
|
11
|
+
this.year_ele = $(".bb-date-picker-input-year", this.element)
|
12
|
+
this.month_ele = $(".bb-date-picker-input-month", this.element)
|
13
|
+
this.day_ele = $(".bb-date-picker-input-day", this.element)
|
14
|
+
this.hour_ele = $(".bb-date-picker-input-hour", this.element)
|
15
|
+
this.min_ele = $(".bb-date-picker-input-min", this.element)
|
16
|
+
|
17
|
+
// Update values on form-submit.
|
18
|
+
if (this.form.length > 0 && this.form.data("bb-date-picker-input") != "true") {
|
19
|
+
this.form.data("bb-date-picker-input", "true")
|
20
|
+
|
21
|
+
this.form.submit(function() {
|
22
|
+
$(".bb-date-picker-input", this).each(function() {
|
23
|
+
$(this).bbDatePickerInput("updateValues")
|
24
|
+
})
|
25
|
+
|
26
|
+
return true
|
27
|
+
})
|
28
|
+
}
|
29
|
+
|
30
|
+
// Update the values when the date is changed or upon blur
|
31
|
+
this.text_ele.on("changeDate blur", function() {
|
32
|
+
var parents = $(this).parents(".bb-date-picker")
|
33
|
+
|
34
|
+
if (parents.length <= 0) {
|
35
|
+
throw "No parents were found"
|
36
|
+
}
|
37
|
+
|
38
|
+
current_input.updateValues()
|
39
|
+
})
|
40
|
+
}
|
41
|
+
|
42
|
+
// Parses the date in the input-field and updates all the hidden Rails-inputs from the parsed values.
|
43
|
+
updateValues() {
|
44
|
+
if (this.year_ele.length <= 0) {
|
45
|
+
throw "Could not find year element: " + this.year_ele
|
46
|
+
} else if (this.month_ele.length <= 0) {
|
47
|
+
throw "Could not find month element: " + this.month_ele
|
48
|
+
} else if (this.day_ele.length <= 0) {
|
49
|
+
throw "Could not find month element: " + this.day_ele
|
50
|
+
}
|
51
|
+
|
52
|
+
var match = null
|
53
|
+
|
54
|
+
if ($.trim(this.text_ele.val()) == "") {
|
55
|
+
this.year_ele.val("")
|
56
|
+
this.month_ele.val("")
|
57
|
+
this.day_ele.val("")
|
58
|
+
this.hour_ele.val("")
|
59
|
+
this.min_ele.val("")
|
60
|
+
} else if(match = this.text_ele.val().match(/^\s*(\d+)-(\d+)-(\d+)\s+(\d+):(\d+)\s*$/)) {
|
61
|
+
this.year_ele.val(match[1])
|
62
|
+
this.month_ele.val(match[2])
|
63
|
+
this.day_ele.val(match[3])
|
64
|
+
this.hour_ele.val(match[4])
|
65
|
+
this.min_ele.val(match[5])
|
66
|
+
}else if(match = this.text_ele.val().match(/^\s*(\d+)-(\d+)-(\d+)\s*$/)) {
|
67
|
+
this.year_ele.val(match[1])
|
68
|
+
this.month_ele.val(match[2])
|
69
|
+
this.day_ele.val(match[3])
|
70
|
+
this.hour_ele.val(0)
|
71
|
+
this.min_ele.val(0)
|
72
|
+
} else {
|
73
|
+
throw "Invalid date-format: '" + this.text_ele.val() + "'."
|
74
|
+
}
|
75
|
+
|
76
|
+
// Set the content to be a date, if this is a date-input-picker.
|
77
|
+
if (match && this.text_ele.hasClass("bb_date_picker")) {
|
78
|
+
this.text_ele.val(match[1] + "-" + match[2] + "-" + match[3])
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
$(document).ready(function() {
|
84
|
+
$(".bb-date-picker").each(function() {
|
85
|
+
new DatePickerInput({element: $(this)})
|
86
|
+
})
|
87
|
+
})
|
@@ -0,0 +1,65 @@
|
|
1
|
+
$(document).ready(function() {
|
2
|
+
// Used to load dynamic content of a tab
|
3
|
+
loadAjaxTab = function(li) {
|
4
|
+
link = $("a", li)
|
5
|
+
content_id = link.attr("href").substring(1, 999)
|
6
|
+
content = $(".bb-tabs-container #" + content_id + " .bb-tab-container")
|
7
|
+
|
8
|
+
li.data("ajax-loaded", true)
|
9
|
+
content.fadeOut(0, function() {
|
10
|
+
$.get(li.data("ajax-url"), function(data) {
|
11
|
+
content.html(data)
|
12
|
+
content.fadeIn("fast")
|
13
|
+
})
|
14
|
+
})
|
15
|
+
}
|
16
|
+
|
17
|
+
//Loads the dynamic content of a tab when activated and sets the URL to the tab ID
|
18
|
+
$("body").on("click", ".bb-tabs-container .nav li", function() {
|
19
|
+
li = $(this)
|
20
|
+
|
21
|
+
if (li.data("ignore-next-history-push")) {
|
22
|
+
li.data("ignore-next-history-push", null)
|
23
|
+
} else if(li.data("specific-id-given")) {
|
24
|
+
urlb = new UrlBuilder(window.location.href)
|
25
|
+
urlb.queryParameters["bb_selected_tab"] = $(this).data("tab-container-id")
|
26
|
+
|
27
|
+
window.history.pushState({active_tab: li.data("tab-container-id"), event: "bb-tab-change"}, null, urlb.pathWithQueryParameters())
|
28
|
+
}
|
29
|
+
|
30
|
+
if (li.data("ajax-url") && !li.data("ajax-loaded")) {
|
31
|
+
loadAjaxTab(li)
|
32
|
+
}
|
33
|
+
})
|
34
|
+
|
35
|
+
// Changes the tab on 'back' and 'forward' events
|
36
|
+
$(window).bind("popstate", function(e) {
|
37
|
+
if (e.originalEvent.state && e.originalEvent.state.event == "bb-tab-change") {
|
38
|
+
selected_tab = e.originalEvent.state.active_tab
|
39
|
+
} else {
|
40
|
+
urlb = new UrlBuilder(window.location.href)
|
41
|
+
selected_tab = urlb.queryParameters["bb_selected_tab"]
|
42
|
+
}
|
43
|
+
|
44
|
+
if (!selected_tab) {
|
45
|
+
selected_tab = $($(".bb-tabs-container .nav li").first()).data("tab-container-id")
|
46
|
+
}
|
47
|
+
|
48
|
+
if (selected_tab) {
|
49
|
+
li = $("li[data-tab-container-id='" + selected_tab + "']")
|
50
|
+
}
|
51
|
+
|
52
|
+
if (li && !li.hasClass("active")) {
|
53
|
+
console.log("Click on LI")
|
54
|
+
li.data("ignore-next-history-push", true)
|
55
|
+
$("a", li).click()
|
56
|
+
}
|
57
|
+
})
|
58
|
+
|
59
|
+
// Makes sure the correct tab is loaded on page load
|
60
|
+
active_tab = $(".bb-tabs-container .nav li.active[data-ajax-url]")
|
61
|
+
|
62
|
+
if (active_tab.length > 0) {
|
63
|
+
loadAjaxTab(active_tab)
|
64
|
+
}
|
65
|
+
})
|
@@ -0,0 +1,143 @@
|
|
1
|
+
class UrlBuilder {
|
2
|
+
constructor(url) {
|
3
|
+
if (url) {
|
4
|
+
this.parseUrlFromString(url)
|
5
|
+
}
|
6
|
+
}
|
7
|
+
|
8
|
+
parseHostAndPortFromUrl() {
|
9
|
+
var match = this.matchAndRemove(/^([A-z\d-\.]+)(|:(\d+))($|\/)/)
|
10
|
+
|
11
|
+
if (match) {
|
12
|
+
alert("MATCHED HOST")
|
13
|
+
this.host = match[1]
|
14
|
+
|
15
|
+
if (match[3]) {
|
16
|
+
this.port = parseInt(match[3])
|
17
|
+
this.portSpecified = true
|
18
|
+
} else {
|
19
|
+
if (this.protocol == "https") {
|
20
|
+
this.port = 443
|
21
|
+
} else {
|
22
|
+
this.port = 80
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
parsePathFromUrl() {
|
29
|
+
var match = this.matchAndRemove(/^([^\?]+)/)
|
30
|
+
|
31
|
+
if (match) {
|
32
|
+
this.path = match[1]
|
33
|
+
} else {
|
34
|
+
this.path = ""
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
parseProtocolFromUrl() {
|
39
|
+
var match = this.matchAndRemove(/^(.+?):\/\//)
|
40
|
+
|
41
|
+
if (match) {
|
42
|
+
this.protocol = match[1]
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
parseQueryParametersFromUrl() {
|
47
|
+
this.queryParameters = {}
|
48
|
+
|
49
|
+
if (this.matchAndRemove(/^\?/)) {
|
50
|
+
var pairs = this.url.split("&")
|
51
|
+
|
52
|
+
for(var pair in pairs) {
|
53
|
+
var match = pair.match(/^(.+?)=(.+)$/)
|
54
|
+
if (match) {
|
55
|
+
this.queryParameters[match[1]] = match[2]
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
parseUrlFromString(url) {
|
62
|
+
this.url = url
|
63
|
+
|
64
|
+
this.parseProtocolFromUrl()
|
65
|
+
this.parseHostAndPortFromUrl()
|
66
|
+
this.parsePathFromUrl()
|
67
|
+
this.parseQueryParametersFromUrl()
|
68
|
+
}
|
69
|
+
|
70
|
+
generateFullUrl() {
|
71
|
+
alert("Protocol: " + this.protocol + "\nHost: " + this.host + "\nPort: " + this.port + "\nPortSpecified: " + this.portSpecified + "\nPath: " + this.path)
|
72
|
+
|
73
|
+
url = this.protocol + "://" + this.host
|
74
|
+
|
75
|
+
if (this.portSpecified) {
|
76
|
+
url += ":" + this.port
|
77
|
+
}
|
78
|
+
|
79
|
+
url += "/" + this.path
|
80
|
+
|
81
|
+
if (this.hasQueryParameters()) {
|
82
|
+
url += "?"
|
83
|
+
url += this.queryParametersAsString()
|
84
|
+
}
|
85
|
+
|
86
|
+
return url
|
87
|
+
}
|
88
|
+
|
89
|
+
pathWithQueryParameters() {
|
90
|
+
generatedPath = this.path
|
91
|
+
|
92
|
+
if (this.hasQueryParameters()) {
|
93
|
+
generatedPath += "?"
|
94
|
+
generatedPath += this.queryParametersAsString()
|
95
|
+
}
|
96
|
+
|
97
|
+
return generatedPath
|
98
|
+
}
|
99
|
+
|
100
|
+
matchAndRemove(regex) {
|
101
|
+
var match = this.url.match(regex)
|
102
|
+
|
103
|
+
if (match) {
|
104
|
+
this.url = this.url.replace(regex, "")
|
105
|
+
return match
|
106
|
+
} else {
|
107
|
+
return false
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
// Returns true if any query parameters has been saved
|
112
|
+
hasQueryParameters() {
|
113
|
+
if (this.queryParameters && Object.keys(this.queryParameters).length > 0) {
|
114
|
+
return true
|
115
|
+
} else {
|
116
|
+
return false
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
// Returns a hash containing the query parameters
|
121
|
+
queryParameters() {
|
122
|
+
this.queryParameters
|
123
|
+
}
|
124
|
+
|
125
|
+
queryParametersAsString() {
|
126
|
+
queryParametersString = ""
|
127
|
+
first = true
|
128
|
+
|
129
|
+
for(key in this.queryParameters) {
|
130
|
+
value = this.queryParameters[key]
|
131
|
+
|
132
|
+
if (first) {
|
133
|
+
first = false
|
134
|
+
} else {
|
135
|
+
queryParametersString += "&"
|
136
|
+
}
|
137
|
+
|
138
|
+
queryParametersString += key + "=" + value
|
139
|
+
}
|
140
|
+
|
141
|
+
return queryParametersString
|
142
|
+
}
|
143
|
+
}
|
@@ -0,0 +1,102 @@
|
|
1
|
+
$(document).ready(function() {
|
2
|
+
sizes = {
|
3
|
+
xs: [0, 767],
|
4
|
+
sm: [768, 991],
|
5
|
+
md: [992, 1199],
|
6
|
+
lg: [1200, 999999]
|
7
|
+
}
|
8
|
+
|
9
|
+
$.bbViewPort = function() {
|
10
|
+
width = window.innerWidth
|
11
|
+
|
12
|
+
for(size in sizes) {
|
13
|
+
size_width = sizes[size][0]
|
14
|
+
size_height = sizes[size][1]
|
15
|
+
|
16
|
+
if (width >= size_width && width < size_height) {
|
17
|
+
return size
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
throw "Could not figure out the Bootstrap view port from this width: " + width
|
22
|
+
}
|
23
|
+
|
24
|
+
$.bbViewPortOrAbove = function(given_size) {
|
25
|
+
current_size = $.bbViewPort()
|
26
|
+
reached = false
|
27
|
+
|
28
|
+
for(size in sizes) {
|
29
|
+
if (size == current_size) {
|
30
|
+
reached = true
|
31
|
+
}
|
32
|
+
|
33
|
+
if (size == given_size) {
|
34
|
+
if (reached) {
|
35
|
+
return false
|
36
|
+
} else {
|
37
|
+
return true
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
throw "Invalid size: " + given_size
|
43
|
+
}
|
44
|
+
|
45
|
+
$.bbViewPortOrBelow = function(given_size) {
|
46
|
+
current_size = $.bbViewPort()
|
47
|
+
reached = false
|
48
|
+
|
49
|
+
for(size in sizes) {
|
50
|
+
if (size == current_size) {
|
51
|
+
reached = true
|
52
|
+
}
|
53
|
+
|
54
|
+
if (given_size == size) {
|
55
|
+
if (reached) {
|
56
|
+
return true
|
57
|
+
} else {
|
58
|
+
return false
|
59
|
+
}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
throw "Invalid size: " + given_size
|
64
|
+
}
|
65
|
+
|
66
|
+
viewport_callbacks = []
|
67
|
+
$.bbViewPortChange = function(func) {
|
68
|
+
viewport_callbacks.push(func)
|
69
|
+
}
|
70
|
+
|
71
|
+
resize_timeout = null
|
72
|
+
current_viewport = $.bbViewPort()
|
73
|
+
$.bbViewPortOnChanged = function() {
|
74
|
+
if (resize_timeout) {
|
75
|
+
clearTimeout(resize_timeout)
|
76
|
+
}
|
77
|
+
|
78
|
+
resize_timeout = setTimeout(function() {
|
79
|
+
$("body").removeClass("bb-view-port-xs bb-view-port-sm bb-view-port-md bb-view-port-lg")
|
80
|
+
new_viewport = $.bbViewPort()
|
81
|
+
$("body").addClass("bb-view-port-" + new_viewport)
|
82
|
+
|
83
|
+
if (new_viewport != current_viewport) {
|
84
|
+
current_viewport = new_viewport
|
85
|
+
|
86
|
+
for(number in viewport_callbacks) {
|
87
|
+
viewport_callback = viewport_callbacks[number]
|
88
|
+
viewport_callback.call()
|
89
|
+
}
|
90
|
+
}
|
91
|
+
}, 200)
|
92
|
+
}
|
93
|
+
|
94
|
+
$(window).resize(function() {
|
95
|
+
$.bbViewPortOnChanged()
|
96
|
+
})
|
97
|
+
|
98
|
+
$.bbViewPortOnChanged()
|
99
|
+
document.addEventListener("turbolinks:load", function() {
|
100
|
+
$.bbViewPortOnChanged()
|
101
|
+
})
|
102
|
+
})
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bootstrap_builders
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.46
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kaspernj
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -48,13 +48,13 @@ files:
|
|
48
48
|
- MIT-LICENSE
|
49
49
|
- README.md
|
50
50
|
- Rakefile
|
51
|
-
- app/assets/javascripts/bootstrap_builders.
|
52
|
-
- app/assets/javascripts/bootstrap_builders/bb-btn-responsive.
|
53
|
-
- app/assets/javascripts/bootstrap_builders/date-picker-input.
|
54
|
-
- app/assets/javascripts/bootstrap_builders/tabs.js
|
51
|
+
- app/assets/javascripts/bootstrap_builders.js
|
52
|
+
- app/assets/javascripts/bootstrap_builders/bb-btn-responsive.js
|
53
|
+
- app/assets/javascripts/bootstrap_builders/date-picker-input.js
|
54
|
+
- app/assets/javascripts/bootstrap_builders/tabs.js
|
55
55
|
- app/assets/javascripts/bootstrap_builders/url-builder/README.md
|
56
|
-
- app/assets/javascripts/bootstrap_builders/url-builder/lib/url-builder.
|
57
|
-
- app/assets/javascripts/bootstrap_builders/view-port-detection.
|
56
|
+
- app/assets/javascripts/bootstrap_builders/url-builder/lib/url-builder.js
|
57
|
+
- app/assets/javascripts/bootstrap_builders/view-port-detection.js
|
58
58
|
- app/assets/stylesheets/bootstrap_builders.scss
|
59
59
|
- app/assets/stylesheets/bootstrap_builders/bb-btn-responsive.scss
|
60
60
|
- app/assets/stylesheets/bootstrap_builders/bb-progress-bar.scss
|
@@ -1,74 +0,0 @@
|
|
1
|
-
(($, window, document) ->
|
2
|
-
methods = {
|
3
|
-
# Constructor.
|
4
|
-
init: (options) ->
|
5
|
-
# The hidden Rails-inputs that will get the actual values like year, month, date, hour and minute.
|
6
|
-
text_ele = $("input.bb_date_picker, input.bb_date_time_picker", $(@))
|
7
|
-
form = text_ele.parents("form").first()
|
8
|
-
|
9
|
-
# Update values on form-submit.
|
10
|
-
if form.length > 0 && form.data("bb-date-picker-input") != "true"
|
11
|
-
form.data("bb-date-picker-input", "true")
|
12
|
-
|
13
|
-
form.submit ->
|
14
|
-
$(".bb-date-picker-input", this).each ->
|
15
|
-
$(this).bbDatePickerInput("updateValues")
|
16
|
-
return true
|
17
|
-
|
18
|
-
# Update the values when the date is changed or upon blur
|
19
|
-
text_ele.on "changeDate blur", ->
|
20
|
-
parents = $(this).parents(".bb-date-picker")
|
21
|
-
throw "No parents were found" if parents.length <= 0
|
22
|
-
parents.first().bbDatePickerInput("updateValues")
|
23
|
-
|
24
|
-
# Parses the date in the input-field and updates all the hidden Rails-inputs from the parsed values.
|
25
|
-
updateValues: ->
|
26
|
-
text_ele = $("input.bb_date_picker, input.bb_date_time_picker", $(@))
|
27
|
-
year_ele = $(".bb-date-picker-input-year", $(@))
|
28
|
-
month_ele = $(".bb-date-picker-input-month", $(@))
|
29
|
-
day_ele = $(".bb-date-picker-input-day", $(@))
|
30
|
-
hour_ele = $(".bb-date-picker-input-hour", $(@))
|
31
|
-
min_ele = $(".bb-date-picker-input-min", $(@))
|
32
|
-
|
33
|
-
throw "Could not find year element: " + year_ele if year_ele.length <= 0
|
34
|
-
throw "Could not find month element: " + month_ele if month_ele.length <= 0
|
35
|
-
throw "Could not find month element: " + day_ele if day_ele.length <= 0
|
36
|
-
|
37
|
-
if $.trim(text_ele.val()) == ""
|
38
|
-
year_ele.val("")
|
39
|
-
month_ele.val("")
|
40
|
-
day_ele.val("")
|
41
|
-
hour_ele.val("")
|
42
|
-
min_ele.val("")
|
43
|
-
else if match = text_ele.val().match(/^\s*(\d+)-(\d+)-(\d+)\s+(\d+):(\d+)\s*$/)
|
44
|
-
year_ele.val(match[1])
|
45
|
-
month_ele.val(match[2])
|
46
|
-
day_ele.val(match[3])
|
47
|
-
hour_ele.val(match[4])
|
48
|
-
min_ele.val(match[5])
|
49
|
-
else if match = text_ele.val().match(/^\s*(\d+)-(\d+)-(\d+)\s*$/)
|
50
|
-
year_ele.val(match[1])
|
51
|
-
month_ele.val(match[2])
|
52
|
-
day_ele.val(match[3])
|
53
|
-
hour_ele.val(0)
|
54
|
-
min_ele.val(0)
|
55
|
-
else
|
56
|
-
throw "Invalid date-format: '" + text_ele.val() + "'."
|
57
|
-
|
58
|
-
# Set the content to be a date, if this is a date-input-picker.
|
59
|
-
if match && text_ele.hasClass("bb_date_picker")
|
60
|
-
text_ele.val(match[1] + "-" + match[2] + "-" + match[3])
|
61
|
-
}
|
62
|
-
|
63
|
-
# Initialize the plugin.
|
64
|
-
$.fn.bbDatePickerInput = (method) ->
|
65
|
-
if methods[method]
|
66
|
-
methods[method].apply(this, Array::slice.call(arguments, 1))
|
67
|
-
else if typeof method is "object" or not method
|
68
|
-
methods.init.apply(this, arguments)
|
69
|
-
else
|
70
|
-
$.error "Method " + method + " does not exist on jquery.inputDatePicker"
|
71
|
-
) jQuery, window, document
|
72
|
-
|
73
|
-
$ ->
|
74
|
-
$(".bb-date-picker").each -> $(this).bbDatePickerInput()
|
@@ -1,48 +0,0 @@
|
|
1
|
-
$ ->
|
2
|
-
# Used to load dynamic content of a tab
|
3
|
-
loadAjaxTab = (li) ->
|
4
|
-
link = $("a", li)
|
5
|
-
content_id = link.attr("href").substring(1, 999)
|
6
|
-
content = $(".bb-tabs-container #" + content_id + " .bb-tab-container")
|
7
|
-
|
8
|
-
li.data("ajax-loaded", true)
|
9
|
-
content.fadeOut 0, ->
|
10
|
-
$.get li.data("ajax-url"), (data) ->
|
11
|
-
content.html(data)
|
12
|
-
content.fadeIn "fast"
|
13
|
-
|
14
|
-
# Loads the dynamic content of a tab when activated and sets the URL to the tab ID
|
15
|
-
$("body").on "click", ".bb-tabs-container .nav li", ->
|
16
|
-
li = $(this)
|
17
|
-
|
18
|
-
if li.data("ignore-next-history-push")
|
19
|
-
li.data("ignore-next-history-push", null)
|
20
|
-
else if li.data("specific-id-given")
|
21
|
-
urlb = new UrlBuilder(window.location.href)
|
22
|
-
urlb.queryParameters["bb_selected_tab"] = $(this).data("tab-container-id")
|
23
|
-
|
24
|
-
window.history.pushState({active_tab: li.data("tab-container-id"), event: "bb-tab-change"}, null, urlb.pathWithQueryParameters())
|
25
|
-
|
26
|
-
if li.data("ajax-url") && !li.data("ajax-loaded")
|
27
|
-
loadAjaxTab(li)
|
28
|
-
|
29
|
-
# Changes the tab on 'back' and 'forward' events
|
30
|
-
$(window).bind "popstate", (e) ->
|
31
|
-
if e.originalEvent.state && e.originalEvent.state.event == "bb-tab-change"
|
32
|
-
selected_tab = e.originalEvent.state.active_tab
|
33
|
-
else
|
34
|
-
urlb = new UrlBuilder(window.location.href)
|
35
|
-
selected_tab = urlb.queryParameters["bb_selected_tab"]
|
36
|
-
|
37
|
-
selected_tab = $($(".bb-tabs-container .nav li").first()).data("tab-container-id") unless selected_tab
|
38
|
-
|
39
|
-
li = $("li[data-tab-container-id='" + selected_tab + "']") if selected_tab
|
40
|
-
|
41
|
-
if li && !li.hasClass("active")
|
42
|
-
console.log("Click on LI")
|
43
|
-
li.data("ignore-next-history-push", true)
|
44
|
-
$("a", li).click()
|
45
|
-
|
46
|
-
# Makes sure the correct tab is loaded on page load
|
47
|
-
active_tab = $(".bb-tabs-container .nav li.active[data-ajax-url]")
|
48
|
-
loadAjaxTab(active_tab) if active_tab.length > 0
|
@@ -1,99 +0,0 @@
|
|
1
|
-
class window.UrlBuilder
|
2
|
-
constructor: (url) ->
|
3
|
-
this.parseUrlFromString(url) if url
|
4
|
-
|
5
|
-
parseHostAndPortFromUrl: ->
|
6
|
-
if match = this.matchAndRemove(/^([A-z\d-\.]+)(|:(\d+))($|\/)/)
|
7
|
-
@host = match[1]
|
8
|
-
|
9
|
-
if match[3]
|
10
|
-
@port = parseInt(match[3])
|
11
|
-
@portSpecified = true
|
12
|
-
else
|
13
|
-
if @protocol == "https"
|
14
|
-
@port = 443
|
15
|
-
else
|
16
|
-
@port = 80
|
17
|
-
|
18
|
-
parsePathFromUrl: ->
|
19
|
-
if match = this.matchAndRemove(/^([^\?]+)/)
|
20
|
-
@path = "/" + match[1]
|
21
|
-
else
|
22
|
-
@path = ""
|
23
|
-
|
24
|
-
parseProtocolFromUrl: ->
|
25
|
-
if match = this.matchAndRemove(/^(.+?):\/\//)
|
26
|
-
@protocol = match[1]
|
27
|
-
|
28
|
-
parseQueryParametersFromUrl: ->
|
29
|
-
@queryParameters = {}
|
30
|
-
|
31
|
-
if this.matchAndRemove(/^\?/)
|
32
|
-
pairs = @url.split("&")
|
33
|
-
|
34
|
-
for pair in pairs
|
35
|
-
if match = pair.match(/^(.+?)=(.+)$/)
|
36
|
-
@queryParameters[match[1]] = match[2]
|
37
|
-
|
38
|
-
parseUrlFromString: (url) ->
|
39
|
-
@url = url
|
40
|
-
|
41
|
-
this.parseProtocolFromUrl()
|
42
|
-
this.parseHostAndPortFromUrl()
|
43
|
-
this.parsePathFromUrl()
|
44
|
-
this.parseQueryParametersFromUrl()
|
45
|
-
|
46
|
-
generateFullUrl: ->
|
47
|
-
url = @protocol + "://" + @host
|
48
|
-
|
49
|
-
if @portSpecified
|
50
|
-
url += ":" + @port
|
51
|
-
|
52
|
-
url += "/" + @path
|
53
|
-
|
54
|
-
if this.hasQueryParameters()
|
55
|
-
url += "?"
|
56
|
-
url += this.queryParametersAsString()
|
57
|
-
|
58
|
-
url
|
59
|
-
|
60
|
-
pathWithQueryParameters: ->
|
61
|
-
generatedPath = @path
|
62
|
-
|
63
|
-
if this.hasQueryParameters()
|
64
|
-
generatedPath += "?"
|
65
|
-
generatedPath += this.queryParametersAsString()
|
66
|
-
|
67
|
-
generatedPath
|
68
|
-
|
69
|
-
matchAndRemove: (regex) ->
|
70
|
-
if match = @url.match(regex)
|
71
|
-
@url = @url.replace(regex, "")
|
72
|
-
return match
|
73
|
-
else
|
74
|
-
return false
|
75
|
-
|
76
|
-
# Returns true if any query parameters has been saved
|
77
|
-
hasQueryParameters: ->
|
78
|
-
if @queryParameters && Object.keys(@queryParameters).length > 0
|
79
|
-
true
|
80
|
-
else
|
81
|
-
false
|
82
|
-
|
83
|
-
# Returns a hash containing the query parameters
|
84
|
-
queryParameters: ->
|
85
|
-
@queryParameters
|
86
|
-
|
87
|
-
queryParametersAsString: ->
|
88
|
-
queryParametersString = ""
|
89
|
-
first = true
|
90
|
-
|
91
|
-
for key, value of @queryParameters
|
92
|
-
if first
|
93
|
-
first = false
|
94
|
-
else
|
95
|
-
queryParametersString += "&"
|
96
|
-
|
97
|
-
queryParametersString += key + "=" + value
|
98
|
-
|
99
|
-
queryParametersString
|
@@ -1,71 +0,0 @@
|
|
1
|
-
$ ->
|
2
|
-
sizes = {
|
3
|
-
xs: [0, 767],
|
4
|
-
sm: [768, 991],
|
5
|
-
md: [992, 1199],
|
6
|
-
lg: [1200, 999999]
|
7
|
-
}
|
8
|
-
|
9
|
-
$.bbViewPort = ->
|
10
|
-
width = window.innerWidth
|
11
|
-
|
12
|
-
for size of sizes
|
13
|
-
size_width = sizes[size][0]
|
14
|
-
size_height = sizes[size][1]
|
15
|
-
return size if width >= size_width && width < size_height
|
16
|
-
|
17
|
-
throw "Could not figure out the Bootstrap view port from this width: " + width
|
18
|
-
|
19
|
-
$.bbViewPortOrAbove = (given_size) ->
|
20
|
-
current_size = $.bbViewPort()
|
21
|
-
reached = false
|
22
|
-
|
23
|
-
for size of sizes
|
24
|
-
reached = true if size == current_size
|
25
|
-
|
26
|
-
if size == given_size
|
27
|
-
if reached
|
28
|
-
return false
|
29
|
-
else
|
30
|
-
return true
|
31
|
-
|
32
|
-
throw "Invalid size: " + given_size
|
33
|
-
|
34
|
-
$.bbViewPortOrBelow = (given_size) ->
|
35
|
-
current_size = $.bbViewPort()
|
36
|
-
reached = false
|
37
|
-
|
38
|
-
for size of sizes
|
39
|
-
reached = true if size == current_size
|
40
|
-
|
41
|
-
if given_size == size
|
42
|
-
if reached
|
43
|
-
return true
|
44
|
-
else
|
45
|
-
return false
|
46
|
-
|
47
|
-
throw "Invalid size: " + given_size
|
48
|
-
|
49
|
-
viewport_callbacks = []
|
50
|
-
$.bbViewPortChange = (func) -> viewport_callbacks.push(func)
|
51
|
-
|
52
|
-
resize_timeout = null
|
53
|
-
current_viewport = $.bbViewPort()
|
54
|
-
$.bbViewPortOnChanged = ->
|
55
|
-
clearTimeout(resize_timeout) if resize_timeout
|
56
|
-
|
57
|
-
resize_timeout = setTimeout( ->
|
58
|
-
$("body").removeClass("bb-view-port-xs bb-view-port-sm bb-view-port-md bb-view-port-lg")
|
59
|
-
new_viewport = $.bbViewPort()
|
60
|
-
$("body").addClass("bb-view-port-" + new_viewport)
|
61
|
-
|
62
|
-
if new_viewport != current_viewport
|
63
|
-
current_viewport = new_viewport
|
64
|
-
|
65
|
-
for number, viewport_callback of viewport_callbacks
|
66
|
-
viewport_callback.call()
|
67
|
-
, 200)
|
68
|
-
|
69
|
-
$(window).resize -> $.bbViewPortOnChanged()
|
70
|
-
$.bbViewPortOnChanged()
|
71
|
-
document.addEventListener "turbolinks:load", -> $.bbViewPortOnChanged()
|