Skip to content

Commit 3947774

Browse files
committed
add search feature into users
1 parent 288d660 commit 3947774

File tree

6 files changed

+297
-4
lines changed

6 files changed

+297
-4
lines changed

app/Http/Controllers/UsersManagementController.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use App\Models\User;
77
use App\Traits\CaptureIpTrait;
88
use Auth;
9+
use Illuminate\Http\Response;
910
use Illuminate\Http\Request;
1011
use jeremykenedy\LaravelRoles\Models\Role;
1112
use Validator;
@@ -238,4 +239,48 @@ public function destroy($id)
238239

239240
return back()->with('error', trans('usersmanagement.deleteSelfError'));
240241
}
242+
243+
/**
244+
* Method to search the users.
245+
*
246+
* @param Request $request
247+
*
248+
* @return \Illuminate\Http\Response
249+
*/
250+
public function search(Request $request)
251+
{
252+
$searchTerm = $request->input('user_search_box');
253+
$searchRules = [
254+
'user_search_box' => 'required|string|max:255',
255+
];
256+
$searchMessages = [
257+
'user_search_box.required' => 'Search term is required',
258+
'user_search_box.string' => 'Search term has invalid characters',
259+
'user_search_box.max' => 'Search term has too many characters - 255 allowed',
260+
];
261+
262+
$validator = Validator::make($request->all(), $searchRules, $searchMessages);
263+
264+
if ($validator->fails()) {
265+
return response()->json([
266+
json_encode($validator),
267+
], Response::HTTP_UNPROCESSABLE_ENTITY);
268+
}
269+
270+
$results = User::where('id', 'like', $searchTerm.'%')
271+
->orWhere('name', 'like', $searchTerm.'%')
272+
->orWhere('email', 'like', $searchTerm.'%')->get();
273+
274+
// Attach roles to results
275+
foreach ($results as $result) {
276+
$roles = [
277+
'roles' => $result->roles,
278+
];
279+
$result->push($roles);
280+
}
281+
282+
return response()->json([
283+
json_encode($results),
284+
], Response::HTTP_OK);
285+
}
241286
}

resources/lang/en/usersmanagement.php

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22

