Can't get access to the clicked element - javascript

I have input search and table, that generates automatically if I change input.
<div class="search">
<form action="" method="post" class="searchform" >
<input type="search" name="" placeholder="Search" class="inputsearchform" ng-model="search"/>
<input type="submit" name="" value="" class="submitsearchform" />
</form>
</div>
<div class="songlist">
<table id="songlistTableR" ng-app='test_table' ng-controller='main_control'>
<tr><th>Name</th><th>Link</th></tr>
<tr ng-repeat="data in loaded | filter:search">
<td><i class="fa fa-plus"></i>{{data.song_name}}</td>
<td><a href="{{data.link}}" target='_blank'>Youtube</a></td>
</tr>
</table>
</div>
JS script for generating data in table is:
var app = angular.module('test_table', []);
var n = [];
app.controller('main_control',function($scope,$http, $rootScope){
load();
function load(){
$http.get("http://localhost:7001/load").success(function(data){
$rootScope.loaded=data;
n = data;
});
}
});
I also have code, that shows table when input.value != 0
$('.inputsearchform').bind('input', function() {
if($(this).val() == 0){
songlistTableR.style.visibility = 'hidden';
}
else{
songlistTableR.style.visibility = 'visible';
}
});
Everything works good, but I can't get access to element .fa.fa-plus when it's clicked. The only two ways, that work are putting $(".fa.fa-plus").click(function(){}); in bind event or creating function outside window.onload that will work if I put in HTML file onclick for .fa.fa-plus element.
First method is bad, because if I change input more than one time, click function will work every time, even if I didn't click on this element.
Second method also isn't appropriate because I need to know index of clicked element.
Can anybody advise me a solution?
UPD Sorry for interruption, I solved this problem. I changed the version of Jquery to 2.2.2 and now it's working. Thanks for helping!

You may want to try to attach the event handler to the document but filtering on your selector. In this way even if the inner DOM changes, your handler will always intercept the event triggered by elements having the class fa fa-plus
$(document).on("click",".fa.fa-plus", function(){});
As #mhodges pointed out, this is a delegated event.

try to change this:
<td><i class="fa fa-plus"></i>{{data.song_name}}</td>
with:
<td><a ng-click="doSomething($event)" ><i class="fa fa-plus"></i>{{data.song_name}}</a></td>
then in the controller:
$scoope.doSomething() = function(event){
do what you need
}
just handle events in the angular way

Related

Dynamically added element is forcing a reload

I have a table that has a range of elements inside of it.
I have registered some event handlers and add these elements dynamically through injecting new html.
Everything works for the original elements, but when I add a new ( dynamically created element ) and trigger one of the newly created event handlers the page seems to force reload and I lose all of my data/content.
Here is a simplified version:
<table id="asset-table" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr class="asset-row">
<td align="center" style="padding-bottom: 32px;">
<form id="asset-title" class="asset-title">
<input type="text" placeholder="Add Asset Title Here ..." id="title-input1" />
<input id="title-submit" class="submit" type="submit">
</form>
<p id="asset-title-replacement" style="text-align: center; display: none;"><strong></strong></p>
</td>
</tr>
</table>
<button id="add-asset-button">Add Asset</button>
EventHandler
// asset title load
$('#asset-table').on("submit", '.asset-title', function (event) {
event.preventDefault();
console.log("asset-title");
let text = $(this).find('#title-input1').val();
let td = $(this).children().first()
td.find('.asset-title').hide();
td.find('.asset-title').next('p').text(function () {
return text
}).css("font-weight", "Bold");
td.find('.asset-title').next('p').show()
});
To add the new element:
$('#add-asset-button').click(function () {
console.log("adding asset");
$('#asset-table').append("<tr class='asset-row'><td align='center' style='padding-bottom: 32px;'><form id='asset-title' class='asset-title'><input type='text' placeholder='Add Asset Title Here ...' id='title-input1' /><input id='title-submit' class='submit' type='submit'></form><p id='asset-title-replacement' style='text-align: center; display: none;'><strong></strong></p>/td></tr>")
})
So when dynamically adding the element, everything goes as planned, it is once I interact with adding the new "title" and click submit that the page seems to reload and I lose any "state" and content previously handled.
The problem that I am having is that the eventHandler is bound to #asset-table, so when a dynamic element is created the "this" keyword is bound to the #asset-table element, so how can I specify which that I am working with for that event??
You will have multiple forms with the same id as you have it now, though that's not the main problem. You're also listening to .assetTitle rather than .asset-title and your listener is wrong, which are the main problem. When you do:
$('.asset-row').on("submit", '.assetTitle', function (event) {
...
})
jQuery will only listen for form submits within .asset-row that currently exist when the listener is attached. All of your subsequent .asset-rows with .asset-titles (not .assetTitle) that are created programmatically do not have listeners attached. Instead, you need to apply it to an element that is present when the listener is attached, and then listen to any programmatically-created elements within it, like this. Note that I've changed .assetTitle to .asset-title.
$('#asset-table').on("submit", '.asset-title', function (event) {
...
})
Fiddle

