I was trying to use some code I found on here, but I can't get it to work..
Original question: https://www.daniweb.com/programming/web-development/threads/374722/update-database-with-ajax-and-with-different-input-names
The code mostly works great for me, so thanks for this code but I have a problem.
In the code it gives handlers for text input and textarea input and suggests adding extra handlers for other input types. I need to use radio buttons and checkboxes, but I'm awful at javascript and though I got radio buttons to work in Firefox, I can't get them to work on Safari. My page needs to work on iPad/Safari. I couldn't get checkboxes to work on any platform. I don't know how to write the handlers, tried various ways, perhaps the functions themselves need tweaking, I don't know enough. I'm hoping this will be so simple for someone in the know to fix. I'm here because I'm well and truly stuck!

Here is my code (very much like original in link).

<html>
<head>
<script type='text/javascript'>
 <!--
window.onload = function() {
    alert(document.getElementById("year"));
};

    function GetXmlHttpObject() {
      var xmlHttp = null;
      try {
        // Firefox, Opera 8.0+, Safari
        xmlHttp=new XMLHttpRequest();
      }
      catch (e) {
        //Internet Explorer
        try {
          xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch (e) {
          xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
        }
      }
      return xmlHttp;
    }
 function updateDB(formElement, elementType, txtHint, xmlHttp, tim) {
     clearTimeout(tim);
     xmlHttp.abort();//abort any incomplete request for this request object that is currently in progress.
     var val = null, timeoutVal = 5000;
     switch(elementType) {
       case 'select':
         val = formElement[formElement.selectedIndex].value;
        //window.alert("select");
       break;
     case 'radio':          
         val = formElement[formElement.checked].value;
       break;
     case 'checkbox':
         val = formElement[formElement.checked].value;
       break;
       default:
         val = formElement.value;
       break;
     }

     if (val !== null) {
       var url = "includes/ajaxProcess-screening.php?recordID=<?php echo $recordID; ?>&" + formElement.name + '=' + val;
       url += "&sid=" + new Date().getTime();//good idea to avoid the consequences of cacheing
      // txtHint.innerHTML = 'updating...'; //&#10003;
    txtHint.innerHTML = '&#10003;';
       tim = setTimeout(function(){
      if(txtHint){
           xmlHttp.abort();
           if(txtHint) { txtHint.innerHTML = 'timeout'; }
      }
       }, timeoutVal);
       xmlHttp.onreadystatechange = function() {
         if (xmlHttp.readyState==4) {
           clearTimeout(tim);
           if (xmlHttp.status==200) {//success
             if(txtHint) { txtHint.innerHTML = xmlHttp.responseText; }//or something based on xmlHttp.responseText
           }
           else {//error
             if(txtHint) { txtHint.innerHTML = "update failed (" + xmlHttp.status + ")"; }
        }
         }
       };
       xmlHttp.open("GET", url, true);
       xmlHttp.send(null);
     }
   }

   function updateDB_closure(formElement, elementType) {//formElement and elementType are trapped in the closure and are reused
    var xmlHttp = GetXmlHttpObject();//xmlHttp is trapped in the closure and is reused
    if (xmlHttp==null) {
        alert ("Browser does not support HTTP Request");
        return;
    }
       var txtHint = document.getElementById(formElement.getAttribute("txtHintID"));//txtHint is trapped in the closure and is reused
    var tim;
    return function(evt) {//this retuned function becomes the handler for the designated event
        updateDB(formElement, elementType, txtHint, xmlHttp, tim);//use of the variables here causes a closure to be formed.
    };
   }

   onload = function(){
    var i;
    var elements = document.getElementsByTagName('input');
    for(i=0; i<elements.length; i++){
        if(elements[i].className.indexOf('updateDB') > -1){
            elements[i].onblur = updateDB_closure(elements[i], 'input');
        }
    }
    elements = document.getElementsByTagName('select');
    for(i=0; i<elements.length; i++){
        if(elements[i].className.indexOf('updateDB') > -1){
            elements[i].onchange = updateDB_closure(elements[i], 'select');
        }
    }
    elements = document.getElementsByTagName('textarea');
    for(i=0; i<elements.length; i++){
        if(elements[i].className.indexOf('updateDB') > -1){
            elements[i].onblur = updateDB_closure(elements[i], 'textarea');
        }
    }
    elements = document.getElementsByTagName('radio');
    for(i=0; i<elements.length; i++){
        if(elements[i].className.indexOf('updateDB') > -1){
        elements[i].onchange = updateDB_closure(elements[i], 'radio');
        }
    }

    elements = document.getElementsByTagName('checkbox');
    for(i=0; i<elements.length; i++){
        if(elements[i].className.indexOf('updateDB') > -1){
            elements[i].onchange = updateDB_closure(elements[i], 'checkbox');
        }
    }
   }
//-->
</script>
</head>

    <body>
        <h1>Form</h1>
        <span id="txthint_1"></span>
        <form>
            <input type="radio" name="icd"  class="updateDB" value="1" txtHintID="txthint_1" <?php if($icd=="1"){echo "checked";}?> > YES 
            <input type="radio" name="icd"  class="updateDB" value="0" txtHintID="txthint_1" <?php if($icd=="0"){echo "checked";};?> > NO
        </form>
    </body>
</html>


<!--Below is the php in the file include ajaxProcess-screening.php -->

<?php
$recordID = $_GET['recordID']; // the primary id for table
$getVars = array_keys($_GET); // array of all the $_GET variable names
$dbVariableName = $getVars[1]; // Second one, in this case the one matching database field name
$formValue = $_GET[$dbVariableName]; // It's value

$query = "UPDATE Screening SET ".$dbVariableName."='".$formValue."'  WHERE recordID= '$recordID'"; 
$updateresult = MYSQL_QUERY($query);
?>

Recommended Answers

All 17 Replies

As with a lot of people that post on coding forums, you need to help us to help you.
The statement "the checkboxes don't work" is hopelessly vague. You would be better off telling us exactly what the expected behavior should be and what you actually see. Then we have something to work with.
You say your checkboxes don't work but your form doesn't even include any, you've got radio buttons only.

Edit your question with what you really need to achieve please.

I am Sorry, hericles, I posted this in a frustrated state of mind and wasn't thinking very clealry. I thank yiou for such swift attention, I didn't expect anyone to get back to me so quickly!

I have complicated the matter by refering to checkboxes, it is the radio buttons that are the chief concern for me. I mentioned them as an afterthought as they too did not work too and that perhaps that was relevent.

The radio buttons do work fine - send a value to the database in firefox.

The issue is that when in safari (particular concern is the iPad, but I'm testing Safari on a Windows10), the radio buttons are clicked they do not send a value to the database.. The text input fields and drop downs do work and send the correct value in safari (ipad and Windows 10). I stripped out a lot from the main form so as to simplify the issue. In testing I put an pop up alert with the value 'val' in the switch/case part and 'val' came up as 'undefined' in the pop up (in Safari).

rproffitt, I did try it in Chrome and the radio buttons did result in the database being updated as planned, seems to be a Safari isssue.

Thanks guys.

@Dennis_8 Chrome was very recently updated but here's the passage that I think needs another reading from that link.

"Doesn't fire an input event when (un)checking a checkbox or radio button"

Here's another reading on it: https://bugs.webkit.org/show_bug.cgi?id=149398
And another at https://github.com/whatwg/html/issues/601

I don't have a setup to test your code at the moment but I've found the 'caniuse' site to help me when things I thought should work, don't.

the jsfiddle seems to work in safari, messages pop up. But not sure how I can apply it to my issue?

I added this

 $(document).ready(function() {
    $('.chk').live('change', function() {
      alert('change event fired');
    });
    $('icd').click(function() {
      $('.chk').attr('checked', true).change();
    });
  });

to the javascript and changed the radio button to this

<input type="radio" name="icd"  class="updateDB chk" value="1" txtHintID="txthint_1" <?php if($icd=="1"){echo "checked";}?> > YES 
            <input type="radio" name="icd"  class="updateDB chk" value="0" txtHintID="txthint_1" <?php if($icd=="0"){echo "checked";};?> > NO

Don't know if I'm doing it rightm but it still didn't send anything to the database. Or cause any alert popups to happen.

the irritating part is that it's basically "code you've found online". Does it actually link to your db, is it correctly configured?
Why not writing your own persistence code?

Member Avatar for diafol

What's this suposed to target?

$('icd').click(function() {
  $('.chk').attr('checked', true).change();
});

No tag called 'icd'

Istultuske, I haven't written my own code because I don't hardly know JavaScript. I only know php. I understand that many people will take pre written code by others. Why re-invent the wheel? I have made it interface with my database fine except fit this radio button issue. I am sorry you find this irritating, i am asking for help with an area that I am weak in.

As I have described the code interacts and works correctly with my database fine when one uses Firefox or chrome. The issue is with Safari. With the original code the author had written various event handlers fir firm elements, but not one for radio buttons. Not knowing JavaScript at all well, I tried to come up with that part myself. I am not very confident I have done that part right, though as i say, it did work with Firefox. I was hoping someone who is very familiar with JavaScript and safari would easily detect an error in my approach, most probably in the event handler.

Diablo, As for the 'icd' I simply tried to incorporate the suggestion by iproffitt to somehow incorporate the code on the page he linked too. As I say I don't know JavaScript, so am basically fumbling in the dark here.

Basically my question is ... Have I written the event handler (line106) for the radio buttons correctly? And anyone any idea why it would not trigger a correct interaction with the database via Safari? And does anyone know how to fix it?

Member Avatar for diafol

OK, let's take a deep breath. You are fine in re-using code we all do it. However, I would just point out that before you do that (on a live site), ensure that you understand what it's doing. There are many reasons for this, but my main concern is always security.

jQuery is supposed to make life a lot easier, but it can often appear as a black box, magically providing a solution to a complicated (or not so complicated process). You stated off with vanilla JS and now you're using jQuery? Mixing these is not a crime, and indeed sometimes the you need to do this. However, in general, and where possible, try to pick one approach.

I'm getting the idea that its the selected radiobutton being changed that is causing the issue not anything else?

If so, try this if now using jQuery...

https://jsfiddle.net/kr69r8qh/1/

Thank you Diafol, I will look at that. I really didn't want to be using any of this, but the client moved the goal posts very drastically and I'm left trying to do something I wouldn't have attempted if I'd known would be involved in the first place. I appreciate your words and help! And agree with your wise points.

I have to go out for a while but will give this my full attention when I return and let you know how I get on with that link.

Sorry for the delay. The jsfiddle was to see if that worked in Safari. Also I see now you need someone to write or fix your code.

You are dealing with less than a page of javascript and what I see missing is you coding up the changes.

My mistake too. I think you wanted to fire the updatedb on each click. Not just on change. Here's the shorter jsfiddle.
http://jsfiddle.net/0d30dww2/1/

Thanks I'm back now, trying toi make sense of all this. Thanks for helping.
Yes the update should happen whenever a form field is changed, text, drop downs and radio button interactions.

There would be many radio buttons and the code needs to be able to sense when any are changed and update each particular button's database field, as I say it does this in firefox. I see that the code you made at jsfiddle does indeed trigger events in Safari. So I'm seeing how to use it in my code so it works, not sure how to at this stage, will persevere.

Well, I can't make sense of any of that in the context of my problem. Sorry.

Member Avatar for diafol

If you can run code on an event you can make it do what you want. Instead of alert change it to an ajax call.

I changed the handlers to this, works on safari now.

 onload = function(){
        var i;
        var elements = document.getElementsByTagName('input');
        for(i=0; i<elements.length; i++){
            if(elements[i].className.indexOf('updateDB') > -1){
                elements[i].onblur = updateDB_closure(elements[i], 'input');
            }
        }
        elements = document.getElementsByTagName('select');
        for(i=0; i<elements.length; i++){
            if(elements[i].className.indexOf('updateDB') > -1){
                elements[i].onchange = updateDB_closure(elements[i], 'select');
            }
        }
        elements = document.getElementsByTagName('textarea');
        for(i=0; i<elements.length; i++){
            if(elements[i].className.indexOf('updateDB') > -1){
                elements[i].onblur = updateDB_closure(elements[i], 'textarea');
            }
        }
        elements = document.getElementsByTagName('radio');
        for(i=0; i<elements.length; i++){
            if(elements[i].className.indexOf('updateDB') > -1){
            elements[i].onchange = updateDB_closure(elements[i], 'radio');
            }
        }
        // didn't bother with checkboxes
   }

And changed the switch statement a tad

 function updateDB(formElement, elementType, txtHint, xmlHttp, tim) {
      clearTimeout(tim);
      xmlHttp.abort();//abort any incomplete request for this request object that is currently in progress.
      var val = null, timeoutVal = 5000;
      switch(elementType) {
        case 'textarea':
           val = formElement.value;
            //document.getElementById('feedback').innerHTML =  "textarea " + val ; // wee bit of feedback for error checking
        break;
        case 'select':
            val = formElement[formElement.selectedIndex].value;
            //document.getElementById('feedback').innerHTML =  "select " + val ;
        break;
         case 'radio':
            val = formElement.value;
            //document.getElementById('feedback').innerHTML =  "radio "  + val ;
        break;
         case 'checkbox':
            val = formElement[formElement.checked].value;
            //document.getElementById('feedback').innerHTML =  "checkbox " + val ;
        break;
        default: // will happily handle text input
            val = formElement.value;
            //document.getElementById('feedback').innerHTML =  "default " + val ;
        break;
      }

Seems Safari recognises the radio clicks now.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.