Get img src of the closest div - javascript

My HTML is:-
<div class="mb10">
<input id="input-upload-img1" type="file" class="file" data-preview-file-type="text" name="img1" accept='image/*,video/*'>
</div>
I'm using FileInput JS library, which initializing a file input type adds more HTML to it.
JQuery
$("#input-upload-img1").fileinput();
After Initializing, it adds few HTML to it.
<div class="mb10">
<span class="file-input file-input-new">
<div class="file-preview "> <!-- This whole div is initially hidden, ie display:none-->
<div class="close fileinput-remove text-right">×</div>
<div class="file-preview-thumbnails"></div>
<div class="clearfix"></div>
<div class="file-preview-status text-center text-success"></div>
<div class="kv-fileinput-error file-error-message" style="display: none;"></div>
</div>
<div class="input-group ">
<div class="form-control file-caption kv-fileinput-caption" tabindex="-1">
<div class="file-caption-name" style="width: 322.42px;"></div>
</div>
<div class="input-group-btn">
<button class="btn btn-default fileinput-remove fileinput-remove-button" type="button"><!-- This button is initially hidden, ie display:none-->
<i class="glyphicon glyphicon-ban-circle"></i>
Remove
</button>
<div class="btn btn-primary btn-file">
<i class="glyphicon glyphicon-folder-open"></i>
Browse …
<input id="input-upload-img1" class="file" type="file" accept="image/*,video/*" name="img1" data-preview-file-type="text">
</div>
</div>
</div>
</span>
</div>
After selecting an image, I get the following HTML:-
<div class="mb10">
<span class="file-input">
<div class="file-preview">
<div class="close fileinput-remove text-right">×</div>
<div class="file-preview-thumbnails">
<div id="preview-1469278203925-0" class="file-preview-frame">
<!--Check added image.-->
<img class="file-preview-image" style="width:auto;height:160px;" alt="IMG_20160606_210238.jpg" title="IMG_20160606_210238.jpg" src="blob:http://127.0.0.1:8000/27307c69-0599-4622-93f1-bf8ae6cc0e5c">
</div>
</div>
<div class="clearfix"></div>
<div class="file-preview-status text-center text-success"></div>
<div class="kv-fileinput-error file-error-message" style="display: none;"></div>
</div>
<div class="input-group ">
<div class="form-control file-caption kv-fileinput-caption" tabindex="-1">
<div class="file-caption-name" style="width: 234.22px;" title="IMG_20160606_210238.jpg"></div>
<div class="input-group-btn">
<button class="btn btn-default fileinput-remove fileinput-remove-button" type="button">
<i class="glyphicon glyphicon-ban-circle"></i>
Remove
</button>
<div class="btn btn-primary btn-file">
<i class="glyphicon glyphicon-folder-open"></i>
Browse …
<input id="input-upload-img1" class="file" type="file" accept="image/*,video/*" name="img1" data-preview-file-type="text">
</div>
</div>
</div>
</span>
</div>
Note the added img tag.
Now, I'm writing a JQuery to get the src of the img tag upon selecting a file. How can I do it?
Here is my jQuery:-
$('.file').change(function(){
var file = this.files[0];
if (!file){
return
}
var source_image = $(this).closest('div .file-preview-frame').find('.file-preview-image')
alert(source_image.attr('src'))
}
It returns undefined. I guess its because the dynamic adding of the image. How can I get the image source of the file selected.??

I think you've wrongly understood the usage of .closest. It reads, For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. You see, when change on .file element occurs, it traverses through its ancestors where in span.file-input will be one of the ancestors and div.file-preview-frame is not. So you should visit span.file-input and then find div.file-preview-frame.
You should be probably doing this.
$('.file').change(function(){
var file = this.files[0];
if (!file){
return
}
var source_image = $(this).closest('span.file-input')
.find('div.file-preview-frame .file-preview-image')
alert(source_image.attr('src'))
}
Update
I went on to check the plugin and found few events like below which you can really use:
fileLoaded:
This event is triggered after a file is loaded in the preview.
Additional parameters available are:
file: the file object instance
previewId: the identifier for the preview file container
index: the zero-based sequential index of the loaded file in the preview list
reader: the FileReader instance if available.
Example:
$('#input-id').on('fileloaded', function(event, file, previewId, index, reader) {
console.log("fileloaded");
});
fileSelect
This event is triggered after files are selected in the file input via
the file browse button. This is slightly different than the change
event in the sense that this will be triggered even if the file browse
dialog is cancelled.
Example:
$('#input-id').on('fileselect', function(event, numFiles, label) {
console.log("fileselect");
});
I would prefer fileLoaded event which you can use as below:
$('.file').on('fileloaded', function(event, file, previewId, index, reader) {
console.log(file);
//file will have many details like lastModified, name, size, type etc.,
});

Related

Find div before button

Im trying addClass to wizard-step when button clicked, but still no luck :/
<div class="mt-4">
<div class="wizard-steps">
<div class="wizard-step">
<div class="wizard-step-icon">
<i class="far fa-user"></i>
</div>
</div>
<form class="wizard-content mt-2" id="regForm">
<fieldset>
<div class="form-group row">
<div class="col-lg-4 col-md-6 text-right">
<button type="button" onclick="step0(this);" class="btn">Next</button>
</div>
</div>
</fieldset>
</form>
</div>
JavaScript:
<script>
function step0(element) {
$(element).prev('div').find('.wizard-step').addClass('wizard-step-active');
}
</script>
Can anyone please help me !
prev is used to retrieve a previous sibling element. The .wizard-step you want to target is a child of a sibling to a parent of the button being clicked. As such you need to use closest() instead.
Also note that onclick (and all the other onX attributes) are not good practice and should be avoided. As you're already using jQuery you can attach your event unobtrusively, like this:
jQuery($ => {
$('.btn').on('click', function() {
$(this).closest('.wizard-steps').find('.wizard-step').addClass('wizard-step-active');
});
});
.wizard-step-active { color: #C00; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="mt-4">
<div class="wizard-steps">
<div class="wizard-step">
<div class="wizard-step-icon">
<i class="far fa-user">User icon</i>
</div>
</div>
<form class="wizard-content mt-2" id="regForm">
<fieldset>
<div class="form-group row">
<div class="col-lg-4 col-md-6 text-right">
<button type="button" class="btn">Next</button>
</div>
</div>
</fieldset>
</form>
</div>
Alternatively, instead of calling find() from the shared parent, you could select the form and use prev():
$('.btn').on('click', function() {
$(this).closest('.wizard-content').prev('.wizard-step').addClass('wizard-step-active');
});
Either is fine, it just depends on how your HTML is structured as to which fits best for this use case.
You don't want the div immediately before the button, but the one containing the relevant item(s). So instead of $(element).prev('div') write $('.mt-4').
Your this parameter is referring your button, not your div.
You can do this without Jquery, just using your function like this:
function step0() {
const element = document.getElementsByClassName('wizard-step');
element.classList.add('wizard-step-active');
}
So, you don't need to pass this as a parameter to step0 function.

Is there a way to programmatically trigger a VueJS element with .native using $refs?

I have searched GitHub Issues and Google but I can't seem to find the solution that fits my needs.
Template:
<v-file-input
dense
accept="image/png, image/jpeg, image/gif"
#change="onImageChangeHandler"
v-show="false"
ref="fileInput"
></v-file-input>
<v-btn
dense
color="primary"
#click="onUploadClickHandler"
small
>
<v-icon left>mdi-camera</v-icon>
Upload Photo
</v-btn>
JS:
onImageChangeHandler(e) {
if (e) {
const fr = new FileReader();
fr.readAsDataURL(e);
fr.addEventListener("load", () => {
this.localPersonalData.image = fr.result.split(
"base64,"
)[1];
});
}
},
onUploadClickHandler(e) {
this.$refs.fileInput.$el.click(); // I need to click the hidden file input
}
Upon closer inspection, I found out that Vuetify parses v-file-input component in nested divs and the input element is at the bottom of the html tree.
<div
data-v-a2f0f47e=""
class="v-input v-input--dense theme--light v-text-field v-text-field--is-booted v-file-input"
style="display: none;"
>
<div class="v-input__prepend-outer">
<div class="v-input__icon v-input__icon--prepend">
<i
role="button"
class="v-icon notranslate v-icon--link mdi mdi-paperclip theme--light"
></i>
</div>
</div>
<div class="v-input__control">
<div class="v-input__slot">
<div class="v-text-field__slot">
<div class="v-file-input__text"></div>
<!-- I want to click this input -->
<input
accept="image/png, image/jpeg, image/gif"
id="input-333"
type="file"
/>
</div>
<div class="v-input__append-inner">
<div class="v-input__icon v-input__icon--">
<i
role="button"
class="v-icon notranslate v-icon--link material-icons theme--light"
></i>
</div>
</div>
</div>
<div class="v-text-field__details">
<div class="v-messages theme--light">
<div class="v-messages__wrapper"></div>
</div>
</div>
</div>
</div>
Therefore, I probably need to use .native but how do I do that programmatically?
EDIT: Should I just use native html input with type file instead?
What I understand is you want to open a file right?
Try this
<input type="file" ref="file" style="display: none">
<v-button #click="$refs.file.click()">Button to open the file</v-button>
And with the ref in js use as this.$ref.file and get your file you uploded
To clear the reference this.$ref.value=""

How to get dimmer on specific card to toggle rather than all my card gallery using Semantic UI and JQuery

I have a gallery of avatars I want to show my user, which are shown in the card format of Semantic-UI. I want the user to click on one of the images which then triggers Semantic's dimmer to appear in that specific image's place.
What I currently get is that all the images get the dimmer to appear on them instead of the specific one I want. Here is the code that puts the dimmer on all images:
$(".selectavatar img").hover(function() {
$('.selectavatar img').removeClass('selectedImage');
$(this).toggleClass("selectedImage");
});
$(".selectavatar img").click(function() {
$(".ui.dimmer").dimmer("toggle");
});
<!--gallery goes here-->
<div class="ui three column grid selectavatar">
<div class="five wide column">
<div class="ui segment">
<form action="/account/<%=currentUser._id%>?_method=PUT" method="POST">
<input name="user[image]" type"submit" value = "image1.jpg" class="hidden" />
<img name="user[image]" src = "image1.jpg" width=300>
<div class="ui dimmer">
<div class="content">
<div class="center">
<button class="ui button blue" type="Submit">
<i class="user icon"></i> Select Avatar
</button>
</div>
</div>
</div>
</form>
</div>
</div>
<div class="five wide column">
<div class="ui segment">
<form action="/account/<%=currentUser._id%>?_method=PUT" method="POST">
<input name="user[image]" type"submit" value = "image2.png" class="hidden" />
<img name="user[image]" src = "image2.png" width=300>
<div class="ui dimmer">
<div class="content">
<div class="center">
<button class="ui button blue" type="Submit">
<i class="user icon"></i> Select Avatar
</button>
</div>
</div>
</div>
</form>
</div>
</div>
The way I envisioned it was that I'll add the class .selectedImage on the image the user wants, then I would be able to toggle the dimmer if selectedImage exists. But when I do use that as so:
$(".selectavatar img.selectedImage").click(function() {
$(".ui.dimmer").dimmer("toggle");
});
then nothing appears, no dimmer whatsoever!
What am I doing wrong?
As a side note, I need to figure out how to generate a gallery from a folder of images using EJS and NodeJS, instead of having to hard code each image. I guess the right thing to do would be a seperate question for that?
Your code will dim all .ui.dimmer divs when you click an image:
$(".selectavatar img").click(function() {
$(".ui.dimmer").dimmer("toggle");
});
This code will dim only the .ui.dimmer div which is located in the same parent container as the clicked image:
$(".selectavatar img").click(function() {
$(this).parent().find(".ui.dimmer").dimmer("toggle");
});
Part 2
Your code will set a click handler on all img.selectedImage which exist when you set the event handlers. Unfortunately no images have the selectedImage class at that point so it doesn't work.
$(".selectavatar img.selectedImage").click(function() {
//code
});
This code will do the same, but it only requires .selectavatar to exist when the event handler is set up:
$(".selectavatar").on("click", "img.selectedImage", function() {
//code
});

jQuery find id after loading

Here is my structure:
Person.html
...
<script src="../../js/site.js"></script>
...
<a id="findPersonById" href="javascript:void(0);" class="btn btn-primary">
Find person by id</a>
...
<div id="person-result">results div</div>
Site.js
$(document).ready(function () {
privateFunction();
});
...
$('#findPersonById').click(function () {
$("#person-result").load('/person/find #inside-container');
});
...
/person/find
<script src="../../js/site.js"></script>
...
<div class="container">
<div id="inside-container">
<br/>
<form id="personFindByIdForm">
<div class="form-group">
<div class="input-group">
<span class="input-group-addon">PERSON'S ID</span>
<input type="text" class="form-control" name="id"/>
<span class="input-group-btn">
<button class="btn btn-default" type="submit">Find</button>
</span>
</div>
</div>
</form>
<div id="find-result">res-div</div>
</div>
So, first of all I'm finding #findPersonById and loading /person/find #inside-container in the #person-result. It works. My next step was about to find two ids #personFindByIdForm and #find-result. I can't do it since document is already loaded if I'm right. How could I do this ?
And the second question - if I add any js code into the div that will be loaded into another div, will that js code run (why is it not running)?
Like:
$("#div-2").load('/any-url #div-1');
<div id='div-1'>
<script>console.log('Any JS')</script>
</div>
Thank you.
You can make sure the items are loaded this way:
$("#div-2").load('/any-url #div-1', function(){
//here all the items loaded will be accessible
});

Jquery not recognizing events that takes place on the HTML templates that is generated on fly

I am using Handlerbars.js and it gives me a dynamic template that is generated on the fly. When I do some Jquery events like click etc .. Jquery is not able to catch those events. Please help me out.
I want to trigger a event when the button with id hitUp is clicked
HandlerBar.js code
{{#each this}}
<div id="accordion2" class="panel-group">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a href="#{{log}}" data-parent="#accordion2"
data-toggle="collapse" class="btn-block" > <img
class="img-rounded" src="/assets/images/default-food.png" /> {{log}}
</a>
</h4>
</div>
<div class="panel-collapse collapse" id="{{log}}">
<div class="panel-body food-details">
<div class="bm pzero col-xs-12">
<div class="input-group spinner">
<input id="spinid" type="text"
name="demo_vertical2" class="form-control input-sm"
/> <span class="input-group-btn vertical">
<button id="hitUp"
class="btn btn-default bootstrap-touchspin-up"
type="button">
<i class="fa fa-caret-up"></i>
</button>
<button id="hitDown"
class="btn btn-default bootstrap-touchspin-down "
type="button">
<i class="fa fa-caret-down"></i>
</button>
</span>
</div>
HTML code
<div id="accordion2" class="panel-group">
</div>
Jquery code
Try1
$('body').on("click",'#hitUp',function(){
console.log("Functionclicked")
});
Try2
$('#hitUp').click(function(){
console.log("Functionclicked")
});
Try3
$( document ).ready(function( $('body').on("click",'#hitUp',function(){
console.log("Functionclicked")
});){})
I have tried the above Jquery methods but no use. Give me some solutions
Just like in the link that #adeno posted, jQuery event handlers need to be registered as the very last thing that happens when all the JavaScript files and libraries are loaded. Calling $(document).ready() does not mean that all JS files have been loaded, it just means that the DOM has been put in place and is ready for manipulation. If you're going to do more DOM manipulation with a library like Handlebars, you need to make sure that your event handlers are registered after all that dynamic generation has already happened.
So if this is my template:
<h1>{{title}}</h1>
<div>{{body}}</h1>
<br />
{{#each buttonIds}}
<input type="button" id="{{this}}" value="Click me" />
{{/each}}
And this is my javascript:
var data = {
title: 'The Title',
body: 'Document Body',
buttonIds: [ 'hitUp1', 'hitUp2', 'hitUp3' ]
};
var templateScript = $('#header').html();
var template = Handlebars.compile(templateScript);
$(document.body).append(template(data));
$('#hitUp1').on('click', function () { alert('clicked 1'); });
$('#hitUp2').on('click', function () { alert('clicked 2'); });
$('#hitUp3').on('click', function () { alert('clicked 3'); });
I'm waiting til very last to register the on click handlers, and they are each unique identifiers.
Here is a working fiddle to demonstrate what I'm saying.
was facing the same issue. use
$('body').on("change", '#amountType', function (){
});
this worked for me

Categories