How to create language selection wrapper from a gist script? - javascript

I have a Gist file written in different languages all do the same thing.
So, I would like to create a language select option similar to Google docs documentation.
Is it possible to create such a wrapper class that accepts a Gist script tag and display as above?
As in embed single file, I tried different query command like <script src="https://gist.github.com/gistid.js?language=python">, but none of them work.

This is the processing code that I ended up with.
With some CSS + javascript hide and toggle logic, it would work like google docs documentation.
I'd appreciate it if anyone updates this answer, with css or js.
import requests
from bs4 import BeautifulSoup
def render_gist_by_file(gist_id):
result = requests.get(f'https://gist.github.com/{gist_id}.js', headers=git_credential)
if result.text.startswith("<!DOCTYPE html>"):
return None
result = result.text
result = result.replace("\\/", "/").replace("\\&", "&").replace("\\$", "$").replace("\\<", "<").replace("\\`", "`").replace("\\n", "\n").replace('\\"', '"')
result = html.unescape(result)
result = result.split("document.write('")[-1][:-3]
bs = BeautifulSoup(result, "html.parser")
for tag in bs.find_all(class_="gist"):
file_box = tag.find(class_="file-box")
root = tag.find(class_="file-box")
toggle_div = bs.new_tag('div', attrs={"class": "gist-meta"})
for i, d in enumerate(tag.find_all(class_="file")):
d["class"] = f"file gist-toggle gist-id-{gist_id}"
if i != 0:
file_box.append(d) # combine to first table
for d in tag.find_all(class_="gist-meta"):
siblings = list(d.next_elements)
file_id, file_name = siblings[4].attrs["href"].split("#")[-1], siblings[5]
gist.file_names.append(file_name)
toggle_a = bs.new_tag('a', attrs={"id": file_id, "class": f"gist-toggle gist-id-{gist_id}", "onclick": f"toggle('gist-id-{gist_id}', '{file_id}')", "style": "padding: 0 18px"})
toggle_a.append(file_name)
toggle_div.append(toggle_a)
d.extract() # remove bottom nav
root.insert(0, toggle_div)
for d in islice(tag.find_all(class_="gist-file"), 1, None):
d.extract() # remove except first
gist.html = str(bs)
return gist

Related

How to add a download button using JavaScritp in Rmarkdown document

