Count images inside a div, then add another/new img src (file) - javascript

I'm currently using Flask for my back-end coding, and working on my front-end as of now. Below are the images uploaded on the server. Now I need to edit those images, like I need to upload another image or change the existing image. We're using a cropper.js on this one, and I don't know how will I manage this one because I'm not that good when it comes to front-end scripting like javascript/jquery/ajax. Maximum images can upload is up to 8 images, I need to count the total existing images, then add another img src file, for example if I had 3 images, then I need to show 5 more img src file for adding new images. Any help will do and will be appreciated. Below is my code on HTML with Jinja2 template.
<div class="col-xs-3">
<label class="rs-thumb rs-thumb-cover">
<div class="rs-thumb-content" id="inputImage1-wrap"><img src="{{ resource.image_url }}" alt="" id="inputImage1-pic" width="100%"><i class="fa fa-picture-o"></i>
<span class="rs-cover">Cover</span>
</div>
</label>
</div>
{% for imgs in resource.images[1:] %}
<div class="col-xs-3">
<label class="rs-thumb rs-thumb-cover">
<div class="rs-thumb-content" id="inputImage1-wrap"><img src="{{ imgs.image }}" alt="" id="inputImage1-pic" width="100%"><i class="fa fa-picture-o"></i>
<!-- <span class="rs-cover">Cover</span> -->
</div>
</label>
</div>
{% endfor %}
Image for Edit Module on front-end

Html + JQuery solution, mostly tested so should work.
HTML
<div class="imgBox">
<!-- Your content will appear here -->
</div>
JQuery
// Get the amount of images on the current page
var amountOfImg = $("img").length;
var amountToCount = 8;
for (var i = 0; i < amountToCount - amountOfImg; i++) {
$(".imgBox").append("<input type='file' name='fileInput' /> <b id='removeImg'>Remove</b>")
}
$("#removeImg").click(function() {
// When the user clicks on the #removeImg text, find the closest "img" element and remove it.
$(this).closest("img").remove();
});

Related

How can I re-run a Django For Loop inside a HTML Div using Javascript on Click Event

