I'm cloning input fields on a table that have an autocomplete class. When I clone the fields I have no problem. The problem is that in the cloned fields, the autocomplete doesnt work (on the one that is not cloned it does work). My autocomplete code is this:
$(document).ready(function() {
$('#btnAdd').click(function() {
var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
var newNum = new Number(num + 1); // the numeric ID of the new input field being added
// create the new element via clone(), and manipulate it's ID using newNum value
var newElem = $('#input' + num).clone().prop('id', 'input' + newNum);
newElem.find(':input').each(function() {
var name = $(this).attr('name').replace(/\d+$/, '');
$(this).prop({id: name + newNum, name: name + newNum}).val("");
});
// insert the new element after the last "duplicatable" input field
$('#input' + num).after(newElem);
// enable the "remove" button
$('#btnDel').prop('disabled','');
// business rule: you can only add 15 names
if (newNum == 15)
$('#btnAdd').prop('disabled','disabled');
});
$('#btnDel').click(function() {
var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
$('#input' + num).remove(); // remove the last element
// enable the "add" button
$('#btnAdd').prop('disabled','');
// if only one element remains, disable the "remove" button
if (num-1 == 1)
$('#btnDel').prop('disabled','disabled');
});
$('#btnDel').prop('disabled','disabled');
});
My Autocomplete code is :
var autoc = {
source: "lib/search.php",
minLength: 1,
select: function( event, ui ) {
log( ui.item ?
"Selected: " + ui.item.value + " aka " + ui.item.id :
"Nothing selected, input was " + this.value );
}
};
var renderItem = function( ul, item ) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( "<a style='height:75px; text-align:center; font-weight:bold;'>"+ item.label + "</a>" )
.appendTo( ul );
};
$(".member").each(function (i) {
$(this).autocomplete(autoc).data("autocomplete")._renderItem = renderItem;
});
I've been trying to fix it by putting the autocomplete code inside of the clone code, Im not sure what Im doing wrong. It would be great if somebody could help! Thanks!
You have to reinitialize the autocomplete field after it's been cloned. And I think wrapping it within .live() is necessary as well
My solution to this was something like this:
$('#my_clone_button').live('click',function() {
my_clone_script; #this is my function to clone
$('select your new cloned input').each(function() {
$(this).autocomplete('destroy');
enable_autocomplete($(this), json_url); #this is my function to initialize autocomplete
});
});
try $('#input' + num).clone(true) passing true tells the clone to copy the events and data also. This means that it will copy that the input is a autocomplete field.
Related
i am not able to export multiple time searched and selected data to CSV.
i am fetching data from database which has more than 1000 records.
so for example, if i select 2 rows on page one then i search for some other record and select that record and export but it is only exports searched record not the records from the page one.
$('#master tfoot th').each(function() {
var title = $(this).text();
$(this).html('<input type="text" placeholder="Search ' + title + '" />');
});
// DataTable
var master = $('#master').DataTable({
dom: 'Blfrtip',
buttons: [
'copy',
'csv',
'excel',
'pdf',
{
extend: 'print',
text: 'Print all (not just selected)',
exportOptions: {
modifier: {
selected: null
}
}
}
],
select: true
});
// Apply the search
master.columns().every(function() {
var that = this;
$('input', this.footer()).on('keyup change', function() {
if (that.search() !== this.value) {
that
.search(this.value)
.draw();
}
});
});
This is a known limitation when using processing on the server-side. In this case the datatable-object only knows the data of the current draw. This is the reason you are only able to export the visible/rendered content of the table.
If you want to export the data from all currently selected rows, you could listen for the select.dt and deselect.dt events of the datatable and store the row-data of the selection in an extra array from that you can create the csv-data for an export.
Further information and examples about the events can be found in the oficial doumentation:
select event
deselect event
Whenever the selection changes, an event will be dispatched. We can listen for this select-event, check if the selection is of type row and add the data to an array or object. Since we want to prevent duplicates, we should choose an unique key for the data (based on an id or some other data of the row).
Depending on how you have implemented your datatable and the processing, you have to watch for the deselect-event too. And maybe add some special handling of the pagination inside the datatable, so that rows on other pages are displayed as selected when you navigate to them again.
let selectedRows = {}; // holds all the data of selected rows
let table = $('#example').DataTable({ /* settings */ });
table.on('select', function(e, dt, type, indexes) {
if ( type === 'row' ) {
let data = table.rows( indexes ).data();
for (let item of data) {
let key = item[0] + '_' + item[2] + '_' + item[2]; // an unique key, for example built from: eventName, firstName and lastName
if (!(key in selectedRows)) {
selectedRows[key] = item;
}
}
}
});
// Todo: handle deselect and maybe pagination...
You can then export that data inside the browser with javascript.
let csvData = 'COLUMN_1,COLUMN_2,COLUMN_3, ..., COLUMN_N';
for (let row of selectedRows) {
csvData = csvData + '\n'
+ '"' + row.column_1 + '",'
+ '"' + row.column_2 + '",'
+ '"' + row.column_3 + '",'
/* ... */
+ '"' + row.column_N + '",';
// Create temporary download-element
let a = window.document.createElement('a');
a.href = window.URL.createObjectURL(new Blob([csvData], { type: 'text/csv;charset=utf-8;' }));
a.download = 'export.csv';
a.display = 'none';
// Append element to body and click it
document.body.appendChild(a);
a.click();
// Remove element from body
document.body.removeChild(a);
Note: If your data has strings that includes double quotes ", you have to escape them with an extra double quote "".
I'm pretty new to web programming so, making a logic for a web-page, I made a mistake and now I'm in trouble.
I named some divs like "Dv_1.2.1.3" (without knowing the problems linked to using the dot) and I have issues trying to clone (via jquery called by button) some of these.
The button id contains the id of the div I want to clone, so, my logic is:
1) extract the id of the div;
2) get the div and clone it (giving a new id).
I'm stuck with getting the div because of the dots in the id.
The below code is what I've done so far:
$('.CloneDiv').click(function () {
var SplittedId = (this.id).split('_');
if (SplittedId[0]=='Clone'){
alert('SplittedId 1 =' + SplittedId[1]);
//Modify id to use it to find the div to clone
var UsableId = SplittedId[1].replace(/\./g, '\\\\.');
alert('UsableId =' + UsableId);
//Count existing elements
var ClonedNum = $('#' + 'Dv_' + UsableId + '_').length;
ClonedNum++;
var OrigElem = $('#' + 'Dv_' + UsableId).length;
alert('OrigElem =' + OrigElem); //THIS IS 0
//NO ELEMENTS FOUND BUT THE ELEMENT EXISTS
//Clone the element and give new id
var ClonedElem = $('#' + 'Dv_' + UsableId).clone().attr('id', function( i, val ) {
return val + '_' + ClonedNum;
});
ClonedElem.find("input").val("");
if (ClonedNum > 1){
ClonedNum--;
var AnteId = '#' + 'Dv_' + UsableId + '_' + ClonedNum;
alert(AnteId);
$(AnteId).after(ClonedElem);
}else{
var AnteId = '#' + 'Dv_' + UsableId;
alert('AnteId = ' + AnteId);
$(AnteId).after(ClonedElem);
};
}else if(SplittedId[0]=='Del'){
alert(SplittedId[0]);
alert('Del');
}else{
//error
};
});
Might these help: developer.mozilla.org/en-US/docs/Web/API/CSS/escape , Polyfill: github.com/mathiasbynens/CSS.escape/blob/master/css.escape.jāās
Is there a chance to have a combobox, which every time I select something in there, it opens a new one, etc, until no more data to select?
(options must not be repeated)
Combo1 - (opt1-opt2-opt3) - selected opt1
Combo2 - (opt2-opt3) - selected opt3
Combo3 - (opt2)
Comboboxes should be populated by querys using php and mysql.
How can I do it ?
Cheers!
Here is some jquery that will do this:
HTML
<select id="combo1" class="combo" data-index="1">
<option></option>
<option val="Opt1">Opt1</option>
<option val="Opt2">Opt2</option>
<option val="Opt3">Opt3</option>
</select>
Javascript
$('body').on('change', '.combo', function() {
var selectedValue = $(this).val();
if ($(this).find('option').size() > 2) {
var newComboBox = $(this).clone();
var thisComboBoxIndex = parseInt($(this).attr('data-index'), 10);
var newComboBoxIndex = thisComboBoxIndex + 1;
$('.parentCombo' + thisComboBoxIndex).remove();
if (selectedValue !== '') {
newComboBox.attr('data-index', newComboBoxIndex);
newComboBox.attr('id', 'combo' + newComboBoxIndex);
newComboBox.addClass('parentCombo' + thisComboBoxIndex);
newComboBox.find('option[val="' + selectedValue + '"]').remove();
$('body').append(newComboBox);
}
}
});ā
Demo
Explanation
// Adds an event listener to each combo box that is created dynmically
$('body').on('change', '.combo', function() {
// Gets this selected value
var selectedValue = $(this).val();
// Checks if there are enough options left to create another combo box
if (selectedValue !== '' && $(this).find('option').size() > 2) {
// Clones the just selected combo box and get the current and next combo index
var newComboBox = $(this).clone();
var thisComboBoxIndex = parseInt($(this).attr('data-index'), 10);
var newComboBoxIndex = thisComboBoxIndex + 1;
// Removes any "children" combo boxes
$('.parentCombo' + thisComboBoxIndex).remove();
// Checks if a blank value is not selected to create another combo box
if (selectedValue !== '' && $(this).find('option').size() > 2) {
// Gives this new combo box the correct id, index, parent class
newComboBox.attr('data-index', newComboBoxIndex);
newComboBox.attr('id', 'combo' + newComboBoxIndex);
newComboBox.addClass('parentCombo' + thisComboBoxIndex);
// Removes the selected option from the new combo box
newComboBox.find('option[val="' + selectedValue + '"]').remove();
// Adds the combo box to the page. Disco!
$('body').append(newComboBox);
}
}
});
I'm using jQuery clone and children concepts for my project. I'm using one table within div (class is clonedInput), by clicking one button I'm cloning the whole div and inserting it after the div. In this time:
"
var num = $('.clonedInput').length;
var newNum = new Number(num + 1);
var newElem = $('#input' + num).clone().attr('id', 'input' + newNum);
$('#input' + num).after(newElem);
"
by using this I'm increasing the div id. At the same time I want to increase the table tr and td's id. For that I tried children.attr(). But this is not increasing the table ids. Can anyone clarify this for me?
Thanks in advance.
I have a function which creates inputs in a row with incremented ids. This is not the thing you are looking for but i am sure it will give you a fairly good idea to how to do the task.
var numbers =0
$(function() {
var newRowNum = 0;
$('#addnew').click(function() {
newRowNum++;
///////////// <a> <td> <tr>
var addRow = $(this).parent().parent();
///////////// In the line below <tr> is created
var newRow = addRow.clone();
$('input', addRow).val('');
$('td:first-child', newRow).html();
$('td:last-child', newRow).html('<a href="" class="remove">Remove<\/a>');
$('input', newRow).each(function(i) {
var newID = newRowNum + '_' + i;
$(this).attr('id', newID).attr('name', newID);
});
addRow.before(newRow);
$('a.remove', newRow).click(function() {
$(this).parent().parent().remove();
return false;
});
return false;
});
numbers = newRowNum;
});
It is not clear what are you trying to do, but my guess is that you can try:
var num = $('.clonedInput').length;
var newNum = new Number(num + 1);
var newElem = $('#input' + num).clone();
newElem.attr('id', 'input' + newNum);
$('#input' + num).after(newElem);
the whole
$('#input' + num).clone().attr('id', 'input' + newNum);
part may not be giving you clone object but rather boolean result or some integer.
If the problem is not resolved you may try append() function also.
I'm working on a form where when user clicks "add server" a div block is repeated. I managed to work that out. But if I have only one server block I want the attribute name="servername" and if there are more elements that attribute should be name="servername[]" on all blocks.
I tried and only thing that works is when clicked add server first and second block gets name="servername[]", but when I click one more time first block gets name="servername[][]".
$('#addserver').click(function() {
var num = $('.clone').length; // how many "duplicatable" input fields we currently have
var newNum = new Number(num + 1); // the numeric ID of the new input field being added
// Create the new element via clone(), and manipulate it's ID using newNum value
var newElem = $('#server1').clone().attr('id', 'server' + newNum);
// Insert the new element after the last "duplicatable" input field
$('#server' + num).after(newElem);
// Add [] for PHP array
$('#server' + num + ' input', '#server' + newNum + ' input').attr('name', function() {
return this.name + '[]';
});
// Enable the "remove" button
$('#delserver').attr('disabled','');
// You can only add 5 elements
if (newNum == 5) $('#addserver').attr('disabled','disabled');
});
$('#delserver').click(function() {
var num = $('.clone').length; // how many "duplicatable" input fields we currently have
$('#server' + num).remove(); // remove the last element
// enable the "add" button
$('#addserver').attr('disabled','');
// If only one element remains
if (num-1 == 1) {
// Remove [] because it's not php array anymore
$('#server1 input').attr('name', function() {
s = this.name.substring(0, this.name.length - 2);
return s;
});
// Disable "remove" button
$('#delserver').attr('disabled','disabled');
}
});
$('#delserver').attr('disabled','disabled');
Here's html example:
<div class="clone" id="server1">
<input type="text" name="servername" size="40" />
</div>
I need [] because of php array, but if user is entering one server and there is [] in name it doesn't work.
I think that you should simply have name="servername[]" no matter what.
Since you can get it to work when servername contains more than one element, I don't see what stops you from having it work correctly with only one (or even none at all) element as well.
If you are not completely convinced, consider how much trouble you are having right now, trying to fight against what I suggest.
Add a check
if ($(this).attr('name').substr(-2) != '[]') {
return $(this).attr('name') + "[]";
}