Javascript (jquery) in my rails app is crashing IE - javascript

I've got a ruby on rails app where I'm using a table to display some data, and then allowing the user to edit the data in the table by clicking on the row and popping up a form for the relevant data. When changes are made to the form, the appropriate row in the table is updated.
The event listener for the table row click, which displays the appropriate form, looks like this:
$('.addable-rows > tbody').on('click', 'tr', function(e){
e.preventDefault();
var fieldset = $($(this).data('id'));
if ($(this).hasClass('selected')){
$(this).removeClass('selected');
fieldset.hide('slow');
} else {
$(this).siblings().removeClass('selected');
$(this).addClass('selected');
fieldset.siblings().hide('slow');
fieldset.show('slow');
}
});
The listener that checks for changes in inputs on the form and updates the appropriate row in the table looks like this:
$('.addable_row_host').on('change', ':input', function(){
var fieldset = $(this).closest('fieldset')
var id = fieldset.attr('id')
$('#'+id+'_tr').replaceWith(build_row(fieldset, id));
});
The build row method referenced above is:
function build_row(fields, id){
row = $("<tr id='"+id+"_tr' data-id='#"+id+"' class='selected'></tr>");
fields.find('select, input:not([type=hidden])').each(function(){
val = $(this).val();
if(val == null){
val = '';
}else if(val.indexOf(",") !== -1){
val.split(",").join(", ");
}
row.append('<td>'+val+' </td>');
});
return row;
}
This all works and is quite lovely in Chrome/FF/Safari, but it causes IE to grash most ungracefully. IE pops up a window reporting a crash and reloads the page. No mention of what caused the problem in the console. Additionally, any and all debugging statements in this code runs and is displayed to the console before the crash, so I haven't been able to pinpoint where it's happening.
Anyone know what I'm missing?

Related

JavaScript doesn't work after ajax loading (using table)

