Link to home
Start Free TrialLog in
Avatar of emi_sastra
emi_sastra

asked on

Format date column laravel

Hi All,

I have below code.



 public function getAvailableDates($format = 'M Y'){
        return $this->getAllDates()->map(function($tgl) use($format){
            $tanggal = new \Carbon\Carbon($tgl);
            return $tanggal->format($format);
        });
    }


May I know what does it mean?

I try below code.


public function getAllDatesForFilter()
    {
        $tanggal = \DB::table('datamaster')
        ->select(\DB::raw("Month"))
            ->groupBy('Month')
            ->orderBy('Month')        
            ->get();      

        $format = 'M Y';
       
                // $tanggal = new \Carbon\Carbon($tgl);

                $month = $tanggal->format($format);    

        return $month->pluck('Month');        
    }


Anything wrong ?

Thank you.
ASKER CERTIFIED SOLUTION
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of emi_sastra
emi_sastra

ASKER

Hi Christ,


    public function getAllDatesForFilter()
    {
        $tanggal = \DB::table('ERV_SP_Fill_List_Date')
        ->select(\DB::raw("Month"))
            ->groupBy('Month')
            ->orderBy('Month')        
            ->get();      

        $format = 'M Y';      

         $month = $tanggal->format($format);    

        return $month->pluck('Month');        
    }

User generated image
The problem is that the list just show 6 months.

Thank you.
What do you mean 'the list shows 6 months' - there's clearly 16 months showing !
At the SSMS is show 16 months.
But at the laravel form it show only six months.

User generated image

The first 6 months exactly.

Thank you.

Even though I sort those data descending. It still shows the first 6 months ascending.

User generated imageThank you.
I use this.

public function getAllDatesForFilter()
    {
        $tanggal = \DB::table('ERV_SP_Fill_List_Date');    

        $format = 'M Y';      

         $month = $tanggal->format($format);    

        return $month->pluck('Month');        
    }

Is there anything to clear, like cache and etc?

Thank you.

Right OK.

There a two distinct moving parts to your application - data retrieval and data presentation. Your function is responsible for the data retrieval. It connects to the database and runs a query. You receive some data, you format it into a nice list and then you pass it on. That's the end of that functions responsibility in this case.

That data, once it's been retrieved from Laravel is passed into your View for presentation. It's up to that View how the data is presented, so it's free to sort it in whatever order it likes. It's free to trim the list down to only show 6 results instead of the full set. Basically, it can do whatever it likes with the data. The fact that you're only seeing 6 records in ascending order tells me that your View is manipulating the data. If this is pure Laravel, then this will happen inside a Blade Template (resources/views folder). If you're using VueJS Components, then the manipulation will happen inside the source code for the Component.

The code you want for your function should probably look like this:

public function getAllDatesForFilter(Request $request)
{
    $dates = DB::table('datamaster')
        ->select(DB::raw("Month"))
        ->groupBy('Month')
        ->orderBy('Month')
        ->pluck('Month');

    return $dates->map(function ($date) {
        $newDate = new \Carbon\Carbon($date);
        return $newDate->format("M Y");
    });
}

Open in new window

Once you've identified which part of your code is responsible for the Presentation, you'll likely find out why you're only getting 6 results displayed in ascending order.

By all means, post up the source for that and I'll be happy to take a look.
The fact that you've written that function is not enough - you need to make sure your View (Blade or Component is actually calling it). You'd need to make sure you have a route set up to it and that the View is making the correct call to that route).