Detect change in an <input> field controlled by a slider

I have a form with a double-handles slider:
<form id="advancedSearch" action="modules/advanced_search.xq" method="post" onsubmit="advancedSearch(this);">
<div class="slider" id="slider" data-aria-valuemin="1725" data-aria-valuemax="1786" data-slider="data-slider" data-start="1725" data-end="1786" data-initial-start="1725" data-initial-end="1786">
<span id="handle1" class="slider-handle" data-slider-handle="data-slider-handle" role="slider" tabindex="1" aria-controls="dateFrom"/>
<span id="handle2" class="slider-handle" data-slider-handle="data-slider-handle" role="slider" tabindex="1" aria-controls="dateTo"/>
[...]
<input type="number" max="1786" min="1725" id="dateFrom" name="dateFrom"/>
</div>
<div class="cell small-2">
<input type="number" max="1786" min="1725" id="dateTo" name="dateTo"/>
[...]
</form>
It all works well.
Now, I'd like to call the function advancedSearch() when changing the slider's handle, without having to hit 'submit' each time.
Adding a oninput='advancedSearch(this.form); return false;' to the <input> elements does the trick only if I change the numbers inside the <input> field. When using the sliders, although document.getElementById('dateFrom').value does get changed, does not trigger the function. onchange also doesn't work. How can I call the function when changing the number by using the slider itself, other than changing the numbers inside the <input> field manually?
Adding a separate function:
document.getElementById('dateFrom').addEventListener('change', (event) => {
var formData = document.getElementById('advancedSearch')
advancedSearch(formData)
});
yields the same result.
Thanks to Prikesh Savla for pointing me towards the changed.zf.slider event. Unfortunately when implementing that with:
$("#slider").on('change changed.zf.slider', function(){ { var formData = document.getElementById('advancedSearch') advancedSearch(formData); }});
the page calls the function when loading it (either refreshing or landing there). After some troubleshooting I haven't been able to find the reason for that. In the end I'm adding this code:
document.querySelector('.slider').addEventListener("click", function () {
advancedSearch(document.getElementById('advancedSearch'));
});
document.getElementById('dateFrom').addEventListener("input", function () {
advancedSearch(document.getElementById('advancedSearch'));
});
document.getElementById('dateTo').addEventListener("input", function () {
advancedSearch(document.getElementById('advancedSearch'));
});
which does what I want, although I appreciate that it's not the most elegant solution.

Retrieve value from input next to a button using THIS selector

I ran into this problem, I have two siblings, an input and a button which calls a function to retrieve the value in the input, but it keeps telling me that Value is Undefined...
Here's the "form":
<li>
<input id="mem3" value="TestU4" disabled="">
<button id="del3" class="delmem" onclick="deleteBandMember();">remove</button>
</li>
Here's jQuery Code:
function deleteBandMember() {
var mmbr = $(this).prev("input").val(); //<-RETURNS UNDEFINED
}
I need to use This selector for there are too many dynamically-created inputs...
Thanks!
Pass this as parameter in deleteBandMember function as shown :-
HTML :-
<li>
<input id="mem3" value="TestU4" disabled="">
<button id="del3" class="delmem" onclick="deleteBandMember(this);">remove</button>
</li>
jQuery :-
function deleteBandMember(elem){
var mmbr = $(elem).prev("input").val();
}
Demo
Directly using jQuery, you can attach a click handler:
HTML:
<li>
<input id="mem3" value="TestU4" disabled="">
<button id="del3" class="delmem">remove</button>
</li>
JS:
$('#del3').click(function(){
var mmbr = $(this).prev("input").val();
})
While Kartikeya is correct. I would suggest not using "onClick" attributes, its no longer a good practise to do so. Plus you are using jQuery so you can take advantage of that. So your code would look like:
$('#del3').click( function() {
var mmbr = $(elem).prev("input").val();
// do more stuff.
})
Just as an aside since the question has a good answer, you might want to consider event delegation if you have a large number of inputs and buttons in your form. jQuery makes this very easy. Instead of attaching an event to each button, attach one event to an element that contains those elements (like <form>):
HTML
<form id="form">
...
<li>
<input id="mem3" value="TestU4" disabled=""></input>
<button id="del3" class="delmem">remove</button>
</li>
<li>
<input id="mem34" value="TestU44" disabled=""></input>
<button id="del34" class="delmem">remove</button>
</li>
...
</form>
JQUERY
$('#form').on('click', '.delmem', function() { deleteBandMember(this); });
DEMO