I have a HTML div like this,
<div class="coment-area ">
<ul class="we-comet">
{% for j in comment %}
<div id="delete_comment{{j.id}}" class="mt-3">
{% if j.post_id.id == i.id %}
<li >
<div class="comet-avatar">
{% if j.user_id.User_Image %}
<img class="card-img-top" style=" vertical-align: middle;width: 50px;height: 50px;border-radius: 50%;" src= {{ j.user_id.User_Image.url }} alt="">
{% else %}
<img class="card-img-top" style=" vertical-align: middle;width: 60px;height: 60px;border-radius: 50%;" src="static\images\resources\no-profile.jpg">
{% endif %}
</div>
Inside of it is a For Loop that is executed when the page is first loaded.
Below this For Loop is a Comments Button
<div >
<button type="submit" onclick="comment_save(event,{{i.id}})" class= "my-2 ml-2 px-2 py-1 btn-info active hover:bg-gray-400 rounded ">Comment</button>
</div>
</div>
</li>
</ul>
</div>
Whenever this button of Comments is clicked, a function in Javascript is called which is defined below,
function comment_save(event,post_id)
{
var comment_value=$("#comment_value"+post_id).val();
var user_id=$("#comment_user_id"+post_id).val()
postdata={
"comment_value":comment_value,
"user_id":user_id,
"post_id":post_id
}
SendDataToServer("readmore",postdata,function()
{
alert()
})
$("#comment_value"+post_id).val(" ")
<! --- document.location.reload().. Something here that refresh that for loop --->
}
What I want is this that whenever the button is clicked, it re-executes that for Loop inside my main div without having to refresh the page. I have been trying to do this for two days but could not find any solution to this. Can anyone help me in doing this?
The Django Templating Language is executed server-side. That means the client (browser, running Javascript) has no access to it whatsoever.
Some of your options are:
Do everything back-end: Re-render the template (which you said don't want to do).
Do everything front-end: You could have your view function return the data used in your template loop and re-implement it in your front-end (but that makes the original template loop kind of pointless).
Hybrid: Return the data for only the new comment in your response and add it to the list with Javascript.

Error label innerHTml disappears when image preview is loaded

I'm working on a django project where I need to permit the user to upload images to the server. Everything's fine except when I want to show an image preview before submitting.
I'm using django-crispy-forms to render the form:
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ["image", "caption"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_method = "post"
self.helper.form_action = 'add-post'
self.helper.add_input(Submit("add-post", "Add Post", css_class='btn-primary btn-dark mt-3'))
This is the HTML template used for rendering the form:
<div class="row justify-content-center mt-4">
<div class="col-md-8">
{% crispy form %}
</div>
</div>
This based on the developer inspector in firefox yields the following input HTML:
<input type="file" name="image" class="custom-file-input" accept="image/*" id="id_image" required="">
<label class="custom-file-label text-truncate" for="id_image">---</label>
After hitting the submit button, the label gets filled with image name. That's exactly what I want.
However, as mentioned I wanted an image preview before submitting so I took look at the following stackoverflow answer and got what I want:
preview image before form submit
Show an image preview before upload
I managed to get an image preview using the following js and HTML:
<div class="row justify-content-center mt-4">
<img id="image-preview">
</div>
<div class="row justify-content-center mt-4">
<div class="col-md-8">
{% crispy form %}
</div>
</div>
JS:
document.addEventListener('DOMContentLoaded', function() {
// Show image preview before submitting
document.getElementById("id_image").onchange = function () {
var src = URL.createObjectURL(this.files[0]);
document.getElementById("image-preview").src = src;
}
})
and now for some reason the label disappears. I tried filling it while reading the image file in the js above but I failed.
Any help is appreciated.

angular repeat with template?

I'm currently trying to figure out how to use templates in angular. At present, I'm playing with ui.router (angular-ui-router) but I can't find good documentation on how the templating language is used to embed a sub-template view, especially as relates to a repeating element for different model instances.
BACKGROUND:
I am basically converting a static-local-filesystem image uploader/manager to work with amazon S3. The background essentials are already worked out, now I'm trying to improve the UI itself by converting it from 10 year old javascript to angular.js. I have it 'working' for an all-in-one html page but would prefer to modularize it to make it more dynamic.
CONTEXT:
I get a list of objects under a given prefix back from a listObjectsV2() call to the AWS sdk via the s3 client. I parse the results to break it into a pseudo-directory tree then display one directory at a time starting at the [virtual] root dir just after the prefix. (FYI the prefix is a userid)
I built a UserDir object that uses a PseudoDir sub object to define a virtual directory with array properties for 'subdirs' (more PseudoDir objects representing virtual sub-directories) and 'images' (S3 objects that are image files of one type or another).
What I want to display for any given 'current' directory (e.g. "" or the user root) is first a list of folder icons for each the curDir.subdirs, then a thumbnail icon for each of the curDir.images.
QUESTION:
I already have this working from a single html file and even managed to figured out how to use ui.router to create a for the main page. Now I want to modularize it so that a different controller will handle folder icon/info behavior, and another for image icons/behaviors.
i.e. I have already started building a 'FolderController' and a 'ImageController' and would like the ngRepeat for 'image in curDir.images' for example, to invoke a state with it's own template but I can't seem to find an example on how to do that.
Here is the current all-in-one template code. But I would like to move each sub-block into a state for FolderController with a templates/folder.html template and one for ImageController with a templates/image.html but can't seem to find an example of how to write the syntax:
<!-- folders -->
<div ng-repeat="(folder, pDir) in subdirs" ng-controller="FolderController" ng-init="folderName=folder;awsObject=pDir">
<div id="{{folderName}}" class="Item">
<div class="Icon ui-draggable ui-draggable-handle">
<img id="{{folderName}}Icon" src="../../images/folder.png">
</div>
<div id="{{folderName}}Desc" class="Description">
<span id="{{folderName}}Name" class="filename" title="{{folderName}}/">{{folderName}}/</span>
</div>
</div>
</div>
<!-- images -->
<div ng-repeat="(filename, uImage) in images" ng-controller="ImageController" ng-init="uImage=uImage">
<div id="image{{uImage.hash}}" class="Item">
<div class="Icon ui-draggable ui-draggable-handle">
<img id="icon{{uImage.hash}}" ng-src="{{ uImage.thumbSrc }}"></div>
<div id="desc{{uImage.hash}}" class="Description">
<span id="name{{uImage.hash}}" class="filename" title="{{filename}}">{{filename}}</span>
<img id="thumb{{uImage.hash}}" src="../../images/tick_image-services.png" class="Check Right" ng-show="uImage.usedInLayout" title="Used in layout"><br />
<span id="date{{uImage.hash}}" ng-show="(uImage.mtime > 0)">Date uploaded: {{ uImage.mtime | date: 'EEE MMM dd yyyy' }}</span><br />
<span id="size{{uImage.hash}}" ng-show="(uImage.size > 0)">Size: {{ uImage.size | humanizeBytes }}</span><br />
<span id="dims{{uImage.hash}}" ng-show="((uImage.width > 0) && (uImage.height > 0))">Dimensions: {{ uImage.width }} x {{ uImage.height }} pixels</span><br />
<span id="aspect{{uImage.hash}}" ng-show="(uImage.aspectRatio)">Aspect Ratio: <span class="AspectRatio">{{ uImage.aspectRatio }}</span></span><br />
</div>
</div>
</div>
You can create two components, one for folders and one for images, see here for official docs.
A rough draft would look like:
angular.module('myApp').component('images', {
templateUrl: 'imageList.html',
bindings: {
images: '='
}
});
imageList.html:
<div ng-repeat="(filename, uImage) in images" ng-controller="ImageController" ng-init="uImage=uImage">
<div id="image{{uImage.hash}}" class="Item">
<div class="Icon ui-draggable ui-draggable-handle">
<img id="icon{{uImage.hash}}" ng-src="{{ uImage.thumbSrc }}"></div>
<div id="desc{{uImage.hash}}" class="Description">
<span id="name{{uImage.hash}}" class="filename" title="{{filename}}">{{filename}}</span>
<img id="thumb{{uImage.hash}}" src="../../images/tick_image-services.png" class="Check Right" ng-show="uImage.usedInLayout" title="Used in layout"><br />
<span id="date{{uImage.hash}}" ng-show="(uImage.mtime > 0)">Date uploaded: {{ uImage.mtime | date: 'EEE MMM dd yyyy' }}</span><br />
<span id="size{{uImage.hash}}" ng-show="(uImage.size > 0)">Size: {{ uImage.size | humanizeBytes }}</span><br />
<span id="dims{{uImage.hash}}" ng-show="((uImage.width > 0) && (uImage.height > 0))">Dimensions: {{ uImage.width }} x {{ uImage.height }} pixels</span><br />
<span id="aspect{{uImage.hash}}" ng-show="(uImage.aspectRatio)">Aspect Ratio: <span class="AspectRatio">{{ uImage.aspectRatio }}</span></span><br />
</div>
</div>
and your original html would look like:
<!-- folders -->
<div ng-repeat="(folder, pDir) in subdirs" ng-controller="FolderController" ng-init="folderName=folder;awsObject=pDir">
<div id="{{folderName}}" class="Item">
<div class="Icon ui-draggable ui-draggable-handle">
<img id="{{folderName}}Icon" src="../../images/folder.png">
</div>
<div id="{{folderName}}Desc" class="Description">
<span id="{{folderName}}Name" class="filename" title="{{folderName}}/">{{folderName}}/</span>
</div>
</div>
</div>
<image-list [images]="images" ></image-list>
EDIT
Here is an example plunker which shows a simple implementation of a component, with data binding and ng-repeat in it, no need for ui-router for what you asked for. Please note that the html I wrote above is a botched copy paste of what you wrote - so the double ng-repeat was a mistake, updated the html.

how to get an array element with javascript variable in django template?

i`m creating a slider so i want to get an element of template array in Django.
my HTML file is:
<div id="sideBar_mostVisited_control">
<a href="">
<p>
{{ mostVisited_names.0 }}
</p>
</a>
<div>
<p>
1
</p>
</div>
<button type="button" id="mostVisited_arrowRight">
<img src="{% static 'icons/base/arrowRight.png' %}" id="mostVisited_arrowRight">
</button>
<button type="button" id="mostVisited_arrowLeft">
<img src="{% static 'icons/base/arrowLeft.png' %}" id="mostVisited_arrowLeft">
</button>
</div>
<div id="sideBar_mostVisited_images">
<div>
{% for image in mostVisited_images %}
<img src="{{ image }}">
{% endfor %}
</div>
</div>
i want to change name when its image changed. my jQuery file is:
var index=$('#sideBar_mostVisited_control div p').html();
$('#sideBar_mostVisited_control div p').html(index+1);
$('#sideBar_mostVisited_control a p').html("{{ mostVisited_names.index }}");
but index is not recognized in {{ mostVisited_names.index }}.
what can i do?
The problem :
Since the JS file is static, you can't put Django variables into it.
A solution :
A way to resolve this situation is to "store" Django variables needed for your js in your html. Afterward you can grab it and use it in your js script !
Some code :
<script type="text/javascript">
// "store" variables from Django in the body
$('body').data('name_index', {{mostVisited_names.index}});
</script>
Then in your JS, get the value from the datamap:
var index=$('#sideBar_mostVisited_control div p').html();
$('#sideBar_mostVisited_control div p').html(index+1);
$('#sideBar_mostVisited_control a p').html($('body').data('name_index'));

Get each element of pagination

I'm creating an ecommerce site that has infinite scroll in the catalog page. I want to know how many times each product is show to an user in the screen (impressions). The problem is how to get the new 12 elements that renders every time a user scrolls down to a new page. Than pass their ids to the server and stores their impressions. Is there a way to access the new elements? I checked laravel documentation and I saw nothing about this.
This is my code that renders the products array in the template:
<div class="product-one">
#foreach($products as $product)
<div class="col-md-3 product-left">
<div class="p-one simpleCart_shelfItem">
<a href="{{ route('getprodpage', ['id' => $product->id]) }}">
<img src="{{ $product->image_url1}}" alt="" />
<div class="mask">
<span>Comprar</span>
</div>
</a>
<h4>{{ $product->name }}</h4>
<p><a class="item_add" href="#"><i></i>
<span class=" item_price">
R$ {{$product->price_min}}
</span></a>
</p>
</div>
</div>
#endforeach()
<div class="clearfix"> </div>
</div>
<?php echo $products->render(); ?>
And this is the infinite scroll javascript:
$(function() {
$('.shoes').jscroll({
loadingHtml: '<center><img src="{{ URL::asset('images/loading.gif') }}" alt="Loading" /> </center>',
autoTrigger: true,
padding: 0,
nextSelector: '.pagination li.active + li a',
contentSelector: 'div.shoes',
callback: function() {
$('ul.pagination:visible:first').hide();
}
});
});
I believe this question has been asked and answered already.
jQuery: How can I trigger an event when a div comes into view?
This post has an answer to see if an element is in the view port and also another answer for an event for when elements are in the view port.

Categories

Resources