Global Search not working with laravel - javascript

Hi guys im trying to get an specific search for my proyect but it doesnt want to work, I'm using relationships this is my code
Php:
public function todos_productos($empresa_id, Request $request)
{
$empresa = Empresa::find($empresa_id);
$productos = $empresa->productos()->with('producto_nombre', 'producto_nombre.seccion', 'producto_nombre.linea');
return Datatables::of($productos)
->filter(function ($query) use ($request) {
if ($request->has('codigo')) {
$query->where('producto_nombre.codigo', 'like', "%{$request->get('codigo')}%");
}
})
->make(true);
}
My js
$(document).ready(function () {
empresa = $('#empresa_id').val()
tablaBusqueda = $('#postTable').DataTable({
processing: true,
serverSide: true,
ajax: {
url: 'api/productos/todos/' + empresa,
data: function (d) {
d.codigo = $('input[name=consulta_producto_codigo]').val()
d.linea = $('select[name=consulta_producto_linea]').val()
d.seccion = $('select[name=consulta_producto_seccion]').val()
}
},
columns: [
{data: 'codigo', name: 'producto_nombre.codigo'},
{data: 'descripcion', name: 'producto_nombre.descripcion'},
{data: 'existencias', name: 'existencias'},
{data: 'precio', name: 'precio'},
{data: 'stock_minimo', name: 'stock_minimo'},
{data: 'stock_maximo', name: 'stock_maximo'},
{data: 'producto_nombre.linea.nombre', name: 'producto_nombre.linea.nombre'},
{data: 'producto_nombre.seccion.nombre', name: 'producto_nombre.seccion.nombre'}
],
'language':
{
'url':
'../plugins/dataTables.spanish.lang'
}
})
})
The problem is that when im trying to search by codigo(code) it says that there isn't the column producto_nombre.codigo, I've replaced it with only codigo but also not working, anyone know why?

$empresa is a single Empresa model instance.
$productos is an Eloquent collection of (assuming) Producto models with the two eager loaded relationships producto_nombre and producto_nombre.seccion. Any queries will there will be run on the (assuming) productos table instead of your relationship table.
Here's how to constrain eager loads: https://laravel.com/docs/5.6/eloquent-relationships#constraining-eager-loads

Related

How to allow models with belongsToMany relationship to be searchable using datatables?

