Hi I have an abject called calc. And inside this I have several functions including init. I have three buttons which I am appending to the div using jquery. So when user clicks any button it will trigger inputs function and after some if else statement based on these conditions it will call one of the rest of the three functions which are calculate, reset and emailtofriend. The problem is the it does not invoke other functions except the input function. Why it behaves like this and how to make it work?
Here is my code
js
var jQuery, container, output,
calc = {
init: function () {
container = $('.calculate');
$(document).on('click','.userButtons',calc.input);
calc.widgetDesign(container);
},
widgetDesign: function (container) {
var widgetContainer = $('<div />').addClass('calculateContainer'),
form = $('<div />'),
buttons = $('<div />');
buttons.append('<button rel="reset" class="userButtons">Reset</button><button rel="emailtofriend" class="userButtons">Email to a friend</button>');
form.append('<div class="label">Weight (kg):</div>');
form.append('<input type="text" name="weight" class="weight inputs" />');
form.append('<div class="label">Height (cm):</div>');
form.append('<input type="text" name="height" class="height inputs" />');
form.append('<div><button rel="calculate" class="userButtons calcButton">Calculate</button></div>');
widgetContainer.append(form);
widgetContainer.append(buttons);
widgetContainer.appendTo(container);
},
input: function () {
var button = $(this).attr('rel');
if ( button == 'calculate' ) {
console.log(button);
calc.calculate;
} else if (button == 'reset') {
console.log(button);
calc.reset;
} else if (button == 'emailtofriend') {
console.log(button);
calc.emailtofriend;
}
},
calculate: function () {
console.log('hello');
},
reset: function () {
alert('reset');
},
emailtofriend: function () {
alert('emailtofriend');
}
};
calc.init();
here is jsfiddle
You will need to invoke the functions, not just select them :-)
if ( button == 'calculate' ) {
console.log(button);
calc.calculate();
// ^^
} else if (button == 'reset') {
console.log(button);
calc.reset();
// ^^
} else if (button == 'emailtofriend') {
console.log(button);
calc.emailtofriend();
// ^^
}
Btw: This can be written much shorter by using the bracket notation as a member operator:
if (button in calc) {
console.log(button);
calc[button]();
}
You should put parens at the end of function names () , like so:
if ( button == 'calculate' ) {
console.log(button);
calc.calculate();
} else if (button == 'reset') {
console.log(button);
calc.reset();
} else if (button == 'emailtofriend') {
console.log(button);
calc.emailtofriend();
}
Related
I need to write custom validated form in Wordpress. After the click on For-Author radio button some checkboxes group should be marked as not required. I tried to change "aria-required" attributes to "false" or remove and add class "wpcf7-validates-as-required" but it doesn't work. I also tried to reinit wpcf7 by
$('div.wpcf7 > form').wpcf7InitForm();
but it's also doesn't work.
This is a code sample:
$radio.button.click(function (event) {
isAuthor(event)
});
var isAuthor = function (event) {
if ($(event.target).attr('data-author') == 'true') {
authorClicked = true;
} else {
authorClicked = false;
}
fieldUpdate();
};
var fieldUpdate = function () {
var $text = $('[name=pres-title]');
if (authorClicked) {
$text.prop('disabled', false).attr('aria-required', true).addClass('wpcf7-validates-as-required').attr('aria-invalid', false)
$fieldRequired.each(function () {
$(this).prop('disabled', false).attr('aria-required', true).addClass('wpcf7-validates-as-required').attr('aria-invalid', false);
});
} else {
$text.prop('disabled', true).attr('aria-required', false).removeClass('wpcf7-validates-as-required').attr('aria-invalid', false);
$fieldRequired.each(function () {
$(this).prop('disabled', true).attr('aria-required', false).removeClass('wpcf7-validates-as-required').attr('aria-invalid', false);
});
}
}
I'm trying to add an autocomplete option to the title field in Wordpress - the titles of one of my custom document types will often (but not always) have a standard name.
I've hooked into Wordpress to add a div with an id of suggestions below title, and add a javascript onKeyUp event to title telling it to make an ajax request to a page that suggests names based on what's typed so far. This is all working fine.
Currently, however, I'm only able to select the suggestions via a mouseclick (which then uses val to update the value of #title. I'd also like users to be able to use the arrow keys to select a suggestion, a la Google.
I'm working on building this by giving each suggestion focus (each line is a li element with a dynamically generated tabindex.)
This works for a split second - the expected element gets the focus - but then it immediately loses it, going back to the body. Why is this happening?
Code for gethint.php:
<?php
$sofar = stripslashes($_GET['sofar']); // This is important as otherwise the url gets confused and won't work on anything with an apostrophe in it.
$common_file_names = array(
"Here's suggestion 1",
"This is suggestion 2",
"Suggestion 3");
if(strlen($_GET['sofar'])>1) { //Ignores single letters
echo '<ul id="autocomplete">';
$tabindex=0;
foreach ($common_file_names as $suggestion) {
if(false !== stripos($suggestion, $sofar)) : ?>
<li
tabindex="<?=$tabindex?>"
onClick="acceptSuggestion('<?=addslashes($suggestion)?>')"
onBlur="console.log('Lost focus!'); console.log(document.activeElement);";
><?=$suggestion?></li>
<?php $tabindex++; endif;
}
echo '</ul>';
}
?>
JS Code:
$.ajaxSetup({ cache: false });
window.onload = function () {
$( "<div id='suggestions'></div>" ).insertAfter( "#title" );
$(document).on('keydown', '#title', function (){
var hint_slash = this.value;
showHint(hint_slash);
checkKey(event);
});
$(document).on('focus', '#acf-field-extranet_client_area', function (){
clearSuggestions();
});
$(document).on('focus', '#acf-field-extranet_document_type', function (){
clearSuggestions();
});
$(document).on('focus', '#acf-date_picker', function (){
clearSuggestions();
});
$(document).on('focus', '#acf-file-value', function (){
clearSuggestions();
});
console.log("Scripts loaded successfully");
}
function showHint(str) { //If the user has typed 2 or more characters, this function looks for possible matches among common document names to speed up data entry.
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("suggestions").innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("GET", "/gethint.php?sofar=" + str, true);
xmlhttp.send();
}
function acceptSuggestion(str) {
$('#title').val(str); //Puts the clicked suggestion into the title box.
clearSuggestions();
}
function clearSuggestions() {
showHint(""); //Clears suggestions.
}
function checkKey(event) {
console.log('Key press: ' + event.keyCode);
if(40 == event.keyCode) {
event.preventDefault(); // Stops scrolling.
var autocomplete = $("#autocomplete");
$(autocomplete.children('li:nth-child(' + 2 + ')')).focus() ;
console.log(document.activeElement);
}
}
This is just test code currently, hence always setting focus to the 3rd child element.
I wouldn't try focus on the suggestions. You'll have to add the keychecking code to every suggestion in this case, because the input will lose focus. Instead, create a CSS class for the "focused" suggestion, remove the class on key up/down and add it to the previous/next suggestion...
$input.keyup(function(e) {
if(e.which == 38) {
// up key
var active = $('.suggestions li.active');
if(active.length) {
active.removeClass('active');
active.prev().addClass('active');
} else {
$('.suggestions li:last').addClass('active');
}
} else if(e.which == 40) {
// down key
var active = $('.suggestions li.active');
if(active.length) {
active.removeClass('active');
active.next().addClass('active');
} else {
$('.suggestions li:first').addClass('active');
}
}
});
Building on #evilunix's answer, I realised that each keystroke was resetting the #suggestions div, which meant that it could never hold focus (or keep an appended class etc).
So, wrote a new function called checkKey:
function checkKey(e) {
if(e.which == 38) {
// up key
e.preventDefault(); //Stops scrolling and cursor movement.
var active = $('#suggestions li.active');
if(active.length) {
active.removeClass('active');
active.prev().addClass('active');
} else {
$('#suggestions li:last').addClass('active');
}
} else if(e.which == 40) {
// down key
e.preventDefault(); //Stops scrolling and cursor movement.
var active = $('#suggestions li.active');
if(active.length) {
active.removeClass('active');
active.next().addClass('active');
} else {
$('#suggestions li:first').addClass('active');
}
} else if(e.which == 13) {
//Return key
e.preventDefault(); //Stops form submission.
acceptSuggestion(document.getElementsByClassName('active')[0].innerHTML);
} else {
console.log(e.which);
showHint($('#title').val());
}
}
and changed #title's onKeydown event to:
$(document).on('keydown', '#title', function (){
checkKey(event);
});
Now #suggestions only refreshes if the keystroke is not an up arrow, down arrow or return, and on a return runs acceptSuggestion on whichever li has the active class.
I have two different example one have mouseover functionality and other have click event functionality but now i want both together below are the description:
Mouseover Example Link: http://wheaton.advisorproducts.com/investment-advisory
Mouse click Example : http://ivyfa.advisorproducts.com/financial-planning-process
Requirement are like this
In this example ( http://ivyfa.advisorproducts.com/financial-planning-process ) right now mouseover functionality is working but now i want below functionality:
When user move mouse over the images then in center thier related text will be visible both for funnel and below circle example.
If user click on any of the image section then their related text will be visible everytime untill user click on another image or portion.
Along with this click event when user mousehover on diif-2 images section then also thier related text will be visible , when user move mouse out of the circle then the selcted text will be shown.
In the end i want to merge both the examples
Its very complicated to explain this example sorry for that :(
Below is the js code used for mouseover functionality:
/*-----Only for hove over image -show hide text------*/
var IdAry=['slide1','slide2','slide3','slide4'];
window.onload=function() {
for (var zxc0=0;zxc0<IdAry.length;zxc0++){
var el=document.getElementById(IdAry[zxc0]);
if (el){
el.onmouseover=function() {
changeText(this,'hide','show')
}
el.onmouseout=function() {
changeText(this,'show','hide');
}
}
}
}
function changeText(obj,cl1,cl2) {
obj.getElementsByTagName('SPAN')[0].className=cl1;
obj.getElementsByTagName('SPAN')[1].className=cl2;
}
Below is the js code used for click event functionality:
/*----------Text change on click - Our Process page---------------*/
var prev;
var IdAry = ['slide1', 'slide2', 'slide3', 'slide4'];
window.onload = function () {
for (var zxc0 = 0; zxc0 < IdAry.length; zxc0++) {
var el = document.getElementById(IdAry[zxc0]);
if (el) {
setUpHandler(el);
el.onmouseover = function () {
changeText(this,'hide','show')
}
el.onmouseout = function () {
changeText(this,'show','hide');
}
}
}
}
/*---------This is used to add selected class on clicked id only and remove class selected from rest---------*/
function setUpHandler(el) {
$("#" + IdAry.join(",#")).click(function () {
$(this).addClass("selected");
$("#graphics .selected").not(this).removeClass("selected");
})
/*---------This will add show hide class to thier spans and vise versa-------*/
$("#" + IdAry.join(",#")).click(
function () {
changeText(this, "hide", "show");
clearSelection();
},
function () {
changeText(this, "show", "hide");
clearSelection();
})
}
function changeText(obj, cl1, cl2) {
obj.getElementsByTagName('SPAN')[0].className = "hide";
obj.getElementsByTagName('SPAN')[1].className = "show";
if (prev && obj !== prev) {
prev.getElementsByTagName('SPAN')[0].className = "show";
prev.getElementsByTagName('SPAN')[1].className = "hide";
}
prev = obj
}
function clearSelection() {
if (window.getSelection) window.getSelection().removeAllRanges();
else if (document.selection) document.selection.empty();
}
Thanks
Sushil
You can add multiple event names to the same assignment:
$(document).on('mouseover click', '.yourObject', function (event) {
if (event.type === "mouseover") {
// Mouse-Over code here
} else if (event.type === "click") {
// Click code here
}
});
Also, try to use addEventListener instead of hardcoding events like el.onmouseout=function(){...}
use:
el.addEventListener("mouseout", function () {...});
That'll make it easier to manage the events (Remove them, for example), should that be needed.
You can add multiple events to a DOM by using
$(document).on('mouseover','.yourObject', function(){ //over code })
.on('click', '.yourObject', function() { //click code});
The problem with your code is that you are setting window.onload twice.
Since your are using jQuery you can make it work by binding on document.ready event.
//first sample
(function($){
/*-----Only for hove over image -show hide text------*/
var IdAry=['slide1','slide2','slide3','slide4'];
$(function() {
for (var zxc0=0;zxc0<IdAry.length;zxc0++){
var el=document.getElementById(IdAry[zxc0]);
if (el){
el.onmouseover=function() {
changeText(this,'hide','show')
}
el.onmouseout=function() {
changeText(this,'show','hide');
}
}
}
});
function changeText(obj,cl1,cl2) {
obj.getElementsByTagName('SPAN')[0].className=cl1;
obj.getElementsByTagName('SPAN')[1].className=cl2;
}
}(jQuery));
//second sample
(function($){
/*----------Text change on click - Our Process page---------------*/
var prev;
var IdAry = ['slide1', 'slide2', 'slide3', 'slide4'];
$(function () {
for (var zxc0 = 0; zxc0 < IdAry.length; zxc0++) {
var el = document.getElementById(IdAry[zxc0]);
if (el) {
setUpHandler(el);
el.onmouseover = function () {
changeText(this,'hide','show')
}
el.onmouseout = function () {
changeText(this,'show','hide');
}
}
}
});
/*---------This is used to add selected class on clicked id only and remove class selected from rest---------*/
function setUpHandler(el) {
$("#" + IdAry.join(",#")).click(function () {
$(this).addClass("selected");
$("#graphics .selected").not(this).removeClass("selected");
})
/*---------This will add show hide class to thier spans and vise versa-------*/
$("#" + IdAry.join(",#")).click(
function () {
changeText(this, "hide", "show");
clearSelection();
},
function () {
changeText(this, "show", "hide");
clearSelection();
})
}
function changeText(obj, cl1, cl2) {
obj.getElementsByTagName('SPAN')[0].className = "hide";
obj.getElementsByTagName('SPAN')[1].className = "show";
if (prev && obj !== prev) {
prev.getElementsByTagName('SPAN')[0].className = "show";
prev.getElementsByTagName('SPAN')[1].className = "hide";
}
prev = obj
}
function clearSelection() {
if (window.getSelection) window.getSelection().removeAllRanges();
else if (document.selection) document.selection.empty();
}
}(jQuery));
I'm trying to generate html on the fly with javascript. I'm binding on the click of buttons on my page. There are multiple buttons on my page which are causing my elements to be bound multiple times which produces the desired results to appear in the amount of times the button has been clicked.
My question is there something that can check if a element is already bound in jquery? If so, how do I incorporate that with the .live() function in jquery.
Here is my code:
$(document).ready(
function () {
$(':button').live("click", ".textbox, :button", function () {
alert("binding");
$(".textbox").click(function () {
defaultVal = this.defaultValue;
if (this.defaultValue) {
this.value = "";
}
});
$(".textbox").blur(function () {
if (this.value == "") {
this.value = defaultVal;
}
});
$('[name="numsets"]').blur(function () {
if (!parseInt(this.value)) {
$(this).val("you need to enter a number");
}
});
$('[name="weightrepbutton"]').click(function () {
var $numsets = $(this).parent().children('[name="numsets"]');
if ($numsets.val() != "you need to enter a number" && $numsets.val() != "Number of Sets") {
var numbersets = parseInt($numsets.val())
repandweight.call(this, numbersets)
$(this).hide();
$numsets.hide();
}
})
});
});
The problem is line 4, every time a button is clicked, all functions that were previous bound seem to be bound to the same function twice, which is a problem.
Thanks for the help!
You are doing it twice ! One inside another. Take out the outer binding and it should work
$(document).ready(function () {
$(document).on("click",".textbox",function () {
defaultVal = this.defaultValue;
if (this.defaultValue) {
this.value = "";
}
});
$(document).on("blur",".textbox",function () {
var item=$(this);
if (item.val() == "") {
item.val(defaultVal);
}
});
$(document).on("blur","input[name='numsets']",function () {
var item=$(this);
if (!parseInt(item.val())) {
item.val("you need to enter a number");
}
});
$(document).on("click","input[name='weightrepbutton']",function () {
var $numsets = $(this).parent().children('[name="numsets"]');
if ($numsets.val() != "you need to enter a number" && $numsets.val() != "Number of Sets") {
var numbersets = parseInt($numsets.val())
repandweight.call(this, numbersets)
$(this).hide();
$numsets.hide();
}
})
});
if you are using jQuery 1.7+ version, consider switching to jQuery on instead of live.
EDIT: Updated live to on as OP mentioned it in the comment.
I have this two HTML Form buttons with an onclick action associated to each one.
<input type=button name=sel value="Select all" onclick="alert('Error!');">
<input type=button name=desel value="Deselect all" onclick="alert('Error!');">
Unfortunately this action changes from time to time. It can be
onclick="";>
or
onclick="alert('Error!');"
or
onclick="checkAll('stato_nave');"
I'm trying to write some javascript code that verifies what is the function invoked and change it if needed:
var button=document.getElementsByName('sel')[0];
// I don't want to change it when it is empty or calls the 'checkAll' function
if( button.getAttribute("onclick") != "checkAll('stato_nave');" &&
button.getAttribute("onclick") != ""){
//modify button
document.getElementsByName('sel')[0].setAttribute("onclick","set(1)");
document.getElementsByName('desel')[0].setAttribute("onclick","set(0)");
} //set(1) and set(0) being two irrelevant function
Unfortunately none of this work.
Going back some steps I noticed that
alert( document.getElementsByName('sel')[0].onclick);
does not output the onclick content, as I expected, but outputs:
function onclick(event) {
alert("Error!");
}
So i guess that the comparisons fails for this reason, I cannot compare a function with a string.
Does anyone has a guess on how to distinguish which function is associated to the onclick attribute?
This works
http://jsfiddle.net/mplungjan/HzvEh/
var button=document.getElementsByName('desel')[0];
// I don't want to change it when it is empty or calls the 'checkAll' function
var click = button.getAttribute("onclick");
if (click.indexOf('error') ) {
document.getElementsByName('sel')[0].onclick=function() {setIt(1)};
document.getElementsByName('desel')[0].onclick=function() {setIt(0)};
}
function setIt(num) { alert(num)}
But why not move the onclick to a script
window.onload=function() {
var button1 = document.getElementsByName('sel')[0];
var button2 = document.getElementsByName('desel')[0];
if (somereason && someotherreason) {
button1.onclick=function() {
sel(1);
}
button2.onclick=function() {
sel(0);
}
}
else if (somereason) {
button1.onclick=function() {
alert("Error");
}
}
else if (someotherreason) {
button1.onclick=function() {
checkAll('stato_nave')
}
}
}
Try casting the onclick attribute to a string. Then you can at least check the index of checkAll and whether it is empty. After that you can bind those input elements to the new onclick functions easily.
var sel = document.getElementsByName('sel')[0];
var desel = document.getElementsByName('desel')[0];
var onclick = sel.getAttribute("onclick").toString();
if (onclick.indexOf("checkAll") == -1 && onclick != "") {
sel.onclick = function() { set(1) };
desel.onclick = function() { set(0) };
}
function set(number)
{
alert("worked! : " + number);
}
working example: http://jsfiddle.net/fAJ6v/1/
working example when there is a checkAll method: http://jsfiddle.net/fAJ6v/3/