Sliders as Inputs

The character Snarf from Thundercats rubbing its hands.

Origin Story

There once was a worksheet that was meant to be used in a face-to-face scenario. The goal was indicate where you fell on a spectrum across a number cultural orientation of measures. The challenge was to transform that into something digital that could then be part of a larger conversations.

Watch the video above to get an idea of what the experience is like or this will make even less sense.

The Sliders

I like sliders as interface elements for things like these.1 You can see the HTML below that builds them or check out the Codepen for more CSS etc. That’s all pretty straight forward.

<div class="slider-container">
<div class="slide-label left">Direct Communication</div>
<div class="slide-label right">Indirect Communication</div>
<input id="directness" class="slider" max="100" min="0" type="range" value="50" />
</div>

I did have to add the input tag to the KSES allowed list to keep WordPress from stripping it out. To do that I added the following to our KSES modifier file.

$allowedposttags["input"] = array(
 "type" => array(),
 "range" => array(),
 "min" => array(),
 "max" => array(),
 "value" => array(),
 "id" => array(),
 "class" => array(),
);

Getting the Values

Now I needed some javascript to look at these sliders and record the values as the sliders were . . . slid in various directions. This little bit gets our values once we loop through the sliders that exist. Simple.

function sliderAmount(slider){
	 sliderValue = slider.value;
	return sliderValue;
}

Gravity Forms Integration

I did this via Gravity Forms because it’s fast and I’m overly comfortable with it. This is where things get a bit weird. We’re using a typical Gravity Forms to post scenario. Nothing odd there but I ended up building a shortcode to let me build the post content which is not as typical.

The javascript below is looking for our form and then writing various variables to the fields (which are hidden by CSS). The shortcode ends up looking like [dih-graph scores=”50,50,50,50,50″] with the 50s being replaced by whatever scores are recorded.

if (document.getElementById('gform_wrapper_6'))//change for prod
{
	let values = [50,50,50,50,50];
	let sliders = Array.from(document.getElementsByClassName('slider'));
	let field = document.getElementById('input_6_4');
	let title = document.getElementById('input_6_1');	
	sliders.forEach(function(slider, index) {
		slider.oninput = function (){				
				values[index] = sliderAmount(slider);
				field.value = '[dih-graph scores="'+values.join(',')+'"]';
				title.value = values.join('/');
		}

	})
}

The Shortcode

The shortcode is pretty ugly but it works. It loops through the data provided and generates the necessary HTML.

function dih_grapher_sc( $atts ) {
	$a = shortcode_atts( array(
		'scores' => '1,2,3,4,5',
	), $atts );
    $graphs = '';
    $lefts = ['Direct Communication','Monochronic','Low Power Distance','Individualism','Task Focus'];
    $rights = ['Indirect Communication','Polychronic','High Power Distance','Collectivism','Relationship Focus'];
    $scores = explode(",", $a['scores']);
    foreach ($scores as $key => $score) {
	   $graphs .= graph_builder($score, $lefts[$key], $rights[$key]);
	}
	
	return $graphs;
}
add_shortcode( 'dih-graph', 'dih_grapher_sc' );

function graph_builder($score, $left, $right){
	return '<div class="slider-container">
<div class="slide-label left">'.$left.'</div>
<div class="slide-label right">'.$right.'</div>
<p><input type="range" min="0" max="100" value="'.$score.'" class="slider" id="directness">
</p></div>';

}

Now because Gravity Forms kept insisting on running filters I didn’t want on the content, I just stuck the data in a custom post field and then appended it to the post via a filter. That seems weird now that I write it but whatever.

function filterPostForTBL($content){
    global $post;	
	if (get_post_meta( $post->ID, 'tbl_score', true )){
	  return $content . get_post_meta( $post->ID, 'tbl_score', true ) . get_post_meta($post->ID, 'discussion-prompt', true);
	} else {
		return $content;
	}
}

add_filter( 'the_content', 'filterPostForTBL');

Scroll to Entries

With our entries showing up on the same page as the form, I wanted to make sure that the person was redirected back to where they’d see other people’s entries. I did this by adding an id to the confirmation message and adding a bit of javascript to scroll to that ID.


function scrollToThanks(){
	console.log('scroll ran')
	if(document.getElementById("thanks")){
		console.log('scroll found thanks')
	  let thanks = document.getElementById("thanks");
	  let topThanks = thanks.offsetTop;
	  window.scrollTo({
		  top: topThanks,
		  left: 0,
		  behavior: 'smooth'
		});
	}
}

var callback = function(){
  // Handler when the DOM is fully loaded
  scrollToThanks();
};

if (
    document.readyState === "complete" ||
    (document.readyState !== "loading" && !document.documentElement.doScroll)
) {
  callback();
} else {
  document.addEventListener("DOMContentLoaded", callback);
}

2 thoughts on “Sliders as Inputs

Comments are closed.