Delegated click event doesn't fire - javascript

I am developing a web application. You can find the website here.
If you click on the "road" icon, and after the menu opened the plus sign ("+"), a text input will appear with a label. This <ul> is using the jQueryUI Sortable plugin, to - of course - be able to sort the addresses after input.
I would like to add a click event to the label of these address fields, so that when a user clicks the number, a dialog box will appear where he/she can manually edit the number (it can get a little counter-productive if there are hundreds of addresses).
Since the <li> elements, in which the label and the inputs are gets created later, I tried to delegate the click event, like so:
$(document.body).on('click', '.control-label', function () {
console.log($(this));
});
However the event never fires. I am starting to think that maybe the sortable plugin disables my events to that label?
Here is the HTML code of an address field (label+input+delete button)
<li>
<div class="form-group">
<label class="col-md-1 control-label">1.</label>
<div class="col-md-11 input-group">
<input type="text" name="waypoints[]" class="form-control form-control-square waypoint animated fadeInRight" placeholder="Megálló" autocomplete="off" required=""><span class="input-group-btn animated fadeInRight"><button type="button" class="btn btn-square btn-danger btn-removewaypoint animated fadeInRight">×</button></span>
<div class="search-suggestions">
<ul></ul>
</div>
</div>
</div>
</li>
Here is the addWaypoint() function which adds a new row. This gets called every time when the user clicks the + button.
Edit: Apparently it isnt the sortable plugin, but something else that blocks the click event. Anyone got any ideas?

You need to setup a variable related to each control-label class in order to console.log it (or alert it, or use it anyway you want).
This is how I suggest you modify the javascript:
$(document.body).on('click', '.conrtol-label', function () {
var spanText=$(this).text();
console.log($(this));
alert(spanText);
});
Maybe this fiddle would help: http://jsfiddle.net/jo6957au/1/
Modified to use li's http://jsfiddle.net/jo6957au/3/

Related

Detect new DOM elements and changes to input boxes - JQuery

