SeaSky
SeaSky

Reputation: 1312

Dynamically modifying a DOM and adding to document

I have a x-template section which contains a survey element (basically a text field and radio button). When the user loads up the screen, based on previously stored sections, the database sends across a jSON object to the UI which then populates this survey template using the JSON objects.

I am able to create the entire template dynamically and have no issues there. However when I try to populate the template with values from the JSON object - i have run into issues. Any help is appreciated on what I could be doing wrong.

Thanks

Fiddle here

Javascript:

    $(document).on('click', '.btn-toggle', function () {
    $(this).find('.btn').toggleClass('active');

    if ($(this).find('.btn-primary').size() > 0) {
        $(this).find('.btn').toggleClass('btn-primary');
    }

    $(this).find('.btn').toggleClass('btn-default');
});

var questions = [{
    "id": "6",
        "survey_id": "23",
        "name": "How are you? Not here?",
        "subtext": "",
        "type": "1",
        "required": "N"
}, {
    "id": "7",
        "survey_id": "23",
        "name": "Where are you?",
        "subtext": "",
        "type": "1",
        "required": "Y"
}];


for (var key in questions) { 
    question = questions[key];
    var questionTemplate = $('#textSurveyTemplate');
    $('#textSurveyTemplate').find('input#question-name').attr('value', question.name);
    $('.test').append($('#textSurveyTemplate').text());
}

HTML code:

    <script id="textSurveyTemplate" type="text/x-tmpl">
    <div class = "text-question" > 
        <div class = "form-group survey-form-group" style = "border-bottom: none;"> 
            <label class = "col-md-2 control-label" > Question </label>
            <div class="col-md-9">
                <input type="text" class="form-control" id="question-name" name="qname" placeholder="Question" value="" data-type="1" />
            </div>
        </div>
        <div class="form-group survey-form-group">
            <label class="col-md-2 control-label">Required</label> 
            <div class = "col-md-9 btn-group btn-toggle" > 
                <button type = "button" class = "btn btn-xs btn-default" > Y </button>
                <button type="button" class="btn btn-xs btn-primary active">N</button > 
            </div>
        </div > 
    </div>
</script>
<div class="test">Test Area</div>

Upvotes: 0

Views: 68

Answers (3)

SeaSky
SeaSky

Reputation: 1312

Fixed it - The trick is to use appendTo and assign the newly appended element to a variable for future manipulation. Apparently, when a DOM is appended to another DOM element, the existing references get wiped out and that is why it didnt work. I updated the fiddle here

The updated JAvascript code is below - note the use of appendTo and the manipulation from there onwards

$(document).on('click', '.btn-toggle', function () {
    $(this).find('.btn').toggleClass('active');

    if ($(this).find('.btn-primary').size() > 0) {
        $(this).find('.btn').toggleClass('btn-primary');
    }

    $(this).find('.btn').toggleClass('btn-default');
});

var questions = [{
    "id": "6",
        "survey_id": "23",
        "name": "How are you? Not here?",
        "subtext": "",
        "type": "1",
        "required": "N"
}, {
    "id": "7",
        "survey_id": "23",
        "name": "Where are you?",
        "subtext": "",
        "type": "1",
        "required": "Y"
}];


for (var key in questions) { //questions is defined in edit.ctp
    question = questions[key];
    var template = $('#textSurveyTemplate').html();
    var curr = $(template).appendTo($('.test'));
    curr.find('input#question-name').val(question.name);
}

Upvotes: 0

emibloque
emibloque

Reputation: 203

My first attempt was replacing your final loop by something like this:

for (var key in questions) {
    question = questions[key];
    var questionTemplate = $('.textSurveyTemplate').html();
    $('.test').append(questionTemplate).find('input#question-name').attr('value', question.name);  
}

But this will replace in each iteration all the generated elements, so we must add an identifier to each element in order to replace its proper value.

for (var i=0 ; i<questions.length ; i++) { 
    question = questions[i];
    var questionTemplate = '<div id="'+i+'" class="text-question">' + $('.textSurveyTemplate').html() + '</div>';
    $('.test').append(questionTemplate);  
    $('#'+i).find('input#question-name').attr('value', question.name);  
}

Upvotes: 1

AshHimself
AshHimself

Reputation: 4112

I ran into a similar problem a few weeks back and ended up using the following plugin. Its extremely lightweight (6kbs) and simply works.

https://code.google.com/p/jquery-load-json/

Upvotes: 0

Related Questions