slider

Undesired rc-slider onAfterChange Event

Tech: javascript, npm rc-slider, react

Challenge: The webapp designer choose to have both the rc-slider’s initial state (null), and the lowest actual value (1), be represented in the lowest/left-most node. If the User simply clicks the left-most node, the null value updates to 1 through the RcSlider onAfterChange API. The problem is whenever the next click occurs… anywhere on the page OR on any element… onAfterChange fires again, which is undesired!

Code:

The rc-slider is wrapped with a custom element. We want the rc-slider onAfterChange event to bubble up, so we pass down our “onClick” function. (Note: these elements & functions have been stripped for ease of explanation.)

onClick function:

onSliderClick = (factorIndex, value) => {

if (value === 0) {

this.props.sliderClickedFromDefault(factorIndex, 0)

}

}

React elements:

parent: <Slider onSliderClick={() => onSliderClick(factorIndex, value)} />

child: <RcSlider onAfterChange={onSliderClick} />

 

The initial click of the rc-slider works great! During troubleshooting, we capture the document.activeElement:

document_active_element_1

 

It is the second click, anywhere on the page OR on any element, that causes the issue. Here is the Redux Inspector Action Event Log:

react_log

 

After reading through known rc-slider issues, and speaking with the Great Google, I have not yet found a solid solution or explanation as to why this is happening. My workaround…

Let’s check the activeElement the second time onAfterChange fires. If it is not my desired element (the slider!), do not dispatch an action!

onSliderClick = (factorIndex, value) => {

const activeClass = document.activeElement.className

if (value === 0 && activeClass === 'rc-slider-handle rc-slider-handle-click-focused') {

this.props.sliderClickedFromDefault(factorIndex, 0)

}

}

 

Takeaway: I do not love this solution and am convinced something else is going on here. Although the workaround is effective, I am writing this post in hopes of coming back to it with a real solution & understanding.

 

References:

https://www.npmjs.com/package/rc-slider

Ruby => JS: Fill a New Array

Tech: javascript, ruby

Challenge: in a React app, I have to format some data coming from an API… I want to fill out the API data array to a certain length with empty strings. Coming from a Ruby background, I have grown very used to Ruby shortcuts. How do I tackle in JS?

Code:

incoming API data = ['string', 'string']

application needs an array with length 5… like ['string', 'string', "", "", ""]

 

In Ruby, I calculate the difference in lengths and create a new array with empty strings, contained within the .new args:

Array.new(5 - apiArray.length, "")

 

Javascript is just slightly different. Just need to combine new Array with an ES6 prototype!

new Array(5 - apiArray.length).fill("")

 

 

Reference:

https://ruby-doc.org/core-1.9.3/Array.html#method-i-fill

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill

 

App Launch! ==> College Football Pick ‘Em!

Concept: a friend facilitates an annual college football pick ’em pool based on game spreads. Each week, a 10-game slate is emailed out to participants. Participants text or email their picks, which are then entered into an elaborate excel spreadsheet for tracking… correct/incorrect picks, standings, tiebreaker game (specific game where participants choose total game pts), etc. Cumbersome process… but the participant pool has grown over the years… it’s fun and competitive. A perfect opportunity to convert the antiquated user experience, not to mention the administrative time, into a modern, web-based application. Let’s take a look.

 

Admin Menu:

shepic_admin_menus

 

Admin Add Game:

shepic_add_game

 

User Active Week Select:

user_select_game

 

User After Selection:

user_game_selected

 

User History:

shepic_user_history

 

User History, Specific Week with Results:

shepic_week_history

 

Standings:

shepic_standings

 

Stack:

 

Takeaway: I am particularly proud of this app. Most of my side projects are personal. This web app will have approximately 12 users weekly, and significantly increase the enjoyment of participating. Additionally, the base platform will allow growth for creative scoring options come college football playoffs… keeping all participants interested until the end, regardless of positional standing. 

 

Features/Posts Coming Soon:

  • Exporting weekly results for incorporation into sophisticated excel sheet (ie … facilitator can continue to publish & explore interesting trends from the excel sheet built up over the years)shepic_excel
  • Incorporating Raspberry Pi. Ruby script cron job runs to check if game has started. Participant can select winner right up to kickoff, a significant difference from past years!
  • Easter Egg
  • Stand Alone Migration (& Heroku Deployment)

Rails: JS Not Loading in Template?

Tech: Rails, Ruby, JavaScript

Challenge: when user initially logs in and navigates to page with HTML/AJAX post forms, JS file not properly loading. The page is a Rails template, and I suspect the jQuery events are not being implemented… thus when clicking to submit the form, an unknown route error is generated instead of a successful AJAX call. If the page is refreshed once navigated to, the listener events/AJAX run perfectly.

Solution: let’s ‘force’ load the JS file to ensure the jQuery listener events are active. I experienced a similar issue here, and that led to a very quick solution this time around. Only two lines of code:

At the top of the _template.html.erb file:

<%= javascript_include_tag('yourJsFile.js') %>

In /config/initializers/assets.rb:

Rails.application.config.assets.precompile += %w(yourJsFile.js )

 

Takeaway: this is the second time running into problems with Rails’ templates not loading code. Are these workarounds correct? Or is there a better ‘Rails’ way?

Reference:

