javascript change class doesn't perform the event - javascript

I am trying to make a ajax load of a table. I have 2 buttons "Free Cars", "Reservations". When click "Free Cars" load all info from database and on click of tr it redirects to an url.
$('.cars_table').on('click', 'tr', function() {
var values = $(this).find('td').map(function() {
return $(this).text();
});
var startdate = $('input[name$="startdate"]').val();
var starttime = $('input[name$="starttime"]').val();
var enddate = $('input[name$="enddate"]').val();
var endtime = $('input[name$="endtime"]').val();
window.location.href = 'rental/create/' + values[0] + '~' + startdate + ' ' + starttime + '~' + enddate + ' ' + endtime + '';
});
Then on click of "Reservations" I change the class of tbody :
$('#cars_table').removeClass('cars_table').addClass('res_made');
But it doesn't perform the script which
$('.res_made').on('click', 'tr', function() {
var values = $(this).find('td').map(function() {
return $(this).text();
});
var startdate = $('input[name$="startdate"]').val();
var starttime = $('input[name$="starttime"]').val();
var enddate = $('input[name$="enddate"]').val();
var endtime = $('input[name$="endtime"]').val();
window.location.href = 'reservations/create/' + values[0] + '~' + startdate + ' ' + starttime + '~' + enddate + ' ' + endtime + '';
});
Instead it performs the first script and on click of reservations rows it goes to the .cars_table redirect url. With inspect element it shows that the class has changed but then it doesnt performs the script for that class. What is happening?

Event bindings happen on the DOM elements themselves. If you try to bind an event on all .res_made elements before there are any elements with this class, no events will be bound.
To solve your problem, you could bind your event once and check inside the handler which class is currently set.

You should dynamically bind the click events, because the class of the table can dynamically change. So to make it work in your case, you should change your javascript to the following:
$(document).on('click', '.cars_table tr', function() {
var values = $(this).find('td').map(function() {
return $(this).text();
});
var startdate = $('input[name$="startdate"]').val();
var starttime = $('input[name$="starttime"]').val();
var enddate = $('input[name$="enddate"]').val();
var endtime = $('input[name$="endtime"]').val();
window.location.href = 'rental/create/' + values[0] + '~' + startdate + ' ' + starttime + '~' + enddate + ' ' + endtime + '';
});
$(document).on('click', '.res_made tr', function() {
var values = $(this).find('td').map(function() {
return $(this).text();
});
var startdate = $('input[name$="startdate"]').val();
var starttime = $('input[name$="starttime"]').val();
var enddate = $('input[name$="enddate"]').val();
var endtime = $('input[name$="endtime"]').val();
window.location.href = 'reservations/create/' + values[0] + '~' + startdate + ' ' + starttime + '~' + enddate + ' ' + endtime + '';
});
See this FIDDLE for an example. Of course, as an alternative, you could also bind the event once and check for the class of the table in the event handler, like Martin Denk suggested.

Related

Deleting an object from an array on click of a button

