skip to Main Content

This question might be too specific to 123FormBuilder, yet I am putting it out there in hopes someone has some insight.

I am adding custom HTML to the form along with jQuery to allow Users to select 1 parking spot from an image of available parking spots (like picking a seat in a theater). The following code is included.

var $drop = $("[data-id='109672317'] select");
var $rvSpot = $("[data-id='110061531'] input");

$("path.enabled").on("mouseover", function(){
  $(this).toggleClass("highlight");
}).on("mouseout", function(){
  $(this).toggleClass("highlight")
}).on("click", makeSelection);

function makeSelection(e){
  var el = $(e.target);
  var l = $drop.find("option:selected").data("index");
  var s = el.attr("id");
  console.log("Making Selection", l, s);
  if($(".selected").length){
    if(!confirm("Are you sure you want to change your Parking Selection?")){
      return false;
    }
    removeSelected(l, e.target);
  }
  $.post("https://myurl.tld/take-spot.php", { land: l, spot: s }, function(results){
    el.addClass("selected");
    $rvSpot.trigger("focus").val(s).trigger("blur");
    console.log($rvSpot.val());
    startCountdown();
  });
}

function removeSelection(l, el){
  s = $(el).attr('id');
  console.log("Removing Selection", l, s)
  $.post("https://myurl.tld/release-spot.php", { land: l, spot: s }, function(){
    $(".selected").removeClass("selected");
    $rvSpot.trigger("focus").val(0).trigger("blur");
    stopCountdown();
  });
}

function startCountdown(){
  var m = 09, s = 60, t, $ct = $(".countdown .timeleft");
  $ct.html("10:00");
  $ct.data("timer", setInterval(function(){
    s--;
    if(s == 00){
      m--;
      s = 59;
    }
    if(m < 2){
      $ct.css("color", "red");
    }
    if(m == 00 && s == 00){
      stopCountdown();
      removeSelection($(".image-map", $(".selected")));
    }
    $ct.html(m + ":" + s);
  }, 1000));
}

function stopCountdown(){
  clearInterval($(".countdown .timeleft").data("timer"));
}

There is some documentation here, that suggest you have to set the value on a Control versus an Input Field. here is an HTML Snippet:

<div data-role="container" data-type="virtual-form-table-row" data-hash="0000001d" data-type-id="0" data-colspan="20" data-num-children="1">
  <div data-role="control" data-type="text" data-hash="0000001c" data-type-id="23" data-colspan="20" data-is-hidden="1" data-renderer-type="tln" data-id="110061531"><label data-role="label" id="text-0000001c-acc" data-i18n-text="control_label_110061531">Parking Spot</label><dt data-role="instructions" id="text-0000001c-instr-acc" data-is-empty="1" data-i18n-text="control_instructions_110061531"></dt>
    <div data-role="input-row" data-is-first-row="1" data-is-last-row="1" data-fill-colspan="0">
      <div data-role="input-container" data-ui-role="ui-element" data-size="full"><span data-role="prefix-label" id="price-0000001c-prefix-acc" style="display: none;"></span><input type="text" data-role="i123-input" data-no-theme="" aria-labelledby="text-0000001c-acc text-0000001c-error-acc text-0000001c-instr-acc" id="text-0000001c"
          value="0" placeholder="" style="padding-left: 8px;"></div>
    </div><label data-role="error" id="text-0000001c-error-acc" data-is-empty="1"></label></div>
</div>

I can see the Control element, yet it is not clear how I can update it so that the Form will accept this data when it is submitted.

Update

I got it to work once and have not been able to replicate it.

I updated code as follows:

$rvSpot.trigger("focus").attr("value", s).trigger("blur");

When I inspect the input element, it does appear to have the attribute change, yet when I submit the form and review the results, I still have a 0 value.

2

