I have a problem with dealing with functions which calls this.form.
Here is that part of my source code:
searchResult.innerHTML += "<td><div class=\"searchcard\" draggable=\"true\" ondragstart=\"isexc=0; clickselect("
searchResult.innerHTML += i
searchResult.innerHTML += "); setformparam(this.form); onDragStart(event)\"
Here I tried to perform setformparam(this.form) when I start dragging div box constructed from within innerHTML script, but it doesn't work.
Any other function like isexc=0, clickselect(i) worked well.
Please teach me how to access this.form from within inner JavaScript. Thanks.
That’s a terrible way of creating elements. Use the DOM:
var cell = document.createElement("td");
var searchCard = document.createElement("div");
searchCard.className = "searchcard";
searchCard.draggable = true;
(function(i) {
searchCard.addEventListener("dragstart", function(e) {
isexc = 0;
clickselect(i);
setformparam(someForm);
onDragStart(e);
}, false);
})(i); // I’m just assuming `i` here is a loop variable of some kind
// You should probably use Array.prototype.forEach
cell.appendChild(searchCard);
searchResult.appendChild(cell);
And use event delegation and stop using global variables. There are a ton of things to potentially clean up here, but you should probably try Code Review for that.
I'm not sure if that's what you are asking for, but if you want to get the form element as a DOM object, you can set an id to the element and call it by getElementById.
Or you can get it by document.getElementsByTagName("form")[x] where x is the index of the form you want.
try
$(this).children('form') and not 'this'
Related
I have a variable that finds the data attribute of an element that is clicked on in a callback function:
var dropdown = document.getElementsByClassName('js-dropdown');
for (i = 0; i < dropdown.length; i++) {
dropdown[i].addEventListener("click", callBack (dropdown[i]));
}
function callBack (i) {
return function () {
var thisDropdown = i.getAttribute('data-dropdown');
//rest of the code here
}
}
I am basically trying to do this
$('#' + thisDropdown ).toggleClass('is-active');
...but in vanilla JS.
This works fine using jQuery however I would like a vanilla version.
So when a user clicks on an element that activates a drop down, I want it to dynamically find its relevant ID matching value within the document so it can toggle a show/hide class.
I've searched through a lot of SO questions and everyone replies with a jQuery answer which is not what I am looking for.
I've been trying to do something along the lines of
var idValue = document.getElementById(thisDropdown);
Then
var findId= idValue + thisDropdown;
findId.toggleClass('is-active');
Obviously that does not work the same way the jQuery statement works... any ideas?
Ignore the toggleClass method! Some of you may find this contradictory as I want vanilla JS.
To replace $('#' + thisDropdown ).toggleClass('is-active'); with plain js, use Element.classList. Like this:
const someElement = document.querySelector('#' + thisDropdown);
someElement.classList.toggle("is-active");
I like #kamyl's answer, but you might need backward compatibility. For that, see if you can find a polyfill.
If you have to write it yourself, use string.split(" ") to get your list of active attributes and iterate to find if it exists; add if not, remove if so...then array.join(" ") and replace the class attribute with it.
In my program I am dynamically creating feedback boxes to respond to user input. My problem is, I don't know how many of these pieces of feedback will be outputted. I have created a function in my javascript that assigns an id to each new element I create at runtime by concatenating a string with a variable number - which is incremented after every time the constructor is called - and appending it to my CSS class for styling, however I'm not sure how to reference a varying id in my html so that they actually appear on the screen.
var counter = 0;
function constructFeedbackBox() {
counter++;
var newElement = 'toast' + counter;
var i = null;
i = document.createElement('div');
i.id = newElement;
i.className = ".toastStyle";
}
In addition, if there are any problems with the way I've done my javascript to create my Id and/or append it to my class, the info would be much appreciated (I'm still pretty new to this)
First of all, document.createElement() takes a tagName as an input. If you are making divs, your line should read document.createElement('div');.
You can then do i.setAttribute(id, 'toast' + counter);.
What are you trying to accomplish overall with this? Maybe there is a better approach. Also worth noting that IDs must be unique, so be careful about that.
In my research and attempts to use JavaScript to add rows to a HTML Table dynamically, it was important that each id tag be incremented according to the row number. I found various suggested ways of doing this. Finally, I thought I'd give a try at writing a recursive function to do the trick. The following works. But I do not know if it could be optimized. Kindly let me know what I can do to improve it.
function incrementElementID(element, incrementVal) {
if(element.hasAttribute("id")) {
idVal = element.getAttribute("id");
element.setAttribute("id",idVal+incrementVal);
}
var numChildren = element.childElementCount;
for (var i=0; i<numChildren; i++)
incrementElementID(element.children[i],incrementVal);
return;
}
Best done with a closure variable if you're not intentionally trying to use recursion.
Set a variable outside the function scope and increment it within the function.
You're better off with some simple jQuery:
var incrementVal = ...
$("[id]").each(function(index, value) {
elem = $(value);
elem.attr("id", +elem.attr("id") + incrementVal);
});
$("[id]") selects any element that has an id attribute: http://api.jquery.com/has-attribute-selector/
.each iterates through all the items in the collection: https://api.jquery.com/jQuery.each/
The + at the front of +elem.attr("id") converts the attribute value from a string to an int.
I am quite new to dojo and I'm stuck with a problem here
I have a zend dojo form where I need to take sum of four elements and set the value to another element. I have assigned a class (score) to those four elements
".score" : {
"found" : function (ele) {
var widgetId = ele.getAttribute('widgetid');
dojo.connect(dijit.byId(widgetId),'onBlur', function(){
var sum = 0;
dojo.query('.score')
.forEach(function(ele){
var widgetId = ele.getAttribute('widgetid');
sum += parseInt(dijit.byId(widgetId).get('value'));
});
//***cannot get the value of sum here
dijit.byId('score_total').set('value', sum);
});
}
}
As commented I am unable to get the sum of those values outside the foreach. Is there any way to get the value out of the loop? Am I doing any thing wrong?
It seems that I had made a mistake in the code and since I am quite new to jscript I was unable to debug. foreach indeed is not a asynchronous and sum was being calculated just that the parseInt(dijit.byId(widgetId).get('value')) was returning not a number NaN hence I was unable to populate the form element, I simply added an if condition and it worked
if(parseInt(dijit.byId(widgetId).get('value'))){
sum = sum + parseInt(dijit.byId(widgetId).get('value'));
}
Sorry for the trouble
One thing to note... dojo.foreach is deprecated ...
http://livedocs.dojotoolkit.org/dojo/forEach
instead ... array.forEach
http://livedocs.dojotoolkit.org/dojo/_base/array#forEach
but i think you might also have a scoping issue as well.. try something like this..
var sum = 0;
var elements = dojo.query('.score');
array.forEach(elements, function(ele) {
var widgetId = ele.getAttribute('widgetid');
sum += parseInt(dijit.byId(widgetId).get('value'));
});
in your case, the parent context has the variable, so it will work as you have used it.
Just a side point that if you want to access the sum variable outside the parent context, you will need to use dojo.hitch or pass the context to dojo.forEach
http://www.ibm.com/developerworks/web/library/wa-aj-dojo/
see the section on "Setting method context"
Usually JavaScript binds events on DOM elements. But I want to know on which word the user clicked. The familiar way for me is just wrap every words like here:
And now the
kung pao chicken.
I think it's a redundant code, and is it possible to make code more concise?
Well, you could always write a JavaScript function to wrap every word for you:
function wrapWords(element) {
var html = element.innerHTML;
var words = html.split(/ /);
var newHtml = '';
for (var i = 0; i < words.length; i++) {
newHtml += '<span>' + words[i] + '</span> ';
}
element.innerHTML = newHtml;
}
Of course, this assumes that the element has not other html in it. You can combine this with Matti's suggestion to make the code much neater.
To do this in any feasible way, you'll probably still have to wrap each word in a separate element like you're doing, but you can at least get rid of all the inline JavaScript.
Add your even listener to the parent element of the words. Any event that the word elements receive will bubble to the parent element, and you can look at the event target property to find out which word was clicked.
Are you using a JS library or are you working without one?
Edit: Since you're not using a library, jQuery is a popular choice (popular enough to be considered a cliché on SO, I guess that says something). Here's how you'd do it with jQuery:
http://jsfiddle.net/eKvdn/ (click the words)
It would be a very good idea to read more about it before using it, though.