I am using BioCircosR to create circos plots. BioCircosR allows to save interactive plots as .hmtl files. However, I need to edit the generated plots in Illustrator to make a figure. I found a script on GitHub that would solve my problems by adding a SVG download button to the .hmtl output from BioCircosR. When I ran this Rmarkdown script with the example provided by the author the SVG button appears in the .hmtl file:
However, when I tried this solution with my own data the SVG button was not appended in the generated .hmtl:
I am thinking I could be doing something wrong in the JS script to add the SVG button. I do not have JS background and I just took it from the GitHub code and create a Rmarkdown document with my own data. Am I missing something from JS script? Is it necessary to add something in the SVG button code? I am sorry to ask you guys, but I posted some months ago a question on the script author GitHub page and I got no answers for this. My Rmarkdown code follows:
---
title: "BioCircos on Xtr and Bbu"
author: "Kaleb Gatto"
output:
html_document:
highlight: textmate
code_folding: show
theme: readable
---
```{r setup, echo=FALSE, message=FALSE}
require(knitr)
#turn off mesages and warnings and make it so output isn't prefixed by anything,
#default is to put "##" in front of all output for some reason
#also set tidy to true so code is wrapped properly
opts_chunk$set(message=FALSE, warning=FALSE, comment = "", cache = F)
options(width = 200)
```
```{js}
function addSvgSaveButtonJquery(buttonId, topSvg) {
$(buttonId).append("<a id=imgDownload></a>")
$(buttonId).click(function() {
var html = $(
$(topSvg).attr("version", 1.1)
.attr("xmlns","http://www.w3.org/2000/svg")).clone()
.wrap('<p/>').parent().html();
// add the svg information to a and then click it to trigger the
// download
var imgsrc = 'data:image/svg+xml;base64,' + btoa(html);
$(buttonId + " #imgDownload").attr("download", "graph.svg");
$(buttonId + " #imgDownload").attr("href", imgsrc);
var a = $(buttonId + " #imgDownload")[0];
a.click();
});
}
```
```{r, fig.width=10, fig.height=10}
library(BioCircos)
Xtr_Bbu_genomes <- list("Xtr1" = 217471166, "Xtr2" = 181034961, "Xtr3" = 153873357, "Xtr4" = 153961319, "Xtr5" = 164033575, "Xtr6" = 154486312, "Xtr7" = 133565930, "Xtr8" = 147241510, "Xtr9" = 91218944, "Xtr10" = 52432566, "Bbu1" = 843366180, "Bbu2" = 842558404, "Bbu3" = 707956555, "Bbu4" = 635713434, "Bbu5" = 567300182, "Bbu6" = 439630435, "Bbu7" = 236595445, "Bbu8" = 231667822, "Bbu9" = 230778867, "Bbu10" = 151572763, "Bbu11" = 103205957) # custom genome
links_chromosomes_01 <- c("Xtr1", "Xtr2", "Xtr3", "Xtr4", "Xtr4", "Xtr5", "Xtr6", "Xtr7", "Xtr7", "Xtr8", "Xtr8", "Xtr9", "Xtr10") # Chromosomes on which the links should start
links_chromosomes_02 <- c("Bbu2", "Bbu3", "Bbu1", "Bbu9", "Bbu10", "Bbu4", "Bbu5", "Bbu6", "Bbu1", "Bbu8", "Bbu3", "Bbu7", "Bbu6") # Chromosomes on which the links should end
links_pos_01 <- c(115060347, 102611974, 14761160, 128700431, 128681496, 42116205, 58890582, 40356090, 146935315, 136481944, 157464876, 39323393, 84752508, 136164354, 99573657, 102580613, 111139346, 120764772, 90748238, 122164776, 44933176, 18823342, 48771409, 128288229, 150613881, 18509106, 123913217, 51237349, 34237851, 53357604, 78270031, 25306417, 25320614, 94266153, 41447919, 28810876, 2802465, 45583472, 81968637, 27858237, 17263637, 30569409) ### links Xtr chromosomes
links_pos_02 <- c(410543481, 463189512, 825903588, 353914638, 354135472, 717707494, 643107332, 724899652, 583713545, 558756961, 642015290, 154999098, 340216235, 557731577, 643350872, 655077847, 85356666, 157889318, 226411560, 161566470, 109857786, 25338955, 473876792, 124495704, 46258030, 572314729, 141584107, 426419779, 531245660, 220131772, 353941099, 62422773, 62387030, 116923325, 76544045, 33452274, 7942164, 642047816, 215981114, 39278129, 23302654, 418922633) ### links Bbu chromosomes
tracklist = BioCircosLinkTrack('myLinkTrack', links_chromosomes_01, links_pos_01, links_pos_01, links_chromosomes_02, links_pos_02, links_pos_02, maxRadius = 1, labels = links_labels)
BioCircos(tracklist, genome = Xtr_Bbu_genomes, elementID = "Xtr_Bbu_circos_plot", genomeFillColor = "RdBu", chrPad = 0.05, displayGenomeBorder = FALSE)
```
```{js}
$("#myXtr_Bbu_circos_plot").append("<button id=save_svg>Save As Svg</button>");
//Give the selectors for button and svg element to download
addSvgSaveButtonJquery("#save_svg", "#myXtr_Bbu_circos_plot svg");
```
Knit render of my own data plot follows:
processing file: Teste_01.Rmd
|............ | 17%
ordinary text without R code
|....................... | 33%
label: setup (with options)
List of 2
$ echo : logi FALSE
$ message: logi FALSE
|................................... | 50%
label: unnamed-chunk-1 (with options)
List of 1
$ engine: chr "js"
Carregando pacotes exigidos: knitr
|............................................... | 67%
ordinary text without R code
|.......................................................... | 83%
label: unnamed-chunk-2 (with options)
List of 3
$ tidy : logi TRUE
$ fig.width : num 10
$ fig.height: num 10
|......................................................................| 100%
label: unnamed-chunk-3 (with options)
List of 1
$ engine: chr "js"
output file: Teste_01.knit.md
"C:/Program Files/RStudio/bin/quarto/bin/tools/pandoc" +RTS -K512m -RTS Teste_01.knit.md --to html4 --from markdown+autolink_bare_uris+tex_math_single_backslash --output Teste_01.html --lua-filter "D:\Users\kaleb\Documents\R\win-library\4.1\rmarkdown\rmarkdown\lua\pagebreak.lua" --lua-filter "D:\Users\kaleb\Documents\R\win-library\4.1\rmarkdown\rmarkdown\lua\latex-div.lua" --self-contained --variable bs3=TRUE --standalone --section-divs --template "D:\Users\kaleb\Documents\R\win-library\4.1\rmarkdown\rmd\h\default.html" --no-highlight --variable highlightjs=1 --variable theme=readable --mathjax --variable "mathjax-url=https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" --include-in-header "C:\Users\User\AppData\Local\Temp\RtmpyeD9Tl\rmarkdown-str3d8c45467.html" --variable code_folding=show --variable code_menu=1
[WARNING] Deprecated: --self-contained. use --embed-resources --standalone
Output created: Teste_01.html
Warning message:
package 'BioCircos' was built under R version 4.1.2
sessionInfo()
R version 4.1.1 (2021-08-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19043)
Matrix products: default
locale:
[1] LC_COLLATE=Portuguese_Brazil.1252 LC_CTYPE=Portuguese_Brazil.1252 LC_MONETARY=Portuguese_Brazil.1252
[4] LC_NUMERIC=C LC_TIME=Portuguese_Brazil.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] knitr_1.38 BioCircos_0.3.4
loaded via a namespace (and not attached):
[1] Rcpp_1.0.9 digest_0.6.29 plyr_1.8.7 jsonlite_1.8.0 evaluate_0.15 rlang_1.0.5
[7] cli_3.2.0 rstudioapi_0.13 rmarkdown_2.13 RColorBrewer_1.1-3 tools_4.1.1 htmlwidgets_1.5.4
[13] xfun_0.30 yaml_2.3.5 fastmap_1.1.0 compiler_4.1.1 htmltools_0.5.2
You'll laugh at this one (hopefully!):
You need to address the comments above, and also need to change elementID to elementId.
---
title: "BioCircos on Xtr and Bbu"
author: "Kaleb Gatto"
output:
html_document:
highlight: textmate
code_folding: show
theme: readable
---
```{r setup, echo=FALSE, message=FALSE}
require(knitr)
#turn off mesages and warnings and make it so output isn't prefixed by anything,
#default is to put "##" in front of all output for some reason
#also set tidy to true so code is wrapped properly
opts_chunk$set(message=FALSE, warning=FALSE, comment = "", cache = F)
options(width = 200)
```
```{js}
function addSvgSaveButtonJquery(buttonId, topSvg) {
$(buttonId).append("<a id=imgDownload></a>")
$(buttonId).click(function() {
var html = $(
$(topSvg).attr("version", 1.1)
.attr("xmlns","http://www.w3.org/2000/svg")).clone()
.wrap('<p/>').parent().html();
// add the svg information to a and then click it to trigger the
// download
var imgsrc = 'data:image/svg+xml;base64,' + btoa(html);
$(buttonId + " #imgDownload").attr("download", "graph.svg");
$(buttonId + " #imgDownload").attr("href", imgsrc);
var a = $(buttonId + " #imgDownload")[0];
a.click();
});
}
```
```{r, fig.width=10, fig.height=10}
library(BioCircos)
Xtr_Bbu_genomes <- list("Xtr1" = 217471166, "Xtr2" = 181034961, "Xtr3" = 153873357, "Xtr4" = 153961319, "Xtr5" = 164033575, "Xtr6" = 154486312, "Xtr7" = 133565930, "Xtr8" = 147241510, "Xtr9" = 91218944, "Xtr10" = 52432566, "Bbu1" = 843366180, "Bbu2" = 842558404, "Bbu3" = 707956555, "Bbu4" = 635713434, "Bbu5" = 567300182, "Bbu6" = 439630435, "Bbu7" = 236595445, "Bbu8" = 231667822, "Bbu9" = 230778867, "Bbu10" = 151572763, "Bbu11" = 103205957) # custom genome
links_chromosomes_01 <- c("Xtr1", "Xtr2", "Xtr3", "Xtr4", "Xtr4", "Xtr5", "Xtr6", "Xtr7", "Xtr7", "Xtr8", "Xtr8", "Xtr9", "Xtr10") # Chromosomes on which the links should start
links_chromosomes_02 <- c("Bbu2", "Bbu3", "Bbu1", "Bbu9", "Bbu10", "Bbu4", "Bbu5", "Bbu6", "Bbu1", "Bbu8", "Bbu3", "Bbu7", "Bbu6") # Chromosomes on which the links should end
links_pos_01 <- c(115060347, 102611974, 14761160, 128700431, 128681496, 42116205, 58890582, 40356090, 146935315, 136481944, 157464876, 39323393, 84752508, 136164354, 99573657, 102580613, 111139346, 120764772, 90748238, 122164776, 44933176, 18823342, 48771409, 128288229, 150613881, 18509106, 123913217, 51237349, 34237851, 53357604, 78270031, 25306417, 25320614, 94266153, 41447919, 28810876, 2802465, 45583472, 81968637, 27858237, 17263637, 30569409) ### links Xtr chromosomes
links_pos_02 <- c(410543481, 463189512, 825903588, 353914638, 354135472, 717707494, 643107332, 724899652, 583713545, 558756961, 642015290, 154999098, 340216235, 557731577, 643350872, 655077847, 85356666, 157889318, 226411560, 161566470, 109857786, 25338955, 473876792, 124495704, 46258030, 572314729, 141584107, 426419779, 531245660, 220131772, 353941099, 62422773, 62387030, 116923325, 76544045, 33452274, 7942164, 642047816, 215981114, 39278129, 23302654, 418922633) ### links Bbu chromosomes
tracklist = BioCircosLinkTrack('myLinkTrack', links_chromosomes_01, links_pos_01, links_pos_01, links_chromosomes_02, links_pos_02, links_pos_02, maxRadius = 1)
BioCircos(tracklist, genome = Xtr_Bbu_genomes, elementId = "Xtr_Bbu_circos_plot", genomeFillColor = "RdBu", chrPad = 0.05, displayGenomeBorder = FALSE)
```
```{js}
$("#Xtr_Bbu_circos_plot").append("<button id=save_svg>Save As Svg</button>");
//Give the selectors for button and svg element to download
addSvgSaveButtonJquery("#save_svg", "#Xtr_Bbu_circos_plot svg");
```

