javascript object/array values into form inputs on click - javascript

I'm doing an autocomplete functionality which fills a datalist with options comprised of an endpoint query, which is working properly. But I have a problem in the end of my ajax call where my function is affecting only the last element of an array, as opposed to the correct one that is being clicked. I'm trying to make sure that when the user clicks their selection in the list, it sends certain values of the object into form input fields to save.
Right now, when i click an option it does put the correct object values into the form, HOWEVER, they are the values that correspond to the final element in the array and not the clicked one.
I've commented where my issue starts, but this is the whole script for reference. Again, the list fills correctly (though a little slow) and the click does fill out the form inputs, but the values are not corresponding to the clicked option, just the last in the array.
What am I doing wrong here?
<script type="text/javascript">
//If user types, send their input in ajax POST on each keystroke
$('#productInput').on('input', function(){
if($(this).val() === ''){
return;
}else{
//their input is searchResult
const searchResult = $(this).val();
$.ajax({ //url
data: {
search_result:searchResult
},
type: "POST",
success: function(response){
//empty out old responses
$('#returnedProducts').empty();
//this starts my index
let searchResult = response.hits.hits;
for(let i = 0; i < searchResult.length; i++) {
//this puts matches into the datalist option, which works
$("#returnedProducts").append("<option value=" + searchResult[i]._source.category + ">" + searchResult[i]._source.category + "</option>");
/*This block is my issue*/
$("#productInput").on('input', function(){
var val = this.val = this.value;
if($('#returnedProducts option').filter(function(){
return this.value === val;
}).length){
//These elements do fill, but the values correspond to only the last array item, not the clicked one
document.getElementById("grpName").value = searchResult[i]._source.frm.grp.grp_name;
document.getElementById("grpNum").value = searchResult[i]._source.frm.grp.grp_code;
}
})
/*end of problem block*/
}
}
});
}
});
</script>

