Preview multiple uploaded images in symfony - javascript

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.

Related

Why html buttons dynamically created by django cannot access my javascript function?

My Django application makes divs dynamically. Each div is a post of a blog post and also I have a like button on each div. Each button will automatically turn into unlike when a user clicks on it without reloading using javascript. I wrote a javascript function for this. Unfortunately, my javascript function works only the last post on a page (As I have pagination property).
document.addEventListener("DOMContentLoaded",function(){
// const colon = document.createElement('div');
// colon.setAttribute('id','colon')
// e.preventDefault()
// const likebtn = document.createElement('button');
// likebtn.setAttribute('class','likebtn btn btn-primary');
// likebtn.setAttribute('class','likebtn');
// document.querySelector('.card-footer').appendChild(likebtn);
// document.querySelector('.likebtn').innerHTML = "Like";
document.querySelector(`#likeform${posts_id}`).addEventListener('submit',(event) => {
event.preventDefault();
like_function();
// return false;
})
// document.querySelector('.likepost').addEventListener('click', ()=> like_function('likepost'));
})
// let is_like = "{{is_like}}";
// let num_like = "{{num_like}}";
function like_function(){
// document.createElement('button').innerHTML = "Love";
// console.log("Updated!")
fetch(`/like/${posts_id}`,{
method:"POST",
body : JSON.stringify({
"is_like" : is_like,
"num_like" : num_like,
})
})
.then(response => response.json())
.then(result => {
if(result.is_like){
console.log("function is liked");
console.log(`${result.is_like} for post ${posts_id}`);
let num_like = result.num_like;
console.log(`Number of posts : ${num_like}`);
document.querySelector(`#likebtn${posts_id}`).innerHTML = "Unlike";
num_like = num_like + 1;
console.log(`Number of posts : ${num_like}`);
document.querySelector(`#num_of_likes_${posts_id}`).innerHTML = `${num_like} `
// location.replace("http://127.0.0.1:8000")
}
else{
console.log("function is unliked, back off!");
console.log(`${result.is_like} for post ${posts_id}`);
let num_like = result.num_like;
console.log(`Number of posts : ${num_like}`);
document.querySelector(`#likebtn${posts_id}`).innerHTML = "Like";
num_like = num_like - 1;
console.log(`Number of posts : ${num_like}`);
document.querySelector(`#num_of_likes_${posts_id}`).innerHTML = `${num_like} `
// location.replace("http://127.0.0.1:8000")
}
})
}
// function like_function(){
// if (document.querySelector("#like").style.color == "blue"){
// document.querySelector("#like").style.color = "red";
// }else{
// document.querySelector("#like").style.color = "blue";
// }
// }
This is my full javascript code. Here I'm sharing my HTML template,
<div id="posts" class="card">
<ul class="card-body">
{% for posts in page_view %}
<li class="card">
<div class="card-header bg-success">
<h5 class="card-title"><a class="text-light" style="text-decoration: none;" href="{% url 'profile' posts.user.id %}">{{ posts.user }}</a></h5>
<h6 class="card-subtitle text-light">{{ posts.timestamp }}</h6>
</div>
<div class="card-body">
<h3 class="card-text">{{ posts.post }}</h3>
</div>
<div id="likeapost{{posts.id}}" class="card-footer">
{% if request.user in posts.likepost.all %}
<form action="{% url 'likepost' posts_id=posts.id %}" id="likeform{{posts.id}}" method="POST" style="display: inline;">
<!-- {% csrf_token %} -->
<button id="likebtn{{posts.id}}" class="btn btn-link" type="submit">Unlike</button>
</form>
{% else %}
<form action="{% url 'likepost' posts_id=posts.id %}" id="likeform{{posts.id}}" method="POST" style="display: inline;">
<!-- {% csrf_token %} -->
<button id="likebtn{{posts.id}}" class="btn btn-link" type="submit">Like</button>
</form>
{% endif %}
<small id="num_of_likes_{{posts.id}}" class="num_of_likes">{{ posts.likepost.all.count }}</small>
{% block script %}
<script>
posts_id = "{{ posts.id }}";
is_like = "{{is_like}}";
num_like = "{{ posts.likepost.all.count }}";
</script>
<script src="{% static 'network/controller.js' %}"></script>
{% endblock %}
<button class="btn btn-link" style="text-decoration: none;">Comment</button>
View Post
{% if request.user.id is posts.user.id %}
Edit
{% endif %}
<!-- <div class="likepost"></div> -->
</div>
</li>
{% empty %}
<h6>No post availabel 😔</h6>
{% endfor %}
</ul>
</div>
This is my HTML template. All the buttons should work like this,
Only this one button works perfectly, but others do not. This is what happening.
What should I do? I am about 90% done. Please help.