33
return [
44

5+
// Titles
6+
'showing-all-users' => 'Showing All Users',
7+
'users-menu-alt' => 'Show Users Management Menu',
8+
'create-new-user' => 'Create New User',
9+
'show-deleted-users' => 'Show Deleted User',
10+
'editing-user' => 'Editing User :name',
11+
'showing-user' => 'Showing User :name',
12+
'showing-user-title' => ':name\'s Information',
13+
514
// Flash Messages
615
'createSuccess' => 'Successfully created user! ',
716
'updateSuccess' => 'Successfully updated user! ',
@@ -42,4 +51,78 @@
4251
'labelUserLevel' => 'Level',
4352
'labelUserLevels' => 'Levels',
4453

54+
'users-table' => [
55+
'caption' => '{1} :userscount user total|[2,*] :userscount total users',
56+
'id' => 'ID',
57+
'name' => 'Name',
58+
'email' => 'Email',
59+
'role' => 'Role',
60+
'created' => 'Created',
61+
'updated' => 'Updated',
62+
'actions' => 'Actions',
63+
'updated' => 'Updated',
64+
],
65+
66+
'buttons' => [
67+
'create-new' => '<span class="hidden-xs hidden-sm">New User</span>',
68+
'delete' => '<i class="fa fa-trash-o fa-fw" aria-hidden="true"></i> <span class="hidden-xs hidden-sm">Delete</span><span class="hidden-xs hidden-sm hidden-md"> User</span>',
69+
'show' => '<i class="fa fa-eye fa-fw" aria-hidden="true"></i> <span class="hidden-xs hidden-sm">Show</span><span class="hidden-xs hidden-sm hidden-md"> User</span>',
70+
'edit' => '<i class="fa fa-pencil fa-fw" aria-hidden="true"></i> <span class="hidden-xs hidden-sm">Edit</span><span class="hidden-xs hidden-sm hidden-md"> User</span>',
71+
'back-to-users' => '<span class="hidden-sm hidden-xs">Back to </span><span class="hidden-xs">Users</span>',
72+
'back-to-user' => 'Back <span class="hidden-xs">to User</span>',
73+
'delete-user' => '<i class="fa fa-trash-o fa-fw" aria-hidden="true"></i> <span class="hidden-xs">Delete</span><span class="hidden-xs"> User</span>',
74+
'edit-user' => '<i class="fa fa-pencil fa-fw" aria-hidden="true"></i> <span class="hidden-xs">Edit</span><span class="hidden-xs"> User</span>',
75+
],
76+
77+
'tooltips' => [
78+
'delete' => 'Delete',
79+
'show' => 'Show',
80+
'edit' => 'Edit',
81+
'create-new' => 'Create New User',
82+
'back-users' => 'Back to users',
83+
'email-user' => 'Email :user',
84+
'submit-search' => 'Submit Users Search',
85+
'clear-search' => 'Clear Search Results',
86+
],
87+
88+
'messages' => [
89+
'userNameTaken' => 'Username is taken',
90+
'userNameRequired' => 'Username is required',
91+
'fNameRequired' => 'First Name is required',
92+
'lNameRequired' => 'Last Name is required',
93+
'emailRequired' => 'Email is required',
94+
'emailInvalid' => 'Email is invalid',
95+
'passwordRequired' => 'Password is required',
96+
'PasswordMin' => 'Password needs to have at least 6 characters',
97+
'PasswordMax' => 'Password maximum length is 20 characters',
98+
'captchaRequire' => 'Captcha is required',
99+
'CaptchaWrong' => 'Wrong captcha, please try again.',
100+
'roleRequired' => 'User role is required.',
101+
'user-creation-success' => 'Successfully created user!',
102+
'update-user-success' => 'Successfully updated user!',
103+
'delete-success' => 'Successfully deleted the user!',
104+
'cannot-delete-yourself' => 'You cannot delete yourself!',
105+
],
106+
107+
'show-user' => [
108+
'id' => 'User ID',
109+
'name' => 'Username',
110+
'email' => '<span class="hidden-xs">User </span>Email',
111+
'role' => 'User Role',
112+
'created' => 'Created <span class="hidden-xs">at</span>',
113+
'updated' => 'Updated <span class="hidden-xs">at</span>',
114+
'labelRole' => 'User Role',
115+
'labelAccessLevel' => '<span class="hidden-xs">User</span> Access Level|<span class="hidden-xs">User</span> Access Levels',
116+
],
117+
118+
'search' => [
119+
'title' => 'Showing Search Results',
120+
'found-footer' => ' Record(s) found',
121+
'no-results' => 'No Results',
122+
'search-users-ph' => 'Search Users',
123+
],
124+
125+
'modals' => [
126+
'delete_user_message' => 'Are you sure you want to delete :user?',
127+
],
45128
];
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<div class="row">
2+
<div class="col-sm-6 col-sm-offset-6 col-md-6 col-md-offset-6 col-lg-5 col-lg-offset-7 col-xl-4 col-xl-offset-8">
3+
{!! Form::open(['route' => 'search-users', 'method' => 'POST', 'role' => 'form', 'class' => 'needs-validation', 'id' => 'search_users']) !!}
4+
{!! csrf_field() !!}
5+
<div class="input-group margin-bottom-2">
6+
{!! Form::text('user_search_box', NULL, ['id' => 'user_search_box', 'class' => 'form-control', 'placeholder' => trans('usersmanagement.search.search-users-ph'), 'aria-label' => trans('usersmanagement.search.search-users-ph'), 'required' => false]) !!}
7+
<a href="#" class="input-group-addon btn btn-warning clear-search" data-toggle="tooltip" title="@lang('lusersmanagement.tooltips.clear-search')" style="display:none;">
8+
<i class="fa fa-times" aria-hidden="true"></i>
9+
<span class="sr-only">
10+
@lang('lusersmanagement.tooltips.clear-search')
11+
</span>
12+
</a>
13+
<a href="#" class="input-group-addon btn btn-info" id="search_trigger">
14+
<i class="fa fa-search fa-fw" aria-hidden="true"></i>
15+
<span class="sr-only">
16+
{{ trans('usersmanagement.tooltips.submit-search') }}
17+
</span>
18+
</a>
19+
</div>
20+
{!! Form::close() !!}
21+
</div>
22+
</div>
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<script>
2+
$(function() {
3+
var cardTitle = $('#card_title');
4+
var usersTable = $('#users_table');
5+
var resultsContainer = $('#search_results');
6+
var usersCount = $('#user_count');
7+
var clearSearchTrigger = $('.clear-search');
8+
var searchform = $('#search_users');
9+
var searchformInput = $('#user_search_box');
10+
var userPagination = $('#user_pagination');
11+
var searchSubmit = $('#search_trigger');
12+
$.ajaxSetup({
13+
headers: {
14+
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
15+
}
16+
});
17+
searchform.submit(function(e) {
18+
e.preventDefault();
19+
resultsContainer.html('');
20+
usersTable.hide();
21+
clearSearchTrigger.show();
22+
let noResulsHtml = '<tr>' +
23+
'<td>@lang("usersmanagement.search.no-results")</td>' +
24+
'<td></td>' +
25+
'<td class="hidden-xs"></td>' +
26+
'<td class="hidden-xs"></td>' +
27+
'<td class="hidden-xs"></td>' +
28+
'<td class="hidden-sm hidden-xs"></td>' +
29+
'<td class="hidden-sm hidden-xs hidden-md"></td>' +
30+
'<td class="hidden-sm hidden-xs hidden-md"></td>' +
31+
'<td></td>' +
32+
'<td></td>' +
33+
'<td></td>' +
34+
'</tr>';
35+
36+
$.ajax({
37+
type:'POST',
38+
url: "{{ route('search-users') }}",
39+
data: searchform.serialize(),
40+
success: function (result) {
41+
let jsonData = JSON.parse(result);
42+
if (jsonData.length != 0) {
43+
$.each(jsonData, function(index, val) {
44+
let rolesHtml = '';
45+
let roleClass = '';
46+
let showCellHtml = '<a class="btn btn-sm btn-success btn-block" href="users/' + val.id + '" data-toggle="tooltip" title="@lang("usersmanagement.tooltips.show")">@lang("usersmanagement.buttons.show")</a>';
47+
let editCellHtml = '<a class="btn btn-sm btn-info btn-block" href="users/' + val.id + '/edit" data-toggle="tooltip" title="@lang("usersmanagement.tooltips.edit")">@lang("usersmanagement.buttons.edit")</a>';
48+
let deleteCellHtml = '<form method="POST" action="/users/'+ val.id +'" accept-charset="UTF-8" data-toggle="tooltip" title="Delete">' +
49+
'{!! Form::hidden("_method", "DELETE") !!}' +
50+
'{!! csrf_field() !!}' +
51+
'<button class="btn btn-danger btn-sm" type="button" style="width: 100%;" data-toggle="modal" data-target="#confirmDelete" data-title="Delete User" data-message="@lang("usersmanagement.modals.delete_user_message", ["user" => "'+val.name+'"])">' +
52+
'@lang("usersmanagement.buttons.delete")' +
53+
'</button>' +
54+
'</form>';
55+
56+
$.each(val.roles, function(roleIndex, role) {
57+
if (role.name == "User") {
58+
roleClass = 'primary';
59+
} else if (role.name == "Admin") {
60+
roleClass = 'warning';
61+
} else if (role.name == "Unverified") {
62+
roleClass = 'danger';
63+
} else {
64+
roleClass = 'default';
65+
};
66+
rolesHtml = '<span class="label label-' + roleClass + '">' + role.name + '</span> ';
67+
});
68+
resultsContainer.append('<tr>' +
69+
'<td>' + val.id + '</td>' +
70+
'<td>' + val.name + '</td>' +
71+
'<td class="hidden-xs">' + val.email + '</td>' +
72+
'<td class="hidden-xs">' + val.first_name + '</td>' +
73+
'<td class="hidden-xs">' + val.last_name + '</td>' +
74+
'<td class="hidden-sm hidden-xs"> ' + rolesHtml +'</td>' +
75+
'<td class="hidden-sm hidden-xs hidden-md">' + val.created_at + '</td>' +
76+
'<td class="hidden-sm hidden-xs hidden-md">' + val.updated_at + '</td>' +
77+
'<td>' + deleteCellHtml + '</td>' +
78+
'<td>' + showCellHtml + '</td>' +
79+
'<td>' + editCellHtml + '</td>' +
80+
'</tr>');
81+
});
82+
} else {
83+
resultsContainer.append(noResulsHtml);
84+
};
85+
usersCount.html(jsonData.length + " @lang('usersmanagement.search.found-footer')");
86+
userPagination.hide();
87+
cardTitle.html("@lang('usersmanagement.search.title')");
88+
},
89+
error: function (response, status, error) {
90+
if (response.status === 422) {
91+
resultsContainer.append(noResulsHtml);
92+
usersCount.html(0 + " @lang('usersmanagement.search.found-footer')");
93+
userPagination.hide();
94+
cardTitle.html("@lang('usersmanagement.search.title')");
95+
};
96+
},
97+
});
98+
});
99+
searchSubmit.click(function(event) {
100+
event.preventDefault();
101+
searchform.submit();
102+
});
103+
searchformInput.keyup(function(event) {
104+
if ($('#user_search_box').val() != '') {
105+
clearSearchTrigger.show();
106+
} else {
107+
clearSearchTrigger.hide();
108+
resultsContainer.html('');
109+
usersTable.show();
110+
cardTitle.html("@lang('usersmanagement.showing-all-users')");
111+
userPagination.show();
112+
usersCount.html(" ");
113+
};
114+
});
115+
clearSearchTrigger.click(function(e) {
116+
e.preventDefault();
117+
clearSearchTrigger.hide();
118+
usersTable.show();
119+
resultsContainer.html('');
120+
searchformInput.val('');
121+
cardTitle.html("@lang('usersmanagement.showing-all-users')");
122+
userPagination.show();
123+
usersCount.html(" ");
124+
});
125+
});
126+
</script>