i have a table automatically generated by database using php with four rows ... the last row (4) has a button to trigger the function below... it repeats for every line.
after i click the button...the script sends a request to update database to switch the status "pendent" to "canceled".
at this point everything is okay... BUT...when i refresh the div with the table"$( '#lista' ).load(location.href + ' #lista > *' );"
the script doesnt work a second time after the loading. ( the div update is okay but only works a once)
i need the script working after the first refresh... everytime i clicked in the row button...
i think that may be a incompatibility of ajax request and javascript.
i really appreciate if you can help me.
thank you all.
<script>
var index, table = document.getElementById('table');
for(var i = 1; i < table.rows.length; i++)
{
table.rows[i].cells[4].onclick = function()
{ //inicio da função
var c = confirm('Você quer cancelar essa aula?');
if(c === true)
{//inicio confirmador
var table = document.getElementById('table');
index = this.parentElement.rowIndex;
value_index_id= table.rows[index].cells[0].innerHTML;
var id = value_index_id;
$.ajax({
type: 'GET',
url: 'cancelar_aulas.php',
data: {id_geral:id},
success: function(data){
alert(data);
$( '#lista' ).load(location.href + ' #lista > *' );
}
})
} //fim do confirmador
//validador
//console.log(index);
//console.log (value_index_id);
console.log(id);
};//fim da função
}
</script>";
You're only attaching the onclick event handler to the table when your page loads. That's why it only works on the first click. When you add new data to the table, you need to do something to add the onclick event to the new rows.
There's a few different ways to do this:
jQuery can attach events to dynamically created elements like so:
$("table").on("click", "table tr", function() {
// Note that this event would fire for ALL rows,
// but it will automatically attach this event to new rows
// that are added after page load
// This would work, you just would have to check if the clicked
// row is one of the last 4.
}
Create your own function to attach the event, and you'll run that function every time you add new rows. Something like:
function AttachClick() {
let table = document.getElementById("table");
let position = table.rows.length;
while (position > table.rows.length - 4) {
table.rows[position].addEventListener("click", function() {
// Do your on click here
// On success, you would fire this "AttachClick()" function
}
position--;
}
}
Notice the while loop starting from the end of the table instead of the start. If you had a table with a lot of rows it could be faster to iterate starting at the end (since those are the only rows you care about).

how to check all checkboxes and keep them checked through pagination

I have the scripts below one which checks all checkboxes in a group which works great, and another to pass the checkbox values over the pagination and all works fine the only problem is that when I click the check all box it checks all the pages on page 1 but when I click page 2 only the check all box is checked although the query is working fine. If I click all the checkboxes individually then they pass through the pagination fine, so I don't know why the check all button doesn't. I would like it so that when you click check all, all the boxes stay checked through the pagination as well.
here is my script that checks all checkboxes
<script type="text/javascript">
window.addEvent('domready', function() {
$$('li.head input[type=checkbox]').addEvent('click', function() {
this.getParent('ul').getElements('input[type=checkbox]').setProperty('checked', this.checked);
});
});
</script>
here is the script that remembers the checkboxes
var aa_checkbox;
function init_checkbox(){
//setup blank cb cookie
if(!Cookie.read('cb')){
Cookie.write('cb', JSON.encode({}));
}
//setup "associative array" to match what is currently in the cookie
aa_checkbox = JSON.decode(Cookie.read('cb'));
//set up each checkbox with class="remember_cb"
$$('input.remember_cb').each(function(el){
//mark checked if it is in the cookie
if(aa_checkbox[el.name]){
el.checked = 'checked'
}
//setup onclick event to put checkbox status in the
el.addEvent('click', function(){
if(el.checked){
aa_checkbox[el.name] = 1;
}else{
delete(aa_checkbox[el.name]);
}
})
})
//save aa_checkbox back into cookie upon leaving a page
window.onbeforeunload = function(){Cookie.write('cb', JSON.encode(aa_checkbox));};
setup_form();
return true;
}
function setup_form(){
//set up form so that it adds the inputs upon submit.
$$('form.remember_cb_form').each(function(form){
form.addEvent('submit', function(ev){
//clean up previously inserted inputs
var aa_hidden_insert = $$('input.hidden_insert');
$each(aa_hidden_insert, function(el){
el.parentNode.removeChild(el);
})
var el_form = this;
//insert hidden elements representing the values stored in aa_checkbox
$each(aa_checkbox, function(i_value, s_name){
if(i_value){
var el_input = document.createElement('input');
el_input.type = 'hidden';
el_input.value = i_value;
el_input.name = s_name;
el_input.setAttribute('class', 'hidden_insert');
el_form.appendChild(el_input);
}
});
});
});
}
window.addEvent('domready', init_checkbox);
If anyone can help me I would be very greatful, Thanks
It has to do with how your code works. I recommend that the check/un-check should affect the in-memory copy of the backing data. EG if you have an array representing the check boxes, set the check/uncheck in the array then render the array to check/uncheck the corresponding check box. That way, when you check all, all the array cells are set to checked! When you change from page to page, simply read the status of the corresponding array cell.

Javascript validation on paging in kendo ui grid

The following code worked as expected, however on the paging click, it still execute and display message "Please select a record first, then press this button". Is there anyway to prevent this unless the export button click. Thank you
$(document).ready(function () {
$("#Product").on("click",function(){
var $exportLink = $('#export');
var href = $exportLink.attr('href');
var grid = $('#Product').data('kendoGrid'); //get a reference to the grid data
var record = grid.dataItem(grid.select()); //get a reference to the currently selected row
if(record !=null)
{
href = href.replace(/refId=([^&]*)/, 'refId='+record.ID);
$exportLink.attr('href', href);
}
else
{
alert("Please select a record first, then press this button")
return false;
}
});
});
Defining a click handler as $("#Product").on("click",function(){...}) you are actually defining it for any click on #Product not just on you Export button. You should define the on for the button and not for the grid

Create hidden field element for each drop

I know this is a similar question to my previous one however its slightly different.
I have this script adding each 'dropped' element to a list. Now i need it adding into a variable / hidden field so i can pass it to the next page via a form.
When i run it at the moment. It alerts for each one however, it does it not just for every item dropped but if there are 10 items dropped it will run 10 times per item droped rather than once per item dropped.
Any help would be great.
//Record and add dropped items to list
var txt = $("#listbox");
var dtstart = copiedEventObject.start + '\n'
var caltitle = copiedEventObject.title
var txt = $('#listbox');
txt.append("<li class ='listItem'> "+dtstart +"</li>")
var listItems = $('.listItem');
$('#calendarform').submit(function() {
listItems.each(function(){ //For each event do this:
alert( listItems.text() );
});
return false;
});
// remove the element from the "Draggable Events" list
$(this).remove();
the problem lies in this code
listItems.each(function(){ //For each event do this:
alert( listItems.text() );
});
you are alerting the text of all the list items for each list item.
use jQuery(this) to access the current item within an each block
listItems.each(function(){ //For each event do this:
alert( $(this).text() );
});
Assuming your code is within a drop event handler, you are also adding a submit handler each time you drop. This means that each time you drop, you queue up another submit event. This is probably not desired. Move this submit(function(){}) block outside your drop handler to prevent it from firing that function more than once.
$('#calendarform').submit(function(e) {
var listItems = $('.listItem');
listItems.each(function(){ //For each event do this:
alert( listItems.text() );
});
e.preventDefault();//stop normal behavior
return false;
});
and to create elements on the fly you just pass jQuery the html, and append it to your form.
$('<input type="hidden" name="listItem[]"/>').appendTo("#calendarForm").val(listItem.text())
you may have to fiddle with the name element to get it to submit as an array in your server side language, but you're also within an each loop, which provides you with an index, so you can do the following.
$('#calendarform').submit(function(e) {
var form = $(this);
var listItems = $('.listItem');
listItems.each(function(index){ //For each event do this:
var listItem = $(this);
$("<input type='hidden'/>").val(listItem.text()).appendTo(form).attr('name', 'listItem[' + index + ']');
});
e.preventDefault();//stop normal behavior
return false;
});

JQUERY: Dynamic AJAX and html element removal

Consider this code:
<tr>
<td>
<input type="checkbox" name="20081846" value="20081846" class="chk-input">
</td>
<td>20081846</td>
<td>AGONOY, JAY TAN</td>
</tr>
Let's say I have N of these in a table (with different sets of data). What I am planning is, if the user checks the input box, it will delete the users are checked. I got it using this JQUERY
var del_users = function(btn,chk,url) {
$(btn).click(function(){
$(chk).each(function(){
if($(this).attr('checked') == 'checked') {
//pass code data
}
});
});
}
Which works, I just have to do the function that deletes the data.
My next problem is, once the data is deleted, I want the row displayed in the table to be removed in the display. Other than refreshing the entire entries, is there a way to selectively remove the checked "tr" elements?
$(chk).each(function(){
if($(this).prop('checked') === true) {
$(this).closest('tr').remove();
}
});
Removes the row with a nice animation:
if($(this).attr('checked') == 'checked') {
//pass code data
var $row = $(this).closest('tr');
$row.slideUp('fast',function() {
$row.remove();
});
}
You didn't post your ajax code, otherwise I would have added the removal code to the success callback (remember closure though!)

Categories

Resources