Ajax like button not showing increment in count or else

I wanted to add like heart button with like count. I want to use ajax for changing likes count and color change. but when I tried to do that it won't work.
HTML
<div id="posts">
{% for post in page_obj %}
<div><a >{{ post.userp }}</a></div>
<div>{{ post.content }}</div>
<div>{{ post.timestamp }}</div>
<div id="post_name">
{% if request.user in post.userl.all %}
<a class="likeu" style="cursor: pointer"><span id="{{ post.id }}" class="likeu1" style="font-size:24px;color:red">♥</span></a>
{% else %}
<a class="likeu" style="cursor: pointer"><span id="{{ post.id }}" class="likeu1" style="font-size:24px;color:grey">♥</span></a>
{% endif %}
<p id="{{ post.id }}l">{{ post.userl.all.count }}</p>
</div>
<hr>
{% endfor %}
</div>
and JAVASCRIPT
document.querySelectorAll('.likeu1').forEach(element => element.addEventListener('click', change_like));
function change_like(){
post_id = this.id
console.log(post_id)
fetch('/likes', {
method: 'POST',
body: JSON.stringify({
post_id : post_id,
})
})
.then(response => response.json())
.then(result => {
value = result["is_liked"];
console.log(value);
console.log(this);
if (value == 'true'){
this.style.color = 'red';
console.log('red');
}
else{
this.style.color = 'grey';
console.log('grey');
}
})
}
It is updating when I refresh but I want it without refresh.
I don't know what I am doing wrong. please help!

Accessing an element in django (for)

I have a Django template with the following code which creates multiple buttons and tries to hide/show description text on a click (on the same button in each card):
{% for comida in comidas %}
{% if comida.slug_food == page.slug %}
<div class="food2">
<div id="food-title">{{comida.titulo}}</div>
<div id="food-price">{{comida.precio|floatformat:"-1"}}€</div>
<button class="button" onclick="showDescription()">ver+
<div id="food-description" >
{{comida.descripcion|safe}}
</div>
</button>
<div id="add-cart">AÑADIR AL PEDIDO</div>
{% if comida.imagen != null %}
<img src="{{comida.imagen.url}}"></img>
{% endif %}
</div>
{% endif %}
{% endfor %}
where comidas is a list of strings, and later in the script block I have
function showDescription(){
var showText = document.getElementById("food-description");
if (showText.style.display === "block"){
showText.style.display = "none";
} else {
showText.style.display = "block";
}
}
The function runs, but as you may expect, it runs only on the first element of my for loop.
My question is ¿anyone can help me? i want work all my buttons and not only the first element.
Use {{comida.id}} to get unique ids :
{% for comida in comidas %}
{% if comida.slug_food == page.slug %}
<div class="food2">
<div id="food-title">{{comida.titulo}}</div>
<div id="food-price">{{comida.precio|floatformat:"-1"}}€</div>
<button class="button" onclick="showDescription('{{comida.id}}')">ver+
<div id="food-description-{{comida.id}}" >
{{comida.descripcion|safe}}
</div>
</button>
<div id="add-cart">AÑADIR AL PEDIDO</div>
{% if comida.imagen != null %}
<img src="{{comida.imagen.url}}"></img>
{% endif %}
</div>
{% endif %}
{% endfor %}
And javascript :
function showDescription(comidaId){
var showText = document.getElementById("food-description-" + comidaId);
if (showText.style.display === "block"){
showText.style.display = "none";
} else {
showText.style.display = "block";
}
}

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 %}

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