can you please describe whats wrong with my code below. Their is an error when I click Update button and getting id of update Request. What I want to do is to update category name and tag with a post (post_tag i.e belongstoMany)
And it says "Trying to get property of non-object.
//class Post extends Model
public function category()
{
return $this->belongsTo('App\Category');
}
public function tags()
{
return $this->belongsToMany('App\Tag');
}
// class Tag extends Model
public function posts()
{
return $this->belongsToMany('App\Post');
}
// class Category extends Model
protected $table = 'categories';
public function posts()
{
return $this->hasMany('App\Post');
}
// PostController
public function edit($id)
{
// find the post in the database and save as a var
$post = Post::find($id);
$categories = Category::with('posts')->get();
$cats = array();
foreach ($categories as $category) {
$cats[$category->id] = $category->name;
}
$tags = Tag::with('posts')->get();
$tags2 = array();
foreach ($tags as $tag) {
$tags2[$tag->id] = $tag->name;
}
// return the view and pass in the var we previously created
return view('backend.pages.posts.edit')->withPost($post)->withCategories($cats)->withTags($tags2);
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
// Validate the data
$post = Post::find($id);
if ($request->input('slug') == $post->slug) {
$this->validate($request, array(
'title' => 'required|max:255',
'category_id' => 'required|integer',
'body' => 'required'
));
} else {
$this->validate($request, array(
'title' => 'required|max:255',
'slug' => 'required|alpha_dash|min:5|max:255|unique:posts,slug',
'category_id' => 'required|integer',
'body' => 'required'
));
}
// Save the data to the database
$post = Post::find($id)->first();
$post->title = $request->input('title');
$post->slug = $request->input('slug');
$post->category_id = $request->input('category_id');
$post->body = $request->input('body');
if (isset($request->tags)) {
$post->tags()->sync($request->tags);
} else {
$post->tags()->sync(array());
}
$post->save();
notify()->success("The blog post was successfully updated!", 'Success');
return redirect()->route('app.posts.show', $post->id);
// return back();
}
//edit.blade.php file
// An error appears in select option finding an id which is a non-object
// A 2 line code below which is inside of form POST METHOD {{ route('app.posts.update', $post->id) }} //
<select class="form-control" name="category_id" class="form-control #error('category_id') is-invalid #enderror" required>
#foreach($categories as $key=>$category)
<option value="{{ $category>id }}" #isset($post) {{ $post->category->id == $category->id ? 'selected' : '' }} #endisset>{{ $category->name}}</option>
#endforeach
// Same error below tag name cannot get property
<select class="form-control select2-multi" id="tags" name="tags[]" multiple>
#foreach($tags as $key=>$tag)
<option value="{{ $tag }}" {{ old('tags[]', $post->tag)->contains($tag) ? 'selected' : '' }}>{{ $tag->name }}</option>
#endforeach
</select>
//End form
I got it. the $categories variable the you pass to the view is an array, with keys are category ids and values are category names. In your view, inside the loop, that $category variable is a string, but you try to access that as an object ($category->id) and get the error.
SOLUTION 1:
You can update your code like this:
<select class="form-control" name="category_id" class="form-control #error('category_id') is-invalid #enderror" required>
#foreach($categories as $categoryId => $categoryName)
<option value="{{ $categoryId }}" #isset($post) {{ $post->category->id == $categoryId ? 'selected' : '' }} #endisset>{{$categoryName}}</option>
#endforeach
<select class="form-control select2-multi" id="tags" name="tags[]" multiple>
#foreach($tags as $tagId => $tagName)
<option value="{{ $tagId }}" {{ old('tags[]', $post->tags)->contains($tagId) ? 'selected' : '' }}>{{ $tagName }}</option>
#endforeach
</select>
SOLUTION 2:
I see that in the controller action, you transform you categories and tags to arrays, which is not necessary. Just get those from the database and pass to the view.
public function edit($id)
{
// find the post in the database and save as a var
$post = Post::find($id);
$categories = Category::with('posts')->get();
$tags = Tag::with('posts')->get();
return view('backend.pages.posts.edit', [
'post' => $post,
'categories' => $categories,
'tags' => $tags,
]);
// Or you can even write: return view('backend.pages.posts.edit', compact('post', 'categories', 'tags'));
}
Then in your view:
<select class="form-control" name="category_id" class="form-control #error('category_id') is-invalid #enderror" required>
#foreach($categories as $category)
<option value="{{ $category->id }}" #isset($post) {{ $post->category->id == $category->id ? 'selected' : '' }} #endisset>{{$category->name}}</option>
#endforeach
<select class="form-control select2-multi" id="tags" name="tags[]" multiple>
#foreach($tags as $tag)
<option value="{{ $tag->id }}" {{ old('tags[]', $post->tags)->contains($tag->id) ? 'selected' : '' }}>{{ $tag->name }}</option>
#endforeach
</select>
Related
I have 2 filters on a user list. A user can select a group containing members and use the search filter to search by last name. When the user backspaces a user to look for another, this resets the groups to all users. I need this to only show the users in the selected group.
TS
updateFilter(event) {
const val = event.target.value.toLowerCase();
const temp = this.temp.filter(function (d) {
return d.lastName.toLowerCase().indexOf(val) !== -1 || !val;
});
this.rows = temp;
if (this.table) {
this.table.offset = 0;
}
}
onGroupSelected($event) {
const groupId = $event.target ? $event.target.value : $event;
if (groupId === 'none') {
this.rows = this.temp;
} else {
const groupUsers = this.groupUserMap.get(groupId);
if (groupUsers) {
this.rows = this.temp.filter((serviceUser) =>
groupUsers.includes(serviceUser.id));
} else {
this.rows = [];
}
}
// #ts-ignore
this.userSelections = this.userSelections ? this.userSelections : {};
this.userSelections.groupId = groupId;
localForage.setItem(this.username, this.userSelections);
}
HTML
<input
type='text'
class="form-control w-200px"
placeholder='Search by Last Name...'
(keyup)='updateFilter($event)'
/>
<select class="form-control w-200px" (change)="onGroupSelected($event)">
<option value="none">All service users</option>
<option *ngFor="let group of groups"
[value]="group.id"
[selected]="userSelections.groupId === group.id">
{{group.name}}
</option>
</select>
You can use ngModel with tow-way binding, to save and manipulate search filters:
<select
class="form-control w-200px"
[(ngModel)]="selectedGroup"
(change)="onGroupSelected()"
>
<option value="none">All service users</option>
<option *ngFor="let group of groups" [value]="group.id">
{{ group.name }}
</option>
</select>
<input
type="text"
class="form-control w-200px"
placeholder="Search by Last Name..."
[(ngModel)]="search"
(keyup)="updateFilter()"
/>
And in order not to lose your users table you can create a copy which will be filtered and displayed.
public initialUsers = [
{ id: 100, groupId: 1, name: 'foo' },
{ id: 101, groupId: 2, name: 'bar' },
{ id: 102, groupId: 1, name: 'john' },
{ id: 103, groupId: 2, name: 'doe' },
{ id: 104, groupId: 2, name: 'baaar' },
{ id: 105, groupId: 1, name: 'fooodoe' },
];
public filteredUsers = [];
ngOnInit(): void {
this.filteredUsers = this.initialUsers;
}
Here is a demo on stackblitz, I used a list to go fast but It's just display. You just have to replace <ul> <li></li> </ul> by your <table> ... </table>
If you would want to take an observable way of doing this, then I would suggest to make a form of your controls, ooooor just use 2 form controls instead. I chose form here as it wraps it up nicely with both form controls (search and dropdown):
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
search: [''],
group: [0] // "all" option as initial id
})
}
Then we would listen to when the form value changes and assign the filtered data to a variable, here named filteredUsers$.
this.filteredUsers$ = this.form.valueChanges.pipe(
startWith(this.form.value), // to trigger initially
// 'this.users' refers to your original users array
map((value: any) => {
// 'all' option is chosen, just filter based on search
if (value.group === 0) return this.users.filter(x => x.lastName.toLowerCase().includes(value.search))
// filter by group and search
return this.users.filter(x => {
return (x.groupId === value.group) && (x.lastName.toLowerCase().includes(value.search.toLowerCase()))
})
})
)
That is it, then we just iterate filteredUsers$ in the template:
<tr *ngFor="let user of filteredUsers$ | async">
Of course we need the form in the view and it would look like this:
<form [formGroup]="form">
<input
type="text"
placeholder="Search by Last Name..."
formControlName="search"
/>
<select formControlName="group">
<option *ngFor="let group of groups" [ngValue]="group.id">
{{ group.name }}
</option>
</select>
</form>
Here is a DEMO with the above code
How to echo the second array value where the array index of Json is same as the clicked select option?
what i need is, when i select the select option that has subject value : Webinar 1, then the will show the total_participation : 100
The API Json
{
"status": 200,
"message": "success",
"data": {
"records": [
{
"subject": "Webinar 1",
"total_participant": 100
},
{
"subject": "Webinar 2",
"total_participant": 165
},
{
"subject": "Webinar 3",
"total_participant": 143
}
]
},
"error": []
}
MY CONTROLLER :
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Utils\Endpoints\WebinarEndpoints;
use Illuminate\Support\Facades\Http;
class WebinarController extends Controller
{
public $webinarEndpoints;
function __construct(){
$this->webinarEndpoints = new WebinarEndpoints;
}
public function index(){
$result = $this->webinarEndpoints->participant()->json();
$webinarlist = $this->webinarEndpoints->webinarlist()->json();
switch ($result['status']) {
case '200':
return view('webinar', [
'participants' => $result['data']['records'],
'lists' => $webinarlist['data']['records']
]);
break;
default :
break;
}
}
}
VIEW :
<div class="col-3">
<select class="form-control">
#foreach ($lists as $list)
<option onclick="total()">{{$list['subject']}} </option>
#endforeach
</select>
</div>
<h3> {{ GET total_participant based on Selected select option index }} </h3>
THANKS FOR HELPING ME!!
a simple way to deal with this could be to give the total_participant to your total() function :
<div class="col-3">
<select class="form-control">
#foreach ($lists as $list)
<option onclick="total({{$list['total_participant']}})">{{$list['subject']}} </option>
#endforeach
</select>
</div>
<h3> {{ GET total_participant based on Selected select option index }} </h3>
In my Laravel-5.8, I passed data from controller to view using JSON.
public function findScore(Request $request)
{
$userCompany = Auth::user()->company_id;
$child = DB::table('appraisal_goal_types')->where('company_id', $userCompany)->where('id',$request->id)->first();
if(empty($child))
{
abort(404);
}
$maxscore2 = 1;
$maxscore = DB::table('appraisal_goal_types')->select('max_score')->find($child->parent_id);
return response()->json([
'maxscore' => $maxscore,
'maxscore2' => $maxscore2
]);
}
Route
Route::get('get/findScore','Appraisal\AppraisalGoalsController#findScore')
->name('get.scores.all');
View
<form action="{{route('appraisal.appraisal_goals.store')}}" method="post" class="form-horizontal" enctype="multipart/form-data">
{{csrf_field()}}
<div class="card-body">
<div class="form-body">
<div class="row">
<div class="col-12 col-sm-6">
<div class="form-group">
<label class="control-label"> Goal Type:<span style="color:red;">*</span></label>
<select id="goal_type" class="form-control" name="goal_type_id">
<option value="">Select Goal Type</option>
#foreach ($categories as $category)
#unless($category->name === 'Job Fundamentals')
<option hidden value="{{ $category->id }}" {{ $category->id == old('category_id') ? 'selected' : '' }}>{{ $category->name }}</option>
#if ($category->children)
#foreach ($category->children as $child)
#unless($child->name === 'Job Fundamentals')
<option value="{{ $child->id }}" {{ $child->id == old('category_id') ? 'selected' : '' }}> {{ $child->name }}</option>
#endunless
#endforeach
#endif
#endunless
#endforeach
</select>
</div>
</div>
<input type="text" id="max_score" value="max_score" class="form-control" >
</form>
<script type="text/javascript">
$(document).ready(function() {
$(document).on('change', '#goal_type', function() {
var air_id = $(this).val();
var a = $(this).parent();
console.log("Its Change !");
var op = "";
$.ajax({
type: 'get',
url: '{{ route('get.scores.all') }}',
data: { 'id': air_id },
dataType: 'json', //return data will be json
success: function(data) {
console.log(data.maxscore);
console.log(data.maxscore2);
$('#max_score').val(data.maxscore);
},
error:function(){
}
});
});
});
</script>
When I click on the dropdown on change, I got these:
Console:
textbox:
I need the direct value to be displayed on the text and not the JSON object as shown in the diagram. For example, only the 75 in the textbox.
How do I get this resolved?
Thank you.
You're seeing this result because maxscore is an object. You can either reference maxscore.max_score from JavaScript when adding to the element, or you can alternatively look at your eloquent code. You can likely replace the ->find() with calls to ->where() and ->first() as you did with $child
You can access the inner elements using something like this, or at least have an idea , and then you can print the elemet you need from the array...
var selectedValue = max_score.options[max_score.selectedIndex].innerHTML;
var arreglo = selectedValue.split(' ');
var arreglo1 = arreglo[0];
how to do the auto fill after select the dropdown list. I'm not really good in js or ajax.
When user select doc_no then both rev_no and title field must be filled up. Thanks!
View
<div class="form-group">
{!! Form::label('text', 'Doc No', ['class' => 'col-lg-3 control-label']) !!}
<div class="col-lg-10">
<select name="docNo" id="docNo" class="form-control" style="width:250px">
#foreach ($soplists as $soplist)
<option value="{{ $soplist->id }}">{{ $soplist->doc_no }}</option>
#endforeach
</select>
</div>
</div>
<input type="hidden" name="carType" value="Internal Audit" class="form-control">
<div class="form-group">
{!! Form::label('text', "Rev No", ['class' => 'col-lg-5 control-label']) !!}
<div class="col-lg-5">
<input type="text" class="form-control" id="rev" />
</div>
</div>
<div class="form-group">
{!! Form::label('text', "Title", ['class' => 'col-lg-5 control-label']) !!}
<div class="col-lg-10">
<input type="text" class="form-control" id="title" />
</div>
<script>
$('#docNo').change(function() {
var id = $(this).val();
var url = '{{ route("getDetails", ":id") }}';
url = url.replace(':id', id);
$.ajax({
url: url,
type: 'get',
dataType: 'json',
success: function(response) {
if (response != null) {
$('#rev').val(response.rev_no);
$('#title').val(response.title);
}
}
});
});
</script>
Controller
---php
public function getDetails($id = 0)
{
$data = sopList::where('doc_no', $id)->first();
echo json_encode($data);
exit;
}
Route
'Route::get('get/details/{id}', 'internalAuditController#getDetails')->name('getDetails');'
Database sop_list table image link
https://ibb.co/SwkJhLc
Dropdown and input image
https://ibb.co/0VN3Z2y
Network tab
https://ibb.co/56w5BLD
Add a route in web.php file:
Route::get('get/details/{id}', 'YourController#getDetails')->name('getDetails');
Controller Function:
public function getDetails($id = 0)
{
$data = sopList::where('doc_no',$id)->first();
return response()->json($data);
}
And in view the script:
$('#docNo').change(function(){
var id = $(this).val();
var url = '{{ route("getDetails", ":id") }}';
url = url.replace(':id', id);
$.ajax({
url: url,
type: 'get',
dataType: 'json',
success: function(response){
if(response != null){
$('#rev').val(response.rev_no);
$('#title').val(response.title);
}
}
});
});
Make sure to add the id rev and title to the rev and title input fields respectively.
you have to make a rout that returns what you need
for example
/**
* #return \Illuminate\Http\JsonResponse
*/
public function getCategories()
{
$category = Category::where('_id', request()->get('_id'))
->select(['name', '_id'])->first();
return response()->json($category);
}
then call it on change of your select box with ajax and show it every where you want
like this example:
$("#docNo").change(function () {
$.ajax({
url: "{{ route('getCategories') }}",
type: 'POST',
data: {
_token: "{{ csrf_token() }}",
_id: $(this).val()
},
success: function (data) {
var newOption = '';
$.each(data, function (k, category) {
newOption += '<option value="' + category.id + '">' + category.name + '</option>';
});
$('#parent').append(newOption);
},
error: function (error) {
console.log(error);
}
});
});
you can add onChange method on your docNo and then call do ajax call to get the rev_no and title and update the content via document.getElementById()
I want to post a record in SQL using Ajax without using a form but I have trouble:
method not allowed
<input type="text" name="name" value=" 2" />
<input type="text" value="detail" />
<input type="hidden" name="_Token" value="{{ csrf_token() }}">
<input type="button" onclick="add()" value="Submit Comment" />
Here is my controller:
class Cdesigination extends Controller
{
public function index()
{
$insertData = array(
"name" => Input::get("name"),
"detail" => Input::get("detail"),
"token_key" => Input::get("_token")
);
return view('company');
}
public function product()
{
$record = array(
"p_name" => Input::get("name"),
"p_price" => Input::get("price"),
"p_detail" => Input::get("detail")
);
return view('product');
}
}
The route is:
Route::post('add', ['as' => 'addrecord', 'uses' => 'Cdesigination#index']);
Ajax Function:
function add()
{
var name = $('#name').val();
var detail = $('#detail').val();
var token = $('#_token').val();
$.ajax({
type: 'POST',
url: '{{url("/posts")}}',
data: "name=" + name + "&detail=" + detail + "&_token=" + token,
success: function(data){ }
});
}
Where is my mistake? Please guide me and explain how to post record in Laravel without using a form.
your url is: {url("/posts")} and you haven't this route defined