Take a look at the following HTML:
<div id="tab1">
<input type="text">
</div>
<div id="tab2">
<input type="text">
<button>Add New Input Box</button> <!-- Adds another <input type="text"> in tab -->
</div>
<div id="tab3">
<input type="text">
<button>Hide Input Box</button> <!-- Adds style 'display:none' to input -->
</div>
I am looking for a way to detect changes to the DOM with JQuery. I am aware of MutationObserver objects and these are great but I would only like to detect changes in the following scenarios:
New HTML elements are added (see #tab2 button - 'Add new input box')
Text is entered into input box (see #tab1 input field)
And NOT detect changes where:
HTML element attributes are changed (see #tab3 button - 'Hide input box')
Of course MutationObserver will flag the changes when the HTML attributes change (which I don't want) but it will not flag when a user types into an input box (which I do want). For this reason I am thinking MutationObserver objects are not suitable for this problem (correct me if I'm wrong).
Are there any other things I can use for this?
My Scenario: Just to give you some more context, I am creating a save prompt to a data entry app that contains multiple tabs. It is easy to forget to save your changes before moving to the next tab but sometimes you may want to move to another tab without saving yet. I am trying to show the user an alert informing them that they have not saved when they click the next tab. Some fields can be hidden/shown on the click of a button which MutationObserver will detect as a change to the DOM even though they may not have entered any new values. Some values can be pulled from another location at the click of a button via ajax which although the user has not typed anything, it should still be flagged as a change that needs to be saved as the DOM has changed.
To detect new elements added or removed from tab2, only add and remove elements, you may use the events: DOMNodeInserted DOMNodeRemoved, while for the changes to the input field you may use the input event.
These events are deprecated because they will be removed from the web.
For a better description see Mutation events
$(function () {
$('div, #tab1 input').on('DOMNodeInserted DOMNodeRemoved webkitTransitionEnd input', function (event) {
switch (event.type) {
case 'input':
if (event.target.parentNode.id == 'tab1') {
event.stopImmediatePropagation();
alert('Content changed');
}
break;
case 'DOMNodeInserted':
if (event.target.parentNode.id == 'tab2') {
alert('Content added!');
}
break;
case 'DOMNodeRemoved':
if (event.target.parentNode.id == 'tab2') {
alert('Content removed');
}
break;
}
});
$('#add').on('click', function (e) {
$(this).after('<input type="text">');
});
$('#remove').on('click', function (e) {
$(this).siblings('input').remove();
});
$('#tab3 button').on('click', function (e) {
$(this).siblings('input').toggle();
})
});
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<div id="tab1">
<input type="text">
</div>
<div id="tab2">
<input type="text">
<button id="add">Add New Input Box</button>
<button id="remove">Remove All Input Boxes</button>
</div>
<div id="tab3">
<input type="text">
<button>Hide/Show Input Box</button>
</div>

How to re-disable (disable) the text box on clicking a button or a link?

I have a script that enables the disabled text box when clicking on a button. But, I just don't know how to re-disable the text box again.
The coding is below.
HTML:
<div class="input-group">
<label for="some-tbox" class="input-group-addon">Label:</label>
<input id="some-tbox" type="text" class="input-box" value="some value" disabled>
<span class="input-group-btn">
<button class="enable" type="button">button</button>
</span>
</div>
JS:
$(".enable").click(function(){
$(this).parent().parent().children(".input-box").removeAttr("disabled");
$(this).toggleClass("disable");
$(this).toggleClass("enable");
});
$(".disable").click(function(){
$(this).toggleClass("enable");
$(this).toggleClass("disable");
$(this).parent().parent().children(".input-box").attr("disabled", "disabled");
});
And I have made a fiddle out of it. But, It's not working. Here is the link.
Instead of messing with adding and removing classes, just toggle the disabled property with:
$(".enable").click(function() {
$(this).closest('.input-group').find('input').prop('disabled', !$(this).closest('.input-group').find('input').prop('disabled'))
});
jsFiddle example
The problem is this line $(".disable").click(function(){ ...})
You are binding a click event handler to a class named disabled which was not available initially during page load, it appears dynamically later.
You need to delegate the event handler to some parent which always exist and then handle the event there, in this case you can do this:
$(".input-group").on('click', '.disable', function(){
$(this).toggleClass("enable");
$(this).toggleClass("disable");
$(this).parent().parent().children(".input-box").attr("disabled", "disabled");
});
jQuery's on function
You cann't bind an element ".disable" that don't exist , In that case you can rebind it when you changed it's class. Code behind may help you:
$(".enable").on("click",enabledClick)
function enabledClick (argument) {
$(".enable").parent().parent().children(".input-box").removeAttr("disabled");
$(".enable").toggleClass("disable");
$(".enable").toggleClass("enable");
$(".disable").on("click",disabledClick)
}
function disabledClick (argument) {
$(".disable").parent().parent().children(".input-box").attr("disabled", "");
$(".disable").toggleClass("enable");
$(".disable").toggleClass("disable");
$(".enable").on("click",enabledClick)
}

How to set focus on text box whenever it appears on the screen

I've made a web application That starts from a specific amount and every time a donation is made it counts down and shows how much is needed. And at one time I might have about 10-20 of these counting down and I am always creating new ones. Now when I am doing that it would be nice that when I click the button it automatically focuses on the text field for ease of use. however I can't quite get that to work.
The window to set the countdown is shown using angularjs dialogs/modals. This means that when I click the a button it writes code onto the page that shows the dialog/modal and when I submit it it is removed from the page completely.
The first time around when I click the button it focuses on the text box and I can type the number and press enter and it's submitted, now I want to create a new one. I click the button, up comes the modal but now I have to grab the mouse, move it to the input and click it. Waste of time and not user friendly.
What I'm asking is for a way to have it focus on the text field when using modals every time I click the button.
here's the window:
<form name="formCountdown" novalidate class="css-form">
<div modal="showCountdownModal" close="showCountdownModal = false" options="opts" ng-cloak>
<div class="modal-header">
<h4>Enter Countdown Amount</h4>
</div>
<div class="modal-body">
<input id="focusbox" type="number" min="1" autofocus required ng-model="countDownAmount" name="countDownAmount" ui-keypress="{13:'setCountdown()'}" select-on-focus />
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary cancel" ng-disabled="formCountdown.$invalid" ng-click="setCountdown()">Set</button>
</div>
</div>
</form>
I've tried using autofocus, and that works fine the first time you press the button after loading the page. but the second and up it does not.
I've also tried using this jquery code with no luck:
<script>
$("#focusbtn").click(function() {
$("#focusbox").focus();
});
</script>
And now I am completely lost and would really love it if someone could help me out here.
Edit: forgot to put in the timeout, to make sure the browser is ready!
add the following line to your setCountDown() function:
$timeout(function (){
document.querySelector('#focusbox').focus();
},0)
You need to inject the $timeout in your controller
That will probably do the trick!
However, this will work, but dom manipulation should be done in a directive!
I copied your posted code together with the script and it works just fine. I'm not sure if I understood the problem but the autofocus works well in my end. Autofocus is present after the page has loaded or refreshed and even after the button has been clicked. Of course the autofocus will be removed if a click outside the input text has been triggered.
Morever, I think Autofocus is an attribute by HTML5. You might want to include in your HTML or maybe it is just a browser compatibility issue.
You can test or check if autofocus is supported by your browser at http://html5test.com/.
Hope this help somehow.
EDIT:
Try this on your script.
$(document).ready(function() {
$(".modalName").on('shown', function() {
$(this).find("[autofocus]:first").focus();
});
});

IDs not being recognized when placed in modals

I am creating a registration form where its contents are contained in DIV (hidden), then when the user clicks a button, the modal shows and the content is loaded through the ID of the DIV.
However, I am encountering a problem where the button of the DIV is not recognized in my script. I assigned a click event using jquery, but it doesn't work. Probably because the hidden DIV has conflicts with the DIV create in the modal (which will eventually have the same IDs).
Here is my script:
$('#addCollege').click(function(e){
modal.open({content: $('#addCollegeForm').html()});
e.preventDefault();`
});
This is the DIV
<div id="addCollegeForm" style="display:none">
<label>College:</label><br>
<input type="text" placeholder = "Enter college name here..." id = "collegeDescription" > <br>
<input type="button" value="Save" id= "addCollege">
</div>
Thanks and I appreciate your help.
I wrote a dialog plugin for bootstrap, and got a similar problem.
I want to pop up an existing dom element.
Here is solution:
$targetElement.detach().appendTo($window.find('.modal-body')) // $targetElement is an existing dom
Detach element and append it to container.
Don't forget to revert the element to old container.
Hope it helps.
Regards
Try moving the button that opens your dialog out of the dialog:
EDIT - something like this should work...
HTML...
<div id="addCollegeForm">things in your dialog</div>
<input type="button" value="open dialog" id="addCollege">
jquery...
$("#addCollegeForm").dialog({
autoOpen: false
});
$('#addCollege').click(function () {
$("#addCollegeForm").dialog("open");
});
http://jsfiddle.net/DTq6m/
http://api.jqueryui.com/dialog/#option-autoOpen

Show Interactive Html elements on top of an anchor tag

I have a area surrounded by an anchor tag and it should be directed to anchor tag href wherever user clicks on that area. And also that area should contain a textbox and button control which should allow user to type some text and submit. The problem is when I click on the textbox or button it does a redirect to the page given in anchor tag.
<a href="http://stackoverflow.com/">
<div style="border:1px solid grey;width:300px;height:100px;">
<div style="">Title</div>
<div>
<input type="text" name="name">
<button type="button" onclick="alert('button clicked');">Click Me!</button>
</div>
</div>
</a>
Please refer this jsfiddle.
I have created a simplified problem here.
However I found a solution for this by giving negative margin-top values. It is working but I am interested in a better solution. Because this solution is not scalable since the button and textbox are not inside the content div.
Each of these sections represent a item in a search result. When a user click on a search item it would navigate to single item page. At the same time users should be able to edit content from search results view by selecting edit option. When they select edit, a textbox and a button to submit should appear.
Unfortunately the HTML5 spec says about the <a> element:
Content model:
Transparent, but there must be no interactive content descendant.
What that means is, an <a> element is allowed to contain any elements that its parent is allowed to contain, except for things like <button>.
You'll need to find a way to get your <button> and <input> working outside of the <a>
Use this
<input type="text" name="name" onclick="return false;" />
Use this only if you don't want to change your markup.
The best solution is go with the semantics of HTML and style it. This way is not correct as Gareth pointed out.
In the case of your button
<button type="button" onclick="buttonClick(event);">Click Me!</button>
function buttonClick(e) {
alert('button clicked');
e.preventDefault();
}
Introduce a onclick for textfield and use stoppropagation method for a event. for ex ,
textfield.onclick = function(e) {
e.stopPropagation();
}
Another alternate is to use <div onclick="function()"> instead of <a> tag for what you think to achieve

Categories

Resources