Before I begin pasting code, allow me to give you a bit of a background story because it is necessary.
I am using Laravel Messenger: http://ift.tt/1vax87u in my app which offers a nice private messaging system between users.
The problem is, the author of that package displays ALL the users with a checkbox each next to it, so you can select the recipient(s) of your message.
Like this
@if($users->count() > 0)
<div class="checkbox">
@foreach($users as $user)
<label title="{!!$user->name!!}"><input type="checkbox" name="recipients[]" value="{!!$user->id!!}">{!!$user->name!!}</label>
@endforeach
</div>
@endif
At this point, if I check a box and send that user a message, 2 records get created in the participants table. One with my user ID and another row with the recipient's user ID along with the thread_id for each row.
While this is fine, it gets cumbersome if I have thousands of users in my database and it would not be ideal for users to go through all the checkboxes to find that one user they wanna send a message to.
So I decided to remove all that and integrate Typeahead JS: http://ift.tt/1pQmP4C
Before I show you the code of Typeahead, please have a look at the MessagesController@store which is the method responsible for inserting data into the database (obviously!)
Keep in mind that at this point, if I select a checkbox (user) and send him a message, 2 rows in the database get created.
public function store()
{
$input = Input::all();
$thread = Thread::create(
[
'subject' => $input['subject'],
]
);
// Message
Message::create(
[
'thread_id' => $thread->id,
'user_id' => Auth::user()->id,
'body' => $input['message'],
]
);
// Sender
Participant::create(
[
'thread_id' => $thread->id,
'user_id' => Auth::user()->id,
'last_read' => new Carbon,
]
);
// Recipients
if (Input::has('recipients')) {
$thread->addParticipants($input['recipients']);
}
return redirect('messages');
}
So I started integrating Typeahead JS instead of the checkboxes.
First, I created the route
Route::get('messages/data/usernames/{query?}', 'MessagesController@getUsernames');
Then I created a function in MessagesController to get the usernames and return JSON
public function getUsernames($query = '') {
$q = User::select('id', 'username');
if ($query) {
$q->where('username', 'LIKE', '%' . $query . '%');
}
return Response::json($q->get());
}
I then edited create.blade.php and added the input fields
<div class="form-group" id="remote">
<input class="form-control typeahead" type="text" placeholder="Choose a Username" name="username_name">
<input type="hidden" class="username_id" value="" name="username_id">
</div>
And this is the JS
var usernames = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('username'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: 'data/usernames',
remote: {
url: 'data/usernames/%QUERY',
wildcard: '%QUERY'
}
});
$('#remote .typeahead').typeahead(null, {
name: 'username',
display: 'username',
source: usernames
});
$('#remote .typeahead').bind('typeahead:select', function(ev, suggestion) {
$('.username_id').val(suggestion.id);
});
So when I start typing a name, it auto-completes it and I can select it and carry on with the message. But no record in the database is being insert with the recipient's ID.
Only 1 record is being created with my user ID, there's no trace of the recipient's ID in the table, therefore, no messages are being delivered.
PS: I messaged the author of the package and he said he has no desire to change the checkboxes or even looking at my code.
via Chebli Mohamed
Aucun commentaire:
Enregistrer un commentaire