Drag and drop a task with FullCalendar.js in symfony project - javascript

I am trying to implement a drag and drop using FullCalendar.js.
I saw in documentation to enable option editable to true for moving event but this don't work.
On the render, you can see my task, i just want to move my task to monday (for exemple).
Do you have suggestion for where error come from ?
Or an issue ?
Thanks !
this is my code
{% extends 'base.html.twig' %}
{% block title %}Calendrier{% endblock %}
{% block body %}
<div>
<a class="btn btn-secondary" href="{{ path('home') }}">
<i class="fas fa-long-arrow-alt-left"></i> Retour</a>
</div>
<div class="row mt-5">
{% if is_granted("ROLE_MANAGER") %}
<div class="col d-flex my-3 justify-content-end">
{{ form_start (form, {'attr': {'class': 'd-flex'}}) }}
{{ form_widget(form.technicien, {'attr': {'class': 'd-inline me-2'}}) }}
{{ form_widget(form.techniciens, {'attr': {'class': 'd-none'}}) }}
<input id="submitBtn" class="btn btn-success d-inline" type="submit" value="Filtrer">
{{ form_end(form) }}
</div>
{% endif %}
<div class="col-12">
<div id="calendar" class="d-flex justify-content-center">
<div class="spinner-border" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
</div>
</div>
</div>
{{ include('loading_spinner.html.twig') }}
<script>
var mainRole = '{{mainRole}}';
if(mainRole == 'MANAGER') {
var idTechniciens = '{{partnerTechniciens}}';
var idTechniensArray = idTechniciens.split(' ');
var technicienSelect = $('#ticket_intervention_user_technicien');
var options = $('#ticket_intervention_user_technicien option');
var optionsToHide = $.map(options ,function(option) {
var extra = new Array();
if(!idTechniensArray.includes(option.value)) {
extra.push(option);
}
return extra;
});
optionsToHide.forEach(function(option) {
option.style.display = 'none'; });
}
</script>
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script src='fullcalendar/main.js'></script>
<script>
window.onload = () => {
calendar('#calendar', {
'events': {{ data|raw }},
'enventStartEditable': true,
'editable': true,
//'eventResizableFromStart': true,
'nowIndicator': true,
eventDidMount: function(info) {
let tooltip = new bootstrap.Tooltip(info.el, {
title: ('Client : ' + info.event.extendedProps.description),
placement: 'top',
trigger: 'hover',
container: 'body'
});
}
});
}
</script>
{% endblock %}
This is the render of my calendar:
in my app.js :
import { calendar } from "./full-calendar";
global.calendar = calendar;
How can i do it ?

ok i change the render with the documentation and it's work
window.onload = () => {
let calendarElt = document.querySelector("#calendar")
let calendar = new FullCalendar.Calendar(calendarElt, {
initialView: 'timeGridWeek',
locale: 'fr',
timeZone: 'Europe/Paris',
headerToolbar: {
start: 'prev,next today',
center: 'title',
end: 'dayGridMonth,timeGridWeek'
},
events: {{ data|raw }},
editable: true,
nowIndicator: true,
eventResizableFromStart: true,
eventDidMount: function(info) {
let tooltip = new bootstrap.Tooltip(info.el, {
//title: ('Client : ' + info.event.extendedProps.description),
placement: 'top',
trigger: 'hover',
container: 'body'
});
}
})

Related

Javascript doesn't execute when the html is called by a hx-get

I have the following html's that i load in a Django app:
pie_chart.html
{% load i18n %}
<div id="chartcontainer" >
<div style= "width: 400px;" "height: 400px;">
<canvas id="pie-chart"></canvas>
<b>Balance: </b> {{balance}}<br>
</div>
<div>
<h5>Detail group:
<select name="group" id="group"
hx-get="groupdetail/"
hx-trigger="click changed delay:1s"
hx-target="#groupchart"
hx-include="[name='year']"
hx-swap="innerHTML"
>}
{% for l in labels %}
{% if l == groupcode %}
<option value={{l}} selected>{{l}}</option>
{% else %}
<option value={{l}}>{{l}}</option>
{% endif %}
{% endfor %}
</select>
</h5>
</div>
<div id=groupchart>
{% include 'bar_chart.html' %}
</div>
</div>
<script>
var config_pie = {
type: 'pie',
data: {
datasets: [{
data: {{ data|safe }},
backgroundColor: {{ backgroundcolor|safe }},
label: 'Amount_EUR',
}],
labels: {{ labels|safe }}
},
options: {
responsive: true
}
};
var ctx_pie = document.getElementById('pie-chart').getContext('2d');
window.myPie = new Chart(ctx_pie, config_pie);
</script>
bar_chart.html
{% load i18n %}
<div>
<div style= "width: 400px;" "height: 400px;">
<canvas id="group-chart"></canvas>
<b>Balance: </b> {{groupbalance|safe}} <br>
<p id="data"> her should com the config_bar var</p>
</div>
</div>
<script>
var config_bar = {
type: 'bar',
data: {
datasets: [{
data: {{ groupdata|safe }},
backgroundColor: {{ backgroundcolor|safe }},
label: 'Amount_EUR',
}],
labels: {{ grouplabels|safe }}
},
options: {
indexAxis: 'y',
responsive: true
}
};
var ctx_bar = document.getElementById('group-chart').getContext('2d');
window.myBar = new Chart(ctx_bar, config_bar);
document.getElementById("data").innerHTML = config_bar;
</script>
When the bar_chart.html is called by the {% include 'bar_chart.html' %}, the script is executed and the chart is properly displayed.
When the bar_chart.html is called by the Django view called with hx-get="groupdetail/", the script is not executed. The html is displayed, but the graph is not build, because the script is not executing.
Already 2 days now I'm breaking my head on this and searching internet for an answer.
If someone could tell me why this is happening, it would be great.
I tried to put the html that has to be replace in and without , change hx-swap="innerHTML" for hx-swap="outerHTML", but nothing changes.
I found what the problem was. When loading the 'bar_chart.html' with hx-get I didn't define the 'backgroundcolor' variable. This missing variable blocked the execution of the script.
I will also look further how I can use the suggestion made by 'mariodev'.
Thanks for the suggestion.