Kendo UI - Set parameter programmatically

# var myVar = false; #
<div>
#(Html.Kendo().Stepper()
.Name("stepper")
.Orientation(StepperOrientationType.Horizontal)
.Label(true)
.Indicator(true)
.Steps(s =>
{
s.Add().Label("Step_1");
s.Add().Label("Step_2").Selected(true);
s.Add().Label("Step_3");
})
.ToClientTemplate())
</div>
The above sets Step_2 to be the selected one.
How do I set it programmatically?
e.g. s.Add().Label("Step_2").Selected(myVar);
You are messing languages layers. myVar is Javascript and its inside a template, Html.Kendo()... is c#, so you CAN'T mix them. You have to change it outside the template.
What I would do is something like this:
<div id="stepper-container" data-step="#= myVar #">
Then after the template was rendered, I would use Javascript to change that:
let stepperIndex = $('#stepper-container').data('step');
$('#stepper').data('kendoStepper').select(stepperIndex);

trigger javascript function based on python variable value

The following 2 js functions can toggle a button to and from the disabled class. I want the disabled state to depend on the global variable filelength in the python code but cannot think of a simple way to do so. The only way I can think of is to have 2 identical but separate templates, one with the button disabled and one with it enabled.
<script type="text/javascript" language="JavaScript">
function enableButton(button){
document.getElementById(button).removeAttribute('class');
document.getElementById(button).setAttribute("class", "button");
}
function disableButton(button){
document.getElementById(button).setAttribute("class", "disabled");
}
</script>
I intended to use the functions for the following index.html template element.
<button id="Test" class="button disabled" >
Test
</button>
The intended toggling would produce the following alt.html template element which elides the "disabled".
<button id="Test" class="button" >
Test
</button>
It seems silly to require 2 separate templates (index.html and alt.html) to accomplish this toggle, but I cannot think of an alternative that permits me to just alter index.html. Initially I thought jinja2 would provide the functionality needed, but that does not seem correct.
How can I accomplish this without a second template using python and GAE?
For more completeness, below I show the relevant state of my python application next.
import os
import jinja2
import webapp2
import urllib
filelength = 0
class MainPage(BaseHandler):
def get(self):
global filelength
logging.info("text length in Main get: %s " % filelength)
template_values = {'filelength':filelength}
template = JINJA_ENVIRONMENT.get_template('index.html')
self.response.out.write(template.render(template_values))
def post(self):
global filelength
url = self.request.get('URL', None)
text = urllib.urlopen(url).read()
logging.info("text length in Main post: %s " % len(text))
filelength = len(text)
if filelength > 0:
return webapp2.redirect('/alt')
else:
return webapp2.redirect('/')
class AltMainPage(BaseHandler):
def get(self):
global filelength
logging.info("text length in Alt get: %s " % filelength)
template_values = {'filelength':filelength}
template = JINJA_ENVIRONMENT.get_template('alt.html')
self.response.out.write(template.render(template_values))
def post(self):
global filelength
url = self.request.get('URL', None)
text = urllib.urlopen(url).read()
logging.info("text length in Alt post: %s " % len(text))
if filelength > 0:
return webapp2.redirect('/alt')
else:
return webapp2.redirect('/')
return webapp2.redirect('/')
app = webapp2.WSGIApplication([
('/', MainPage),
('/alt', AltMainPage),
],
debug=True)
In the template index.html simply use jinja2 to define the class attribute like this where the value of buttonclass is defined as either button or button disabled in python using the "if ... else" construct.
<button id="Test" class="{{ buttonclass }} " >
Test
</button>