https://stackoverflow.com/questions/18533969/how-to-load-a-javascript-file-to-rails-html-erb

 

job_bluth

Materialize-Sass: Disappearing Select Elements

Tech: Materialize-Sass, Rails, Ruby, JavaScript

Challenge: when rendering templates in a Rails view.html.erb, Material select elements display, then quickly disappear.

Code: lots of solutions found on this. Two examples used in other projects, but not this time!

Typical JS document ready:

$(document).ready(function() {

$(".dropdown-button").dropdown();

$('select').material_select();

});

 

Slight variation successfully used in converting an Access DB to an Oracle instance with Rails CRUD interface. (BTW, this is a backlog task as to why two calls to activate.)

var ready = function() {

$(".dropdown-button").dropdown();

$('select').material_select();

});

$(document).ready(ready);

$(document).on('page:load', ready);

 

After much troubleshooting, a lightbulb moment occurred. What if this has to do with a view loading, picking up the Material JS activation code, and then rendering a (sub) template? Maybe the template is not processing the JS activation. The below code, placed on each template containing Material select tags, did the trick.

script

$('select').material_select();

/script

{{ng2}} Relocating Public JS Files

Tech: Angular2, TypeScript, JavaScript

Challenge: the app directory quickly gets crowded with components, models, etc… especially with three versions of a file (.ts, .js, .js.map). Let’s tuck those JS files away, so the focus is strictly on the TypeScript files!

Code:

Need updates in 3 places. We will use a “deploy directory for the .js & .js.map files. Our baseDir in bs-config.json is “src“.

 

in src/systemjs.config.js:

System.config({

map: {

‘app’: ‘deploy/app’

}

})

 

in src/tsconfig.json

{ “compilerOptions”: {

“outDir”: “deploy”

}

}

 

and finally in src/index.html head:

<script>

System.import(‘/deploy/main.js’).catch();

</script>

 

Reference:

http://stackoverflow.com/questions/34034482/correct-approach-to-reference-typescript-compiled-files-using-outdir

JavaScript: HTML Element Animation

Tech: vanilla JavaScript

Challenge: animate the day blocks in the calendar when clicking an html link

animating_fade_outs_screenshot

 

Code:

Initially, I thought this would work. Iterate over the week row, then each block. Put a timeout in place to delay the looping on the day block.

animating_fade_outs_initial_attemptWhat actually happens is the JS for loop runs very quickly (obviously). When the timeout fires, 5 is outputted five times… The loop iterated 5 times, in less than a second, thus setting the variable i to 5. I also experimented with having the timeout inside the second loop. Either way, the desired effect wasn’t happening because the timeout wasn’t delaying the looping.

New solution… First, set a timeout to delay the clicked html link.

animating_fade_outs_link_delay

 

Second, use setInterval to roll through the rows/blocks.animating_fade_outs_animate_interval

 

Presto!

 

Here is the final JS:

animating_fade_outs_final_js

 

Reference:

Thanks again to AnimateCSS !

 

Kinvey API Console: Adding Users to Group

Tech: Kinvey, Angular2, JS

Problem: users in Kinvey data collection have field “isAdmin” for displaying Angular2 dynamic page elements. However, when a TRUE “isAdmin” user logs in, the proper elements are not displaying.

kinvey_api_ng2_ngif

 

Solution: admin users need to be added to the Kinvey group “admin” due to a postFetch hook.

kiney_api_postfetchhook

Since the users were not in the group “admin”, their field value for “isAdmin” was being overwritten to FALSE in the postFetch hook.

 

Code: let’s take a look at the Kinvey API Console.

GET /appdata/KINVEY_APP_KEY/ => returns high-level project data

GET /appdata/KINVEY_APP_KEY/project => returns data from collection “project”. Pass in a data-collection name here to see what’s available.

GET /group/KINVEY_APP_KEY/admin => returns data from the group admin. Referencing the above example, this was initially empty:

kinvey_api_no_group_found

 

Let’s create and add users to an Admin group.

POST /group/KINVEY_APP_KEY

{

“_id”: “admin”,

“users”: {

“all”: “false”,

“list”: [

{ “_type”: “KinveyRef”, “_collection”: “user”, “_id”: “########” },

{ “_type”: “KinveyRef”, “_collection”: “user”, “_id”: “########” }

]

},

“groups”: [

{“_type”: “KinveyRef”, “_collection”: “group”, “_id”: “G1”},

{“_type”: “KinveyRef”, “_collection”: “group”, “_id”: “G5”}

]

}

 

Reference Note: pretty strong resources online. The aim of this post is for my own reference in relation to solving a bug we were experiencing.

http://devcenter.kinvey.com/rest/guides/users#usergroups

Angular2 Firebase Connection

Tech: Angular2, Firebase, Javascript

Challenge: hook up ng2 web application to Google Firebase (read only for now)

Directions: although I got hung up a bit on the database.ref pathway, connecting was way easier than I imagined. I just followed the “For Web” guidelines… one of the easiest How-Tos I have ever implemented! Initialize a project, go to the overview and choose “Add Firebase to your webapp“… drop this code in the index.html file, and then… 

Code:

Add these scripts as needed to index.html:

screen-shot-2016-11-21-at-2-36-45-pm

 

And in the component:

coolhands_firebase_appcomponentjs

 

Reference:

https://firebase.google.com/docs/web/setup