How to make available the keyboard on a Otree application for cellular

I adapted a IAT (Implicit Association Task), I used this for an experiment using computers,but now I need to implement this IAT on tablets or cellulars,
This is how the IAT looks in a celullar:
The people get stuck on this screen, because they can't use the keyboard in their celullar to press E, I or SPACE. Someone can give an idea of how to make this works.
I have the next code in the models.
class Constants(BaseConstants):
name_in_url = 'iat'
players_per_group = None
LEFT, RIGHT = iat_order.LEFT, iat_order.RIGHT
FIRST, SECOND = iat_order.LEFT, iat_order.RIGHT
num_rounds = len(default_iat_blocks.iat_block_list)
LEFT_KEYCODE = 69
LEFT_KEY_NAME = '"E" (Presione E)'
RIGHT_KEYCODE = 73
RIGHT_KEY_NAME = '"I" (Presione I)'
META_KEYCODE = 32
META_KEY_NAME = 'Barra de Espacio'
OR = " o"
And this is the code that configure the keypresses.
const is_key_valid = (keycode) => {
return keycode === left_keycode || keycode === right_keycode;
};
const mark_wrong = () => {
$(".wrong_answer_mark").show();
};
const is_correct = (pressed_side, correct_side) => {
return (pressed_side === correct_side);
};
const which_side = (keycode) => {
if (keycode === left_keycode) return side['left'];
else if (keycode === right_keycode) return side['right'];
else return undefined;
};
This is my template
% extends "global/Page.html" %}
{% load otree static %}
{% block title %}
{% endblock %}
{% block app_scripts %}
<script>
/*
All variables which take their values from django tag should be placed here
with ES5 format. I.e., use var rather than let or const.
*/
var round_number = {{ subsession.round_number }};
var iat_items = {{ iat_items|json }};
var correct_sides = {{ correct_sides|json }};
var side = {
'left': {{ Constants.LEFT }},
'right': {{ Constants.RIGHT }},
};
var left_keycode = {{ Constants.LEFT_KEYCODE }};
var right_keycode = {{ Constants.RIGHT_KEYCODE }};
var category = {
'main': {
'left': {{ left_main_category|json }},
'right': {{ right_main_category|json }},
},
'sub': {
'left': {{ left_sub_category|json }},
'right': {{ right_sub_category|json }},
}
};
var main_items = {{ main_items|json }}
var sub_items = {{ sub_items|json }}
var META_KEYCODE = {{ Constants.META_KEYCODE }}
var left_category_name = {{ left_category_name|json }};
var right_category_name = {{ right_category_name|json }};
var current_item;
</script>
<script src="{% static 'iat/lib/iat.js' %}?{{ seed_for_refresh_js_cache }}"></script>
{% endblock %}
{% block content %}
<div class="container">
{# <div class="row" id="progress"> </div>#}
<div class="row" id="mainbox">
<div class = "col-lg-6 col-md-6 col-sm-6 col-xs-6"
style="" id="left_panel">
<h2 id = "left_key">
{{ Constants.LEFT_KEY_NAME }}
</h2>
<div id = "left_category">
{% if left_main_category %}
<h1 class="keyword main">
{{ left_main_category|safe|escape }}
</h1>
{% if left_sub_category %}
<h4>o</h4>
<h1 class="keyword sub">
{{ left_sub_category|safe|escape }}
</h1>
{% endif %}
{% elif left_sub_category %}
<h1 class="keyword sub">
{{ left_sub_category|safe|escape }}
</h1>
{% endif %}
</div>
</div>
<div class = "col-lg-6 col-md-6 col-sm-6 col-xs-6" id="right_panel">
<h2 id = "right_key">
{{ Constants.RIGHT_KEY_NAME }}
</h2>
<h1 id = "right_category">
{% if right_main_category %}
<h1 class="keyword main">
{{ right_main_category|safe|escape }}
</h1>
{% if right_sub_category %}
<h4>o</h4>
<h1 class="keyword sub">
{{ right_sub_category|safe|escape }}
</h1>
{% endif %}
{% elif right_sub_category %}
<h1 class="keyword sub">
{{ right_sub_category|safe|escape }}
</h1>
{% endif %}
</h1>
</div>
</div>
<div class="row">
<div class="wrong_key_box col-lg-12 col-md-12 col-sm-12 col-xs-12">
Tipeaste la letra equivocada! <br>
En la izquierda. <span class="emph">{{ Constants.LEFT_KEY_NAME }}</span>,
En la derecha. <span class='emph'>{{ Constants.RIGHT_KEY_NAME }}</span> Presiona la tecla!
</div>
</div>
<div class="row_keyword">
<div id="keyword">
Cargando... Por favor espera.
</div>
</div>
<div class="next_block_box">
Buen trabajo oprime <span class="emph">{{ Constants.META_KEY_NAME }}</span> para continuar
</div>
</div>
<div class="wrong_answer_mark">×</div>
<form id="form">
<input type="hidden" name="category_table" id="category_table">
<input type="hidden" name="item_table" id="item_table">
<input type="hidden" name="keypress_table" id="keypress_table">
<input type="hidden" name="iat_table" id="iat_table">
</form>
{% endblock %}
Thanks in advance
What about adding a visible input field outside of the viewport ?
$('body').append("<input type='text' id='dummy'>");
$("#dummy").css({"position":"fixed","left":"120%"});
Then set a touch event as follows
$(document).on("touchstart",
() => $(document).find("#dummy").focus()
)
?
To summarize, put this
$( document ).ready(function() {
$('body').append("<input type='text' id='dummy'>");
$("#dummy").css({"position":"fixed","left":"120%"});
$(document).on("touchstart",
() => $(document).find("#dummy").focus()
)
});
here :
<script src="{% static 'iat/lib/iat.js' %}?{{ seed_for_refresh_js_cache }}"></script>
/* HERE */
{% endblock %}

Highcharts in Django using ajax

I am new to Django. I am making polls application and want to use highcharts to display graphs. I have a template which displays all the polls. I want to show the corresponding results of poll beside it in form of chart. Part of the template:
{% for question in poll_questions %}
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-body">
<div class="row">
<div class="col-sm-12">
{{question.question_text}}
{% for choice in question.poll_choices_set.all %}
<div>
<label><input type="radio" name="{{question.pk}}" value="{{ choice.pk }}">&nbsp {{choice.choice_text}}</label>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-6">
<div id="{{ question.pk }}" class="chart" style="height: 400px; width: 400px"></div><br>
<script>
var question_id = '{{ question.pk }}'
</script>
<script src="{% static 'er_interface/polls.js' %}"></script>
</div>
{% endfor %}
Javascript file- polls.js:
$.getJSON('/er/poll/'+question_id ,function(data) {
$('#'+question_id).highcharts({
chart: {
type: 'pie'
},
title: {
text: question_id
},
tooltip: {
pointFormat: ':<b>{point.y}</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: false
},
showInLegend: true
},
series: {
dataLabels: {
enabled: true,
formatter: function() {
return Math.round(this.percentage*100)/100 + ' %';
},
distance: 0,
}
}
},
series: data
});
});
The problem is that graph is shown just for the last poll question. Thanks
This is because in each of the for loops, question_id is overwritten. You might want to do something like this instead:
$('.chart').each(function() {
var that = this;
var question_id = $(this).attr('id');
$.getJSON('/er/poll/'+question_id ,function(data) {
$(that).highcharts({
...
That way, after rendering the page, you loop through each of the divs and render the appropriate chart.
Even better: use data-id="{{ book.id }}" and retrieve it with $(this).data('id') do avoid using the id attribute for something it's not really meant for.

Preview multiple uploaded images in symfony

I wanna preview my images with javascript before uploading it, I'm working in symfony & I use its FileType for form.. Here is my Code :
{% block content %}
{{ form_start(form, {'attr': {'id': 'image_form', 'class': 'form-horizontal container'}} ) }}
<div class="col-md-6">
<div class="form-group">
<div class="col-md-3 text-right">
{{ form_label(form.name, 'Images to upload :', {'label_attr': {'class': 'control-label'}}) }}
</div>
<div class="col-md-8">
<div id="wrapper" style="margin-top: 20px;">
{{ form_widget(form.name, {'attr': {'id' : 'fileUpload'}}) }}
</div>
{{ form_errors(form.name) }}
</div>
</div>
<div class="col-md-offset-7">
{{ form_label(form.Upload) }}
{{ form_widget(form.Upload, { 'label': 'Upload', 'attr': {'class': 'btn btn-info'}}) }}
<button type="reset" class="btn btn-default">Clear</button>
</div>
<div id="image-holder"></div>
</div>
{{ form_end(form) }}
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script>
$(document).ready(function() {
$("#fileUpload").on('change', function() {
//Get count of selected files
var countFiles = $(this)[0].files.length;
var imgPath = $(this)[0].value;
var extn = imgPath.substring(imgPath.lastIndexOf('.') + 1).toLowerCase();
var image_holder = $("#image-holder");
image_holder.empty();
if (extn == "gif" || extn == "png" || extn == "jpg" || extn == "jpeg") {
if (typeof(FileReader) != "undefined") {
//loop for each file selected for uploaded.
for (var i = 0; i < countFiles; i++)
{
var reader = new FileReader();
reader.onload = function(e) {
$("<img />", {
"src": e.target.result,
"class": "thumb-image"
}).appendTo(image_holder);
}
image_holder.show();
reader.readAsDataURL($(this)[0].files[i]);
}
} else {
alert("This browser does not support FileReader.");
}
} else {
alert("Pls select only images");
}
});
});
</script>
{% endblock %}
I, tried the same thing with a simple html input of type of file, & it was working fine, but why it doesn't in the Symfony form?
It's because Symfony2 form_div_layout adding own id to every widget
{%- block widget_attributes -%}
id="{{ id }}" name="{{ full_name }}"
....
So you have to change {'id' : 'fileUpload'} to {'class' : 'fileUpload'} and $("#fileUpload").on('change' to $(".fileUpload").on('change' and check the result. Or rewrite form layout.

reactive.js + displaying boards

I can't seem to understand why I can't spam click my "create board" button and keep creating boards
when I add a board the new empty board dict should be prepended to the front of the array but only one board will show up then no more..Thanks for the help!!!
<div id="target"></div>
<script id="template" type="text/ractive">
<button class="btn btn-primary" on-click="add_board"><i class="fa fa-plus"></i> Board</button>
<br><br>
editing: {% editing %}
{% #board_list:title %}
{% title %}
{% /board_list %}
<div class="board_list">
{% #board_list:name %}
<div class="board">
{% #if editing %}
<textarea id="editarea" on-blur="editdone" data-areaid="3" value="{% text %}"></textarea>
{% else %}
<div on-click="startedit"><p>{% text %}</p></div>
{% /if %}
</div>
{% /board_list %}
</div>
</script>
<script src='http://cdn.ractivejs.org/latest/ractive.min.js'></script>
<script>
$(function() {
// Ractive object
var MAIN = new Ractive({
el: '#target',
template: '#template',
delimiters: ['{%', '%}'],
tripleDelimiters: ['{%%', '%%}'],
data: {
editing: false,
board_id: -1,
text: "Edit Me",
board_list: [],
loading: false
},
});
MAIN.on("add_board", function() {
board_list = MAIN.get('board_list');
alert(board_list);
var empty_board = {title: ''};
board_list.splice(0, 1, empty_board);
MAIN.set('board_list', board_list);
});
MAIN.on("startedit", function() {
MAIN.set("editing", true);
$("#editarea").focus();
});
MAIN.on("editdone", function() {
MAIN.set("editing", false);
var text = MAIN.get("text");
alert(text);
if (text.trim().length > 0) {
//update_board()
alert('not empty');
}
else {
//delete_board()
alert('empty');
}
});
The second argument in splice is the number of elements to remove, you currently have it set to remove 1. If you change it to 0 then it will add more.
board_list.splice(0, 0, empty_board);
https://jsfiddle.net/6qz84476/

Categories

Resources