How do I avoid data from different tabs to be concatenated in one cell when I scrape a table?

I scraped this page https://www.capfriendly.com/teams/bruins, specifically looking for the tables under the tab Cap Hit (Fowards, Defense, GoalTenders).
I used Python and BeautifulSoup4 and CSV as the output format.
import requests, bs4
r = requests.get('https://www.capfriendly.com/teams/bruins')
soup = bs4.BeautifulSoup(r.text, 'lxml')
table = soup.find(id="team")
with open("csvfile.csv", "w", newline='') as team_data:
for tr in table('tr', class_=['odd', 'even']): # get all tr whose class is odd or even
row = [td.text for td in tr('td')] # extract td's text
writer = csv.writer(team_data)
writer.writerow(row)
This is the output that I get:
['Krejci, David "A"', 'NMC', 'C', 'NHL', '30', '$7,250,000$7,250,000NMC', '$7,250,000$7,500,000NMC', '$7,250,000$7,500,000NMC', '$7,250,000$7,000,000Modified NTC', '$7,250,000$7,000,000Modified NTC', 'UFA', '']
['Bergeron, Patrice "A"', 'NMC', 'C', 'NHL', '31', '$6,875,000$8,750,000NMC', '$6,875,000$8,750,000NMC', '$6,875,000$6,875,000$6,000,000NMC', '$6,875,000$4,375,000$3,500,000NMC', '$6,875,000$4,375,000$1,000,000Modified NTC, NMC', '$6,875,000$4,375,000$1,000,000Modified NTC, NMC', 'UFA']
['Backes, David', 'NMC', 'C, RW', 'NHL', '32', '$6,000,000$8,000,000$3,000,000NMC', '$6,000,000$8,000,000$3,000,000NMC', '$6,000,000$6,000,000$3,000,000NMC', '$6,000,000$4,000,000$3,000,000Modified NTC', '$6,000,000$4,000,000$1,000,000Modified NTC', 'UFA', '']
['Marchand, Brad', 'M-NTC', 'LW', 'NHL', '28', '$4,500,000$5,000,000Modified NTC', '$6,125,000$8,000,000$4,000,000NMC', '$6,125,000$8,000,000$3,000,000NMC', '$6,125,000$7,500,000$4,000,000NMC', '$6,125,000$5,000,000$1,000,000NMC', '$6,125,000$6,500,000$4,000,000NMC', '$6,125,000$5,000,000$3,000,000Modified NTC']
As you can see data from different tabs is concatenated together:
'$7,250,000$7,000,000Modified NTC'
Somebody advised me to use javascript to scrape the table and that it should solve my problem?
Based on the source code, this is some text in specific rows that is conditionally visible depending on what tab you're on (as your title states). The class .hide is added to the child element in the td when it is intended to be hidden on that specific tab.
When you're parsing the td elements to retreive the text, you could filter out those elements which are suppose to be hidden. In doing so, you can retrieve the text that would be visible as if you were viewing the page in a web browser.
In the snippet below, I added a parse_td function which filters out the children span elements with a class of hide. From there, the corresponding text is returned.
import requests, bs4, csv
r = requests.get('https://www.capfriendly.com/teams/bruins')
soup = bs4.BeautifulSoup(r.text, 'lxml')
table = soup.find(id="team")
with open("csvfile.csv", "w", newline='') as team_data:
def parse_td(td):
filtered_data = [tag.text for tag in td.find_all('span', recursive=False)
if 'hide' not in tag.attrs['class']]
return filtered_data[0] if filtered_data else td.text;
for tr in table('tr', class_=['odd', 'even']):
row = [parse_td(td) for td in tr('td')]
writer = csv.writer(team_data)
writer.writerow(row)