I am trying to create my own small Twitter.
It is all working fine but I cannot find a way to delete specific tweet on click of a button. I have tried splice() but it deletes the first object of an array always.
Here is my code:
var tweets = []
function postNewTweet() {
var today = new Date();
var date = today.getDate() + '-' + (today.getMonth() + 1) + '-' + today.getFullYear();
var time = today.getHours() + ':' + today.getMinutes();
var id = tweets.length + 1;
var li = document.createElement('li');
var inputValue = document.getElementById('newTweet').value;
var finalValue = id + ' ' + inputValue + ' ' + date + ' ' + time;
var t = document.createTextNode(finalValue);
li.appendChild(t);
tweets.push({
id: id,
content: inputValue,
date: date + ' ' + time
});
document.getElementById('list').appendChild(li);
document.getElementById('newTweet').value = "";
console.log(tweets);
var buttonDelete = document.createElement("button");
buttonDelete.innerHTML = '<i class="far fa-trash-alt"></i>';
buttonDelete.onclick = deleteItem;
function deleteItem(e) {
var ul = document.getElementById('list');
ul.removeChild(li);
var list = document.getElementById('list');
list.addEventListener('click', function(e) {
var index = e.target.getAttribute('value');
tweets.splice(index, 1);
console.log(tweets)
});
}
li.appendChild(buttonDelete);
}
<div id='post'>
<textarea maxlength="160" id='newTweet'></textarea>
<button id='postIt' onclick="postNewTweet()">Post</button>
</div>
<ul id='list'>
</ul>
So it deletes it in HTML, but not in array correctly.
The second part of your deleteItem function's body seems useless. While there are couple of ways to resolve it, I suggest the following:
function deleteItem(e) {
var ul = document.getElementById('list');
ul.removeChild(li);
var foundIndex = tweets.findIndex(function (tweet) {
return tweet.id == id;
});
if (foundIndex > -1) {
tweets.splice(foundIndex, 1);
}
}
There are two issues:
If you just take the length of the array as the id you will get duplicate entries, if you delete an entry. Perhaps go to a timestamp - i just used the one you already had there but added seconds
You retrieve the value-attribute but for splice you need the index of the element. I just added the timestampt as an attribute to the button and used it for removal.
Probably not my best code but I hope it gives you the right hints.
var tweets = []
function postNewTweet() {
var today = new Date();
var date = today.getDate() + '-' + (today.getMonth() + 1) + '-' + today.getFullYear();
var time = today.getHours() + ':' + today.getMinutes() + ':' + today.getSeconds();
var id = tweets.length + 1;
var li = document.createElement('li');
var inputValue = document.getElementById('newTweet').value;
var finalValue = id + ' ' + inputValue + ' ' + date + ' ' + time;
var t = document.createTextNode(finalValue);
li.appendChild(t);
tweets.push({
id: id,
content: inputValue,
date: date + ' ' + time
});
document.getElementById('list').appendChild(li);
document.getElementById('newTweet').value = "";
console.log(tweets);
var buttonDelete = document.createElement("button");
buttonDelete.innerHTML = '<i class="far fa-trash-alt" del-date="'+date + ' ' + time +'">del</i>';
buttonDelete.onclick = deleteItem;
function deleteItem(e) {
var ul = document.getElementById('list');
ul.removeChild(li);
var list = document.getElementById('list');
list.addEventListener('click', function(e) {
var delDate = e.target.getAttribute('del-date');
let index = tweets.map((item) => item.date).indexOf(delDate);
console.log(index);
tweets.splice(index, 1);
console.log(tweets)
});
}
li.appendChild(buttonDelete);
}
<div id='post'>
<textarea maxlength="160" id='newTweet'></textarea>
<button id='postIt' onclick="postNewTweet()">Post</button>
</div>
<ul id='list'>
</ul>
As you have access to li in your delete function, you have access to all the other data too. You can use them to find out the element to remove from the tweets array.
For example, in your current code, you can use the id:
tweets.splice(id - 1, 1)
Or you can use filter with any of the data that you store in tweets.And I don't see any use for this part:
var list = document.getElementById('list');
list.addEventListener('click', function(e) {
var index = e.target.getAttribute('value');
tweets.splice(index, 1);
console.log(tweets)
});
You can just remove the tweet under the ul.removeChild

Load JS function inside a div

I have a simple span and I want to show full date from Javascript inside this span. I'm not getting how to do it.
HTML (The date would be in place of the "..."):
<h3>Data Atual: </h3><span id="date" onload="newDate()">...</span>
Javascript:
function newDate() {
var dateBox = document.getElementById('date');
dateBox.innerHTML = '';
var date = new Date();
var newDate = date.getDay + ', ' + date.getDate + ' de ' + date.getMonth + ', ' + date.getFullYear + '.';
dateBox.innerHTML += newDate;
}
Thanks in advance
The load event doesn't fire on static HTML elements, only elements that load their data asynchronously from an external URL.
Put the call in the body's onload event.
<body onload="newDate()">
you can use this code to show the complete day in your span text:
document.getElementById("date").innerHTML = createNewDate();
function createNewDate() {
const date = new Date();
const newDate = date.getDay + ', ' + date.getDate + ' de ' + date.getMonth + ', ' + date.getFullYear + '.';
return newDate;
}
do not need to load it on start. Actually you are using get dates wrongly. This following code will solve it your problem. Put it before </body>
<script>
var date = new Date();
var newDate = date.getDay() + ', ' + date.getDate() + ' de ' + date.getMonth() + ', ' + date.getFullYear() + '.';
document.getElementById("date").innerHTML = newDate;
</script>

