Compare value in combo box with value in hidden field - javascript

I have several telerik radComboboxes and each has a corresponding hidden field.
The combos have an id prefix of cmb and their hidden field have a prefix of hd. I used these to detect if any combo box has had its value changed or if I need to reset the combo back to its initial value. I have the following JavaScript which is fired onClienSelectedIndexChanged...
function cmbSelectedIndexChanged(sender, eventArgs) {
            var selectedItem = eventArgs.get_item();
            var selectedItemText = selectedItem != null ? selectedItem.get_text() : sender.get_text();
            var hd = sender.attr('id').replace("cmb", "hd");
            if (selectedItemText !== $('#' + hd).val()) {
                registerChange();
            }
        }
 
I get an error - object doesn't this property or method - on the line beginning var hd
What am I doing wrong...?

You need to be searching for the ClientId of the control therefore the code will not work. Instead of
var hd = sender.attr('id').replace("cmb", "hd");
You should try something along the lines of:
var hd = sender.get_id().replace("cmb", "hd").replace(/_/,"$");
The above code will convert the client id of the telerik combo box into the "name" attribute of the element of the asp hidden control. I believe the code below should resolve the problem described (I apologize for the extra comments I was using this as a teaching aid earlier and thought it might be beneficial to other users)
function cmbSelectedIndexChanged(sender, eventArgs) {
// Get Selected Item
var selectedItem = eventArgs.get_item();
// Get Selected Text
var selectedItemText = selectedItem != null ? selectedItem.get_text() : sender.get_text();
// Convert Telerik element id to Asp Control name
var hd = sender.get_id().replace("cmb", "hd").replace(/_/g,"$");
// Compare the asp:HiddenField value to the selected text
if (selectedItemText !== document.getElementsByName( hd)[0].value) {
registerChange();
}
}
When debugging this locally I didn't have JQuery registered on the page so my updated function uses the .getElementsByName function instead of the JQuery equivalent e.g. $('[name="' + hd + '"]').

Related

USB Barcode scanner repeat scans without server call

