Laravel 8 & Yajra Datatables complicated search - laravel

I have a datatable that fetches orders and is working and displaying properly. I show the orders to the users that initiated them. Then they can only search on their owns orders. Now I need to display a message to a user, if an order was found but it was initiated by another user, instead of displaying an empty result in the datatable. This will happen after typing in the search box and not when loading the datatable in the beggining. The problem is that the query already filters the results by user id so I cannot change it during manual search.
I can display code if needed but the function is quite big and I don't really need code but the logic/way of doing that.
Do you have any suggestions on how I could accomplish this?

Well, maybe not the best way to do it but that's how I solved it:
In the controller, I check for the search field, and run a query on the relationship but only on the orders that have different seller than the logged in user:
$otherSeller = "";
if(!empty($request->search['value']))
{
$ordersOtherSeller = Order::where('status_id', "!=", 3)->where('seller_id', '!=', $loggedUser->id)->whereHas('user', function ($q) use ($request){
$q->searchFullName($request->search['value']);
})->first();
if($ordersOtherSeller != NULL && $ordersOtherSeller->count() > 0)
$otherSeller = $ordersOtherSeller->user->full_name . ' ' . $ordersOtherSeller->seller->full_name;
}
And I set a custom variable with the table's json:
...
->with('otherSeller', $otherSeller)
->make(true);
Then on the datatable jquery drawCallBack, I check for a populated string that guarantees that the result is not returned by a query from the current user:
fnDrawCallback: function( oSettings ) {
var api = this.api();
if(api.ajax.json().otherSeller != "")
{
$('#alert-info span').text(api.ajax.json().otherSeller);
$('#alert-info').show();
}
else
$('#alert-info').hide();
},
And last is the toggling of the materialert element with updated text:
<div id="alert-info" class="materialert info" style="display: none;">
<i class="material-icons">info</i> <span></span>
<button type="button" class="close-alert">×</button>
</div>

Related

How to get Unique value in blade file laravel

I want to fetch unique value for filters of all products.
My db structure as follows
id Product category_id format attribute
1 demo1 5 HD test1
2 demmo2 4 SD test3
3 demmo3 4 HD test2
4 demmo4 3 HD test3
I want add filters of format and attribute in product page. But in that HD comming 3 times. I want to display that one only.
I am not getting how to display only single time.
Below is my controller code:
$item = Item::where('active_status', 1)->where('status', "1");
$data['item_count'] = $item;
$data['item'] = $item->paginate(20);
return view('frontend.pages.explore', compact('data'));
Below is blade file
<div class="filter-btn">
#foreach($data['item'] as $resolution)
<a class="btn btn-white-outline display-4" href="">{{array_unique($resolution->format)}}</a>
#endforeach
</div>
I am not getting how to display unique value only. Anyone have idea then let me know
since you are paginating your data, your "first page" might not have all the formats, so you have to do another query to your database:
$formats = DB::table('items')->select('format')->distinct()->get()
...
view(..., compact('data', 'formats'))
in the blade table:
#foreach($formats as $resolution)
<a class="btn btn-white-outline display-4" href="">{{$resolution->format}}</a>
#endforeach
If I am correct about your query, then you need to use groupby to list the items in your controller.
$items = Item::groupBy('format')->get();
The solution would be to create a sperate model for Formatand relationship between it and Product or whatever model that needs format , then fetch formats from its table and apply eager load .
this may look longer than your solution , but this is standards shoiuld be taken for vrious reasons :
less sql queries
more flexibility and options regarding our new table
better and less code to crud format
single source for change
less database data and faster load
...
Product.php
public function format(){
return $this->belongsTo(Format::class);
}
Format.php
public function products(){
return $this->hasMany(Product::class);
}
Usage
in controller
// get all formts eager loaded with products
$formats = Format::with('products')->get();
//get all products
$product = Format::latest()->paginate(20);
return view('frontend.pages.explore', compact( 'products' ,'formats'));
in your view
// all prodcuts
#foreach($formats as $format)
<a class="btn btn-white-outline display-4" href="">{{$format->name}}</a>
#endforeach
// in filter ( at clicking ) no additional query
#foreach($format->products as $product)
...
#endforeach

Repopulate Dynamic Dropdown with "set_select" after Form Validation fails in Codeigniter?

