0

I am trying to replace some texts in html string but it throws Uncaught TypeError: Cannot read property 'replace' of undefined error.

var formHtml = ($('#cx-record-answer-form-div .'+$('#cx-user-survey-questions-record-edit').find('#answer_type').val()).html());

In the console when I logged the formHtml variable it says that formData is undefined but when I remove .html() from the end of the above code it returns valid html. But still the replace function is throwing the undefined error!

JS:

var $addAnswerButton = $('#add-answer-button');
var newAnswerFormIndex =  0;

$addAnswerButton.on('click', function() {
    newAnswerFormIndex++;

    if($.trim($('#cx-user-survey-questions-record-edit').find('#answer_type').val()) != ''){
        // get form html
        var formHtml = ($('#cx-record-answer-form-div .'+$('#cx-user-survey-questions-record-edit').find('#answer_type').val()).html());
        console.log(formHtml);
        var appendFormHtml = formHtml.replace('cx-record-answer-form-<#id#>','cx-record-answer-form-new-'+newAnswerFormIndex);
        console.log(appendFormHtml);

        appendFormHtml = appendFormHtml.replace(/\<#id#>/g,newAnswerFormIndex);
        appendFormHtml = appendFormHtml.replace('bootstrapSwitch-class','bootstrapSwitch');
        $('#answer-container').append(appendFormHtml);

    }
});

HTML Markup:

<form id="cx-user-survey-questions-record-edit">
        <div class="row">
            <section class="col col-6">
                <label class="label">Select type</label>
                <label class="input">
                    <select id="answer_type" name="answer_type" class="select2 select2-hidden-accessible" data-bind="select2Binding: answer_type, select2Options: { data: listAnswerTypes, width: &quot;100%&quot;, placeholder: &quot;Select a type...&quot;}" tabindex="-1" aria-hidden="true">
                        <option value="0">Free Text</option><option value="1">Multiple</option></select><span class="select2 select2-container select2-container--default select2-container--below select2-container--open" dir="ltr" style="width: 100%;"><span class="selection"><span class="select2-selection select2-selection--single" role="combobox" aria-haspopup="true" aria-expanded="true" tabindex="0" aria-labelledby="select2-answer_type-container" aria-owns="select2-answer_type-results"><span class="select2-selection__rendered" id="select2-answer_type-container" title="Multiple">Multiple</span><span class="select2-selection__arrow" role="presentation"><b role="presentation"></b></span></span></span><span class="dropdown-wrapper" aria-hidden="true"></span></span>                                            </label>
                </section>
        </div>
        <button id="add-answer-button" class="btn btn-primary pull-left" type="button">Add Answer</button>
        <button class="btn btn-success cx-btn-submit" type="submit">Save Question</button>
</form>

<div id="answer-container"></div>

<div id="cx-record-answer-form-div" class="hide">
    <div class="multiple">
        <form id="cx-record-answer-form-<#id#>" data-answer-id="<#id#>" class="cx-record-answer-form smart-form" data-edit-allowed="true">
            <section class="col col-4">
                <label class="label">Answer</label>
                <label class="input">
                    <input type="text" id="answer" name="answer" class="form-control" placeholder="Answer" data-bind="value: answer">                </label>
            </section>
        </form>
    </div>

</div>
3
  • If $ is really jQuery then $('#cx-record-answer-form-div .'+$('#cx-user-survey-questions-record-edit').find('#answer_type').val()) won't ever return "html" Commented Jun 13, 2019 at 18:24
  • This is invalid - ($('#cx-record-answer-form-div .'+$('#cx-user-survey-questions-record-edit'). Your formHtml is undefined. Commented Jun 13, 2019 at 18:27
  • @randomSoul This is only "invalid" when you ignore the parts you've removed. And even without the removed parts it will only generate an invalid selector. But also in this case formHtml won't be undefined Commented Jun 13, 2019 at 18:32

1 Answer 1

1

($('#cx-record-answer-form-div .'+$('#cx-user-survey-questions-record-edit') is incorrect. If you want to get the value of select with id answer_type use - $('#cx-user-survey-questions-record-edit').find('#answer_type').val().

var $addAnswerButton = $('#add-answer-button');
var newAnswerFormIndex = 0;

$addAnswerButton.on('click', function() {
  newAnswerFormIndex++;

  if ($.trim($('#cx-user-survey-questions-record-edit').find('#answer_type').val()) != '') {
    // get form html
    var formHtml = ($('#cx-user-survey-questions-record-edit').find('#answer_type').val());
    console.log(formHtml);
    var appendFormHtml = formHtml.replace('cx-record-answer-form-<#id#>', 'cx-record-answer-form-new-' + newAnswerFormIndex);
    console.log(appendFormHtml);

    appendFormHtml = appendFormHtml.replace(/\<#id#>/g, newAnswerFormIndex);
    appendFormHtml = appendFormHtml.replace('bootstrapSwitch-class', 'bootstrapSwitch');
    $('#answer-container').append(appendFormHtml);

  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="cx-user-survey-questions-record-edit">
  <div class="row">
    <section class="col col-6">
      <label class="label">Select type</label>
      <label class="input">
                    <select id="answer_type" name="answer_type" class="select2 select2-hidden-accessible" data-bind="select2Binding: answer_type, select2Options: { data: listAnswerTypes, width: &quot;100%&quot;, placeholder: &quot;Select a type...&quot;}" tabindex="-1" aria-hidden="true">
                        <option value="0">Free Text</option><option value="1">Multiple</option></select><span class="select2 select2-container select2-container--default select2-container--below select2-container--open" dir="ltr" style="width: 100%;"><span class="selection"><span class="select2-selection select2-selection--single" role="combobox" aria-haspopup="true" aria-expanded="true" tabindex="0" aria-labelledby="select2-answer_type-container" aria-owns="select2-answer_type-results"><span class="select2-selection__rendered" id="select2-answer_type-container" title="Multiple">Multiple</span><span class="select2-selection__arrow" role="presentation"><b role="presentation"></b></span></span></span><span class="dropdown-wrapper" aria-hidden="true"></span></span>                                            </label>
    </section>
  </div>
  <button id="add-answer-button" class="btn btn-primary pull-left" type="button">Add Answer</button>
  <button class="btn btn-success cx-btn-submit" type="submit">Save Question</button>
</form>

<div id="answer-container"></div>

<div id="cx-record-answer-form-div" class="hide">
  <div class="multiple">
    <form id="cx-record-answer-form-<#id#>" data-answer-id="<#id#>" class="cx-record-answer-form smart-form" data-edit-allowed="true">
      <section class="col col-4">
        <label class="label">Answer</label>
        <label class="input">
                    <input type="text" id="answer" name="answer" class="form-control" placeholder="Answer" data-bind="value: answer">                </label>
      </section>
    </form>
  </div>

</div>

Edit -

From the line of code ($('#cx-record-answer-form-div .'+$('#cx-user-survey-questions-record-edit').find('#answer_type').val()).html()); it seems like you want to get the html of div with class multiple nested inside div with id cx-record-answer-form-div and you want to get the class name multiple dynamically from the first select dropdown.

The line - find('#answer_type').val() will return either 0 or 1. Instead use text() to get text content of the selected option.

var $addAnswerButton = $('#add-answer-button');
var newAnswerFormIndex =  0;

$addAnswerButton.on('click', function() {
    newAnswerFormIndex++;

    if($.trim($('#cx-user-survey-questions-record-edit').find('#answer_type').val()) != ''){
        // get form html
        const selectedOption = $('#cx-user-survey-questions-record-edit').find('#answer_type option:selected').text().toLowerCase();
        const formHtml = $('#cx-record-answer-form-div .' + selectedOption).html();
        console.log('Before Replace ', formHtml);
        if(formHtml) {
            let appendFormHtml = formHtml.replace('cx-record-answer-form-<#id#>', 'cx-record-answer-form-new-' + newAnswerFormIndex);
            console.log('After Replace ', appendFormHtml);
            // var appendFormHtml = formHtml.replace('cx-record-answer-form-<#id#>','cx-record-answer-form-new-'+newAnswerFormIndex);
            // console.log(appendFormHtml);
             
            // appendFormHtml = appendFormHtml.replace(/\<#id#>/g,newAnswerFormIndex);
            // appendFormHtml = appendFormHtml.replace('bootstrapSwitch-class','bootstrapSwitch');
            // $('#answer-container').append(appendFormHtml);
        }
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="cx-user-survey-questions-record-edit">
  <div class="row">
    <section class="col col-6">
      <label class="label">Select type</label>
      <label class="input">
                    <select id="answer_type" name="answer_type" class="select2 select2-hidden-accessible" data-bind="select2Binding: answer_type, select2Options: { data: listAnswerTypes, width: &quot;100%&quot;, placeholder: &quot;Select a type...&quot;}" tabindex="-1" aria-hidden="true">
                        <option value="0">Free Text</option><option value="1">Multiple</option></select><span class="select2 select2-container select2-container--default select2-container--below select2-container--open" dir="ltr" style="width: 100%;"><span class="selection"><span class="select2-selection select2-selection--single" role="combobox" aria-haspopup="true" aria-expanded="true" tabindex="0" aria-labelledby="select2-answer_type-container" aria-owns="select2-answer_type-results"><span class="select2-selection__rendered" id="select2-answer_type-container" title="Multiple">Multiple</span><span class="select2-selection__arrow" role="presentation"><b role="presentation"></b></span></span></span><span class="dropdown-wrapper" aria-hidden="true"></span></span>                                            </label>
    </section>
  </div>
  <button id="add-answer-button" class="btn btn-primary pull-left" type="button">Add Answer</button>
  <button class="btn btn-success cx-btn-submit" type="submit">Save Question</button>
</form>

<div id="answer-container"></div>

<div id="cx-record-answer-form-div" class="hide">
  <div class="multiple">
    <form id="cx-record-answer-form-<#id#>" data-answer-id="<#id#>" class="cx-record-answer-form smart-form" data-edit-allowed="true">
      <section class="col col-4">
        <label class="label">Answer</label>
        <label class="input">
                    <input type="text" id="answer" name="answer" class="form-control" placeholder="Answer" data-bind="value: answer">                </label>
      </section>
    </form>
  </div>

</div>

The replace will work, only if you select option two with text multiple because there does not exist html code with #cx-record-answer-form-div .free text. appendFormHtml.replace(/\<#id#>/g,newAnswerFormIndex); is not required because it is already replaced in formHtml.replace. As well formHtml do not have bootstrapSwitch-class. So the line appendFormHtml = appendFormHtml.replace('bootstrapSwitch-class','bootstrapSwitch'); won't replace anything.

Sign up to request clarification or add additional context in comments.

1 Comment

you're right about getting value of select but I want to get $('#cx-record-answer-form-div div html also so therefore I have added concatenation !

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.