How to jump the control to an option in a dropdown list by just pressing the first letter of it from the keyboard?

Following is the html code I am using to create a dynamic list of VF pages along with the Jquery function I am using to achieve the functionality.I found that using the keypress element would help me in achieving the requirement which I am looking for, but it does not work.
HTML CODING
<div id="VFPageListsDropDown">
<span></span>
<button type="button" data-toggle="dropdowns" data-dropdowns="#dropdowns-1" class="btn btn-primary dropdowns-toggle" id="btnSort" >
<table width="100%">
<tr>
<td width="81%" id="BtnDropDown">Select VF Pages</td>
<td width="19%"> <span class="caret"></span></td>
</tr>
</table>
</button>
<span>
<div id="dropdowns-1" class="dropdowns dropdowns-tip">
<ul class="dropdowns-menu" id="VFPageListsDropDown"></ul>
</div>
</span>
</div>
Jquery function:
$('#').on('shown.bs.dropdown', function () {
var $this = $(this);
// attach key listener when dropdown is shown
$(document).keypress(function(e){
// get the key that was pressed
var key = String.fromCharCode(e.which);
// look at all of the items to find a first char match
$this.find("li").each(function(idx,item){
$(item).removeClass("active"); // clear previous active item
if ($(item).text().charAt(0).toLowerCase() == key) {
// set the item to selected (active)
$(item).addClass("active");
}
});
});
// unbind key event when dropdown is hidden
$('#').on('hide.bs.dropdown', function () {
$(document).unbind("keypress");
})
Please suggest me if there is any solution for it...

How to Input and Output Javascript?

Ok Guys I need help in this case and please help if you can :(
I have following div created with text-type input
<div class="footer">
<div id="footerInner">
<form>
<input type="text" name="enter" value="" id="input"/>
</form>
</div>
</div>
I have also created above .footer .mainBody
<div class="mainBody">
<script src="Scripts/main.js">
var h = document.getElementById('input').value;
document.write(h);
</script>
</div>
And I have included Javascript in it
I want to work it this way: when I input text in input tag to appear in .mainBody div.
And also do I need button to submit input or it can be done with key press for Ex. "Enter"?
Guys onkeyup="writeThis()" isn't working it just reloads page :(
To execute some events on keyevents, you need to write the onkeyup or onkeydown or any other key function in the element. And in that attribute you can add the function's name which would respond to the event. I will write my function's name as writethis() which will write the value to the div.
You then need to use this:
<input type="text" id="input" onkeyup="writethis()" />
And the function would be:
function writethis() { // the function
var h = document.getElementById('input').value; // the value
document.getElementsByClassName('mainBody').innerHTML = h; // the input
}
This way, you will get the input written on a keypress!
You can also try and use some keyevents such as:
if(event.keyCode == 13) { // enter key event
/* key code for enter is 13
* do what so ever you want */
}
Ok, try this as your JS script content in html head section:
function writeOnBody() {
var inputText = document.getElementById('input').value;
var mainBodyEl = document.getElementById('mainBody');
mainBodyEl.innerHTML = inputText;
}
your HTML code:
<div class="footer">
<div id="footerInner">
<form>
<input type="text" name="enter" value="" id="input" onkeyup="writeOnBody()" />
</form>
</div>
</div>
<div id='mainBody' class="mainBody"></div>
I hope it helps. JSFiddle sample: http://jsfiddle.net/amontellano/JAF89/
var h = document.getElementById('input').value; // the value
document.getElementsByClassName('mainBody').innerHTML = h;
avoid using getElementsByClassName instead give you div a id and use getElementById..
rest is in my opinion the best solution..
and yes you can also you a button also all you have to do is call you function on onclick event like this
<button onclick="functionZ()">click me</button>
and define that functionZ in your java script
What we are doing here is..
Adding a button and a click event upon it..such that when that button will be clicked it will call a function for us..
Make sure to add your scripts in lasts part of your page as page loads from top to bottom so its good practice to add scripts just near to end of body

Categories

Resources