Mandatory slider in oTree/django

I want to use oTree as an alternative for conducting experiments. For this purpose I am looking for a possibility to include mandatory slider questions in forms, i. e. sliders you are required to move before you are able to proceed to the next question. As a start I tried to modify oTrees survey template to achieve a solution for future usage but wasn't able to integrate common approaches like a fieldtracker into the project.
Here are two modified (yet currently after a number of unsuccessful try-outs not really functioning) versions of the models.py and views.py files which give a hint in which direction I want to go. Is there a way to get this to work?
# -*- coding: utf-8 -*-
## models.py
# <standard imports>
from __future__ import division
from django.db import models
from django_countries.fields import CountryField
from model_utils import FieldTracker,
from otree import widgets
from otree.constants import BaseConstants
from otree.db import models
from otree.models import BaseSubsession, BaseGroup, BasePlayer
class Constants(BaseConstants):
name_in_url = 'survey'
players_per_group = None
num_rounds = 1
class Subsession(BaseSubsession):
pass
class Group(BaseGroup):
pass
class Player(BasePlayer):
def set_payoff(self):
"""Calculate payoff, which is zero for the survey"""
self.payoff = 0
q_country = CountryField(
verbose_name='What is your country of citizenship?')
q_age = IntegerFielder(verbose_name='What is your age?',
min=13, max=125,
initial=25,
widget=widgets.SliderInput())
q_gender = models.CharField(initial=None,
choices=['Male', 'Female'],
verbose_name='What is your gender?',
widget=widgets.RadioSelect())
tracker = FieldTracker()
crt_bat = models.PositiveIntegerField()
crt_widget = models.PositiveIntegerField()
crt_lake = models.PositiveIntegerField()
Here comes the second file:
# -*- coding: utf-8 -*-
##views.py
from __future__ import division
from . import models
from ._builtin import Page, WaitPage
from otree.common import Currency as c, currency_range
from .models import Constants, integerfieldcustom
class Demographics(Page):
form_model = models.Player
form_fields = ['q_country',
'q_age',
'q_gender']
check_age = q_age.tracker.has_changed()
def q_age_error_message(self, ):
if Demographics.check_age == False:
return 'You must move the slider before you can continue'
class CognitiveReflectionTest(Page):
form_model = models.Player
form_fields = ['crt_bat',
'crt_widget',
'crt_lake']
def before_next_page(self):
self.player.set_payoff()
page_sequence = [
Demographics,
CognitiveReflectionTest
]
Thanks in advance!
There are two ways of doing it: by using JS only, on the client's side, and by using Django at the server side.
The simple JS solution:
in the template add:
{% block scripts %}
<script>
var SliderTouched = false;
var selector = $('[data-slider] input[type="range"]');
selector.change(function() {
SliderTouched = true;
});
$( ".form" ).submit(function( event ) {
if (!SliderTouched){
event.preventDefault();}
});
</script>
{% endblock %}
So until the user triggers change event, the SliderTOuched var is set to False which prevents a form to be submitted. It is a compact way, but you have to deal with showing an error message to the user yourself.
=================
The longer server-side solution is the following:
in models.py define an additional field:
class Player(BasePlayer):
checkslider = models.IntegerField(blank=True)
in views.py in addition to your slider field pass also this extra field that will check that the slider was changed:
class MyPage(Page):
form_model = models.Player
form_fields = ['q_age', 'checkslider']
def checkslider_error_message(self, value):
if not value:
return 'Please make your decision using slider'
in template insert this hidden extra field to html:
<input type="hidden" name="checkslider" value="" id="id_checkslider"/>
and set this field to current slider value as soon as slider is changed:
{% block scripts %}
<script>
var selector = $('[data-slider] input[type="range"]');
selector.change(function() {
$('#id_checkslider').val(selector.val());
});
</script>
{% endblock %}
By default, Django assumes an input is required.
I think that means if you just remove the initial value, it will self-validate.
Also, you called something named "IntegerFielder()." Did you mean models.IntegerField() or is there an import that we're not seeing?
I suggest a slight modification to Philipp's answer.
The code above still triggers the error message if the participant touches the slider, but returns the slider to the default starting position.
To fix this, I used the following script:
{% block scripts %}
<script>
$('input[name=q_age]').on('input', function(){
$('#id_checkslider').val(1);
});
</script>
{% endblock %}
The code changes checkslider from None to 1 when the slider is touched, even if the participant sets the slider to the default starting position.

Categories

Resources