I was wondering if it is possible to repopulate a dynamic dropdown(specifically the option of a select) after form validation fails which is generated by another dropdown at on change event.
My jQuery is working good on populating dynamic option of a select as well as at server-side when fetching the data, my only problem is when the form is submitted and validation fails, so basically the dynamic select option/s will reset.
Can somebody help me with this issue?
You have 2 options here:
1) You manually set the 2x select fields with CI and repopulate/set them. You would construct these based on the POST values that were incorrect.
Assuming that list A populates list B which populates list C you may not want to do that. In which case you could define some hidden variables such as this:
var field1 = '<?php $_POST['field1']; ?>';
var field2 = '<?php $_POST['field2']; ?>';
var field3 = '<?php $_POST['field3']; ?>';
$(document).ready(function(){
$('#field1').val(field1).trigger('change'); // or whatever on() query event you use
$('#field2').val(field1).trigger('change'); // or whatever on() query event you use
$('#field3').val(field1).trigger('change'); // or whatever on() query event you use
})
Might help? You would do the trigger to then load whichever lists/ajax calls populate each select box.
Yes it is possible,
this example works with Codeigniter 4 but I'm quite sure it works also with Codeigniter 3. Here I wanted to do a multiple dropdown field with Select2
<div class="form-group">
<label>Categories</label>
<?php
$parameters = array('class' => 'form-control select2_cat', "multiple" => "multiple");
$options = array();
foreach ($categories as $cat) {
$options[$cat['name']] = $cat['name'];
}
echo form_dropdown(
'categories[]',
$options,
set_value('categories[]') != "" ? set_value('categories[]') : 0,
$parameters
);
?>
</div>
You see from the code, I'm using set_value() . I'm checking also if set_value is empty string.
You could find more info here: https://www.py4u.net/discuss/37330

how construct route pattern for an unknown number of tags - Laravel & Conner/Taggable