How is this variable still NULL

I'm in the process of writing a CasperJS script to automate a search form and capture the subsequent page. However, the search form goes to a loading splash page first until data arrives. So i added the waitForSelector function which seems to be working for some of my pages, but others return the variable name as NULL. How can that be if it is truly "waiting" for that element to be on the DOM?
casper.each(searchPages,function(casper,index){
var currentTime = new Date();
var month = currentTime.getMonth() + 2;
var day = currentTime.getDate();
var year = currentTime.getFullYear();
var dateStart = month + "/" + day + "/" + year;
month = currentTime.getMonth() + 3;
var dateEnd = month + "/" + day + "/" + year;
casper.thenOpen(url,function(){
var myfile = "data-"+year + "-" + month + "-" + day+".html";
this.evaluate(function(j) {
document.querySelector('select[name="searchParameters.localeId"]').selectedIndex = j;
},index);
this.evaluate(function(start) {
$("#leaveDate").val(start);
},dateStart);
this.evaluate(function(end) {
$("#returnDate").val(end);
},dateEnd);
this.evaluate(function() {
$("#OSB_btn").click();
});
this.waitForSelector('#destinationForPackage', function() {
var name = casper.evaluate(function() {
return $("#destinationForPackage option[value='" + $("#destinationForPackage").val() + "']").text()
});
if (name != "Going To"){
if (name == null){
console.log("it's null");
}else{
name = name.replace("/","_");
casper.capture('Captures/Searches/search_' + name + '.jpg');
console.log("Capturing search_" + name);
}
}
},function(){
console.log("Search page timed-out.");
},20000);
});
});
I was able to solve this by creating a recursive function if the element is still not available. Now i'm having a memory issue though, new question here => CasperJS running out of memory
casper.each(searchPages,function(casper,index){
loadSearch(casper,index);
});
function loadSearch(casper,index){
var currentTime = new Date();
var month = currentTime.getMonth() + 2;
var day = currentTime.getDate();
var year = currentTime.getFullYear();
var dateStart = month + "/" + day + "/" + year;
month = currentTime.getMonth() + 3;
var dateEnd = month + "/" + day + "/" + year;
casper.thenOpen(url,function(){
var myfile = "data-"+year + "-" + month + "-" + day+".html";
this.evaluate(function(j) {
document.querySelector('select[name="searchParameters.localeId"]').selectedIndex = j;
},index);
this.evaluate(function(start) {
$("#leaveDate").val(start);
},dateStart);
this.evaluate(function(end) {
$("#returnDate").val(end);
},dateEnd);
this.evaluate(function() {
$("#OSB_btn").click();
});
this.waitForSelector('#destinationForPackage', function() {
if (this.exists('#destinationForPackage')){
var name = casper.evaluate(function() {
return $("#destinationForPackage option[value='" + $("#destinationForPackage").val() + "']").text()
});
if (name != "Going To"){
if (name == null){
console.log("it's null");
}else{
name = name.replace("/","_");
casper.capture('Captures/Searches/search_' + name + '.jpg');
console.log("Capturing search_" + name);
}
}
}else{
console.log("Still doesn't exist...retry");
loadSearch(casper,index);
}
},function(){
console.log("Search page timed-out.");
},20000);
});
}

Jquery Clone method increment name tag

