I have a <div> element that does not appear on the page unless some function is activated. I want to remove this <div> after it appears on the page.
how do I run my JavaScript code when and only when this <div> element is added ?
I am new at this and would appreciate some help. Thanks.
ps. element is generated by jquery and only has classname.
Detailed explanation:
I implementing a excel export in an existing web application.
I am using a form surrounding filters for search and a ajaxgrid gridstate.
This form is submitted to a controller that has the corresponding viewmodels.
My code for submitting the form is this:
$(function () {
$('div.btn-group #export-citizen-list').on('click', function () {
var gridstate = $('#citizenIndexGrid').ajaxgrid('getState');
var form = $('#create-citizen-csv-file');
// add ajaxgrid state to post data
$.each(gridstate, function (k, v) {
form.addAjaxgridHidden(k, v);
});
// submit entire form, with ajaxgrid state
form.submit();
// remove all hiddenfields that belongs to ajaxgrid
form.find(":hidden.ajaxgrid").remove();
document.getElementById("filterSearch").className = "default ui-button ui-widget ui-state-default ui-corner-all";
$('#filterSearch').removeAttr('disabled');
// function that removes unwanted <div> ---->$('.ajaxWorkingNotification').slideUp();
})
jQuery.fn.addAjaxgridHidden = function (name, value) {
return this.each(function () {
var input = $('<input>').attr('type', 'hidden').attr('name', name).attr('class', 'ajaxgrid').val(value);
$(this).append($(input));
});
};
});
When I submit my form the excel is downloaded and the unwanted <div> is inserted in the DOM. The thing is that I don't know when the postback is returned in this case. And therefore I don't know when this <div> is inserted.
Hope this clarifies my issue.
You can do something like this.
// Assuming your element is created by this line ...
$(".your_elements_class_name").ready(function() {
// write code here
// this is executed after the element is created and added to DOM
})
You can do it by implement a listener on DOM node insertion event.
There was an explanation here on how to detect DOM node insertion & pure javascript code to demonstrate how it works
And if you like a jQuery version, then here is the sample code that I translated from above link.
HTML:
<input type="button" id="addme" value="Add"/>
<div id="container">
</div>
CSS:
#keyframes nodeInserted {
from { opacity: 0.99; }
to { opacity: 1; }
}
#container div#mydiv {
animation-duration: 0.001s;
animation-name: nodeInserted;
}
Javascript:
$(function () {
$('#addme').click(function () {
var div = $('<div/>').attr('id', 'mydiv').html("Hello");
$('#container').append(div);
});
var handler = function (e) {
if (e.originalEvent.animationName == "nodeInserted")
alert("An HTMLElement has been inserted to DOM tree !")
};
var eventSignature = 'MSAnimationStart';
if ($.browser.webkit) eventSignature = 'webkitAnimationStart';
if ($.browser.mozilla) eventSignature = 'animationstart';
$(document).on(eventSignature, handler);
});
JSFiddle Demo
Related
I have following code, where, based on event, I add some html code. I would like to refer to 'id' from this dynamically injected html in other event (or just from other part of the code):
<div id="choice"></div>
var decisionList = document.getElementById("decisionList");
decisionList.addEventListener("change", function () {
var finalChoice = document.getElementById("choice");
finalChoice.innerHTML='<input id="finalDate" type="date">'
}
and other event referring to 'id' from innerHTML:
var payment = document.getElementById("finalDate");
payment.addEventListener("change", function () {
var textDate = payment.textContent;
alert(textDate);
})
The above is not working. Is it possible or not?
It is possible, but make that payment getter lazy. What that means is, instead of setting up that second change listener right away (in your other code), make that other code a function. Then in your first trigger, where you created the extra div or input or something, call that setup function.
decisionList.addEventListener("change", function () {
const finalChoice = document.getElementById("choice");
finalChoice.innerHTML='<input id="finalDate" type="date">'
createFinalDateListener();
}
function createFinalDateListener() {
const payment = document.getElementById("finalDate");
payment.addEventListener("change", function () {
const textDate = payment.textContent;
alert(textDate);
});
}
Here's a similar example. I do not have the input immediately. Or listener. And I only create a listener after I create the input.
// Here's the main trigger
function addExtraElements() {
// let's create a datepicker dynamically.
document.querySelector('#placeholder').innerHTML = '<input type="date" placeholder="pick date">';
listenDateChanges();
// TODO: don't forget to add cleanup code! Each time you fill that innerHTML, the old listener will remain
}
// Here's your datepicker listener
function listenDateChanges() {
const datePickerEl = document.querySelector('input[type="date"]');
if (!datePickerEl) {
console.log('no picker');
return;
}
datePickerEl.addEventListener('change', () => alert(datePickerEl.value));
}
<div id="placeholder">
Placeholder
</div>
<button onclick="addExtraElements()">Add extra elements</button>
Hello could someone help me? I'm having trouble transforming this part of my code to JS:
$(".custom-select-trigger").on("click", function() {
$('html').one('click',function() {
$(".custom-select").removeClass("opened");
});
$(this).parents(".custom-select").toggleClass("opened");
event.stopPropagation();
});
I have it so far:
const customSelectTrigger = document.querySelector(".custom-select-trigger");
const customSelect = document.querySelector(".custom-select");
function showOptions(e) {
e.preventDefault();
customSelect.classList.toggle("opened");
e.stopPropagation();
}
but I'm not able to do this part for javascript:
$('html').one('click',function() {
$(".custom-select").removeClass("opened");
});
Here is working code for to remove class opened from your custom select when you press anywhere in the DOM.
You need to use JS addEventListener and click function to do this.
To remove class from an element we can use .remove function and getting the classList of your element by querySelector which will .custom-select
Edit: If you just want to use the click function once only per DOM load. Then setting setting the args { once: true } will only invoke the function once.
I have recreated your example and its working.
Run snippet below.
//Getting HTML element
const htmlElement = document.querySelector("html");
//Getting element where to remove the class from
const customSelect = document.querySelector(".custom-select");
//Adding eventlistener to remove class opened from classList
htmlElement.addEventListener("click", function(e) {
customSelect.classList.remove("opened");
console.log('Class Removed')
e.preventDefault();
},{ once: true });
.opened {
background-color: red;
}
<html>
<h3>
Click anywhere on the DOM to remove class from Custom select
</h3>
<div class="custom-select opened">
My Custom Select
</div>
</html>
Okay So I what to have 3 buttons
<div id="button1" onclick="choose1()">Button1</div>
<div id="button2" onclick="choose2()">Button2</div>
<div id="button3" onclick="choose3()">Button3</div>
And a start button
<div id="startButton" onclick="noFunction()">Start</div>
I want to make it so that pressing on of the 3 option buttons it changes what function will be called from the start button and the background image of the start button should change.
Is there a way to do this with just javascript or do I need jquery?
It also doesn't seem possible to use onclick on div tags, jquery to do that aswell?
jsFiddle
You can use onclick on <div> tags. But you shouldn't use onclick on any tags. Don't confuse your HTML layout and display with your JavaScript functionality. Bind your click handlers directly in the JS code (note that this solution is using jQuery):
HTML:
<div id="button1">Button1</div>
<div id="button2">Button2</div>
<div id="button3">Button3</div>
<div id="startButton">Start</div>
JS:
function choose1() {
// ...
}
function choose2() {
// ...
}
function choose3() {
// ...
}
$(function() {
$("#button1").click(choose1);
$("#button2").click(choose2);
$("#button3").click(choose3);
});
You can do it in javascript (anything possible with jQuery is possible with plain javascript, since jQuery is written in javascript).
Changing the click handler for the startButton from javascript is very straightforward:
document.getElementById("startButton").onclick = newFunction;
Changing the background image is also pretty simple:
document.getElementById("startButton").style.backgroundImage = "image.png";
Obviously, you should replace newFunction and "image.png" with the function and image you actually want to use respectively.
You can say
function choose1() {
document.getElementById('startButton').onclick = function() {
alert("Button one was originally press");
}
}
jQuery IS javascript. It is just a library of functions/methods that you can call.
To solve your problem, you should write a function that changes the onclick property of your start button, and add the function you write to the onclick of the other buttons.
Like so:
function chooseOne(){
document.getElementById('startButton').onclick="/\*whatever\*/";
}
A technology like what #nbrooks said in the comments that would do this very well is AngularJS
If you give each selector button a class, you can use javascript to interate them and bind a click event. Then you can store in a data property a key which you can lookup in a json object start stores the related action handler and image. Finally in your click handler you can pull these properties and apply them to the start button by setting the onClick handler and background image of the start button.
<div class="startSelector" data-startdataid="1">Button1</div>
<div class="startSelector" data-startdataid="2">Button2</div>
<div class="startSelector" data-startdataid="3">Button3</div>
<div id="startButton">Start</div>
<script>
var startData = {
"1": {
action: function() {
alert("Button 1 was selected");
},
image: "/images/button1.jpg"
},"2": {
action: function() {
alert("Button 2 was selected");
},
image: "/images/button2.jpg"
},"3": {
action: function() {
alert("Button 3 was selected");
},
image: "/images/button3.jpg"
}
}
var changeStartButton = function(e) {
var startDataIndex = e.target.dataset.startdataid
var data = startData[startDataIndex]
document.getElementById("startButton").onclick = data.action
document.getElementById("startButton").style.backgroundImage = data.image
}
items = document.getElementsByClassName("startSelector")
for (var i = 0; i < items.length; i++) {
items[i].addEventListener("click", changeStartButton);
}
</script>
Example
http://jsfiddle.net/Xk8rv/3/
I'm using the jQuery File Upload plugin. I'm hiding the file input and activating it upon clicking a separate button. (See this fiddle.)
HTML:
<div>
<button class="browse">Browse</button>
<input id="upload" type="file" style="display: none;" />
</div>
JavaScript:
var element = $("#upload");
$(".browse").click(function () {
$("#upload").trigger("click");
});
element.fileupload({
add: function () {
alert("add");
}
});
Notice that if you press the button then select a file, the add method is activated and you'll get an alert. Do it again, and you'll get another alert.
Now, see this fiddle. The only difference is that I've changed the following line
$("#upload").trigger("click");
to
element.trigger("click");
Notice that now, the first time you click the button then select a file, the add method is activated and you get the alert (just like before), but if you do it again, the add method never activates.
What is causing this difference in behavior?
This can also be solved by setting replaceFileInput to false, as stated by the documentation. This is because the plugin recreates the input element after each upload, and so events bound to the original input will be lost.
It looks as though the scope of element is being lost / changed after the add function. Resetting it like below seems to work.
var element = $("#upload");
$(".browse").click(function () {
element.trigger("click");
});
element.fileupload({
add: function () {
alert("add");
element = $(this);
}
});
Fiddle
Try this one: http://jsfiddle.net/xSAQN/6/
var input = $("#upload");
$(".browse").click(function () {
input.trigger("click", uploadit(input));
});
function uploadit(input){
$(input).fileupload({
add: function () {
alert("add");
}
});
}
Although there is one more way:
just change to this:
var element = $("#upload");
$(".browse").click(function () {
$("#upload").click(); // <----trigger the click this way
});
element.fileupload({
add: function () {
alert("add");
}
});
In jQuery, if I assign class=auto_submit_form to a form, it will be submitted whenever any element is changed, with the following code:
/* automatically submit if any element in the form changes */
$(function() {
$(".auto_submit_form").change(function() {
this.submit();
});
});
However, if I want to the form to submit only when specified elements are changed:
/* submit if elements of class=auto_submit_item in the form changes */
$(function() {
$(".auto_submit_item").change(function() {
$(this).parents().filter("form").submit();
});
});
I'm just learning jQuery. Is there a better way to do this?
/* submit if elements of class=auto_submit_item in the form changes */
$(function() {
$(".auto_submit_item").change(function() {
$("form").submit();
});
});
Assumes you only have one form on the page. If not, you'll need to do select the form that is an ancestor of the current element using $(this).parents("form").submit()
You can use an expression in the parents() method to filter the parents. Hence this might be a little more efficient:
/* submit if elements of class=auto_submit_item in the form changes */
$(".auto_submit_item").change(function() {
$(this).parents("form").submit();
});
I would give an id to the form:
$(".auto-submit-item").change(function() {
$("form#auto-submit").submit();
});
I came up with a generic approach to this:
$('.autoSubmit, .autoSubmit select, .autoSubmit input, .autoSubmit textarea').change(function () {
const el = $(this);
let form;
if (el.is('form')) { form = el; }
else { form = el.closest('form'); }
form.submit();
});
All elements of a form:
<form class="autoSubmit">
<select><option>1</option><option>2</option></select>
</form>
Only individual elements
<form>
<select class="autoSubmit"><option>1</option><option>2</option></select>
</form>