I have the following model that has a belongsToMany relationship:
class Sale extends Model
{
public function items()
{
return $this->belongsToMany(Item::class)->select(
[DB::raw("COUNT(*) as quantity"),
DB::raw("CONCAT('(', GROUP_CONCAT(serial_number SEPARATOR ', '), ')') AS serial_number"),
'items.name',
'items.upc',
'items.id',
'items.with_serial_number',
'items.selling_price',
'item_sale.sold_price',
'item_sale.item_purchase_id'])
->join('item_purchase', 'item_sale.item_purchase_id', '=', 'item_purchase.id')
->orderBy('item_sale.id', 'ASC')
->groupBy('item_sale.item_id', 'item_sale.sale_id');
}
and on my controller
public function demo(Request $request)
{
if ($request->ajax()) {
$data = Sale::with(['branch', 'items', 'customer', 'user'])->select(['*']);
return Datatables::of($data)
->addIndexColumn()
->make(true);
}
}
and on my jquery
$('#search_sale_list').DataTable({
"processing": true,
"serverSide": true,
"ajax": "{{ route('rma.demo') }}",
"columns": [
{data: 'created_at'},
{data: 'branch.address'},
{data: 'sale_number'},
{data: 'items'}
]
});
My problem is i cant seem to search for the 'items' in my view when i use the searchbox of datatables, it gives out an error. is this even possible to do using datatables?

Need Help Looping Out Content Of Json Data Response Fetched From DB In Using Ajax And Laravel

I have a table with a list of subjects, each subject has its own topics, so I wrote an ajax script to fetch the topics of each subject "onclick" of the subject, using the subject id.
I tried console logging the JSON success response from my controller, I'm seeing the results of the query so I used Js append functionality to append the data to a div on my index.blade but its returning topics:[object Object],[object Object]
Ajax Request To Show Topics of Selected Subjects track_id means subject_id
$( ".show-topics" ).click(function() {
var track_id= $(this).data('id');
var html ='';
$.ajax({
type: "GET",
dataType: "json",
url: 'showTopics',
headers: {'X-CSRF-TOKEN': '{{ csrf_token() }}' },
data: {'id': track_id},
success: function(data)
{
// For loop statement to loop out the data```
if(data.topics)
{
for(var key in data)
{
var value = data[key];
html+='<div>'+key+':'+value+'</div>'
}
$("#topic-data").append(html);
}
}
});
});
In my controller, I have this as my showtopics method ```
public function showTopics(Request $request)
{
$topics = Topic::where('track_id', $request->id)->latest()->get();
return response()->json(['topics' => $topics]);
}
the div to append those data:
<div id="topic-data">
</div>
When I
console.log(data.topics)
I got this,
(2) [{…}, {…}]
0:
created_at: "2019-07-29 18:04:32"
duration: 5
id: 7
title: "My Porfolio Adesanya Folorunso"
track_id: 44
updated_at: "2019-07-29 18:04:32"
1:
created_at: "2019-07-29 18:04:11"
duration: 2
id: 6
title: "Adesanya Folorunso"
track_id: 44
updated_at: "2019
I want to display topics->id, topics->title and duration.
not this topics:[object Object],[object Object]
I am assuming that your data looks something like the following. If so, replace your loop code with mine...
var data =
{
"topics":
[
{
"created_at":"2019-07-29 18:04:32",
"duration":5,
"id":7,
"title":"My Porfolio Adesanya Folorunso",
"track_id":44,
"updated_at":"2019-07-29 18:04:32"
},
{
"created_at":"2019-07-29 18:04:11",
"duration":2,
"id":6,
"title":"Adesanya Folorunso",
"track_id":44,
"updated_at":"2019-07-30 19:04:21"
}
]
};
if(data.topics)
{
for(var i=0; i < data.topics.length; i++)
{
$("#topic-data").append( $("<div />").text(data.topics[i].created_at) );
$("#topic-data").append( $("<div />").text(data.topics[i].duration) );
$("#topic-data").append( $("<hr />") );
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="topic-data">
</div>

How to remove image url on Autocomplete in Materialize CSS?

I have this JavaScript method that get all my data from a department table using API:
<script type="text/javascript">
$(document).ready(function() {
//Autocomplete
$(function() {
$.ajax({
type: 'GET',
url: 'http://127.0.0.1/EnrollmentSystem/api/department/read.php',
success: function(response) {
var departmentArray = response;
var dataDepartment = {};
//console.log(departmentArray['records']['0'].name);
console.log(departmentArray['records'].length);
for (var i = 0; i < departmentArray['records'].length; i++) {
console.log(departmentArray['records'][i]);
dataDepartment[departmentArray['records'][i].name] = departmentArray['records'][i].name; //departmentArray[i].flag or null
}
$('input.autocomplete_department').autocomplete({
data: dataDepartment,
});
}
});
});
});
</script>
and i am calling it on my page using this one:
<div class="row lt-row-content input-field">
<div class="col s12 m3 l3 lt-input-field">Department</div>
<div class="col s12 m8 l8 lt-input-field"><input type="text" name="" id="autocomplete-input" class="autocomplete_department lt-input-field"></div>
</div>
My concern is how can i remove the image shown on the Autocomplete?
As for the my Object only the id and name which i include on my models
class Department{
private $conn;
private $table_name = "department";
public $id;
public $name;
public function __construct($db){
$this->conn = $db;
}
...
This is the output of console.log(departmentArray['records'][i]);
const departmentArray = {
records: [
{ id: 1, name: 'DEPARTMENT 1' },
{ id: 2, name: 'DEPARTMENT 2' },
{ id: 3, name: 'DEPARTMENT 3' },
{ id: 4, name: 'DEPARTMENT 4' },
]
}
const dataDepartment = departmentArray.records.map(record => record.name);
$('#input').autocomplete({
source: dataDepartment
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
<input id="input" type="text">
The autocomplete documentation accepts a simple array of strings, so lets create that from your departmentArray response using Array map.
var dataDepartment = departmentArray.records.map(record => record.name);
Also, autocomplete expects the options attribute source instead of data.
$('input.autocomplete_department').autocomplete({
source: dataDepartment
});
Looking for a similar answer as the original post. The answer given by camaulay would be right if the original post was about Jquery autocomplete. It is not. The original post is about Materializecss autocomplete and it should be data and NOT source for the list of autocomplete elements. `
// copy/pasted from https://materializecss.com/autocomplete.html
$(document).ready(function(){
$('input.autocomplete').autocomplete({
data: {
"Apple": null,
"Microsoft": null,
"Google": 'https://placehold.it/250x250'
},
});
});`[codepen example.][1]
See "Apple": null - the null value is the way to suppress the image in the Materializecss autocomplete.

What is the proper way to get the data for Highcharts in Rails

My Rails website display a simple table about name and age of students.
name age
Lily 25
Tom 27
Chris 19
...
So I have #names = Student.pluck(:name), #ages = Student.pluck(:age). Now I would like to generate a line chart by using Highcharts:
HTML: <div id='students-chart'></div>
JavaScript:
$(function() {
Highcharts.chart('students_chart', {
...
};
};
Now I should provide the name and age to the chart as the xAxis and yAxis. The simplest way is to include the JavaScript in the html.erb file and provide the data by <%= #names %> and <%= #ages %>. However, it's not recommended, and I want to put the JavaScript code in the assets/javascripts/students.js file.
A very common way to fetch the data in the JavaScript file is using the Ajax, however, my data is already in the page so I don't want to add an extra action in the controller to send the data.
So what's the best practice to get the data for the Highcharts? data- attribute?
No front-end frameworks in the project, only jQuery. I know some gems could help me like Chartkick or LazyHighCharts, but I would like to know the basic strategy.
This is one way to show the chart, just jQuery getting data from the controller.
In controller fetch the data, adjust and convert to json. Customise respect to on your models. Here is an example with an array of hashes (data are passed as arrays):
#series = [ {name: 'Lily', data: [25]}, {name: 'Tom', data: [27]}, {name: 'Chris', data: [19]} ].to_json
For example, if your User model includes the age column, you can adjust like this:
#series = User.all.map{ |user| {name: user.name, data: [user.age]} }.to_json
In view (customise as you will), passing the variable here:
<div id='students_chart'></div>
<script>
$(function () {
var myChart = Highcharts.chart('students_chart', {
chart: {
type: 'column'
},
title: {
text: 'User ages'
},
xAxis: {
categories: ['Users']
},
yAxis: {
title: {
text: 'Age'
}
},
series: <%= raw #series %>
});
});
</script>
Edit - get data from server
Instead of sending data to view, render as json (no need to add e new action):
respond_to do |format|
format.html
format.json { render json: #series }
end
Then place the javascript in a file and get json data using jQuery.getJSON():
$.getJSON(window.location.href, function(json) {
var highChartData = json;
console.log(json)
var myChart = Highcharts.chart('students_chart', {
chart: {
type: 'column'
},
title: {
text: 'User ages'
},
xAxis: {
categories: ['Users']
},
yAxis: {
title: {
text: 'Age'
}
},
series: highChartData
});
});

How can I parse this JSON for use in Backbone View

I'm trying to learn Backbone and can't seem to match data from the fetch function into my Underscore template. How can can I get the children array in my JSON and match it to the template?
The Backbone.View looks like this:
var Projects = Backbone.Collection.extend({
url: '/tree/projects'
});
var Portfolio = Backbone.View.extend({
el: '.page',
render: function () {
var that = this;
var projects = new Projects();
projects.fetch({
success: function (projects) {
var template = _.template($('#projects-template').html());
that.$el.html(template({projects: projects.models}));
}
})
}
});
At the url: http://localhost:3000/portfolio/api/tree/projects
The JSON returned looks like this:
{
id:"projects",
url:"http://localhost:8888/portfolio/projects",
uid:"projects",
title:"Projects",
text:"",
files:[
],
children:[
{
id:"projects/example-1",
url:"http://localhost:8888/portfolio/projects/example-1",
uid:"example-1",
title:"Example 1",
images:"",
year:"2017",
tags:"Website",
files:[
],
children:[
]
},
{
id:"projects/example-2",
url:"http://localhost:8888/portfolio/projects/example-2",
uid:"example-2",
title:"Example #"2
text:"Example 2's text",
year:"2016",
tags:"Website",
files:[
{
url:"http://localhost:8888/portfolio/content/1-projects/4-example-2/example_ss.png",
name:"example_ss",
extension:"png",
size:244845,
niceSize:"239.11 kB",
mime:"image/png",
type:"image"
}
],
children:[
]
},
]
}
My Underscore file looks like this:
<script type="text/template" id="projects-template">
<h4>tester</h4>
<div>
<% _.each(projects.children, function (project) { %>
<div>
<div><%= project.get('year') %></div>
<div><%= project.get('title') %></div>
<div><%= project.get('tags') %></div>
</div>
<% }); %>
</div>
</script>
You can define a parse method on the collection:
var Projects = Backbone.Collection.extend({
url: '/tree/projects',
parse: function(response){
/* save other data from response directly to collection if needed.
for eg this.title = response.title; */
return response.children; // now models will be populated from children array
}
});
Do not use parse
While I usually agree with TJ, using parse on the collection is more like a hack than a definite solution. It would work only to get the children projects of a project and nothing more.
The parse function shouldn't have side-effects on the collection and with this approach, changing and saving fields on the parent project wouldn't be easily possible.
It also doesn't deal with the fact that it's a nested structure, it's not just a wrapped array.
This function works best when receiving wrapped data:
{
data: [{ /*...*/ }, { /*...*/ }]
}
Models and collections
What you have here are projects that have nested projects. A project should be a model. You also have files, so you should have a File model.
Take each resource and make a model and collection classes with it. But first, get the shared data out of the way.
var API_ROOT = 'http://localhost:8888/';
File
var FileModel = Backbone.Model.extend({
defaults: {
name: "",
extension: "png",
size: 0,
niceSize: "0 kB",
mime: "image/png",
type: "image"
}
});
var FileCollection = Backbone.Collection.extend({
model: FileModel
});
Project
var ProjectModel = Backbone.Model.extend({
defaults: function() {
return {
title: "",
text: "",
files: [],
children: []
};
},
getProjects: function() {
return this.get('children');
},
setProjects: function(projectArray, options) {
return this.set('children', projectArray, options);
},
getFiles: function() {
return this.get('files');
},
getSubProjectUrl: function() {
return this.get('url');
}
});
var ProjectCollection = Backbone.Collection.extend({
model: ProjectModel,
url: API_ROOT + '/tree/projects'
});
Project view
Then, make a view for a project. This is a simple example, see the additional information for tips on optimizing the rendering.
var ProjectView = Backbone.View.extend({
template: _.template($('#projects-template').html()),
initialize: function(options) {
this.options = _.extend({
depth: 0, // default option
}, options);
// Make a new collection instance with the array when necessary
this.collection = new ProjectCollection(this.model.getProjects(), {
url: this.model.getSubProjectUrl()
});
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
this.$projectList = this.$('.list');
// use the depth option to avoid rendering too much projects
if (this.depth > 0) this.collection.each(this.renderProject, this);
return this;
}
renderProject: function(model) {
this.$projectList.append(new ProjectView({
model: model,
depth: depth - 1
}).render().el);
}
});
With a template like this:
<script type="text/template" id="projects-template">
<h4><%= title %></h4>
<span><%= year %></span><span><%= tags %></span>
<p><%= text %></p>
<div class="list"></div>
</script>
Using the view:
var model = new ProjectModel({ id: "project" });
model.fetch({
success: function() {
var project = new ProjectView({
model: model,
depth: 2
});
}
});
Additional info
Nested models and collections
Efficiently rendering a list

Categories