Skip to content
This repository was archived by the owner on Jun 21, 2022. It is now read-only.

Commit 8f45f25

Browse files
authored
Merge pull request #175 from dboehmer/no-jQuery
Remove jQuery and migrate Bootstrap to v5.1.3
2 parents 2fe413e + f5d6135 commit 8f45f25

File tree

76 files changed

+60365
-37139
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+60365
-37139
lines changed

lib/Coocook/Controller/Root.pm

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,13 @@ sub auto : Private {
9090

9191
$c->stash(
9292
css => [
93-
'/lib/bootstrap-4.4.1-dist/css/bootstrap' . ( $c->debug ? '.css' : '.min.css' ),
93+
'/lib/bootstrap-5.1.3-dist/css/bootstrap' . ( $c->debug ? '.css' : '.min.css' ),
9494
'/css/local_bootstrap_modifications.css',
9595
'/css/material-design-icons.css',
9696
'/css/style.css',
9797
],
9898
js => [
99-
'/lib/jquery-3.5.1' . ( $c->debug ? '.js' : '.min.js' ),
100-
'/lib/bootstrap-4.4.1-dist/js/bootstrap' . ( $c->debug ? '.js' : '.min.js' ),
99+
'/lib/bootstrap-5.1.3-dist/js/bootstrap' . ( $c->debug ? '.js' : '.min.js' ),
101100
'/lib/marked/marked' . ( $c->debug ? '.js' : '.min.js' ),
102101
'/js/script.js',
103102
],

root/static/js/article/edit.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
$(function() {
1+
(() => {
22
// check 'preorder' when changing preorder details
3-
$('input[name="preorder_workdays"],input[name="preorder_servings"]').on( 'change click input', function() {
4-
$('input[name="preorder"').prop('checked', true);
3+
const preorderInputElem = document.getElementById('preorder');
4+
const preorderWorkdaysInputElem = document.getElementById('preorder_workdays');
5+
const preorderServingsInputElem = document.getElementById('preorder_servings');
6+
[preorderWorkdaysInputElem, preorderServingsInputElem].forEach(elem => {
7+
elem.addEventListener('input', () => preorderInputElem.checked = true);
58
});
69

710
// check 'shelf life' when changing shelf life period
8-
$('input[name="shelf_life_days"]').on( 'change click input', function() {
9-
$('input[name="shelf_life"').prop('checked', true);
10-
});
11-
});
11+
const shelfLifeInputElem = document.getElementById('shelf_life');
12+
const shelfLifeDaysInputElem = document.getElementById('shelf_life_days');
13+
shelfLifeDaysInputElem.addEventListener('input', () => shelfLifeInputElem.checked = true);
14+
})();
Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,56 @@
1-
$( function() {
2-
$('form#import table td.article select').change(function() {
3-
let $this = $(this);
4-
5-
let $selectedOption = $this.find('option:selected');
6-
7-
let $unit = $this.closest('tr').find('td.unit select');
8-
let $units = $unit.find('option');
9-
10-
if( !$selectedOption.val() ) {
11-
$units.show();
12-
return;
13-
}
14-
15-
let unitIds = $selectedOption.attr('data-units').split(',');
16-
17-
// if select unit is not applicable to article, reset unit selector
18-
if( unitIds.indexOf( $unit.val() ) == -1 ) {
19-
$unit.val('');
1+
(() => {
2+
const articleElemList = document.querySelectorAll('form#import table td.article select');
3+
articleElemList.forEach(articleElem => {
4+
articleElem.onchange = () => {
5+
let selectedArticleElem = articleElem.options[articleElem.options.selectedIndex];
6+
7+
let unitElem = articleElem.closest('tr').querySelector('td.unit select');
8+
let unitOptionElems = unitElem.options;
9+
10+
if( !selectedArticleElem.value ) {
11+
Array.from(unitOptionElems).forEach(unitOptionElem => {
12+
unitOptionElem.style.display = 'block';
13+
});
14+
return;
15+
}
16+
17+
let unitIds = selectedArticleElem.getAttribute('data-units').split(',');
18+
// if select unit is not applicable to article, reset unit selector
19+
if( unitIds.indexOf( unitElem.value ) == -1 ) {
20+
unitElem.value = '';
21+
}
22+
23+
// show only applicable units
24+
Array.from(unitOptionElems).forEach(unitOptionElem => {
25+
let unitId = unitOptionElem.value;
26+
if( unitId == '' || unitIds.indexOf(unitId) > -1 ) {
27+
unitOptionElem.style.display = 'block';
28+
} else {
29+
unitOptionElem.style.display = 'none';
30+
}
31+
});
2032
}
21-
22-
// show only applicable units
23-
$units.each( function() {
24-
let $u = $(this);
25-
let unitId = $u.val();
26-
27-
$u.toggle( unitId == '' || unitIds.indexOf(unitId) > -1 );
28-
});
29-
}).trigger('change');
33+
});
3034

3135
// check uniqueness of recipe name
32-
$('form#import input[name="name"]').on('change input', function() {
33-
let name = this.value;
34-
35-
this.setCustomValidity( existingRecipeNames.indexOf(name) == -1 ? '' : "This recipe name already exists in this project" );
36-
}).trigger('input');
36+
const nameInputElem = document.querySelector('form#import input[name="name"]');
37+
nameInputElem.addEventListener('input', () => {
38+
let name = nameInputElem.value;
39+
40+
nameInputElem.setCustomValidity( existingRecipeNames.indexOf(name) == -1 ? '' : "This recipe name already exists in this project" );
41+
});
3742

3843
// skip checkboxes
39-
$('form#import table td.import input[type="checkbox"]').on( 'change', function() {
40-
let skip = !this.checked;
41-
let $tr = $(this).closest('tr');
44+
const checkboxElemList = document.querySelectorAll('form#import table td.import input[type="checkbox"]');
45+
checkboxElemList.forEach(checkboxElem => {
46+
checkboxElem.onchange = () => {
47+
let skip = !checkboxElem.checked;
48+
let trElem = checkboxElem.closest('tr');
4249

43-
$tr.toggleClass( 'skip', skip );
50+
trElem.classList.toggle('skip');
4451

45-
$tr.find('input,select').not(this).prop( 'disabled', skip );
46-
}).trigger('change');
47-
} );
52+
Array.from(trElem.querySelectorAll('input,select')).filter((item) => item != checkboxElem)
53+
.forEach(item => skip ? item.setAttribute( 'disabled', skip ) : item.removeAttribute('disabled') );
54+
}
55+
});
56+
})();

root/static/js/script.js

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,30 @@
1-
$(function() {
1+
(() => {
22

33
// reduce options of <select> inputs for unit to units applicable to selected article
4-
$('select[name=article]').each(function() {
5-
let $article = $(this);
6-
let $unit = $article.closest('form').find('select[name=unit]');
4+
const articleElems = document.getElementsByName('article');
5+
Array.from(articleElems).forEach(articleElem => {
6+
const unitElem = articleElem.closest('form').querySelector('select[name=unit]');
77

8-
if( $unit.length == 1 ) {
9-
let $units = $unit.find('option');
8+
if( unitElem.type == "select-one" ) {
9+
const unitOptionElems = unitElem.options;
1010

1111
// event handler
12-
$article.change(function() {
13-
let data_units = $article.find('option:selected').attr('data-units');
14-
15-
if( ! data_units ) { // no 'data-units' attribute, e.g. for "choose article" placeholder
16-
$units.show();
17-
return;
18-
}
12+
articleElem.onchange = () => {
13+
let data_units = articleElem.options[articleElem.selectedIndex].getAttribute('data-units');
1914

2015
let units = data_units.split(',');
2116
let units_hash = {};
2217
units.forEach(function(unit) { units_hash[unit] = true } );
2318

24-
$units.each(function() {
25-
let $unit = $(this);
26-
$unit.toggle( Boolean( units_hash[ $unit.attr('value') ] ) );
27-
});
28-
29-
$units.prop('selected', false);
30-
31-
// select first visible option ( :visible does not work properly for select options)
32-
$units.each(function () {
33-
if ($(this).css('display') != 'none') {
34-
$(this).prop('selected', true);
35-
return false;
19+
Array.from(unitOptionElems).forEach(unitOptionElem => {
20+
if( Boolean( units_hash[ unitOptionElem.value ] ) ) {
21+
unitOptionElem.style.display = "block";
22+
unitOptionElem.selected = true;
23+
} else {
24+
unitOptionElem.style.display = "none";
3625
}
3726
});
38-
})
39-
.change(); // trigger on page load
27+
}
4028
}
4129
});
4230

@@ -75,4 +63,4 @@ $(function() {
7563
}
7664
});
7765

78-
});
66+
})();

root/static/js/user/register.js

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,40 @@
1-
$( function() {
2-
$('input[name="url"]').attr('tabindex', -1);
1+
(() => {
2+
document.querySelector('input[name="url"]')?.setAttribute('tabindex', -1);
33

4-
var MAX_STARS = 5;
4+
const MAX_STARS = 5;
55

6-
let $password = $('input[name="password"]');
7-
let $password2 = $('input[name="password2"]');
8-
let $meter = $( '<span>' );
6+
const passwordElem = document.querySelector('input[name="password"]');
7+
const password2Elem = document.querySelector('input[name="password2"]');
8+
const meterElem = document.createElement('span');
9+
passwordElem.parentElement.appendChild(meterElem);
910

10-
$meter.insertAfter($password);
11-
$meter.before('&nbsp;');
12-
13-
$password.on( 'change input', function() {
14-
let password = $password.val();
11+
passwordElem.addEventListener('input', () => {
12+
let password = passwordElem.value;
1513

1614
let stars = password == '' ? 0 : ( zxcvbn(password).score + 1 );
1715

1816
let html = 'strength: ';
1917
html += '&#x2605;'.repeat( stars );
2018
html += '&#x2606;'.repeat( MAX_STARS - stars );
2119

22-
$meter.html( html );
23-
$meter.attr( 'title', stars + ' of ' + MAX_STARS );
20+
meterElem.innerHTML = html;
21+
meterElem.setAttribute( 'title', stars + ' of ' + MAX_STARS );
2422
});
2523

26-
$password.change();
27-
28-
let $comparator = $('<span>');
29-
30-
$comparator.insertAfter($password2);
31-
$comparator.before('&nbsp;');
32-
33-
$password.add($password2).on('change input', function() {
34-
let password = $password .val();
35-
let password2 = $password2.val();
36-
37-
if( password.length || password2.length ) {
38-
$comparator.text( password == password2 ? "matches" : "doesn't match" );
39-
}
40-
else {
41-
$comparator.text('');
42-
}
24+
const comparatorElem = document.createElement('span');
25+
password2Elem.parentElement.appendChild(comparatorElem);
26+
27+
[passwordElem, password2Elem].forEach(item => {
28+
item.addEventListener('input', () => {
29+
let password = passwordElem.value;
30+
let password2 = password2Elem.value;
31+
32+
if( password.length || password2.length ) {
33+
comparatorElem.innerHTML = password == password2 ? "matches" : "doesn't match";
34+
}
35+
else {
36+
comparatorElem.innerHTML = '';
37+
}
38+
});
4339
});
44-
} );
40+
})();

0 commit comments

Comments
 (0)