Skip to content

Commit 130b8f4

Browse files
authored
Merge pull request #2340 from Laravel-Backpack/fix-html5-validation
[Bug Fix] Save actions inside dropdown don't trigger HTML5 Validation
2 parents 962f2ae + 1643d4b commit 130b8f4

File tree

2 files changed

+86
-14
lines changed

2 files changed

+86
-14
lines changed

src/resources/views/crud/form_content.blade.php

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,15 +119,8 @@ function preventUnload(event) {
119119
@endif
120120
121121
// Save button has multiple actions: save and exit, save and edit, save and new
122-
var saveActions = $('#saveActions'),
123-
crudForm = saveActions.parents('form'),
124-
saveActionField = $('[name="_save_action"]');
125-
126-
saveActions.on('click', '.dropdown-menu a', function(){
127-
var saveAction = $(this).data('value');
128-
saveActionField.val( saveAction );
129-
crudForm.submit();
130-
});
122+
var saveActions = $('#saveActions')
123+
crudForm = saveActions.parents('form')
131124
132125
// Ctrl+S and Cmd+S trigger Save button click
133126
$(document).keydown(function(e) {

src/resources/views/crud/inc/form_save_buttons.blade.php

Lines changed: 84 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313

1414
<div class="btn-group" role="group">
1515
@if(!empty($saveAction['options']))
16-
<button id="btnGroupDrop1" type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span class="caret"></span><span class="sr-only">&#x25BC;</span></button>
17-
<div class="dropdown-menu" aria-labelledby="btnGroupDrop1">
18-
@foreach( $saveAction['options'] as $value => $label)
19-
<a class="dropdown-item" href="javascript:void(0);" data-value="{{ $value }}">{{ $label }}</a>
20-
@endforeach
16+
<button id="bpSaveButtonsGroup" type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span class="caret"></span><span class="sr-only">&#x25BC;</span></button>
17+
<div class="dropdown-menu" aria-labelledby="bpSaveButtonsGroup">
18+
@foreach( $saveAction['options'] as $value => $label)
19+
<a class="dropdown-item" href="#" data-value="{{ $value }}">{{ $label }}</a>
20+
@endforeach
2121
</div>
2222
@endif
2323
</div>
@@ -33,3 +33,82 @@
3333
</div>
3434
@endif
3535

36+
@push('after_scripts')
37+
<script>
38+
39+
// this function checks if form is valid.
40+
function checkFormValidity(form) {
41+
// the condition checks if `checkValidity` is defined in the form (browser compatibility)
42+
if (form[0].checkValidity) {
43+
return form[0].checkValidity();
44+
}
45+
return false;
46+
}
47+
48+
// this function checks if any of the inputs has errors and report them on page.
49+
// we use it to report the errors after form validation fails and making the error fields visible
50+
function reportValidity(form) {
51+
// the condition checks if `reportValidity` is defined in the form (browser compatibility)
52+
if (form[0].reportValidity) {
53+
// hide the save actions drop down if open
54+
$('#saveActions').find('.dropdown-menu').removeClass('show');
55+
// validate and display form errors
56+
form[0].reportValidity();
57+
}
58+
}
59+
60+
function changeTabIfNeededAndDisplayErrors(form) {
61+
// we get the first erroed field
62+
var $firstErrorField = form.find(":invalid").first();
63+
// we find the closest tab
64+
var $closestTab = $($firstErrorField).closest('.tab-pane');
65+
// if we found the tab we will change to that tab before reporting validity of form
66+
if($closestTab.length) {
67+
var id = $closestTab.attr('id');
68+
// switch tabs
69+
$('.nav a[href="#' + id + '"]').tab('show');
70+
}
71+
reportValidity(form);
72+
}
73+
74+
// make all submit buttons trigger HTML5 validation
75+
jQuery(document).ready(function($) {
76+
77+
var selector = $('#bpSaveButtonsGroup').next();
78+
var form = $(selector).closest('form');
79+
var saveActionField = $('[name="save_action"]');
80+
var $defaultSubmitButton = $(form).find(':submit');
81+
// this is the main submit button, the default save action.
82+
$($defaultSubmitButton).on('click', function(e) {
83+
e.preventDefault();
84+
$saveAction = $(this).children('span').eq(1);
85+
// if form is valid just submit it
86+
if(checkFormValidity(form)) {
87+
saveActionField.val( $saveAction.attr('data-value') );
88+
form.submit();
89+
}else{
90+
// navigate to the tab where the first error happens
91+
changeTabIfNeededAndDisplayErrors(form);
92+
}
93+
});
94+
95+
//this is for the anchors AKA other non-default save actions.
96+
$(selector).find('a').each(function() {
97+
$(this).click(function(e) {
98+
//we check if form is valid
99+
if (checkFormValidity(form)) {
100+
//if everything is validated we proceed with the submission
101+
var saveAction = $(this).data('value');
102+
saveActionField.val( saveAction );
103+
form.submit();
104+
}else{
105+
// navigate to the tab where the first error happens
106+
changeTabIfNeededAndDisplayErrors(form);
107+
}
108+
e.stopPropagation();
109+
});
110+
});
111+
});
112+
113+
</script>
114+
@endpush

0 commit comments

Comments
 (0)