Not able to track change in input value - javascript

In the template I have a input element.
<input class='qq-edit-caption-selector qq-edit-caption kk-editing' placeholder='Enter Caption here ...' onkeypress='captionUpdate();'>
I want to track the change in the input value,and enable the Update button.Tried below options:
onkeypress='captionUpdate();'
Tried jquery change or click on the class
$('.qq-edit-caption').change(function() {
alert('qq-edit-caption');
});
Both options does not get fired up!!not sure I have anything issues with my setup or Fine Uploader does not allow that? Please see my screenshot:
Any way to solve this problem with FU?

If you are simply adding this inline event handler directly to the template element, then it's not surprising that it's never triggered. Fine Uploader templates are quite primitive in that the template is interpreted as an HTML string and then used to create DOM elements inside of your container element (the element referenced as your element option).
You really should never use inline event handlers. There are quite a few disadvantages to this approach. I talk about this in more depth in my book - Beyond jQuery. And the method of attaching event handlers is not necessary at all in your case, as far as I can tell. Instead, after constructing a new instance of Fine Uploader, simply attach an event handler of your choice to the input element using addEventListener. For example if your <input> element is given a CSS class name of 'qq-edit-caption', you can attach a "change" event handler like this:
var uploadContainer = document.querySelector('#my-uploader')
var uploader = new qq.FineUploader({
element: uploadContainer
...
})
uploadContainer.querySelector('.qq-edit-caption')
.addEventListener('change', function(event) {
// event handler logic here...
})
...and if you are creating this input element for each file and need to attach a "change" handler to all of these input elements, you should attach a single delegated event handler to the container element, and react based on the element that initially triggered the event (look at the target property of the event). You can determine the ID of the file by looking at the CSS class of the parent <li> of the event.target, or you can look for a 'qq-file-id' attribute on the parent <li> of the target element (the value will be the file ID). That code might look something like this:
var uploadContainer = document.querySelector('#my-uploader')
var uploader = new qq.FineUploader({
element: uploadContainer
...
})
uploadContainer.addEventListener('change', function(event) {
if (event.target.className.indexOf('qq-edit-caption') >= 0) {
var fileId = parseInt(event.target.getAttribute('qq-file-id'))
// ...
}
})