The problem is that for each search result which is returned, you add another "input" event handler function to the "productInput" element. So if there are 5 results, you create 5 more event handlers. Then when something is input into that box, all 5 handlers (plus the original one, so 6) will execute in sequence. Since each time it overwrites the same textboxes, hence you only ever see the the last value. I'm pretty sure that's not even close to what you wanted.
You're adding options to the "returnedProducts" select list, and when the user selects an option you want some data to go into a form, is that right? If so, it would make more sense to handle the "change" event of the select list (and handle it once outside of your "success" function!!), and set data attributes on the option for the extra values. When the change event runs, retrieve the data attributes from the currently selected option and use those to populate your form.
Here's the general idea:
In the loop through your results:
for(let i = 0; i < searchResult.length; i++) {
//this puts matches into the select list option
$("#returnedProducts").append("<option value='" + searchResult[i]._source.category + "' data-grpName='" + searchResult[i]._source.frm.grp.grp_name + "' data-grpNum='" + searchResult[i]._source.frm.grp.grp_code + "'>" + searchResult[i]._source.category + "</option>");
}
Then separately (outside your $('#productInput').on('input', function(){ block entirely):
$("#returnedProducts").change(function() {
var selectedOption = $(this).find("option:selected");
$("#grpName").val(selectedOption.data("grpName"));
$("#grpNum").val(selectedOption.data("grpNum"));
});

Related

Form values are overwritten after change

I have a form that shows up when each row in a table is double clicked. The values of this form can be updated and the form should be submitted with all row changes. But each time I double click on a row and edit the values of that form for that row, the previous values I had changed get overwritten. In order to work around this, I tried adding all the changes to a map with the row id as the key and the values of the form as the value. But the form still won't update with the new values. Here is a fiddle to demonstrate what I mean:
https://jsfiddle.net/4fr3edk7/2/
If I double click on the row that says "Adam Smith" and change that name to John Doe, when I double click on the second row and then double Click on "Adam Smith" again, it should say "John" on the first textbox and "Doe" on the second one. But the new value never seems to save.
This code snippet loops through each key, then loops through each value of that key:
for(var i = 0; i<key.length; i++){
var getval = globalchanges[key[i]];
for(var k=0; k<getval.length; k++){
$("#input1").val(getval[0]);
$("#input2").val(getval[1]);
}
}
How can I get the new changes to save? (The table rows don't have to show the changes, just the textbox values). Any help would be appreciated.
First, as mentioned by #Taplar you are binding the click event multiple times. Your approach is close enough, the idea of storing the changes is valid. You should have 2 functions, store the changes on button click and the second one to retrieve the changes by id.
Updated Fiddle
This function will get the values of the form and will store in on a global object
function setMap(id){
var firstrow = $("#input1").val();
var secondrow = $("#input2").val();
globalchanges[id] = [firstrow,secondrow];
}
This other function will check if the global object has values for the passed id, if not, it will use the values on the row
function getMap(id, tr){
if(globalchanges[id] != undefined && globalchanges[id].length == 2){
$("#input1").val(globalchanges[id][0]);
$("#input2").val(globalchanges[id][1]);
}
else{
$("#input1").val($(tr).find('td').eq(1).text());
$("#input2").val($(tr).find('td').eq(2).text());
}
}
Please note there are also changes on the dbclick and click events, they should be separated
$("#table tr").dblclick(function(){
$("#txtbox-wrapper").css({"display" : "block"});
var id = $(this).find('td').eq(0).text();
$('#id').val(id);
getMap(id,this);
});
$("#savebtn").click(function(){
var id = $('#id').val();
setMap(id);
});
And that we added and additional input to store the id on the form.
You are going to need to rethink your logic because of this part
$("#table tr").dblclick(function(){
$("#txtbox-wrapper").css({"display" : "block"});
var id = $(this).find('td').eq(0).text();
$("#input1").val($(this).find('td').eq(1).text());
$("#input2").val($(this).find('td').eq(2).text());
$("#savebtn").click(function(){
addToMap(id);
});
});
-Every time- you double click a table row you are adding a new click binding to the savebtn element. This means if you double click both rows, when you click that button it will execute addToMap for both ids. You may have other issues with your logic relying on only two other inputs for multiple rows, but this double/triple/+ binding is going to bite you.
There are few changes required in your logic as well as implementation.
1: Do not bind save event inside row click.
2: You are selecting the value in row double click event from td element. You need to update this element to keep your logic working
3: Keep track of which row is getting updated.
Updated Code
var globalchanges = {};
var rowSelected = null;
$("#table tr").dblclick(function() {
$("#txtbox-wrapper").css({
"display": "block"
});
rowSelected = $(this).find('td').eq(0).text();
$("#input1").val($(this).find('td').eq(1).text());
$("#input2").val($(this).find('td').eq(2).text());
});
$("#savebtn").click(function() {
addToMap(rowSelected);
});
function addToMap(row) {
var array = [];
var changes = {};
var firstrow = $("#input1").val();
var secondrow = $("#input2").val();
array.push(firstrow, secondrow);
globalchanges[row] = array;
makeChanges(row);
}
function makeChanges(row) {
var key = Object.keys(globalchanges);
console.log(key);
$("#table tr td").each(function(k, v) {
if ($(v).text() == key) {
$(v).next().html(globalchanges[row][0]);
$(v).next().next().html(globalchanges[row][1]);
globalchanges = {};
}
});
}
Working fiddle : https://jsfiddle.net/yudLxsgu/

how to get previously selected rows of a bootstrap dataTable while searching

I have used a bootstrap DataTable to show data. At the same time i have a HTML checkbox as a column of that dataTable. I have a submit button to get the selected checkbox's value to do some stuff. I am fetching the following problem while select checkboxes under searching.
When i select all checkboxes and Click Save button I got all the values. It works as my expectation.
But Unexpected occures when i search via built-in search box of bootstrap dataTable.Here is the pictorial view
In this case when i press Save i got just the two value though all other values are still selected. How can i get all the selected values while searching
Here is my jquery code of Save button of getting the checkboxes value
$("#btnSave").click(function () {
var checkboxes = document.getElementsByName('foo');
var vals = "";
for (var i = 0, n = checkboxes.length; i < n; i++) {
if (checkboxes[i].checked) {
vals += "," + checkboxes[i].value;
}
}
....
//Other stuff
....
}
Please help me.
When you are doing a search, it is going to check only for the rows, that satisfy the given criteria. So your search logic works like this
if(searchCriteria==true)
{
showValue
}
Even if you had previously selected values it won't be showing all of them, because they don't satisfy the given criteria. Now in this case when you click on Save, it is taking only those rows in the datatable which are checked and satisfy the given criteria, as per your java script.
Now if you still wish, that all selected values should be taken in, there is one way you can try, put the selected values in some kind of List or Set, and place the list object in session. So everytime you click on Save, you can retrieve the List from the session. But I really don't see why you would want to do it, unless you need to retrieve the selected values every time.
I got my job done like this
var table = $('#tblReportList').dataTable();
When i was searching through dataTable, i was getting just the selected values matching the search criteria. But the previously selected values was disappeared. To get the previously selected value i used the following code...
table.$('input[type="checkbox"]').each(function () {
if (!$.contains(document, this)) {
if (this.checked) {
previousVal = previousVal + ',' + this.value;
}
}
});
Now, for getting the selected values of search I used the previous code posted before. And that was
var checkboxes = document.getElementsByName('foo');
var vals = "";
for (var i = 0, n = checkboxes.length; i < n; i++) {
if (checkboxes[i].checked) {
vals += "," + checkboxes[i].value;
}
}
So all selected checkbox's values are
var allValues=previousVal+vals;

JQuery DataTables How to get selected rows from table when we using paging?

For example I selected (checked) 2 rows from second page than go to first page and select 3 rows. I want get information from 5 selected rows when I stay at first page.
$('tr.row_selected') - not working
Thanks.
Upd.
I created handler somthing like this:
$('#example').find('tr td.sel-checkbox').live("click", function () {
/*code here*/
});
But right now when click event is hadle the row from table is hidding. I think it may be sorting or grouping operation of DataTables. Any idea what I must do with this?
When a checkbox gets selected, store the row information you want in a global object as a Key-Value pair
I don't remember specifically how i did it before but the syntax was something like
$('input[type=checkbox]').click(function()
{
var row = $(this).parent(); //this or something like it, you want the TR element, it's just a matter of how far up you need to go
var columns = row.children(); //these are the td elements
var id = columns[0].val(); //since these are TDs, you may need to go down another element to get to the actual value
if (!this.checked) //becomes checked (not sure may be the other way around, don't remember when this event will get fired)
{
var val1 = columns[1].val();
var val2 = columns[2].val();
myCheckValues[id] =[val1,val2]; //Add the data to your global object which should be declared on document ready
}
else delete myCheckValues[id];
});
When you submit, get the selected rows from your object:
for (var i = 0; i < myCheckValues.length; i++)
...
Sorry, haven't done JS in a long time so code as is might not work but you get the idea.
$('#example').find('tr td.sel-checkbox').live("click", function () {
var data = oTable.fnGetData(this);
// get key and data value from data object
var isSelected = $(this).hasClass('row_selected');
if(isSelected) {
myCheckValues[key] = value;
checkedCount++;
} else {
delete myCheckValues[key];
checkedCount--;
}
});
.....
On submit
if(checkedCount > 0) {
for(var ArrVal in myCheckValues) {
var values = myCheckValues[ArrVal]; // manipulate with checked rows values data
}
}

Remove selected items from other select inputs

I have a problem with select input items.
What I want to achieve is dynamically remove already selected options from other select boxes so that I cannot select same item on multiple boxes. The problem is that elements are loaded in array via AJAX and I need to fill the select input with options after. This makes it so much harder.
In short - How can I make sure that if I select one item in select it will be deleted on all others, but when I select something else the previous item will be shown again and so on...
I have a fiddle as well, this is how far I got: http://jsfiddle.net/P3j4L/
You can try something like this
function updateSelects()
{
$('.selectContainer .select').each(
function (i, elem)
{
// Get the currently selected value of this select
var $selected = $(elem).find("option:selected");
// Temp element for keeping options
var $opts = $("<div>");
// Loop the elements array
for (i = 0; i < selectElements.length; i++)
{
var value = selectElements[i];
// Check if the value has been selected in any select element
if ($selected.val() == value || !$('.select option[value=' + value + ']:selected').length)
{
// if not create an option and append to temp element
$opts.append('<option value="' + value + '">' + value + '</option>');
}
}
// replace the html of select with new options
$(elem).html($opts.html());
if ($selected.length)
{
// set the selected value if there is one
$(elem).val($selected.val());
}
else
{
// new select element. So remove its selected option from all other selects
$('.selectContainer .select').not(this).find('option[value=' + $(elem).val() + ']').remove();
}
}
);
}
see a demo here : http://jsfiddle.net/P3j4L/1/

jquery- unable to access individual elements that are part of list/select box in a web page form

I am trying to access each individual element, ie option, defined for a list box (or drop down box).
For some reason the code I am using is not working. It is given below---
$(jQuery('input', $(this).parent('form'))).each(function() {
element= $(this);
textmsg=" Element # " + (count+1) + "...Name of this input element = " + $(this).attr('name') + " multiplechoice-" + $(this).attr('multiple');
textmsg= textmsg + "...Also, for this element, the value is " + $(this).val() + " and type =" + $(this).attr('type');
alert (textmsg);
var listofoptions = new Array();
type=$(this).attr('type');
if(type=="select")//this means we have to go through the children for this select element, to obtain the values for each option
{
var elements= $('option', this);
for(var i=0; i<elements.length; i++)
{
// add $(this).val() to your list
alert("Value of this option=" + $elements[i].val());
});
}
});
How do I make the above code work? Or can you suggest an alternative way of accessing each option value? Thanks...
In order to select all inputs you would need to use the :input selector and not just $('input') as this will select inputs by tag name and the select will be excluded.
So do
$(this).parent('form').find(':input')
Also, since there's no type attribute on a select element. You could use .is() instead to check if it's a select.
$(this).is('select')
Edit: for the if statement i would do the following
if( $(this).is('select') )
{
$(this).find('option').each(function(){
alert( $(this).val() );
});
}
Here's a fiddle
the select tag is not an input so it would never be a part of the selection
You could try
$("input, select")

Categories

Resources