resources/views/usersmanagement/show-users.blade.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333

3434
<div style="display: flex; justify-content: space-between; align-items: center;">
3535

36-
Showing users
36+
<span id="card_title">
37+
@lang('usersmanagement.showing-all-users')
38+
</span>
3739

3840
<div class="btn-group pull-right btn-group-xs">
3941

@@ -64,9 +66,11 @@
6466

6567
<div class="panel-body">
6668

69+
@include('partials.search-users-form')
70+
6771
<div class="table-responsive users-table">
6872
<table class="table table-striped table-condensed data-table">
69-
<thead>
73+
<thead class="thead">
7074
<tr>
7175
<th>ID</th>
7276
<th>Username</th>
@@ -81,7 +85,7 @@
8185
<th></th>
8286
</tr>
8387
</thead>
84-
<tbody>
88+
<tbody id="users_table">
8589
@foreach($users as $user)
8690
<tr>
8791
<td>{{$user->id}}</td>
@@ -131,9 +135,16 @@
131135
</tr>
132136
@endforeach
133137
</tbody>
138+
<tbody id="search_results"></tbody>
134139
</table>
135140

136-
{{ $users->links() }}
141+
<span id="user_count"></span>
142+
<span id="user_pagination">
143+
{{ $users->links() }}
144+
</span>
145+
146+
147+
137148
</div>
138149
</div>
139150
</div>
@@ -152,4 +163,9 @@
152163
{{--
153164
@include('scripts.tooltips')
154165
--}}
166+
167+
{{-- @if(config('laravelusers.enableSearchUsers')) --}}
168+
@include('scripts.search-users')
169+
{{-- @endif --}}
170+
155171
@endsection

routes/web.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@
112112
'deleted',
113113
],
114114
]);
115+
Route::post('search-users', 'UsersManagementController@search')->name('search-users');
115116

116117
Route::resource('themes', 'ThemesManagementController', [
117118
'names' => [

0 commit comments

Comments
 (0)