I am trying to replace a value in a drop down box. The replacing works fine (after help from this fine community) but afterwards the slide function stops working. I can't find any errors so I'm asking if this could be related to how jQuery and javaScript works? Are elements "mapped" to the DOM on load and if so; would that imply that replacing a div with another div would result in jQuery loosing track of the divs?
I use this code to check if a div is clicked:
$(document).ready(function () {
$('.button_slide').click(function () {
var num = $(this).attr('rel');
$('div.content_slide:not(.' + num + ') ').slideUp(400);
$('div.' + num).slideToggle(400);
});
return false;
});
This is the div:
<div class="button_slide" rel="slide1">Alts:</div>
<div class="content_slide slide1">
<input id="Button1" rel="slide1" class="button_vertical click_button" type="button" value="2" size="10px" />
<input id="Button2" rel="slide1" class="button_vertical click_button" type="button" value="3" />
</div>
This is the jQuery that drops down the box:
$(function () {
$('.click_button').click(function () {
var num = $(this).attr('rel');
$('.button_slide[rel="' + num + '"]').replaceWith("<div class='button_slide' rel='" + num + "' >" + $(this).val() + "</div>");
$('div.content_slide').slideUp(600);
});
});
I'm pulling my hair on this one and jQuery isn't my stronger side...
How would you solve this?
The click function adds a handler to the element(s) currently in the jQuery object.
The new replacement element doesn't have any handlers.
You need to call .live, which will add a handler to all elements that match a selector, whenever they were created.
For example:
$('.click_button').live('click', function() {
...
});
jQuery bind calls (e.g. click) bind to particular elements. If you replace one such element, any handlers bound to it will be removed.
The easiest way around this is to use the delegate syntax. This uses a Javascript feature called event bubbling, which means that events further up the DOM tree are also notified of an event on a child element. This allows you to bind to a parent element (e.g. document.body or a nearer common ancestor, depending on your HTML) and wait for events on the child element there:
$(document).ready(function () {
$(document.body).delegate('.button_slide','click', function () {
var num = $(this).attr('rel');
$('div.content_slide:not(.' + num + ') ').slideUp(400);
$('div.' + num).slideToggle(400);
});
return false;
});
Try this:
$('.click_button').live('click', function() {
... your code...
});
Delegate is better but since you say jQuery isn't your strong side, we won't go there for now :)
Basically what is happening is the new DIVs don't exist at the time you bind your event handler. Live() binds the event handler for all present and future divs by binding a single event handler to the document and searching for matches at the time of the event.
Hope this helps.
Related
In JsViews i can bind events in the following way:
<li id="myElement" data-link="{on 'click' eventHandler}">Some Content</li>
This will execute the method "eventHandler" after a click.
But I need an event which will be fired when the template is loaded. I tried "ready" or "show", but nothings works. Is there a event which can handle this?
The {on xxx eventHandler} handles events on HTML elements, such as mouse events, submit, change, blur, etc.
With JsViews, the loading of the template happens directly as a result of your own code calling the link method. So elements in the rendered template will have been rendered during that call, and immediately after you can run whatever code you want to call after rendering and linking, such as using jQuery to find your <li> element, and act on the element
JsViews also provides many life-cycle events on tags, so if you want you can create a custom tag just for handling those events:
For example, try running the following code:
<span id="result"></span>
<script>
var data = {};
$.views.tags("test", {
attr:"none",
render: function(data) {
debugger;
},
onBind: function(tagCtx, linkCtx) {
var elem = this.parentElem;
elem.textContent += " added text";
}
});
var myTmpl = $.templates('<ul><li id="myElement" data-link="{test}">Some Content</li></ul>');
myTmpl.link("#result", data);
$("#myElement").css('color', 'red');
</script>
You could use an onload event:-
https://www.w3schools.com/jsref/event_onload.asp
and attach that to the template itself. If you're limited in your options or need to do it in a specific way, explain the use case and why you want to do it a certain way and we'll try to help.
All the best,
Phil
I have a div with a close button on it. The close button has a function fired via Knockout.js that I would like to add a class to the parent of this button, i.e. the encapsulating div. However, in my JS file (see below) the function firing is linked to an object in an array.
HTML
<div>
<button data-bind="click: $parent.myFunc">
</div>
JS file
this.myFunc = function(e) {
// this.addClass('boo'); does not work
}
I can fire a console.log off in this function, but can't seem to manipulate this element through standard jQuery.
Knockout way of doing it would be to add a css binding to the parent and then manipulate it within your function fired by click event:
<div data-bind="css: someClass">
<button data-bind="click: myFunc">
</div>
And within your JS file:
this.someClass = ko.observable("");
this.myFunc = function(e) {
this.someClass("boo");
}
since you tagged jQuery, I assume you can use it, so:
$('button').click(function(){
$(this).parent().addClass('boo');
});
This is my first answer on here but how about looking into jQuery's .parent() api? http://api.jquery.com/parent/
I'm not familiar with Knockout.js but perhaps something like this could work..
$('button').data('bind','click: $parent.myFunc').click(function(){
$(this).parent().addClass('boo');
});
I'm trying to prevent the user from clicking on more than one postback-causing element on the page. In other words, if they click the 'continue' submit button, they shouldn't be able to cause another postback before the original request comes back.
I've had a go with two versions of jQuery code. Neither does exactly what I want:
This version will disable all the postback elements, but in doing so, it stops the clicked element from firing. For the record, I don't think the .removeAttr('onclick') is really required, but leaving it out doesn't seem to change the behaviour.
$(function() {
$('a, :button, :submit').click(function() {
var elements = $('a, :button, :submit');
elements.attr('disabled', 'disabled').removeAttr('onclick');
});
});
This version disables all other postback elements, but it lets me reuse the same element that was clicked - I don't want to be able to hit the same button twice.
$(function() {
$('a, :button, :submit').click(function() {
var otherelements = $('a:not(#' + $(this).attr('id') + '), :button:not(#' + $(this).attr('id') + '), :submit:not(#' + $(this).attr('id') + ')');
elements.attr('disabled', 'disabled').removeAttr('onclick');
});
});
How can I prevent this behaviour?
I just tested your first approach without JQuery, and it worked fine, i.e. disabling the submit button didn't prevent the form submission.
<form method="get">
<input type="text" name="textfield" value="a" />
<input type="submit" onclick="this.disabled=true">
</form>
Maybe you want to double check is there is anything else, e.g. JQuery, going on?
Maybe you could put a flag or something that it could remember what button it was clicked and if that flag exist, you can remove the onclick event on that postback-causing element. But I think this cannot be done in client side scripting alone, since once the page is submitted, all client side elements and scripts are refreshed.
Perhaps instead of making this a click function make it onmouseup so it fires after the click event has occured.
Here's a final version that worked - just overriding the form submit event rather than looking at any individual elements.
var submitted = false;
$(function() {
$('form').bind('submit', function() {
if (!submitted) {
submitted = true;
return true;
} else {
return false;
}
});
});
Thanks all for your suggestions.
I want basically the same as
jquery select image
a row of images that you can select one of.
But I'm trying to style the one I select, and store it.
var selectedicon = "";
function selecticon(){
$('#iconselect').children().click(function(){
$(".selectedicon").removeclass("selectedicon");
selectedicon = $(this).attr("src");
$(this).addclass("selectedicon");
});
}
on this
<div id="iconselect">
<img src="/red-dot.png" class="selectedicon" />
<img src="/green-dot.png" />
<img src="/blue-dot.png" />
<img src="/orange-dot.png" />
</div>
What am I doing wrong?
jQuery addClass and removeClass are mistyped (C should be capital).
Is the function selecticon called at all?
As you are not saying what does not work, here is a wild guess:
Probably the function selection() is never called and thus the click handler is never attached to the elements. Put your code into the document.ready callback instead:
var selectedicon = "";
$(function() {
// I would use $('#iconselect img').click(...)
$('#iconselect').children().click(function(){
$(".selectedicon").removeClass("selectedicon");
selectedicon = $(this).attr("src");
$(this).addClass("selectedicon");
});
});
This ensures that your code is executed once the DOM is loaded.
You also have some typos in the method names:
removeclass() must be removeClass()
addclass() must be addClass()
How can I have every button on an html page perform the same function using prototype.js?
I used the someElement.observe() method and it worked for one button. But how can I do this for every button on the page without coding separately for each button?
Use the css selector to select multiple elements:
$$('input[type="button"]').observe(...)
You can also use event delegation to register one event handler on the element that contains your buttons (e.g. the document body) and take advantage of the fact that events bubble up the DOM.
This will ensure that your event handler is called for every button, even if you dynamically add new buttons to the page.
E.g.
document.observe( 'click', function( event )
{
var elem = event.element();
if ( elem.match( 'input[type="button"]' ) )
{
// Do your event handler
}
});
You can use this also:
Event.observe(window, 'load', function(){
$('idForm').getInputs('radio', 'nameRadio').each(function(el){
el.onclick = function(){
//Actions<br>
});
});