I'd be very surprised if that code you've just posted actually works. The fact that you haven't reported any errors tells me that it's never being called. Look at your View and see exactly how it's getting it's data (what route it's calling) and what controller method (or closure) that route is using.
- By all means, post up the source for that and I'll be happy to take a look.                                  
I can not find the presentation source code, how could I find it ? What to search ?

Thank you.

- I'd be very surprised if that code you've just posted actually works.
The function get called, I made error in coding then it will show error at running time.

Thank you.

Route::any('filter-dates', [DashboardController::class, 'getAllDatesForFilter'])->name('filterDates');

 <filter-component url="{{ route('admin.filters') }}"  url-dates="{{ route('admin.filterDates') }}"></filter-component>

 public function getAllDatesForFilter()

Thank you.


OK. That function you've just posted up has errors in it so it won't run.

Because I don't know your app, I can't tell you specifically where to find the View files. Like I say - if it's purely a Laravel application, then the view files are usually stored in a folder called resources/views, and they usually end in blade.php.

If however you're using VueJS Components, then you'll need to look in the src folder for your VueJS app. Normally, components are stored in a components folder, but you could have sub-folders within that (admin / customer / orders etc).

If you can't track it down, then you'll need to start from the URL that you use to view the page. Look in your browser at the URL, and then match that URL to a registered route - that will tell you where the page is being called from. Follow that and it will lead you to the correct place eventually.
Right,

So the view you're looking for is a VueJS component called filter-component. Maybe in a file called FilterComponent.js under the Vue src folder.
User generated image
@php
    $request = request();
    $sortDefault = true;
    if($request->has('sort'))
        $sortDefault = false;
@endphp
<div class="dropdown">
    <button class="btn btn-outline dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
        <strong>Sort by</strong>@if (isset($sortByLabel))
            : {{$sortByLabel}} {{ $order != 'desc' ? '↓' : '↑' }}
        @endif
    </button>
    <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
        @foreach ($sorts as $sort)
            <a class="dropdown-item 
                @if($sortDefault && isset($sort['is_default']) && @$sort['is_default'] != 'desc')
                    active
                @endif 
                @if($request->input('sort') ==  $sort['field'] && $request->input('order') != 'desc') 
                    active 
                @endif" 
                href="{{ $request->fullUrlWithQuery(['sort' => $sort['field']]) }}">{{$sort['label']}} ↓</a>
            <a class="dropdown-item 
                @if($sortDefault && isset($sort['is_default']) && @$sort['is_default'] == 'desc') 
                    active 
                @endif
                @if($request->input('sort') ==  $sort['field'] && $request->input('order') == 'desc')
                    active
                @endif" href="{{ $request->fullUrlWithQuery(['sort' => $sort['field'], 'order' => 'desc']) }}">{{$sort['label']}} ↑</a>
        @endforeach
    </div>
</div>&nbsp;
<button type="button" class="btn btn-info"  data-toggle="collapse" data-target="#filterCollapse" aria-expanded="false" aria-controls="filterCollapse">
    <i class="fas fa-filter">
        @if (count(@$filters) > 0)
            <span class="icn-dot"></span>
        @endif
    </i><!-- /.fas fa-filter -->
</button><!-- /.btn btn-default -->


No - that's not it. It's a VueJS file - not a Laravel Blade file.
{{ html()->modelForm($filters, 'POST')->class('form-horizontal')->open() }}
    <div class="row">
        <div class="col">
            <div class="form-group">
                {{ html()->text('q')
                    ->placeholder('Search Store Name')
                    ->class('form-control') }}
            </div><!-- /.form-group -->
            <div class="row">
                <div class="col" style="max-width: 700px">
                    <div class="input-group">
                        {{ html()->select('start', $months)
                            ->class('form-control') }}
                        <div class="input-group-prepend input-group-append">
                            <span class="input-group-text">to</span>
                        </div>
                        {{ html()->select('end', $months)
                            ->class('form-control') }}
                    </div><!-- /.input-group -->
                </div><!-- /.col-md-6 -->
            </div><!-- /.row -->
            
            <div class="mt-2 text-right">
                <button 
                    type="submit" 
                    name="submit"
                    id="submit"
                    class="btn btn-success">Filter</button>&nbsp;
                <input 
                    type="submit" 
                    value="Reset"
                    name="clear"
                    id="clear"
                    class="btn btn-secondary">
            </div><!-- /.mt-2 -->
        </div><!-- /.col-md-6 -->
    </div><!-- /.row -->
{{ html()->closeModelForm() }}


<div id="filters" class="flex-grow-1 pb-4" style="position: relative">
            {{-- <filter-component url="{{ route('admin.filters') }}"  url-dates="{{ route('admin.dates') }}"></filter-component> --}}
            <filter-component url="{{ route('admin.filters') }}"  url-dates="{{ route('admin.filterDates') }}"></filter-component>
        </div>

Route::any('filter-dates', [DashboardController::class, 'getAllDatesForFilter'])->name('filterDates');

Is the problem reside at filters  ?

Thank you.
<div id="filters" class="flex-grow-1 pb-4" style="position: relative">
Is the problem reside at  id = "filters"  ?

Thank you.

User generated image
How could I know the name of those dropdown list?

Thank you.
Right.

Look at this code:

<filter-component url="{{ route('admin.filters') }}"  url-dates="{{ route('admin.filterDates') }}"></filter-component>

That code looks very much like a VueJS component, NOT a Laravel one. You're passing in the route to your new function as a property called url-dates. Within that component, it will make a call to that route to retrieve the data. Once it's retrieved the data, it will probably manipulate it before displaying it. If you want to know how it's being manipulated before being displayed, your need to look inside the source code for that component. It's probably in a file called FilterComponent.vue.

Do you know where the source files are for your VueJS application?
The names of those dropdowns will be defined INSIDE your Vue Component. Everything in that ScreenShot from the title, to the dropdowns, to the buttons, will be contained inside the Componenet. What happens when you click on the buttons will be defined in that Component. How the data is sorted and displayed will be defined inside that Component. It's a self-contained component - you pass in a URL and then everything else that happens is handled inside of it. You need the source code of that component if you want to know what's going on.
OK. I've just had a look at one of my Laravel apps to see how the Vue Components are integrated. It amy be different on your based on the version of Laravel you're running, but take a look in your resources/js/components folder. That's the default location for Vue components within Laravel.

You might also want to take a look at the the js/app.js file as that's where the components get registered. You should find a registration in there for your filter-component pointing to the source file that's used:

Vue.component('filter-component', require(...))
You might also want to take a look at the the js/app.js file as that's where the components get registered.

 import '@coreui/coreui'
import { store } from './store/store';

const files = require.context('./components/', true, /\.vue$/i);
files.keys().map(key => {
    Vue.component(key.split('/').pop().split('.')[0], files(key).default);
});

const app = new Vue({
    el: '#app',
    store,
});

How about it?

Thank you.
The store.js file

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export const store = new Vuex.Store({
    state: {
        nama: '',
        dimension: [],
        overall: [],
        gkam: [],
        region: [],
        passingGrade: [],
        bottom5partner: [],
        top5partner: [],
        bottom5store: [],
        top5store: [],
    },
    mutations: {
        change(state, nama){
            state.nama = nama;
        },
        updateDimension(state, data){
            state.dimension = data.map((val, index) => {
                if(index > 0)
                    val[0] = val[0].substring(2).trim().replace(/\s/g, "\n");
                return val;
            });
        },
        updateOverall(state, data){
            state.overall = data;
        },
        updateGkam(state, data){
            state.gkam = data;
        },
        updateRegion(state, data){
            state.region = data;
        },
        updatePassingGrade(state, data){
            state.passingGrade = data;
        },
        updateBottom5partner(state, data){
            state.bottom5partner = data;
        },
        updateTop5partner(state, data){
            state.top5partner = data;
        },
        updateBottom5store(state, data){
            state.bottom5store = data;
        },
        updateTop5store(state, data){
            state.top5store = data;
        },
    },
    getters: {
        nama: state => state.nama,
        dimensionData: state => state.dimension,
        dimensionCategory: state => {
            const items = state.dimension.filter((d, k) => k == 0);
            return items[0] ? items[0].filter((d, k) => k > 0) : [];
        },
        overallData: state => state.overall,
        overallCategory: state => {
            return state.overall.filter((d, k) => k > 0).map(d => d[0]);
        },
        gkamData: state => state.gkam,
        gkamCategory: state => {
            const items = state.gkam.filter((d, k) => k == 0);
            return items[0] ? items[0].filter((d, k) => k > 0) : [];
        },
        regionData: state => state.region,
        regionCategory: state => {
            const items = state.region.filter((d, k) => k == 0);
            return items[0] ? items[0].filter((d, k) => k > 0) : [];
        },
        passingGradeData: state => state.passingGrade,
        bottom5partnerData: state => state.bottom5partner,
        top5partnerData: state => state.top5partner,
        bottom5storeData: state => state.bottom5store,
        top5storeData: state => state.top5store,
    }
});
OK. This line here:

const files = require.context('./components/', true, /\.vue$/i);

Is telling your app to look for components in the /resources/js/components folder. It will search that folder (and any subfolders) for files ending in .vue and register them as components. Yours is going to be called FilterComponent.vue (it could be called filter-component.vue but that's less likely).

Find that file !
Still can not find the the from and to date filter form.

Thank you.


/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */

import '../bootstrap';
import '../plugins';

/**
 * The following block of code may be used to automatically register your
 * Vue components. It will recursively scan this directory for the Vue
 * components and automatically register them with their "basename".
 *
 * Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
 */

// const files = require.context('./', true, /\.vue$/i);
// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default));

Vue.component('example-component', require('./components/ExampleComponent.vue').default);

/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

const app = new Vue({
    el: '#app',
});
What file is that??

It looks like the default app.js file, but the code you previously posted from app.js looks different! Where was that from ?

Go into your resources/js folder and look through every Vue file. Show me a screenshot of that folder with it's content.
Do me a file dump of everything in your resources/js folder. Go to a command prompt and navigate to the resources/js folder. Once there, run the following:

dir /s /b > files.txt

When done, post up the content of the files.txt file here.
D:\MorriganDashboard\resources\js\backend
D:\MorriganDashboard\resources\js\bootstrap.js
D:\MorriganDashboard\resources\js\files.txt
D:\MorriganDashboard\resources\js\frontend
D:\MorriganDashboard\resources\js\plugins.js
D:\MorriganDashboard\resources\js\backend\after.js
D:\MorriganDashboard\resources\js\backend\app.js
D:\MorriganDashboard\resources\js\backend\before.js
D:\MorriganDashboard\resources\js\backend\components
D:\MorriganDashboard\resources\js\backend\store
D:\MorriganDashboard\resources\js\backend\store\store.js
D:\MorriganDashboard\resources\js\frontend\app.js
D:\MorriganDashboard\resources\js\frontend\components
D:\MorriganDashboard\resources\js\frontend\components\ExampleComponent.vue


Right. It's not there !!

I'm really struggling to find a way to help you. Unfortunately, you don't really know how your application is built, so I'm left guessing and working blind !

Here's how these things usually work. Your application needs to use some VueJS components. In order to do that, the source code of these components is created. This source code is then compiled into a .js file and that js file is included in your page (<script src="....js">). Then you can include those components in your HTML, such as <filter-component>

If you don't have access to those source files, or you don't know where to find them, then unfortunately you're going be stuck with what you've got as you'll have no way of changing the behaviour of your components. I'm guessing you didn't write this application, so it must have come from somewhere. Is it possible that you've just not been given all the relevant files. Is it possible that your source files for your Vue app are stored somewhere else on your computer. have you tried doing a full system-wide search for .vue files.

Really clutching at straws here, but I don't know what else to suggest
Hi Christ,

I have all the source code.  

Thank you.
- I have all the source code.  
The application is running well.

Thank you.
This is filter function get called from route.

public function filters(Request $request){
        $fields = [
            'BranchCode',
            'NameStore',
            'SESSEP',
            'ARTI',
            'ARCO',
            'EROS',
            'RSM',
            'ClusterSize',
            'Channel',
            'ASM',
            'GKAMRSM',
            'ASMKAM',
            'Partner',
            'Location',
            'City',
            'Region',
            'Date',
        ];
        $inputs = collect($request->input('filters'))->only($fields);
        $filters = $this->getFilters();
        if($inputs->count() > 0){
            foreach($inputs as $key=>$inp){
                $filters[$key] = $inp;
               
            }
            if(isset($filters['Date'])){
                $from = date('M Y', strtotime($filters['Date'][0]));
                $to = date('M Y', strtotime($filters['Date'][1]));
                if(strtotime($to) < strtotime($from) || strtotime($from) > strtotime($to))
                    $to = $from;
                $filters['Date'] = [$from, $to];
            }
            session(['filters' => $filters]);
            // return $filters;
        }
        $from = date('Y-m-d', strtotime($filters['Date'][0]));
        $to = date('Y-m-d', strtotime($filters['Date'][1]));
        $all_data = \DB::table('datamaster')
            ->distinct()
            ->select(array_slice($fields, 0, -1));
        $filtered_data = \DB::table('datamaster')
            ->distinct()
            ->select(array_slice($fields, 0, -1));
       
        foreach ($filters as $key => $value) {
             
                if($key != 'Date' && is_array($value) && count($value) > 0)
                    $filtered_data->whereIn($key, $value);
        }
        $user = auth()->user();
        if(!$user->can('view all store data')){
            $all_data->whereIn('BranchCode', $user->tokos->pluck('BranchCode'));
            $filtered_data->whereIn('BranchCode', $user->tokos->pluck('BranchCode'));
        }
        $all_data = $all_data->get();
        // dd($all_data);
        $filtered_data = $filtered_data->get();
        $all_filters = [];
        $filtered_filters = [];
        $selected = $filters;
        $filter_rules = $this->filterDataAffecteds();
        foreach($fields as $f){
            if($f != 'Date'){
                $dt = $all_data->pluck($f)->unique();
                $dt2 = $filtered_data->pluck($f)->unique();
               
                    $all_filters[$f] = array_values($dt->toArray());
                    $filtered_filters[$f] = array_values($dt2->toArray());
            }
        }
        $af = $this->affectedFilters();
        foreach($selected as $key => $filt){
             
            if(isset($af[$key]) && count($selected[$key]) > 0){
                foreach ($af[$key] as $filter ) {
                    $all_filters[$filter] = $filtered_filters[$filter];
                    // dump($filter);
                }
            }
        }
        // dd('a');
        return compact('all_filters', 'selected', 'filter_rules');
    }

I just want to know which code that fill the drop down list date filter.

Thank you.
Hey Emi,

I can't really help you any more. I've told you several time where to find the code that populates the dropdowns, but you can't find the source file that you need to. If you can't find the file, then you can't edit it.

These dropdowns are populated because your Vue component makes a call to your admin.filterDates route. How it actually populates the dropdowns is hidden inside the source code for the filter-component. If you want to see how that's done, then you need to open up the file that contains the source code for the component - which you can't find!

Do a full search of your computer for ALL files ending in .vue and see what you get.
Hi Christ,

I have search all of them, but really can not find it.

- I can't really help you any more.
Thank you any way.

Hmmm. It does sound like you've got chuncks of the source code to your application missing, which means there will be parts of it that you just can't edit.
- It does sound like you've got chuncks of the source code to your application missing,
What is chuncks of the source code, such as ?

Thank you
The Vue Components - you don't seem to have the source code for the <filter-component>, so you can't edit it. If you can't edit it, you can't see how the dropdowns are populated. If you can't see how they're populated, then you can't see why you only get 6 dates sorted ascending.
If I don't have the source then why it running well ?

Thank you.
Because with Vue Components, you only need to Source Files while you're developing, and if you need to change something. You then run a build tool to convert those Source Files into a Compiled JS File which you then use in your browser - you have the compiled file, which is why it's running. You don't have the Soure Files, which is why you can't edit or change them.
- You then run a build tool to convert those Source Files into a Compiled JS File
I see, so Vue could be compile ? Into what extension ? Where it should be reside?

Thank you.
User generated image
Is this the compiled file ?

Could we do something about it? Could we reverse engineering it?

Thank you.

If you look at your current application. Look in the resources/js/frontend folder. You'll see an app.js file that loads up a Component. When you run the build tool (Laravel Mix by default), it creates a compiled Javascript file (called app.js by default) and puts it in the public/js folder. This file contains all the code needed to use the components in your webpages.
Yes - that is the compiled file - this is created as a result of running a build tool against your source code.

Reverse engineering it would be a nightmare and I wouldn't recommend it.

Can you not get the proper source files from whoever wrote the application in the first place?
- Can you not get the proper source files from whoever wrote the application in the first place?                                  
The programmer is no longer wants to support.

He wants a lot of money for it.

Thank you.
Then it is compiled, the vue.js is just a view form ?
Because we do not change the screen format, then it should be no problem ?

Thank you.

If you're happy with the way everything is working, then you don't need the source files.

If you need to change the way something looks or behaves, or fix any bugs, then you'll need the source files.
- If you're happy with the way everything is working, then you don't need the source files.
                                   
I mean the screen format is okay, but need to change the data in it.
In my case is the data for the dropdown list.will be called from other function.

Without the source code, could we know from controller which part of the view that hold the data?

Thank you.
OK. We've gone over this a few times now, so this is the last time I'm going to cover it:

Look at this:

<filter-component url="{{ route('admin.filters') }}"  url-dates="{{ route('admin.filterDates') }}"></filter-component>

That is a Vue component. You're passing in 2 URLS for it to use (admin.filters and admin.filterDates). You can change what those URLs do by editing the method on your controller, but you have NO CONTROL over how that data is used INSIDE the component, because you DON'T have the source code. The Component will ask for data from the URL. Once it gets that data, you can't do anything with it - it's up to the component how it uses - which you can't change
-<filter-component url="{{ route('admin.filters') }}"  url-dates="{{ route('admin.filterDates') }}"></filter-component>
Let's say I still want to use the same controller, but I want to change the code inside the controller that show the drop down list of date. How could I know which of codes that fill the data into the vue js component?

Thank you.

You'll have to guess. I would suspect that you need to change the Controller Method that the admin.filterDates points to ... but if you change it, you need to make sure that the Method ONLY returns a list of dates.
Hi Christ,

I know the problem why it show just 6 months, nothing related to the view form.
I use stored procedure to show data. The problem it is not refresh after I change the SP.
How could I solve this ?

Thank you.

  public function getAllDatesForFilter()
    {
        $tanggal = \DB::table('ERV_SP_Fill_List_Date_Test');    

        $format = 'M Y';      

         $month = $tanggal->format($format);    

        return $month->pluck('Month');        
    }

I try to delete the SP : ERV_SP_Fill_List_Date_Test. But the application does not show error.

Thank you.

I don't know.

Try creating a new SP and run that instead. See what happens
How to clear it to make the new source code take effect ?

Thank you.
What do you mean by new source code?
I mean if I change some code or add new function to a file.
How to make application laravel refresh ?

Usually using php artisa cache:clear. Any other command to use?

Thank you.
Normally, if you're just changing Laravel functions, you don't need to refresh.

Sometimes you may need dto rebuild the autoloaders:

composer dump-autoload

Open in new window


I think we've probably now finished with this question. It started out as a question about formatting a date column but we've strayed far away from that. You'll get better answers if you open other specific questions and stay on-topic for each one.
- I think we've probably now finished with this question.
Yes, thank you very much for your help.