I have a blog and a quotationfamous sayings repository on one site.
The quotations are tagged and the entries are tagged too.
I use this rtconner/laravel-tagging package.
Now, what I want to do is to display ALL Quotation models which share the same tags as article.
The Eloquent syntax is simple, as the original docs provide an example:
Article::withAnyTag(['Gardening','Cooking'])->get();
possible solution
Optional routing parameters. The asker-picked answer in this question gives a solution:
//in routes.php
Route::get('/{book?}/{chapter?}/{topic?}/{article?}', 'controller#func');
//in your controller
public function func($book = null, $chapter = null, $topic = null, $article = null) {
...
}
my problem
In my app the shared tags might count more than 3 or 5. I will soon get an example with even 10 tags. Possibly more
My question
Does it mean that I have to construct an URL with 10 optional routing parameters? Do I really need sth like this:
Route::get('quotations/tags/{tag1?}/{tag2?}/{tag3?}/{tag4?}/{tag5?}/{tag6?}/{tag7?}', 'controller#func');
my question rephrased
I could create a form with only a button visible, and in a hidden select field I could put all the tags. The route would be a POST type then and it would work. But this solution is not URL-based.
I think you could process the slashes, as data:
Route::get('quotations/tags/{tagsData?}', 'controller#func')
->where('tagsData', '(.*)');
Controller:
public function controller($tagsData = null)
{
if($tagsData)
{
//process
}
}
Ok, this is my solution. As I have a tagged model, I dont't need to iterate through tags in url to get the whole list of tags.
The enough is this:
// Routes file:
Route::get('quotations/all-tags-in/{itemtype}/{modelid}', 'QuotationsController#all_tagged_in_model');
Then in my controller:
public function all_tagged_in_topic($itemtype, $id) {
if($itemtype == 'topic') {
$tags = Topic::find($id)->tags->pluck('name')->all();
$topic = Topic::find($id);
}
if($itemtype == 'quotation') {
$tags = Quotation::find($id)->tags->pluck('name')->all();
$quotation = Quotation::find($id);
}
// dd($tags);
$object = Quotation::withAnyTag($tags)->paginate(100);;
And it is done.
Now, the last issue is to show tags in the URL.
TO do that, the URL should have an extra OPTIONAL parameter tags:
// Routes file:
Route::get('quotations/all-tags-in/{itemtype}/{modelid}/{tags?}', 'QuotationsController#all_tagged_in_model');
And in the {url?} part you can just write anything which won't break the pattern accepted by route definition.
In your view you might generate an URL like this:
// A button to show quotes with the same set of tags as the article
// generated by iteration through `$o->tags`
<?php
$manual_slug = 'tag1-tag2-tag3-tag4`;
?>
<a href="{{ URL::to('quotations/all-tags-in/article/'.$o->id.'/'.$manual_slug) }}" class="btn btn-danger btn-sm" target="_blank">
<i class="fa fa-tags icon"></i> Tagi:
</a>

Create google suggest effect with asp.net mvc and jquery

What I want to achieve, is not the autocomplete effect. What I want to achieve is that when you type on google the search results come up almost inmediately without cliking on a search button.
I already did the ajax example with a search button, but I would like it to make it work while you type it shows the results in a table.
The problem is I have no idea where to start.
EDIT: To ask it in another way.
Lets suppose I have a grid with 1000 names. The grid is already present on the page.
I have a textbox, that when typing must filter that grid using AJAX, no search button needed.
Thanks
Use a PartialView and jQuery.ajax.
$(document).ready(function () {
$("#INPUTID").bind("keypress", function () {
if($(this).val().length > 2) {
$.ajax({
url: "URL TO CONTROLLER ACTION",
type: "POST|GET",
data: {query: $("#INPUTID").val(),
success: function (data, responseStatus, jQXHR)
{
$("#WRAPPERDIVID").html(data);
}
});
}
});
});
Then in your view:
<div>
<input type="text" id="INPUTID" />
</div>
<div id="WRAPPERDIVID"></div>
Edit
Also, you could build in some sort of timer solution that submits the request after say 1 second of no typing, so you don't get a request on every key press event.
Theres a good example you can check here try to type 's' in the search
if thats what you want
then the code and the tutorial is here
another good example here
If you are working on "filtering" a set already located on the page, then you seem to want to set the visibility of the items in the list, based upon the search criteria.
If so, then first, you need to first establish your HTML for each item. You can use the following for each item:
<div class="grid">
<div class="item"><input type="text" value="{name goes here}" readonly="readonly" /></div>
{ 999 other rows }
</div>
Then, you must use some jquery to set each row visible/invisible based on the search criteria:
$("#searchBox").live("change", function () {
$("div[class='grid'] input").each(function () {
var search = $("#searchBox").val();
if ($(this).val().toString().indexOf(search) != -1)
$(this).parent().show();
else
$(this).parent().hide();
});
});
This will cause the visibility of each item to change, depending on whether or not the text in the search box matches any text in the item.

Help needed on running a MYSQL script in the background of a web page and taking different actions dependent on the result

I have a form on a web page, with one field to enter a code, to search for a property.
On clicking 'submit' I want to be able to run a script in the background without leaving the page.
The script will need to run a MYSQL statement which will have one of these results:
The property code does not exist, so display a Javascript Alert saying it does not exist.
The property is for sale, so call an existing javscript function 'saleSubmit(propertyCode)' to overwrite the exsiting web page with a new page sale.php for that property code
The property is for rent, so call an existing javscript function 'rentSubmit(propertyCode)' to overwrite the exsiting web page with a new page rent.php for that property code
The property is for sale and rent, so display 2 checkboxes within a div on the page to choose either the sales details or the rental details.
Can anybody point me in the right direction here?
Hi Nick - I think I screwed the system up a bit as I initially posted a question, then created an account which would not let me comment on the thread.
The status of the query is as simple as: does not exist, sale, rent, sale & rent
Extra advice would be really appreciated as I am problems googling for examples or a tutorial to point me in the right direction.
I first took this approach when I was looking at this problem to check that the form and Select statement were working correctly. So my form code looked like this:
<form name="idsearch" action="" method="post" onsubmit="xmlhttpPostForm('includes/idsearch-response.php', 'idsearch', 'idSearchResult', '<img src=\'images/loading.gif\'>'); return false;">
<input type="text" id="idRefNo" name="idRefNo" value="Enter Property Code" onfocus="this.value='';" />
GO <input type="image" src="img/template/search2.gif" alt="Click to Search for Properties"/>
and the php code called looked like this:
$idRefNo = $_POST['idRefNo'];
$query = "SELECT DISTINCT * FROM property WHERE property.Title = '".$idRefNo."' AND suspend != 'Yes'"; $result = #mysql_query ($query);
if ($result) { // If the query runs ok
if ($result != "") {
while ($row = mysql_fetch_array ($result, MYSQL_ASSOC)) {
if ($row["BaseRental"] > 0 AND $row["Saleprice"] > 0) {
echo 'This property is for RENT and for SALE <br/>';
} else if ($row["BaseRental"] > 0) {
echo 'This property is for RENT only <br/>';
} else if ($row["Saleprice"] > 0) {
echo 'This property is for SALE only <br/>';
} else {
echo 'DOH! What is going on here!!! <br/>';
}
}
As I said above I would appreciate it if you could point me in the right direction to achieve what I want to do at the beginning of this thread.
First of all let's differentiate between the page(client) and your mysql database(server). Your page will have to send some request to your server which triggers a script to query the database. The result of that query is returned as a response to your page.
You could send a request by using javascript and the xmlhttprequest or try jquery which offers very simple methods to make requests ($.ajax(...)).
Your server and the script which queries your db should then return some meaningful status back to your client which has to interprete the result: Doing alerts, showing your div or whatever you'd like to do. I suggest returning the response as json which can be directly used in javascript without any parsing hassle. If the status of your query as simple as: does not exist, sale, rent, sale & rent. You could go as far and encode those as plaintext numbers, no json needed.

Resources