Sean Magyar
Sean Magyar

Reputation: 2380

jquery adding new select option and send data to server

I have a validation on the revenue field. If I run the code when the jquery code doesn't get invoked then the form gets submitted without any validation problem.

But if a user selects "no revenue" option in the first select then the jquery gets invoked ant the new $0 gets inserted and selected in the 2nd select form. If I check out the new HTML code everything looks good (new option is there and selected) but on submission it raises "revenue can't be blank error". So for some reason when the validation runs it thinks the field is empty.

I guess this is connected to my jQuery code. How can I solve this problem?

form (for showing original select options)

    <div class="form-group">
      <div><%= f.label :revenue_type, "Revenue Type" %></div>
      <%= f.select :revenue_type, ["recurring revenue", "non-recurring revenue", "no revenue"],
        { :selected => "recurring revenue" }, { "data-behavior" => "revenue-type-select", class: "form-control" } %>
    </div>

    <div class="form-group">
      <div><%= f.label :revenue %></div>
      <%= f.select :revenue, ["< $100k", "$100k < $1M", "> $1M"], {},
        { "data-behavior" => "revenue-number-select", class: "form-control" } %>
    </div>

jquery

$(document).on('change', '[data-behavior="revenue-type-select"]', function (event) {
  if ($(this).val() === "no revenue") {
    $('[data-behavior="revenue-number-select"]').append(new Option("$0", "$0"));
    $('[data-behavior="revenue-number-select"] option[value="$0"]').attr("selected", "selected").change();
    $('[data-behavior="revenue-number-select"]').prop("disabled", true);
  } 
  else {
    $('[data-behavior="revenue-number-select"] option[value="$0"]').remove();
    $('[data-behavior="revenue-number-select"]' ).prop("disabled", false);
  }
});

Html after jquery code invoked before submit:

<select data-behavior="revenue-number-select" class="form-control" name="company[revenue]" id="company_revenue" disabled="">
  <option value="< $100k">< $100k</option>
  <option value="$100k < $1M">$100k < $1M</option>
  <option value="> $1M">> $1M</option>
  <option value="$0" selected="selected">$0</option>
</select>

UPDATE

company.rb

validates :revenue, presence: { message: "can't be blank" }

This validates if the given value is nil or empty like ("", " "). It's weird since if I choose any of the original options like < $100k then the validation passes.

Upvotes: 0

Views: 116

Answers (2)

Sean Magyar
Sean Magyar

Reputation: 2380

I found this solution. Maybe it's not the best but working:

$(document).on('change', '[data-behavior="revenue-type-select"]', function (event) {
  if ($(this).val() === "no revenue") {
    $('[data-behavior="revenue-number-select"]').append(new Option("$0", "$0"));
    $('[data-behavior="revenue-number-select"] option[value="$0"]').attr("selected", "selected");
    $('[data-behavior="revenue-number-select"]').prop("disabled", true);
  } 
  else {
    $('[data-behavior="revenue-number-select"] option[value="$0"]').remove();
    $('[data-behavior="revenue-number-select"]' ).prop("disabled", false);
  };
});

$(document).on('bind', '[data-behavior="company-form"]', function (event) {
  $(this).find('[data-behavior="revenue-number-select"]').prop("disabled", false);
});

Upvotes: 0

Turan
Turan

Reputation: 142

Instead of changing the selected attribute you can try to change the selection of the directly by

setting selectedIndex to the last index of your select list using .prop

See Demo: https://jsfiddle.net/7da197j4/1/

Upvotes: 2

Related Questions