Implement Table Sorting In Badgeyay

In this blog post I am going to explain about implementation of inplace table sorting in badgeyay. This is not about just adding the sortable class as described in the semantic docs, but the data inside the table has different characteristics and needs to be sorted in a different manner. Not like the traditional way of comparing strings as it will not be suitable for dates. For creating a custom comparison function for sorting, either we can implement a custom comparator using JQuery or we can use the data values for comparison. The latter option is more preferable as it can be extended  to different columns in the table. Procedure Adding the sortable class in the table, which needs to be sorted. <table class="ui sortable table">   . . . </table>   We need to enable a javascript function when DOM completely gets loaded. <script type="text/javascript">  $('table').tablesort(); </script>   After this we need to create a template helper to return us the time stamp from the UTC formatted DateTime string. The value that will be returned by the helper will be used as the data value for the column entries. import { helper } from '@ember/component/helper'; export function extractTimeStamp(date) { return Math.floor((new Date(date)).getTime() / 100); } export default helper(extractTimeStamp);   The value that will be returned by the helper will be used as data value for comparison by table sorter. <td data-sort-value={{extract-time-stamp user.created_at}}>{{sanitizeDate user.created_at}}</td>   Now we need that certain columns do not sort, as there is no need. Such columns are photoURL, actions etc. These columns should be ignored by the sorter for sorting, so we will add a class to avoid sorting of these columns. <th class="no-sort">User Photo</th> Resources Semantic UI table class - Link Data sorting in the table API - Link Pull Request for the same - Link Template helper guide ember - Link

Continue ReadingImplement Table Sorting In Badgeyay

Sorting Photos in Phimpme Android

The Phimpme Android application features a fully fledged gallery interface with an option to switch to all photos mode, albums mode and to sort photos according to various sort actions. Sorting photos via various options helps the user to get to the desired photo immediately without having to scroll down till the end in case it is the last photo in the list generated automatically by scanning the phone for images using the Android’s mediaStore class. In this tutorial, I will be discussing how we achieved the sorting option in the Phimpme application with the help of some code snippets. To sort the all photos list, first of all we need a list of all the photos by scanning the phone using the media scanner class via the code snippet provided below: uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;       String[] projection = {MediaStore.MediaColumns.DATA};       cursor = activity.getContentResolver().query(uri, projection, null, null, null); In the above code we are using a cursor to point to each photos and then we are extracting the path of the images and storing it in a list using a while loop. After we generate the list of path of all the images, we have to convert the into a list of media using the file path using the code below: for (String path : listOfAllImages) {           list.add(new Media(new File(path)));       }       return list;   } After generating the list of all images we can sort the photos using the Android’s collection class. In Phimpme Android we provide the option to sort photos in different categories namely: Name Sort action Date Sort action Size Sort action Numeric Sort action As sorting is somewhat heavy task so doing this in the main thread will result in freezing UI of the application so we have to put this into an AsyncTask with a progress dialog to sort the photos. After putting the above four options in the menu options. We can define an Asynctask to load the images and in the onPreExecute method of the AsyncTask, we are displaying the progress dialog to the user to depict that the sorting process is going on as depicted in the code snippet below AlertDialog.Builder progressDialog = new AlertDialog.Builder(LFMainActivity.this, getDialogStyle()); dialog = AlertDialogsHelper.getProgressDialog(LFMainActivity.this, progressDialog,       getString(R.string.loading_numeric), all_photos ? getString(R.string.loading_numeric_all) : getAlbum().getName()); dialog.show(); In the doInBackgroundMethod of the AsyncTask, we are sorting the list of all photos using the Android’s collection class and using the static sort method defined in that class which takes the list of all the media files as a parameter and the MediaComparator which takes the sorting mode as the first parameter and the sorting order as the second. The sorting order decides whether to arrange the list in ascending or in descending order. getAlbum().setDefaultSortingMode(getApplicationContext(), NUMERIC); Collections.sort(listAll, MediaComparators.getComparator(getAlbum().settings.getSortingMode(), getAlbum().settings.getSortingOrder())); After sorting, we have to update the data set to reflect the changes of the list in the UI. This we are doing in the onPostExecute method of the AsyncTask after dismissing the progress Dialog to avoid the window leaks in the application. You can read more about…

Continue ReadingSorting Photos in Phimpme Android

Sorting Events in Open Event Organizer Android App

While working on Open Event Organizer project, we had to display events in a single list in custom order with proper sub headings. Initially, we were thinking of using tabbed activity and showing events in respective tabs. But the thing with tabs is that it requires you to nest fragments and then each of them will have adapters. Also, we have used Model View Presenter pattern in the project, so this is another reason we did not use view pager as it would increase the number of presenter and view classes for the same feature. So we decided to display events in a single list instead. The custom order decided was that events would be divided into three categories - live, upcoming and past. In each category, a recent event will be at the top of another. Adding SubHeadings support to the Recycler View So the first thing was adding subheading support to the recycler view. We have used timehop's sticky header decorators library for subheadings implementation. First, your adapter should implement the interface StickyRecyclerHeadersAdapter provided by the library. In our case the implemented methods look like: @Override public long getHeaderId(int position) { Event event = events.get(position); return DateService.getEventStatus(event).hashCode(); } @Override public EventsHeaderViewHolder onCreateHeaderViewHolder(ViewGroup viewGroup) { return new EventsHeaderViewHolder(EventSubheaderLayoutBinding.inflate(LayoutInflater.from(viewGroup.getContext()), viewGroup, false)); } @Override public void onBindHeaderViewHolder(EventsHeaderViewHolder holder, int position) { Event event = events.get(position); holder.bindHeader(DateService.getEventStatus(event)); } @Override public int getItemCount() { return events.size(); }   The first one is getHeaderId which returns a unique id for a group of items which should appear under a single subheading. In this case, DateService.getEventStatus returns status of an event (either live, past or upcoming) and so hashcode of it is returned as a unique id for that header. OnCreateHeaderViewHolder is same as onCreateViewHolder of your adapter. Return your header view here. Similarly in onBindViewHolder, bind data to the header. getItemCount returns total number of items. Sorting Events The important thing to do was sorting events in the order decided. We had to implement the Comparable interface to Event model which will compare any two events using our custom rules such that after sorting we get events in the order - Live, Upcoming and Past with recent one at the top in each category. The compareTo method of Event model looks like: public int compareTo(@NonNull Event otherEvent) { Date now = new Date(); try { Date startDate = DateUtils.getDate(getStartTime()); Date endDate = DateUtils.getDate(getEndTime()); Date otherStartDate = DateUtils.getDate(otherEvent.getStartTime()); Date otherEndDate = DateUtils.getDate(otherEvent.getEndTime()); if (endDate.before(now) || otherEndDate.before(now)) { // one of them is past and other can be past or live or upcoming return endDate.after(otherEndDate) ? -1 : 1; } else { if (startDate.after(now) || otherStartDate.after(now)) { // one of them is upcoming other can be upcoming or live return startDate.before(otherStartDate) ? -1 : 1; } else { // both are live return startDate.after(otherStartDate) ? -1 : 1; } } } catch (ParseException e) { e.printStackTrace(); } return 1; }   The compareTo method returns a positive integer value for greater than, the negative integer value…

Continue ReadingSorting Events in Open Event Organizer Android App