Unable to call JS function from onclick event - javascript

I am trying to call a JavaScript function from the onclick event of two different buttons. I have dug around and searched for like problems but have not found a solutions. When I click either button I get the error
Error: 'RemoveCode' is undefined'
What am I doing wrong?
<script type="text/javascript">
$(document).ready(function ()
{
function RemoveCode(codeType)
{
var selectedProjectsField = $("#SelectedProjects");
var selectedProjectCodesField = $("#SelectedProjectCodes");
var selectedTasksField = $("#SelectedTasks");
var selectedTaskCodesField = $("#SelectedTaskCodes");
var selectedOption;
if (codeType = "Project")
{
selectedOption = $("#SelectedProjects :selected").index();
}
else
{
selectedOption = $("#SelectedTasks :selected").index();
}
alert(selectedOption);
}
});
</script>
Code for my buttons:
<li>
<label for="SelectedProjects">Selected Projects:</label>
<select size="1" id="SelectedProjects" name="SelectedProjects" multiple></select> <button class="removeButton" onclick="RemoveCode('Project')" type="button">-</button>
</li>
<li>
<label for="SelectedTasks">Selected Tasks:</label>
<select size="1" multiple id="SelectedTasks" name="SelectedTasks"></select> <button class="removeButton" onclick="RemoveCode('Task')" type="button">-</button>
</li>
I should note that on the same page there are multiple change events for the other elements on the page and they all work fine. It is just this `onclickP that is failing.

Firstly note that in your if condition you need to use == (not =) to compare values.
To solve your issue you have two options. Firstly you could simply move the RemoveCode function out of the scope of the document.ready handler so that it can be accessed from the onclick attribute:
<script type="text/javascript">
function RemoveCode(codeType)
{
// your code...
}
$(document).ready(function ()
{
// your code...
});
</script>
Alternatively, it would be much better practice to add your event handlers using unobtrusive Javascript. As you're using jQuery, here's how you can do that:
$(function() {
$('button').click(function() {
var $selectedProjectsField = $("#SelectedProjects");
var $selectedProjectCodesField = $("#SelectedProjectCodes");
var $selectedTasksField = $("#SelectedTasks");
var $selectedTaskCodesField = $("#SelectedTaskCodes");
var selectedOption;
if ($(this).data('codetype') == "Project") {
selectedOption = $selectedProjectsField.find(':selected').index();
} else {
selectedOption = $selectedTasksField.find(':selected').index();
}
alert(selectedOption);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<label for="SelectedProjects">Selected Projects:</label>
<select size="1" id="SelectedProjects" name="SelectedProjects" multiple></select>
<button class="removeButton" data-codetype="Project" type="button">-</button>
</li>
<li>
<label for="SelectedTasks">Selected Tasks:</label>
<select size="1" multiple id="SelectedTasks" name="SelectedTasks"></select>
<button class="removeButton" data-codetype="Task" type="button">-</button>
</li>
</ul>

You are defining your RemoveCode method inside a closure. This function will thus not be available as onclick callbacks of your HTML elements.
You can just update your code to this and it should work:
<script type="text/javascript">
function RemoveCode(codeType)
{
var selectedProjectsField = $("#SelectedProjects");
var selectedProjectCodesField = $("#SelectedProjectCodes");
var selectedTasksField = $("#SelectedTasks");
var selectedTaskCodesField = $("#SelectedTaskCodes");
var selectedOption;
if (codeType = "Project")
{
selectedOption = $("#SelectedProjects :selected").index();
}
else
{
selectedOption = $("#SelectedTasks :selected").index();
}
alert(selectedOption);
}
</script>

put your function out side of document.ready()
<script type="text/javascript">
$(document).ready(function () // No Need of this Function here
{ });
function RemoveCode(codeType) // Automatically load when Your page is getting loaded on Browser.
{
var selectedProjectsField = $("#SelectedProjects");
var selectedProjectCodesField = $("#SelectedProjectCodes");
var selectedTasksField = $("#SelectedTasks");
var selectedTaskCodesField = $("#SelectedTaskCodes");
var selectedOption;
if (codeType = "Project")
{
selectedOption = $("#SelectedProjects :selected").index();
}
else
{
selectedOption = $("#SelectedTasks :selected").index();
}
alert(selectedOption);
}
</script>

You are defining your ready() method inside of a closure.
You then have two approaches you can use. First is you can not use $(document).ready() as the buttons that call ready() can't be clicked until the document is ready anyway.
Second is you could bind the onclick inside of your $(document).ready().
$(document).ready(function() {
$('#firstItem').click(function() { Ready('Project'); });
....
});

Related

Javascript plugin needs to call back to client's Javascript

I am working on a plugin that allows to add an item to the shopping cart. The plugin is mine, and the shopping cart belongs to the customer. The idea is to add my plugin with a few lines of code to configure.
Once an item is bought, I need to call a function on the customer page so it can be added to the cart, but I didn't manage.
I have this code:
<script type="text/javascript">
$(document).ready(function () {
//plugin1.CallBackTest;
});
var plugin1 = new function() {
this.CallBackTest = function (str) {
console.log("callback in class");
FunctionIWantToCall(str);
}
}
function FunctionIWantToCall(str) {
console.log("callback on client " + str);
}
</script>
<div class="htmlcreatedbyplugin">
<button onclick="CallBackTest('something')">send back</button>
</div>
if I change this line to
send back
it will work, but this html is generated through the plugin class, and I don't know how to retrieve the name of the variable.
The customer should be able to tell the plugin which function to call, e.g
plugin1.AddToCartFunction = FunctionIWantToCall;
Any ideas?
Thank you Stavros Angelis, it works:
<script type="text/javascript">
$(document).ready(function () {
plugin1.CallBackFunction = "FunctionIWantToCall";
});
var plugin1 = new function () {
var myplugin = this;
this.CallBackFunction = "";
this.CallBackTest = function () {
console.log("callback in class");
var item = JSON.parse($(this).attr("vals"));
if (myplugin.CallBackFunction != "") {
window[myplugin.CallBackFunction](item);
}
}
function BindCartButtons() {
console.log("binding buttons")
$(document).on("click", ".htmlcreatedbyplugin > button", myplugin.CallBackTest);
}
BindCartButtons();
}
function FunctionIWantToCall(item) {
console.log("callback on client " + item.id);
}
</script>
<div class="htmlcreatedbyplugin">
<button type="button" vals="{"id":12345, "color":"blue"}">Buy Me</button>
</div>

Nested quotes in javascript and html

I have a big problem with quotes in java script and html dom.
I want to use just double quotes("), not ' at all!
Here is my code:
<a onclick="aClicked("<span onclick="spanClicked("You clicked me")">I'm an Span</span>")">Add span</a>
<script type="text/javascript">
function aClicked(str) {
$(document).append(str);
}
function spanClicked(str) {
alert(str);
}
</script>
Can anyone help throw kind of these problems!?
Tanks.
here is my original code (it work correctly but I just want to simplfy it and underestand it):
"I call this function with ajax"
<?php
function getTags() {
$values = ['test1', 'test2'];
$valuesString = '';
$baseSpanString = '<span><span class="tag">?</span><a onclick="Tags.Update($(this).parent().parent(), $(this).parent(), "tag");">x</a></span>';
foreach ($values as $tmpValue) {
if(trim($tmpValue) == '') {
continue;
}
$valuesString .= str_replace('?', $tmpValue, $baseSpanString);
}
$xhtml = '
<div>
<input type="text" onkeydown="return Tags.Insert($(this).parent(), $(this), event, \''.str_replace('"', '\\\'', $baseSpanString).'\', \'tag\');"/>
<textarea style="display:none;">'.implode('-', $values).'</textarea>
'.$valuesString.'
</div>
';
return $xhtml;
}
?>
<script type="text/javascript">
Tags = {};
Tags.Update = function(div, span, tagClass) {
div = $(div);
if(!div.length) {
alert('Error');
return false;
}
$(span).remove();
var tagsSpan = $('.'+tagClass, div);
var tagsString = [];
if(tagsSpan.length) {
$.each(tagsSpan, function(index, val) {
tagsString.push($(val).text());
});
}
$('textarea', div).text(tagsString.join('-'));
};
Tags.Insert = function(div, input, event, baseSpanString, tagClass) {
if (event.keyCode == 13)
{
div = $(div);
input = $(input);
if(!div.length || !input.length) {
alert('Error');
return false;
}
var val = input.val();
if(val && val != '') {
input.val('');
var spanString = baseSpanString.replace('?', val);
div.append(spanString);
}
var tagsSpan = $('.'+tagClass, div);
var tagsString = [];
if(tagsSpan.length) {
$.each(tagsSpan, function(index, val) {
tagsString.push($(val).text());
});
}
$('textarea', div).text(tagsString.join('-'));
return false;
}
};
</script>
Two answers:
Your string question
The right way instead
Your string question
' is the feature specifically designed for this. But sometimes this stuff does legitimately come up...
The key is to be aware of what kind of text you're dealing with at each stage:
Within the " of the attribute (onclick="..."), you're writing HTML text, even though what you're writing in that HTML text is JavaScript. So you can use " for quotes if you insist on not using '.
If you need to use a string within your JavaScript code (such as the onclick in the string we're passing aClicked) and insist on not using ', put a \ before the ".
If you need to use a quote within an HTML string within an HTML string (such as the string being passed to spanClicked, which is an HTML string inside a JavaScript string inside an HTML string), then you need something that will end up being " after the entities in the first HTML string are processed. So that's &quot;
So:
<a onclick="aClicked("<span onclick=\"spanClicked(&quot;You clicked me&quot;)\">I'm an Span</span>")">Add span</a>
Example:
function aClicked(str) {
$(document.body).append(str);
}
function spanClicked(str) {
alert(str);
}
<a onclick="aClicked("<span onclick=\"spanClicked(&quot;You clicked me&quot;)\">I'm an Span</span>")">Add span</a>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
The right way instead
But again, this is all just a way to make your code complicated unmaintainable; instead, just use jQuery, as you're already using jQuery:
Example:
$("a").on("click", function() {
var span = $("<span>I'm a span</span>");
span.on("click", function() {
spanClicked("You clicked me");
});
$(document.body).append(span);
});
function spanClicked(str) {
alert(str);
}
<a>Add span</a>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
As you are using jQuery use unobtrusive event handlers, for this .on() method can be used. When generating elements dynamically you need to use Event Delegation.
I would also recommend you to use semantically correct elements, thus used <button> element
$("#addSpan").on("click", function() {
$('#container').append("<span class=\"myspan\">I'm an Span</span><br/>");
})
$("#container").on("click", ".myspan", function() {
console.log("You clicked me");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" id="addSpan">Add span</button>
<div id="container">
</div>
Better make it as a function like this
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a onclick="adds();">Add span</a>
<script type="text/javascript">
function adds(){
aClicked("<span onclick='spanClicked(\"You clicked me\")'>I'm an Span</span>");
}
function aClicked(str) {
$(document.body).append(str);
}
function spanClicked(str) {
alert(str);
}
</script>

how to move selected item in a list using up and down arrow keys in javascript?

I am trying to implement up and down arrow buttons for a list in HTML. the up arrow moves the selected element of list upwards and the down arrow moves the selected list element downwards. I tried this code, but not working ::
function reorder_up(node) {
$(".go_up").click(function() {
var $current = $(this).closest('li')
var $previous = $current.prev('li');
if ($previous.length !== 0) {
$current.insertBefore($previous);
}
return false;
});
}
function reorder_down(node) {
$(".go_down").click(function() {
var $current = $(this).closest('li')
var $next = $current.next('li');
if ($next.length !== 0) {
$current.insertAfter($next);
}
return false;
});
}
// for adding to the result page i am using this function, where i am creating a list dynamically and provinding the id to the selected element when clicking on it. I need to move up - down in the result section of the list ::
function add_to_result() {
//var moparent = document.getElementById("parent").innerHTML;
var moname = document.getElementById("moselect").innerHTML;
var node = document.createElement('LI');
node.setAttribute('onclick', 'giveid_Result(this)');
node.setAttribute('ondblclick', 'fillprops()');
var text = document.createTextNode(moname);
node.appendChild(text);
document.getElementById("result").appendChild(node);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button type="button" class='go_up' onclick="reorder_up(this)" style="height:40px;width:40px">↑</button>
<button type="button" class='go_down' onclick="reorder_down(this)" style="height:40px;width:40px">↑</button>
<div id="results">
<div class="boxheader">
<STRONG>RESULTS</STRONG>
</div>
<div class="boxcontent">
<ul id="result">
</ul>
</div>
</div>
Your jQuery click event listeners are added after the click event happens so they are never handled, on the click event you are just binding the click handler. Move the $().click outside of the onclick and since you are using jQuery selectors for the buttons you can get rid on onclick
$(".go_up").click(function() {
var $current = $(this).closest('li')
var $previous = $current.prev('li');
if ($previous.length !== 0) {
$current.insertBefore($previous);
}
return false;
});
$(".go_down").click(function() {
var $current = $(this).closest('li')
var $next = $current.next('li');
if ($next.length !== 0) {
$current.insertAfter($next);
}
return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button type="button" class='go_up' style="height:40px;width:40px">↑</button>
<button type="button" class='go_down' style="height:40px;width:40px">↑</button>
<div id="results">
<div class="boxheader">
<STRONG>RESULTS</STRONG>
</div>
<div class="boxcontent">
<ul id="result">
</ul>
</div>
</div>
var selected;
for(var x=0;x<5;x++){
addToResult("Node:"+x);
}
$("li").click(function(){
console.log("pressing"+$(this).attr("id"));
select($(this))
});
$(".go_up").click(function(){reorder_up(selected)});
$(".go_down").click(function(){reorder_down(selected)});
function reorder_up(node) {
var dnode=node;
console.log("RUP");
var $current = $(dnode).closest('li')
$current.css("background-color","blue");
var $previous = $current.prev('li');
$previous.css("background-color","yellow");
if ($previous.length !== 0) {
$current.insertBefore($previous);
}
return false;
}
function reorder_down(node) {
console.log("RDO");
var dnode=node;
var $current = $(dnode).closest('li')
$current.css("background-color","blue");
var $next = $current.next('li');
$next.css("background-color","yellow");
if ($next.length !== 0) {
$current.insertAfter($next);
}
return false;
}
// for adding to the result page i am using this function, where i
//am creating a list dynamically and provinding the id to the selected
//element when clicking on it. I need to move up - down in the result section of the list
// ::
function addToResult(id) {
var node = document.createElement('li');
node.setAttribute('id',id);
// node.setAttribute('onclick', 'select(id)');
node.setAttribute('ondblclick', 'fillprops()');
var text = document.createTextNode(id);
node.appendChild(text);
document.getElementById("result").appendChild(node);
}
function select(selector){
selector.css("background-color","green");
console.log("youre pressing"+selector.attr("id"));
selected=selector;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" class='go_up' style="height:40px;width:40px">↑</button>
<button type="button" class='go_down' style="height:40px;width:40px">↓</button>
<div id="results">
<div class="boxheader">
<STRONG>RESULTS</STRONG>
</div>
<div class="boxcontent">
<ul id="result">
</ul>
</div>
</div>
The $(something).click query executes when you click on that something. So it doesn't make sense to put into a function. You want it to trigger some function execution.
I added the dnode var to keep the scope of the node since this is no longer attached to the node when you call reorder node. So I substituted this with dnode and it works fine. Here is the fully working code:
Javascript:
for(var x=0;x<5;x++){
add_to_result("Node"+x);
}
$("li").click(function(){
select($(this))
});
$(".go_up").click(function() {
reorder_up(selectedNode);
});
$(".go_down").click(function() {
reorder_up(selectedNode);
});
function reorder_up(node) {
var dnode=node;
var $current = $(dnode).closest('li')
var $previous = $current.prev('li');
if ($previous.length !== 0) {
$current.insertBefore($previous);
}
return false;
}
function reorder_down(node) {
var dnode=node;
var $current = $(node).closest('li')
var $next = $current.next('li');
if ($next.length !== 0) {
$current.insertAfter($next);
}
return false;
}
You can remove the onclik attribute from html. It is not needed
About the add to result function: There is no element with the moselect id, so moname is null and the compiler gives an error. Next, you never call it so it will never execute. You should add a loop somewhere to add the elements. You don't need to set attribute onclick, just use a jquery
selector.I added set attribute id to pass it to select function. By the way, I don't see give_id function anywhere so I created a function to select the node to be moved
function add_to_result(id) {
var node = document.createElement('li');
node.setAttribute('id',id);
node.setAttribute('ondblclick', 'fillprops()');
var text = document.createTextNode(id);
node.appendChild(text);
document.getElementById("result").appendChild(node);
}
function select(selector){
selector.css("background-color","green");
console.log("youre pressing"+selector.attr("id"));
selected=selector;
}

How can I address the element that called a function from within the function?

I am trying this HTML code:
<button name="darkBlue" onclick="setThemeColor(this.name)">Blue</button>
<button name="black" onclick="setThemeColor(this.name)">Black</button>
and script:
function setThemeColor(buttonName) {
localStorage.themeColor = buttonName;
document.getElementsByTagName('html')[0].className = buttonName
var themeButtons = document.querySelectorAll(".theme");
for (var button in themeButtons) {
themeButtons[button].disabled = false;
}
// this.disabled = false;
// element.setAttribute("disabled", "disabled");
}
I am having a problem here setting the disabled state of the button that called the function. Can someone tell me how i can do this. I have tried two things but neither seem to work.
Pass in a reference to your button instead of just the name:
HTML
<button name="darkBlue" onclick="setThemeColor(this)">Blue</button>
<button name="black" onclick="setThemeColor(this)">Black</button>
JS
function setThemeColor(button) {
localStorage.themeColor = button.name;
document.getElementsByTagName('html')[0].className = button.name;
var themeButtons = document.querySelectorAll(".theme");
for (var button in themeButtons) {
themeButtons[button].setAttribute("disabled", "disabled");
}
button.setAttribute("disabled", "disabled");
}
document.getElementById("buttonid1").disabled=false;

Jquery all my functions work except the following

(function($) {
var selectIds = new Array();
var sortOnSelect = false;
var nameModifier = "tsms";
function removeFormField() {
$(id).remove();
}
All the other functions after this work. This function says it undefined using firebug.
removeFormField is not defined
Another function creates this field and the top function is suppose to remove it.
<label for="txt4">Field 4 <input type="text" id="txt4" name="txt[]" size="20"> <a onclick="removeFormField("#row4"); return false;" href="#">Remove</a></label>
You need to put your function outside of the document ready function then call it from within.
(function($) {
var selectIds = new Array();
var sortOnSelect = false;
var nameModifier = "tsms";
removeFormField();
});
function removeFormField() {
$(id).remove();
}
In addition to the problem where the function is declared in the jQuery ready() handler, your function as written does not take an input value.
It should be:
function removeFormField(id) {
$(id).remove();
}

Categories

Resources