How to change parameters in javascript function written in html - javascript

I have some function in html code.
<span id='test' onclick="test("1", "2")">Click Me</span>
after executing i need to replace this function by other with other parameters. can you advice if it is any opportuity to write this function not by eventlistener, but as html-attribute with the aim to see this function as html code, delete this
onclick="test("1", "2")
and add new one dynamically in html code
onclick="test("3", "4")

You'd have to change the attribute (as long as it can be represented as a string) or reference a global variable.
<span id='test' onclick="test(window.globalVar1, window.globalVar2)">Click Me</span>
However this probably shouldn't be done. It would be better to have test() call a function with your parameters.
var actualFunction = function() { // your actual function }
var wrapper = function() { actionFunction.apply(null, arrayOfArgs); }
Then the html-
<span id='test' onclick="wrapper()">Click Me</span>

Beginning, you have a syntax problem (You cannot use " in attribute value), change your HTML:
<span id='test' onclick="test('1', '2')">Click Me</span>
You change attribute onclick by jQuery:
$( document ).ready(function() {
$('#test').attr('onclick',"alert('3','4')");
});
JSFiddle:
http://jsfiddle.net/LACqP/
Enjoy your code!

If your must intrude your html with javascript then here:
HTML
<span id='test' onclick="test()">Click Me</span>
Javascript
// Note: This script must go before the html unless you have a onDocReady
var testA = 1,
testB = 2;
function test () {
// use testA & testB for testing
...
// test is over increment them
testA++;
testB++;
}

Related

detect element where the function was called from

I need to know where my jQ function was called from...
In head:
function call_pl2(){
$(this).text('some text');
}
in Body:
<p> <script> call_pl2(); </script> </p>
<!-- OR -->
<div> <script> call_pl2(); </script> </div>
I got your point, I'm afraid you cannot get from the function the element that your js function is there, but each time that your function is called you can use another function and search your html content to see where this function is inside. I assume that this function is called ones from the html code when this is loaded.
Instead of trying to determine which element contains the the script tag (and, by extension, a particular call to call_pl2()) you could explicitly pass the containing element to call_pl2() as a parameter:
$(function() {
var call_p12 = function(element) {
if ($(element).is('p')) {
$(element).text('here is some text added to a paragraph');
}
if ($(element).is('div')) {
$(element).text('here is some text added to a div');
}
}
$('div, p').each(function() {
call_p12($(this));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<p></p>
<div></div>
It would be relatively easy to modify the call_p12() function to swap in a more specific selector in the jQuery is(). For example is('.someclass') to check for a class value instead of a tag name.

How to change class name of two IDs at same time using js?

I have two IDs in same name ! if any one clicked among them , i need to change the class name of the both IDs. i know we should use ID for single use. Because of my situation(I have two classes for button ) so i have moved to ID.
Her is my code if i click one id that name only changes another one is remains same
<button class="success" id="1" onClick="reply(this.id)"> Added </button>
<button class="success" id="1" onClick="reply(this.id)"> Added </button>
js function
function reply(clicked_id)
{
document.getElementById(clicked_id).setAttribute('class', 'failed');
var el = document.getElementById(clicked_id);
if (el.firstChild.data == "Added")
{
el.firstChild.data = "Add";
}
}
if i use instead of 'class' to id while renaming class which one will be renamed success class or 'class name 1' ?
You can't. Getelementbyid will only return one element. Probably the first one.
Pure JS Is Second Example
My JS Fiddle Example: http://jsfiddle.net/eunzs7rz/
This example will use the class attribute only to perform the switching that you need, its a extremely basic example as do not want to go beyond what is needed... Also i forgot to remove the id's in the JS Fiddle Example.. so just ignore them
THE CSS:
.success {
background-color:#00f;
}
.failed {
background-color:#f00;
}
THE HTML:
<button class="success"> Added </button>
<button class="success"> Added </button>
THE JAVSCRIPT:
$(function() {
$(".success").click(function(){
Reply(this);
});
});
function Reply(oElm) {
$(oElm).attr('class', 'failed');
}
EDIT - PURE JAVASCRIPT VERSION
Sorry, did not think to check the post tags if this was pure JS. But here you go anyway ;)
<style>
.success {
background-color:#00f;
}
.failed {
background-color:#f00;
}
</style>
<button class="success" onclick="Reply(this)"> Added </button>
<button class="success" onclick="Reply(this)"> Added </button>
<script>
function Reply(oElm) {
oElm.className = 'failed';
}
</script>
THE MAIN THING HERE
Once you have the element either by using 'this' or by using 'getElementBy', you can then simply use ".className" to adjust the class attribute of the selected element.
As already explained by others, id is for single use and is quicker than using class or type. So even if you have a group, if only one is ever used.. use an id.
Then you use the object/reference of 'this' from an event on an element, in this case the onclick... that will send that variable to the function / code called.
So using 'this' is a preferred option as it will always reference the element that it is used/called from.
pass elemenet, not it's Id
<button class="success" id="1" onClick="reply(this)"> Added </button>
<button class="success" id="1" onClick="reply(this)"> Added </button>
function reply(elem)
{
$(elem).setAttribute('class', 'failed');
if (elem.firstChild.data == "Added")
{
elem.firstChild.data = "Add";
}
}
the ID attribute must be unique or else it will get the last defined element with that ID.
See this for reference.
Use a class instead of an id. ids are supposed to be unique in a dom tree.
html:
<button class="success" onClick="reply()"> Added </button>
<button class="success" onClick="reply()"> Added </button>
js:
var ary_success = document.querySelectorAll(".success"); // once and forever. If the set of elements changes, move into function `reply`
function reply () {
var elem;
var s_myclasses;
for (var i=0; i < ary_success.length; i++) {
elem = ary_success[i];
s_myclasses = elem.getAttribute('class');
s_myclasses = s_myclasses.replace ( /(success|failed)/g, '' );
s_myclasses = s_myclasses + ' failed';
elem.setAttribute('class', s_myclasses );
if ( elem.firstChild.data.indexOf("Added") !== -1) {
elem.firstChild.data = "Add";
}
}
}
Live Demo here.
Notes
Make sure that you set ary_successin the onload handler or in an appropriately placed script section - at the timeof execution the buttons must be present in the dom ! If in doubt, move it to the start of reply' body.
If you employ jquery, the code simplifies (well...) to:
$(document).ready( function () {
$(".success").on ( 'click', function ( eve ) {
$(".success").removeClass("success").addClass("failed");
$(".success *:first-child:contains('Added')").text(" Add ");
});
});
Updates
Notes, Live Demo
Iterator method changed, every not supported on test platform

Can't bind event to element, created by script

I'm learning a pure JavaScript. Currently I'm exploring DOM objects, like WINDOW, DOCUMENT, ELEMENT and so on ...
I'm creating text fields on a fly and want to bind function to each element's event (onfocus or onblur for example), and pass self element as argument (like 'this').
The following script creates text field and binds it to a specific function.
var txt= document.createElement("input");
txt.type="text";
txt.value='0';
txt.size=12;
txt.style.textAlign="right";
txt.id="txt_"+self.count;
txt.addEventListener('focus', txt_focus(txt));
txt.addEventListener('blur', txt_blur(txt));
And below is the functions:
function txt_focus(txt){
txt.value=txt.id;
txt.style.backgroundColor='yellow';
}
function txt_blur(txt){
txt.style.backgroundColor='white';
}
This function recognizes given argument as element and sets its ID to value attribute, but it not affects to background color.
What have I missed?
Here is the entire HTML code:
<html>
<head>
<script type="text/javascript">
self.count =0;
function txt_focus(txt){
txt.value=txt.id;
txt.style.backgroundColor='yellow';
}
function txt_blur(txt){
txt.style.backgroundColor='white';
}
function removeGroup(){
if (self.count<1) {return;}
var parent=document.getElementById("myDiv");
var fs_x =document.getElementById('fs_'+self.count);
parent.removeChild(fs_x);
self.count--;
}
function addGroup(){
if (self.count>11) {return;}
self.count++;
var parent=document.getElementById("myDiv");
var fs=document.createElement("fieldSet");
fs.style.borderRadius="7px";
fs.style.height="45px";
fs.id='fs_'+self.count;
var l=document.createElement("legend");
l.innerHTML="interval_"+self.count;
l.style.color="darkgreen";
l.style.fontStyle="italic";
fs.appendChild(l);
var d1= document.createElement("input");
d1.type="date";
d1.value='2014-05-01';
d1.id='d1_'+self.count;
fs.appendChild(d1);
var d2= document.createElement("input");
d2.type="date";
d2.value='2014-05-22';
d2.id='d2_'+self.count;
fs.appendChild(d2);
var txt= document.createElement("input");
txt.type="text";
txt.value='0';
txt.size=12;
txt.style.textAlign="right";
txt.id="txt_"+self.count;
txt.addEventListener('focus', txt_focus(txt));
txt.addEventListener('blur', txt_blur(txt));
fs.appendChild(txt);
parent.appendChild(fs);
fs.scrollIntoView();
}
</script>
</head>
<body>
<input type="hidden" id="hd1" value="0"> </input>
<button onclick="addGroup();"> Add a group</button>
<button onclick="removeGroup();"> Remove a group</button>
<div id="myDiv" style="padding:7px;position:relative;margin-top:15px;width:500px;height:500px;background-color:#ccbbcc;overflow-y:auto;border:1px red solid;border-radius:15px;">
</div>
</body>
</html>
Solution is desired in pure JavaScript, but JQuery solution is also interesting.
My second question is:
I've some background of basic JavaScript (like Math, strings, functions, arrays, classes and so on), and there I want your advice: Is there any necessity to dig deep into JavaScript details instead of jump to a JQuery?
The issue here is the difference between referencing a function and calling it. Whenever you add the parenthesis you call the function and return the result, and the default result is undefined.
In an event handler you want to reference the function only
txt.addEventListener('focus', txt_focus);
If you have to pass arguments, you'd use an anonymous function
txt.addEventListener('focus', function() {
txt_focus(txt);
});
but here that doesn't make sense, as you're passing the element, which you could access with this inside the function instead
txt.addEventListener('focus', txt_focus);
function txt_focus() {
var txt = this; // the element
}

Replacing widget element with a newly constructed DOM structure

<script>
(function( $ ) {
$.widget( "my.dropbox", {
errorText: function(text) {
$(this.element).next().html(text);
},
_create: function() {
var id = $(this.element).attr("id");
var customDropbox = $(
"<div class='form-group'>"+
"<label for='"+id+"'>"+getLabelFor(id)+"</label>"+
"<select id='"+id+"'></select>"+
"<div class='errors'></div>"+
"</div>"
);
customDropbox.attr("id", id);
$(this.element).replaceWith(customDropbox); // This removes original element from DOM
populateOptions(id);
},
});
}( jQuery ));
$(document).ready(function(){
$("#field1").dropbox(); //blank input field turns into a select with a label, populated options e.t.c..
$("#button1").on("click", function(){
$("#field1").dropbox("errorText", "This is a validation error message"); //throws an error saying dropbox is not initialized
});
});
</script>
<html>
<body>
<input id="field1" />
<button id="button1">Press me</button>
</body>
</html>
So I want a widget with public methods that will replace the original element with all the widget data associated with it. The problem with the above code is that the <select..> element is just a DOM element and if you call .dropbox(..) on it, it will say the widget is not initialized. Is there a way to make the select element into the widget object with the .errorText() method? All widget examples online add stuff around the original element but never replace it. As for the bigger picture, I'm trying to make a generic tool to configure forms dynamically. It's going to be all <input id="..."> in html but then javascript will query a database, get configuration for the field and turn it into a dropbox, checkbox or, say, a date picker with all the labels, validation, and other bells and whistles.
There is more than one issue with your widget code. I'll try to summarize them:
1. Copy the data
You're not copying the data to the newly created customDropbox, so before
this.element.replaceWith(customDropbox);
you should copy the data:
customDropbox.data(this.element.data());
Now the widget will remember that it was initialized.
2. this.element is gone
After
this.element.replaceWith(customDropbox);
you should update this.element so that it points to the newly created customDropbox:
this.element = customDropbox;
3. errorText message takes wrong element
Since the widgets element (this.element) is now pointing to the <div class='form-group'></div> element, the errorText function must be slightly modified to:
this.element.find(".errors").html(text);
4. id should be unique
Now, both the wrapper <div> and the <select> have the same id, which is not allowed in HTML so remove the one on the <select> tag. Luckily, <label> can work without the for attribute, just write it like this:
<label>labelForId <select></select></label>
Then to get the <select>-element, use this.element.find("select") in the widget.
Side note
`this.element` is already a jQuery element, so no need for the additional `$()` wrapping.
See this jsFiddle
function show(){
$("#field1").input({....});
}
function hide(){
$("#field1").input("hide");
}
<button onclick="show()">show</button>
<button onclick="hide()">hide</button>
i think to replace the origin element which initial dropbox() is not a good solution,
because this will force you to rely on the implemention details of jQuery ui factory,
it is easy to make a mistake or introduce bugs, sometimes harder for other people to understand your code
if jquery ui factory change the implemention in the future, you have to modify all your code to make it work
(sorry for my limit understand of jquery ui)
i think we can put the <input/> into a container and initial dropbox() on the container which inturn
replace <input/> with <select> datepicker ..etc.. we can build modules easily by doing so:
<form>
<div class="dropbox"><label for="someID">aaaaaa</label><input id="someID"/></div>
<div class="datepicker"></div>
<div class="othermodule"></div>
</form>
js:
$(".dropbox").dropbox(); // init dropbox you defined
$(".datepicker").datepicker(); // ...
$(".othermodule").othermodule(); // ...
$(".dropbox").dropbox("errorText", "error"); // invoke it smoothly
here is a simple demo: http://jsfiddle.net/m4A3D/
#Wouter Huysentruit's answer provides a list of good suggestion for me
<form>
<div class="dropbox">
<label for="someID">aaaaaa</label>
<input id="someID"/>
</div>
<div class="datepicker"></div>
<div class="othermodule"></div>
</form>
<button id="button1">Press me</button>
<script>
(function ($){
$.widget("my.dropbox", {
_create: function () {
var $input = this.element.find("input");
var sID = $input.attr("id");
var $select = $("<select>");
$select.attr("id", sID);
$input.replaceWith($select);
this.element.append("<div class='errors'></div>");
}, // end _create()
errorText: function (text) {
this.element.find(".errors").text(text);
} // end errorText()
});
}(jQuery));
$(".dropbox").dropbox();
$("#button1").click(function () {
$(".dropbox").dropbox("errorText", "this is error");
});
</script>

zclip: refer to sender element in afterCopy callback

I have multipule "copy code" buttons on one page. Each code has its own button.
here is my basic html:
<a id="1" href="#" class="small-white-btn copyme">Copy Source</a>
<div id="code-1" style="display:none;">html source code goes here</div>
<div class="msg1"></div>
<a id="2" href="#" class="small-white-btn copyme">Copy Source</a>
<div id="code-2" style="display:none;">html source code goes here</div>
<div class="msg2"></div>
My zclip jquery looks like this:
$('.copyme').zclip({
path: 'http://www.steamdev.com/zclip/js/ZeroClipboard.swf',
copy: function () {
var id = $(this).attr('id');
var copythis = $('#code-' + id).text();
return copythis;
},
afterCopy: function () {
$("div.msg" + id).html("<p>Source Code Copied</p>");
}
});
This works, however, I cannot get the message injected into the div class="msg" tag.
How can I target the var id, add it to the div msg and display it on the page when the button is clicked.
The reason you cannot access the id variable you created in the copy function from afterCopy is because variables defined inside of a function are scoped to that function. However, this is easily overcomable.
There is no need to save the value from $(this).attr('id') as a global variable when the copy function is called, because you can just as easily get the id of the calling element in the afterCopy function by using the same exact expression: i.e.
afterCopy: function () {
var id = $(this).attr('id');
}
This answers your original question, but there is a much better way to determine which elements to select. Rather than relying on the ID field to never change and using it to construct the id of another element, you can just store the exact id of your copy text and copy message elements in the form of custom data-* attributes on your .copyme anchor, like this:
<a data-copy="#code-1" data-copy-msg="#msg1" class="copyme">Copy Source 1</a>
Then, in the copy function, you can grab that attribute and pass it into a jQuery selector to get the text value to copy, like this:
copy: function () {
var copySelector = $(this).data('copy');
return $(copySelector).text();
}
You can handle the afterCopy event the same way. You can use this instead of having to store the ID in memory. Grab the selector where you want the message to go, and apply the html to that, like this:
afterCopy: function () {
var copyMsgSelector = $(this).data('copy-msg');
$(copyMsgSelector).html("Source Code Copied");
}
Working Demo in Fiddle
So the whole thing would look like this:
HTML:
<a data-copy="#code-1" data-copy-msg="#msg1"
href="#" class="copyme" >Copy Source 1</a>
<div id="code-1" style="display:none;">source code 1</div>
<span id="msg1"></span>
<br/>
<a data-copy="#code-2" data-copy-msg="#msg2"
href="#" class="copyme" >Copy Source 2</a>
<div id="code-2" style="display:none;">source code 2</div>
<span id="msg2"></span>
JavaScript:
$('.copyme').zclip({
path: 'http://www.steamdev.com/zclip/js/ZeroClipboard.swf',
copy: function () {
var copySelector = $(this).data('copy');
return $(copySelector).text();
},
afterCopy: function () {
var copyMsgSelector = $(this).data('copy-msg');
$(copyMsgSelector).html("Source Code Copied");
}
});
You're declaring var id within a function, so it's a private variable that gets destroyed after the function finishes running. You need to declare the variable outside of your function; then when it runs you can assign and preserve the value.
try this:
var id;
$('.copyme').zclip({
path: 'http://www.steamdev.com/zclip/js/ZeroClipboard.swf',
copy: function () {
id = $(this).attr('id');
var copythis = $('#code-' + id).text();
return copythis;
},
afterCopy: function () {
$("div.msg" + id).html("<p>Source Code Copied</p>");
}
});

Categories

Resources