Not sure if my terminology is correct on all of this. I know my code is not efficient either. Looking for functional over efficiency at this point. (just a teacher trying to solve logistical issues).
I have a webapp that we use to check students into and out of the library. Because of COVID, we are trying to touch the keyboard less and have a faster check-in process. To do this, we have a USB scanner that will scan student IDs.
My Webapp loads template html and then adds names etc to the different select elements. When a student checks in, the name appears on the other half of the window and waits for them to click the checkout next to their name. I believe this is done on what is called client side.
To add the barcode scanner, I added a form element with a text input. Is this the only way to have the barcode scanner interact with the client side?
<form><input type="text" id = "barcodeInput" size="1"></form>
I then have some jQuery that tests to see that the input is a barcode (Prefix and return key pressed), if so, the student ID number from the barcode is then put through a loop to find the matching id in the select options of student names (ids are stored in the values and student names are stored in the text). Default action is also prevented here
All of this works and I can get 1 student to add to the "checked in" panel of my app.
I cannot get the scanner to work on a second student. I think this has to do with the fact that I'm using the form input element and that might require a server call but I cannot do that since I need to have a growing list of students who are checked into the library.
I borrowed this and am currently using
$(document).ready(function() {
var barcode=""; //sets my variable
$(document).keydown(function(e) //looking to intercept the barcode scanner output
{
var code = (e.keyCode ? e.keyCode : e.which); //don't really know what this does since I borrowed this
if(code==13&&(barcode.substring(1,5)=="SCAN"))// Enter key hit & from scanner
{
e.preventDefault(); //stops the enter key from actually "running" and stops the barcode from going into the input field (I think)
barcode = barcode.slice(5);// remove the prefix so I am left with student number aka barcode
alert(barcode); //lets me know I'm getting the correct student number
processBarcode(barcode); //sends to process barcode
}
else if(code==9)// Tab key hit //I may not need these next 10ish lines
{
e.preventDefault();
alert(barcode);
}
else
{
e.preventDefault();
barcode=barcode+String.fromCharCode(code);
}
});
});
This find the student in the select element and then changes the select element to read that name and also posts the name on the "Who is checking in" Table cell
function processBarcode(barcode){
var name = "";
$("#studentNameSelect option").each(function(){ //runs through the select element that has all student names...the name is in the parameter "text" and student ID # is in the parameter val
if($(this).val()==barcode){ //looking to see if the student ID # matches the specific option in the select element
name = $(this).text(); //figure out the student name based on ID #
$(this).prop('selected', true); //set the select element to show this specific option
$("#selectedName").html(name); //puts student name in a table cell so they know they are picking the correct name
//$("#barcodeInput").trigger("reset"); //here I'm trying to get the form element input to reset so I can use it again...this didn't work so its commented out
$("#teacherNameSelect").focus(); //puts the focus onto the next select item so I can do other things
return false; //breaks the each loop once student name has been found
}
});
}
And then this is the code that moves the name onto the "checked in" panel so that the next student can check in
function buildAttendanceRow(stringPackage){ //this function takes info from the selection panel and builds a table row in the "I'm at the library" panel. Students click check out when they leave the library
console.log(stringPackage);
var package = JSON.parse(stringPackage); //receives a package of info from the selects, I do send this to a server function to email teachers that student arrived to the library...
console.log(package);
var html = "";
var hiddenId = new Date().getTime().toString(); //this cell is used to keep track of a specific instance of a student checked into the library so I can remove later and then mark in a backend spreadsheet database
var nameCell = '<td class="package" id="'+hiddenId+'">'+package.student+'</td>';
var checkOutButton = '<input type="button" value="Check Out" id="COButton">';
var checkoutButtonCell = '<td class="center">'+checkOutButton+'</td>';
html+="<tr>"+nameCell+checkoutButtonCell+"</tr>";
$("#checkedInTable").append(html); //puts the new table row into the checked in table
$('#'+hiddenId).data("package",package); //stores info so I can remove table row and update database
var lastTableRow = $('#checkedInTable tr:last');
var button = lastTableRow.find('#COButton');
//add the click function for removing row and sending checked out info to server for email and for database purposes
button.click(function(e){
var x = e.pageX;
var y = e.pageY;
var o = {
left: x,
top: y
};
$("#progressMonitor").show().offset(o);
$(this).prop("disabled",true);
var row = $(this).closest('tr');
var carrierCell =$('#'+hiddenId);
var d = new Date();
var payload = new Object(); //this object gets transferred to the server function, the user interface doesn't refresh here, it just has a dynamic html table built and shrunk as kids check in or check out
payload.checkInTime = carrierCell.data("package").checkInTime;
payload.timeIn = carrierCell.data("package").timeIn;
payload.student = carrierCell.data("package").student;
payload.teacherEmail = carrierCell.data("package").teacherEmail;
payload.teacherName = carrierCell.data("package").teacherName;
payload.reason = carrierCell.data("package").reason;
payload.checkOutTime = d;
payload.timeOut = d.getTime();
var stringPayload = JSON.stringify(payload);
row.hide();
alternateRowColors($("#checkedInTable"));
google.script.run.withSuccessHandler(emailAndRecordsSuccess).withFailureHandler(emailAndRecordsFailure).emailAndRecords(stringPayload);//calling the server function
});
var numRows = $("#checkedInTable tr" ).length;
if(numRows>2){
alphaSortTable(); //puts the student names in alpha order so it is easier for them to checkout of the library
}
alternateRowColors($("#checkedInTable"));
$("#progressMonitor").hide();
$("#barcodeInput").focus(); //here is me trying to get the scanner back into the input field so there is somewhere for the scanner data to go; I expected this to be all I needed to do, but at this point, even though the input is focused, the the scanner won't fire onto the document or into the field or anything like that
alert($("#barcodeInput").val()); //this is telling me that there is no value in the input field at this point, I thought there might be info stored here screwing up the scanner
}
The solution was to rebind a function to the document after my client side work was done.
Changed this into a named function:
$(document).ready(function() {
var barcode="";
$(document).keydown(function(e)
{
var code = (e.keyCode ? e.keyCode : e.which);
if(code==13&&(barcode.substring(1,5)=="SCAN"))
{
e.preventDefault();
barcode = barcode.slice(5);
processBarcode(barcode);
}else if(code==9)// Tab key hit
{e.preventDefault();
}else{
e.preventDefault();
barcode=barcode+String.fromCharCode(code);
}
});
});
Now I have:
function getBarcode(){
var barcode="";
$(document).keydown(function(e)
{
var code = (e.keyCode ? e.keyCode : e.which);
if(code==13&&(barcode.substring(1,5)=="SCAN"))
{
e.preventDefault();
barcode = barcode.slice(5);
processBarcode(barcode);
}else if(code==9)// Tab key hit
{e.preventDefault();
}else{
e.preventDefault();
barcode=barcode+String.fromCharCode(code);
}
});
and
$(document).ready(function() {
getBarcode();
}
and I can call
getBarcode();
anywhere to re-connect the document to be looking for the barcode scanner.

changing text for a selected option only when its in selected mode

I am not sure if I confused everyone with the above title. My problem is as follows.
I am using standard javascript (no jQuery) and HTML for my code. The requirement is that for the <select>...</select> menu, I have a dynamic list of varying length.
Now if the length of the option[selectedIndex].text > 43 characters, I want to change the option[selectecIndex] to a new text.
I am able to do this by calling
this.options[this.selectedIndex].text = "changed text";
in the onChange event which works fine. The issue here is once the user decides to change the selection, the dropdownlist is showing the pervious-selected-text with changed text. This needs to show the original list.
I am stumped! is there a simpler way to do this?
Any help would be great.
Thanks
You can store previous text value in some data attribute and use it to reset text back when necessary:
document.getElementById('test').onchange = function() {
var option = this.options[this.selectedIndex];
option.setAttribute('data-text', option.text);
option.text = "changed text";
// Reset texts for all other options but current
for (var i = this.options.length; i--; ) {
if (i == this.selectedIndex) continue;
var text = this.options[i].getAttribute('data-text');
if (text) this.options[i].text = text;
}
};
http://jsfiddle.net/kb7CW/
You can do it pretty simply with jquery. Here is a working fiddle: http://jsfiddle.net/kb7CW/1/
Here is the script for it also:
//check if the changed text option exists, if so, hide it
$("select").on('click', function(){
if($('option#changed').length > 0)
{
$("#changed").hide()
}
});
//bind on change
$("select").on('change', function(){
var val = $(":selected").val(); //get the value of the selected item
var text = $(':selected').html(); //get the text inside the option tag
$(":selected").removeAttr('selected'); //remove the selected item from the selectedIndex
if($("#changed").length <1) //if the changed option doesn't exist, create a new option with the text you want it to have (perhaps substring 43 would be right
$(this).append('<option id="changed" value =' + val + ' selected="selected">Changed Text</option>');
else
$('#changed').val(val) //if it already exists, change its value
$(this).prop('selectedIndex', $("#changed").prop('index')); //set the changed text option to selected;
});

Cannot get selectedIndex from select element positioned in cell in hidden row

I'm using DataTable and I'm trying to get some filtering function working with select element positioned in cells of the table.
The filtering works by entering text in input field positioned below each column. Then the filter function checks the selected text in all cells of that column and if no match is found in one cell, related row is hidden.
When the table has been loaded, it works to filter the table once. The problem is when clearing the filter, then it doesn't work. The reason seems to be related to that I'm using selectedIndex for the select DOM objects positioned in the rows that are not visible for the moment.
"qu_owner_xxx" is the ID of the select elements.
var el1 = document.getElementById("qu_owner_4"); //Visible, works like a charm
console.log("ID 1 " + el1.id); //ID is printed
console.log("EL 1 " + el1.selectedIndex);
var el2 = document.getElementById("qu_owner_17"); //Hidden, returns null
console.log("ID 2 " + el2.id); //Not reaching here
console.log("EL 2 " + el2.selectedIndex) ; //Not reaching here
str = el.options[el.selectedIndex].text; //Just for showing how to get the string used for filtering later
The thing is that the data of the cell is passed to the filter function as pure html, not as object. I can get the id from that part doing $(aData[i2]).attr('id') where aData is the table row. But using jQuery there seems to be some information you cannot reach compared to using the actual DOM object (e.g. selectedIndex), especially when you have to "recreate" the object from html.
How can I get the text from the selected value of the hidden select box/row? Is it even possible?
UPDATE
I tested my theory in jsfiddle, but it actually works retrieving the information from the hidden row/select. But it's no question about it, in my filter function is the rows that are not displayed that's failing.
My filter function (DataTable is calling this function when it is time for filtering)
$.fn.dataTableExt.afnFiltering.push(
function( oSettings, aData, iDataIndex ) {
var ret = true;
//Loop through all input fields i tfoot that has class 'sl_filter' attached
$('tfoot .sl_filter').each(function(i, obj){
//$(this) can be used. Get the index of this colum.
var i2 = $("tfoot input").index($(this));
//Create regexp to math
var r = new RegExp($(this).val(), "i");
var str = "";
if(i2 == 5){//This is just during development, don't want to care about other columns with select element so just doing things on this column
//Here I just pick two id, one that I know is visible and one that is not
var el1 = document.getElementById("qu_owner_4"); //Visible, works like a charm
console.log("ID 1 " + el1.id); //ID is printed
console.log("EL 1 " + el1.selectedIndex); //selectedIndex is printed
var el2 = document.getElementById("qu_owner_17"); //Hidden, returns null
console.log("ID 2 " + el2.id); //Not reaching here
console.log("EL 2 " + el2.selectedIndex) ; //Not reaching here
//This is how I intended to get it working, but fail
var el = document.getElementById($(aData[i2]).attr('id'));
str = el.options[el.selectedIndex].text; //String to be used for comparing
}
/*Test to see if there is a match or if the input value is the default
(the initial value of input before it has any fokus/text) */
if(r.test(str) || $(this).val()=="Search"){
//Return true only exits this function
return true;
}else{
/*Return false returns both function an .each. Retain 'false' in a variable scoped
to be reached outside the .each */
ret = false;
return false;
}
});
//Return true or false
return ret;
}
);
aData = the row. aData[x] gives me the cell content of cell x on that row. For the select element it's the raw html.
this = the input field in which the search string i entered.
Of course you can have the text from the selected value !
Here is one way (probably not the best, but works) :
$('select').change(function() {
var selectedValue = jQuery(this).val();
var selectedText = '';
jQuery(this).children('option').each(function() {
if (jQuery(this).val() == selectedValue) {
selectedText = jQuery(this).text();
}
});
});
The selectedText variable will contain the text from the selected value.
See here.

Altering the value of an option (select) element?

I'm attempting to select the selected value of a <select> form element, and append the value with -R. (This will be for regex matching later on). Anyway, so far I've tried the following:
Attempt 1:
var country = $('select[name=g_country\\['+value+'\\]]').val();
$('select[name=g_country\\['+value+'\\]]').find('option[value=' + value +']').val(country + '-R');
Attempt 2:
var country = $('select[name=g_country\\['+value+'\\]]').val();
$('select[name=g_country\\['+value+'\\]]').val(country + '-R');
I can tell that the selection of the correct form element (using delete_x, where x is a number) works fine, as the form elements to disable when .select-delete is clicked, however the value setting doesn't. The commented portion down the bottom is what I've been using to check the value of the <select> element post-value change (or what should be post-value change).
Here's a link to my jsFiddle: http://jsfiddle.net/gPF8X/11/
Any help/edits/answers will be greatly appreciated!
Try this:
$('.select-delete').click( function() {
var value = $(this).attr('id');
value = value.replace('delete_', '');
var country = $('select[name=g_country\\['+value+'\\]] option:selected').val() + '-R';
alert(country);
$('select[name=g_country\\['+value+'\\]] option:selected').val(country);
$('select[name=g_country\\['+value+'\\]]').attr('disabled','1');
$('input[name=g_url\\['+value+'\\]]').attr('disabled','1');
$(this).css('display', 'none');
var check = $('select[name=g_country\\['+value+'\\]]').val();
$('#test').append(check);
});
There is an issue with your HTML as well.
Finally came up with the right selector, props to #gjohn for the idea.
Here's my final working code, that appropriately adds -R to the end of g_country[x]:
$('.select-delete').click( function() {
var value = $(this).attr('id');
value = value.replace('delete_', '');
var country = $('select[name=g_country\\['+value+'\\]]').val();
$('select[name=g_country\\['+value+'\\]] > option:selected').val(country + '-R');
$('select[name=g_country\\['+value+'\\]]').attr('disabled','1');
$('input[name=g_url\\['+value+'\\]]').attr('disabled','1');
$(this).css('display', 'none');
});

UpdatePanel Javascript Error on Adding Clientside Listbox items After postback

I have a Dynamic list control of Metabuilder.Webcontrol inside UpdatePanel,I am adding removing Items using Javascript from the list control. It works fine Inside UpdatePanel.
I have another control Gridview along with checkbox's which require postback to get populated.
Once It gets populated successfully inside update without postback. I checked few rows and wanted to add them into List Control using Javascript.
It says "object doesn't support this property or method"
function addItmList(idv,valItem) {
var list =document.getElementById('ctl00_ContentPlaceHolder1_MyList');
//var generatedName = "newItem" + ( list.options.length + 1 );
list.Add(idv,valItem);
}
function checkitemvalues()
{
var gvET = document.getElementById("ctl00_ContentPlaceHolder1_grd");
var target = document.getElementById('ctl00_ContentPlaceHolder1_lstIControl');
var newOption = window.document.createElement('OPTION');
var rCount = gvET.rows.length;
var rowIdx = 0;
var tcount = 1;
for (rowIdx; rowIdx<=rCount-1; rowIdx++) {
var rowElement = gvET.rows[rowIdx];
var chkBox = rowElement.cells[0].firstChild;
var cod = rowElement.cells[1].innerText;
var desc = rowElement.cells[2].innerText;
if (chkBox.checked == true){
addItmList(rowElement.cells[1].innerText,rowElement.cells[2].innerText);
}
}
}
Code Behind
ScriptManager.RegisterClientScriptBlock(
Me.Page, Me.GetType(), MyList.ClientID, "" & vbCr & vbLf & "window.mylistid='" + MyList.ClientID + "';" & vbCr & vbLf & "", True
)
Remember my code works fine. It cannot maintain the state of List Control thats why It says Object reqiured.
Can any one help me out. After Update Panel Why My javascript doesnt add Items into ListBox.
Thanks In advance
are your functions inside the pageLoad javascript event that updatepanel calls each time it updates?

Categories