This might get you started:
$('.inp input').keyup(function(){
if (this.value.length > 0) {
$(this).closest('.row').find('.cell.btn button.upload').prop('disabled', false);
}else{
$(this).closest('.row').find('.cell.btn button.upload').prop('disabled', true);
}
});
* {position:relative;box-sizing:border-box;}
.row{overflow:hidden;}
.cell{float:left;height:40px;}
.pic{width:82px;}
.inp{width:230px;}
.inp input{font-size:1rem;padding:2px 5px;}
.btn{width:60px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="row">
<div class="cell pic">
<img src="http://lorempixel.com/80/40">
</div>
<div class="cell inp">
<input class='qq-edit-caption-selector qq-edit-caption kk-editing' placeholder='Enter Caption...'>
</div>
<div class="cell btn">
<button class="upload" disabled>Upload</button>
</div>
<div class="cell btn">
<button class="del" disabled>Delete</button>
</div>
</div><!-- .row -->

You can enable and disable the state of button by the input value.Using the Keyup function
$('.qq-edit-caption').keyup(function() {
if(this.value.length > 0){
$("#edit").prop('disabled', false);
}
else {
$("#edit").prop('disabled', true);
}
});

Have you tried the onchange event? Does it work?
<input class='qq-edit-caption-selector qq-edit-caption kk-editing' placeholder='Enter Caption here ...' onchange='captionUpdate();'>

Related

Input value of a cloned div not changing or firing events

I have a mock hidden div that I edit, clone and show to users. In this div is an input for which I set the value attribute using jQuery (tried with probably all methods). After I generate the new div and show it to users, the input does not fire any kind of events (focus, focusout, change) neither does the value of input change in HTML.
What am I missing or doing wrong?
Edit (code): HTML
<div class="item-wrapper" id="mock-item">
<div class="item-img"></div>
<div class="item-primary">
<p class="item-name">Foo Bar</p>
<input type="text" class="set-amount">
</div>
</div>
JS:
$("div.item-wrapper").click((e) => {
let item_id = e.currentTarget.id
let itemDetails = {
item_name: $(`#${item_id} .item.name`).text(),
suggested_amount: $(`#${item_id} #item-amount`).text(),
icon_url: $(`#${item_id} .item.big`).attr("style"),
}
$(".item-img", tmp).attr("style", itemDetails.icon_url)
$("#mock-item .item-name").text(itemDetails.item_name)
$("#mock-item .set-amount")[0].setAttribute("value", itemDetails.suggested_amont)
$("#mock-item").clone().removeAttr("id").appendTo(".item-wrapper").show()
})
Cloning an element removes all the event listeners from it. If you would like to listen for all event listeners on elements with a given selector, you can use jQuery's .on:
$(document).on("click", ".class", function () {
const $this = $(this);
});
You could also set the withDataAndEvents parameter on .clone to true: .clone(true).

jQuery display property not changing but other properties are

I'm trying to make a text editable on clicking it. Below is the code I'm trying. When the title is clicked it shows an input box and button to save it.
<div class="block">
<div class="title">Title</div>
<div class="title-edit">
<input type="text" name="title" value="Title">
<button>Save</button>
</div>
</div>
I have changed other properties like color or changing the text of the elements and its working, but it is not applying the display property or .show()/.hide() function on the title or edit elements.
Below is my jQuery
$(function(){
$('.block').on('click', editTitle);
$('.title-edit button').on('click', saveTitle);
});
function saveTitle(){
var parent = $(this).closest('.block');
var title = $('.title', parent);
var edit = $('.title-edit', parent);
$(title).show();
$(edit).hide();
}
function editTitle(){
$('.title-edit', this).show();
$('.title', this).hide();
}
Here's the jsfiddle
https://jsfiddle.net/ywezpag7/
I've added
$(title).html('abcd');
to the end to show that other properties/functions are working, but just not the display.
For checking the html change on title element you will have to check the source through developer tools cause the title element is hidden.
Where am I going wrong?
Your problem is in the function saveTitle. The first line must stop the event propagation otherwise after this function the editTitle function is called.
The snippet:
$(function(){
$('.block').on('click', editTitle);
$('.title-edit button').on('click', saveTitle);
});
function saveTitle(e){
// this line
e.stopPropagation();
var parent = $(this).closest('.block');
var title = $('.title', parent);
var edit = $('.title-edit', parent);
title.show();
edit.hide();
title.text($('.title-edit input').val());
}
function editTitle(e){
$('.title-edit', this).show();
$('.title', this).hide();
}
.title-edit{
display:none
}
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<div class="block">
<div class="title">Title</div>
<div class="title-edit">
<input type="text" name="title" value="Title">
<button>Save</button>
</div>
</div>
The issue as mentioned already is that your click events are fighting. In your code, the title-edit class is within the block, so when you click on the save button it triggers events for both clicks.
The easiest and, imho, cleanest way to resolve this is to switch your click event to be called on .title, and .title-edit button. You can also simplify the code beyond what you've got there.
$(function(){
$('.title').click(editTitle);
$('.title-edit button').click(saveTitle);
});
function saveTitle(){
$('.title').show();
$('.title-edit').hide();
$(title).html('abcd');
}
function editTitle(){
$('.title-edit').show();
$('.title').hide();
}
https://jsfiddle.net/ywezpag7/7/
I tried debug your code, and I had seen, that then you click to "Save" button, handled both functions, saveTitle() and editTitle(), and in that order. Therefore, the elements initially hidden, and then shown.

Removing a group of event listeners

I have a bunch of event listeners as illustrated below :
<a id="target0" >target0</a>
<div id="container">
<a id="target1" >target1</a>
<a id="target2" >target1</a>
<a id="target3" >target1</a>
.. more targets with event listeners
<script>
document.getElementById("#target1").addEventListener("click", ...);
document.getElementById("#target2").addEventListener("mouseover", ...);
document.getElementById("#target3").addEventListener("mouseout", ...);
...
</script>
</div>
<script>
document.getElementById("#target0").addEventListener("click", ...);
</script>
How do I write a function that will kill ALL DOM elements with event listeners binded to them ( with function reference or anonymous functions ) that are inside the container div ?
function killEvtListenersInsideContainerDiv(){
// loop to all DOM elements inside container that has event listeners and disable them
}
The container div is dynamically loaded by AJAX so the event listeners inside them will vary. The only one "static" is target0.
If you will have more than ont container you should add inside class for each a, something like this:
<div>
<a class="container1" id="#target1"></a>
...
</div>
To remove events there are two ways, I recommend the second because it easier and more modern:
1)Use native javascript, only if you can't use jquery for some technical reasons
var elements = document.getElementsByClassName("container1");
elements.forEach(function(elem, i, arr) {
element.removeEventListener("click");
}, this);
2)Use jquery:
//set
$('.container1').click(function() {
alert("click");
});
//remove
$('.container1').click(function(){}); //just empty function() :) the same as .click(null)
UPDATE: If you can't add class use this
javascript:
var elements = document.querySelector('#idDiv a'); //or '.classId a'
elements.forEach(function(elem, i, arr) {
element.removeEventListener("click");
}, this);
jquery
$('#idDiv a).click(function(){});
There is no way to check if event has been set before, if you really need you should implement this functionality with your hands(use flags for example). If function has already existed, new function will always override previous. In 99.9% cases it is enough.

How do I add an event listener to all the childnodes of a div in and array of those div?

I'm teaching myself JS and trying to avoid jQuery until my JS skills are better.
Goal: add an eventlistener, for click event, to all the divs of a certain class. Have all the child nodes of that class respond to the event.
My HTML
<div class="grid-panel six columns">
<div class="grid-panel-image">
<i class="fa fa-css3"></i>
</div>
<div class="grid-panel-title">
<h4>css3</h4>
</div>
</div>
<div class="grid-panel six columns">
<div class="grid-panel-image">
<i class="fa fa-paint-brush"></i>
</div>
<div class="grid-panel-title">
<h4>tamberator</h4>
</div>
</div>
I select all the .grid-panel divs using this JS
var gridPanels = document.querySelectorAll('.grid-panel');
then, since that returns an array of divs with the class .grid-panel
I add the event listener for click as such
for(i=0; i<gridPanels.length; i++){
gridPanels[i].addEventListener('click', myFunction);
}
my function is this
myFunction(){
var e = event.target;
switch(e){
case gridPanels[0]:
modalArray[0].setAttribute("data-modal-display", "show");
break
case gridPanels[1]:
modalArray[1].setAttribute("data-modal-display", "show");
break
}
console.log(e);
}
This does work if I click a very specific part of the .grid-paneldiv and the e logs that specific element. However, clicking any children of the div logs the e as the element i clicked, but the eventlistener is not applied to that element. I'm clearly missing something here with this event delegation. I really want the function to fire on the div clicked and all of its childnodes.
You're binding correctly, but if you want to get the element to which the handler is bound in the handler, then use this or event.currentTarget instead of event.target.
The event.target represents the actual element that was clicked, which is sometimes useful as well.
Also, you should define the event parameter in the function. Not all browsers have it available as a global variable.
function myFunction(event){
var e = this
// var e = event.currentTarget // same as above
switch(e){
case gridPanels[0]:
modalArray[0].setAttribute("data-modal-display", "show");
break
case gridPanels[1]:
modalArray[1].setAttribute("data-modal-display", "show");
break
}
console.log(e);
}

JS Events not attaching to elements created after load

Problem: Creating an Element on a button click then attaching a click event to the new element.
I've had this issue several times and I always seem to find a work around but never get to the root of the issue. Take a look a the code:
HTML:
<select>
<option>567</option>
<option>789</option>
</select>
<input id="Add" value="Add" type="button"> <input id="remove" value="Remove" type="button">
<div id="container">
<span class="item">123</span>
<br/>
<span class="item">456</span>
<br/>
</div>
JavaScript
$(".item").click(function () {
if ($("#container span").hasClass("selected")) {
$(".selected").removeClass("selected");
}
$(this).addClass("selected");
});
$("add").click(function() {
//Finds Selected option from the Select
var newSpan = document.createElement("SPAN");
newSpan.innerHTML = choice;//Value from Option
newSpan.className = "item";
var divList = $("#container");
divList.appendChild(newSpan);//I've tried using Jquery's Add method with no success
//Deletes the selected option from the select
})
Here are some methods I've already tried:
Standard jQuery click on elements with class "item"
Including using the `live()` and `on()` methods
Setting inline `onclick` event after element creation
jQuery change event on the `#Container` that uses Bind method to bind click event handler
Caveat: I can not create another select list because we are using MVC and have had issues retrieving multiple values from a list box. So there are hidden elements that are generated that MVC is actually tied to.
Use $.on instead of your standard $.click in this case:
$("#container").on("click", ".item", function(){
if ( $("#container span").hasClass("selected") ) {
$(".selected").removeClass("selected");
}
$(this).addClass("selected");
});
It looks to me like you want to move the .selected class around between .item elements. If this is the case, I would suggest doing this instead:
$("#container").on("click", ".item", function(){
$(this)
.addClass("selected")
.siblings()
.removeClass("selected");
});
Also note your $("add") should be $("#add") if you wish to bind to the element with the "add" ID. This section could also be re-written:
$("#add").click(function() {
$("<span>", { html: $("select").val() })
.addClass("item")
.appendTo("#container");
});

Categories

Resources