Hello I am trying to add increment in my all form fields from zero to the number whenever I add new clone it assigns the next number to the name tag, I tried all the ways but no any methods works for me.
Here is my fiddle
https://jsfiddle.net/o5wam5r2/
and here is my JS code
var formItem;
$(document).ready(function() {
//Clone and remove your div instead of hiding it
formItem = $('.ScheduleextraPartTemplate').clone();
$('.ScheduleextraPartTemplate').remove();
formItem.addClass('clone clone-1');
$('#Schedulecontainer').append(formItem);
});
$(document).on('click', '#ScheduleaddRow', function() {
var cloneForm = $('.clone').last().clone();
var cloneNum = $('.clone').length;
cloneForm.removeClass('clone-'+cloneNum).addClass('clone-' + (cloneNum+1));
var date = cloneForm.find('[name="txtSchedule"]').val();
cloneForm.find('[name="txtSchedule"]').val(addOneMonth(date));
$('#Schedulecontainer').append(cloneForm);
})
function addOneMonth(date) {
var year = parseInt(date.split("-")[0]);
var month = parseInt(date.split("-")[1]) + 1;
var day = parseInt(date.split("-")[2]);
if(month > 12) {
month = month - 12;
year++
}
return year + "-" + month + "-" + day;
}
I fixed it by changing a little piece of code
var formItem;
var counter = 0;
$(document).ready(function() {
//Clone and remove your div instead of hiding it
formItem = $('.ScheduleextraPartTemplate').clone();
formItem.find('[name^=txtSchedule]')[0].name = "txtSchedule" + counter;
formItem.find('[name^=txtScheduleAmountPay]')[0].name = "txtScheduleAmountPay" + counter;
$('.ScheduleextraPartTemplate').remove();
formItem.addClass('clone clone-1');
$('#Schedulecontainer').append(formItem);
});
$(document).on('click', '#ScheduleaddRow', function() {
var lens = counter++;
var cloneForm = $('.clone').last().clone();
var cloneNum = $('.clone').length;
cloneForm.removeClass('clone-'+cloneNum).addClass('clone-' + (cloneNum+1));
var date = cloneForm.find('[name^="txtSchedule"]').val();
cloneForm.find('[name^="txtSchedule"]').val(addOneMonth(date));
cloneForm.find('[name^=txtSchedule]')[0].name = "txtSchedule" + (lens+1);
cloneForm.find('[name^=txtScheduleAmountPay]')[0].name = "txtScheduleAmountPay" + (lens+1);
$('#Schedulecontainer').append(cloneForm);
})
function addOneMonth(date) {
var d = new Date( date );
d.setMonth( d.getMonth( ) + 1 );
return d.getFullYear() + '-' + ("0" + ((d.getMonth() + 1))).slice(-2) + '-' + ("0" + (d.getDate())).slice(-2);
}

javascript change textbox value onchange

I have a StartDate and an ExpiryDate textbox. Both take values in the forms of 10/12/2013.
What I would like to be able to do is, when you change the StartDate textbox (whether from empty or just updating the date) the ExpiryDate textbox needs to add 1 year onto the date.
Example:
If StartDate = 10/12/2013 then ExpiryDate will automatically change to 10/12/2014.
How to do that with JS?
function MyFunc() {
MyTextBox = document.getElementById("<%= TextBox1.ClientID %>");
MyTextBox2 = document.getElementById("<%= TextBox2.ClientID %>");
var date = new Date(MyTextBox.value);
var day = date.getDate();
var month = date.getMonth() + 1;
var year = date.getFullYear() + 1;
MyTextBox2.value = day + "/" + month + "/" + year;
}
Try this, call the setExpiryDate() function whenever you need to set the expiration date.
function setExpiryDate() {
var txtStartDate = document.getElementById("ctrl1");
var txtExpiryDate = document.getElementById("ctrl2");
var dt = new Date(txtStartDate.value);
if (!isNaN(dt)) {
dt = dt.setYear(dt.getYear() + 1);
txtExpiryDate.value = padStr(temp.getDate()) + '/' + padStr(temp.getMonth() + 1) + '/' + temp.getFullYear().toString();
}
}
function padStr(i) {
return (i < 10) ? "0" + i : "" + i;
}
How about this:
function updateInput(value){
document.getElementsById('Yourelement').Value = value;
}
Other than that, all you need is some date parsing/string manipulation to find the correct year.

Categories

Resources