Answers


  1. Chosen as BEST ANSWER

    I finally found the answer here:

    https://www.123formbuilder.com/docs/js-tips-how-to-pass-an-input-from-one-field-to-another-in-the-same-form/

    There appears to be a handler with Get and Set methods.

    Here is the working code.

    var $drop = $("[data-id='000000000']");
    var $rvSpot = $("[data-id='000000000']");
    var targetControlId = 000000000,
    targetControlInstance = loader.getEngine().getDocument().getElementById(targetControlId);
    
    $("path.enabled").on("mouseover", function(){
      $(this).toggleClass("highlight");
    }).on("mouseout", function(){
      $(this).toggleClass("highlight")
    }).on("click", makeSelection);
    
    function makeSelection(e){
      var el = $(e.target);
      var l = $drop.find("select option:selected").data("index");
      var s = el.attr("id");
      if($(".selected").length){
        if(!confirm("Are you sure you want to change your RV Selection?")){
          return false;
        }
        removeSelected(l, el, function(){
          console.log("Spot removed, callback executed");
          makeSelection(e);
        });
      } else {
          console.log("Making Selection", l, s);
          $.post("https://www.unscruz.org/ticketing/take-spot.php", { land: l, spot: s }, function(results){
              el.addClass("selected");
              targetControlInstance.setValue({value: s});
              $(".countdown").append("<span id='spot-selected'>Selected: " + s + "</span>");
              startCountdown();
          });
      }
    }
    
    function removeSelected(l, el, callback){
        var s = $(el).attr('id');
        console.log("Removing Selection", l, s);
        $.post("https://www.unscruz.org/ticketing/release-spot.php", { land: l, spot: s }, function(){
            $(".selected").removeClass("selected");
            targetControlInstance.setValue({value: ""});
            stopCountdown();
            if(callback != undefined && typeof callback == "function"){
                callback();
            }
        });
    }
    

  2. Without knowing 123FormBuilder, I find .attr("value", s) strange: I would use .val(s), which is the correct way to set values of input elements in jQuery (see, for instance, "Difference between attr() and val() in jQuery".

    Double-check the $rvSpot selector is correct, and is targeting the right element. And make sure the value attribute is directly on the input element, and there are no other scripts or form validation that might be resetting the value to 0 on submission.

    I would also use .on( "change" [, eventData ], handler) (since the .change() handler API is deprecated) to trigger the change event after setting the value. That is important, as some forms listen to the change event to register that a value has been updated.

    +------------------+           +-----------------+
    | User Interaction | --click-> | makeSelection() |
    +------------------+           +-----------------+
             |                                     |
             |                                     |
             v                                     v
    +------------------+           +------------------+
    | Update $rvSpot   |           | startCountdown() |
    +------------------+           +------------------+
    

    Your updated code would be:

    // rest of your code
    
    function makeSelection(e){
      // existing code
      $.post("https://myurl.tld/take-spot.php", { land: l, spot: s }, function(results){
        el.addClass("selected");
        $rvSpot.val(s).trigger("change"); // use trigger to programmatically trigger the change event
        console.log($rvSpot.val()); // for debugging
        startCountdown();
      });
    }
    
    // rest of your code
    
    // Bind change event handler to $rvSpot if needed elsewhere in the code
    $rvSpot.on("change", function() {
      // Handler code here
    });
    

    That should properly update the value of $rvSpot and notify any other event listeners that the value has changed.

    Remember to verify the name and ID attributes of the input element to make sure the form will recognize the input when the form is submitted.


    Another approach would be described in How to Prefill Form Fields: 123FormBuilder supports prefilling form fields by constructing a customized URL with parameters that correspond to the form field IDs and the values you want to prefill. That is useful when you want to direct users to a form with some fields already filled in, based on known information.

    However, this method differs from the approach you have been using, which involves setting the value of a form field dynamically using JavaScript after the form has already loaded in the user’s browser.

    Based on the 123FormBuilder documentation, the form fields are not directly filled by manipulating the DOM elements with jQuery (as you were trying to do with $rvSpot.val(s).trigger("change")). Instead, you would construct a URL with the form’s field IDs and the desired prefill values as query parameters.

    For the scenario described in your JavaScript code, it seems that you want to update a form field in real-time as a user interacts with the form, rather than prefilling it via URL before the form loads. So…, the prefill URL method from the 123FormBuilder documentation does not apply directly to your situation.


    In your JavaScript code, when you are setting the value of the input dynamically and want the form to recognize this when submitted, you need to make sure:

    1. the JavaScript code correctly updates the value of the input field.
    2. any event listeners that the form builder relies on to detect changes are triggered.
    3. the form’s submission process recognizes the dynamically set values.

    If the form submission does not recognize the JavaScript-updated values, it might be due to the form builder’s internal mechanisms that track changes or validate inputs, which could be expecting user input events that are not being replicated by the JavaScript .trigger("change") method.

    The handler ($rvSpot.on("change", function() {...}) mentioned above is related to point 2.
    An example would be

    $rvSpot.on("change", function() {
      // That is the handler code that will run every time the value of $rvSpot changes.
      var newValue = $(this).val();
      
      // You might want to perform some validation, logging, or other functionality when the value changes.
      console.log("New parking spot selected:", newValue);
    
      // If the form relies on some validation or additional processing on change events,
      // you would include that logic here. For example:
      validateParkingSpot(newValue); // A hypothetical function to validate the selection.
      
      // Or, if you need to enable/disable a submit button based on this value:
      var isFormValid = newValue !== "0" && newValue !== ""; // Simple validation check.
      $("#submit-button").prop("disabled", !isFormValid); // Enable/disable the button.
    });
    

    That would be how you make sure the form’s submission process recognizes the dynamically set values because the handler makes sure all the steps, from validation to enabling the submission button, are processed whenever the input value changes, whether that change comes from the user directly or from a script.


    .attr("value") is not a good method, yet I tried .val() and did not get improved results; so I was trying alternates.

    Inspecting the Input element, it has focus and blur events bound to it from 123Forms. I do not see any for change.

    I suspect you are right that there is some higher form validation that I need to find. It seems just adding the value to the Input is not enough to get it to be accepted.

    If the input element has focus and blur events bound to it, it is possible that 123FormBuilder uses these events as part of its validation or state management system. The lack of a direct change event handler does not necessarily mean that changes to the input value will not be detected, but it does suggest that the form may rely on focus and blur events to trigger its internal change detection mechanisms.

    After setting the value with .val(), you could try triggering both focus and blur events to mimic a user interaction:

    $rvSpot.val(s).trigger("focus").trigger("blur");
    

    That is similar to Mark Schultheiss‘s comment:

    Perhaps just change $rvSpot.trigger("focus").attr("value", s).trigger("blur"); to fill the value first, then trigger the triggers i.e. $rvSpot.val(s).trigger("focus").trigger("blur");

    This should mimic a user selecting a value: the input gets the value (val(s)), the user "focuses" on the input (trigger("focus")), and then moves away from it (trigger("blur")). If the form builder is looking for these events to validate or process the input, this sequence would be more likely to be recognized as a legitimate user action.

    The form might have additional event handlers attached to its fields for validation or other purposes. You can inspect the element in the browser’s developer tools to see if there are event listeners that are not immediately visible in the code.

    If the form builder is using a more complex mechanism to track changes, you might need to use a MutationObserver to monitor changes to the input element and react accordingly.

    Make sure the input field has a name attribute that corresponds with what the server expects. Form data is typically keyed by the name attribute when submitted.

    If all else fails and you have control over the server-side logic, consider updating the value directly on the server after the form is submitted. That would be a less elegant solution and should only be used if no other options work.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search