0

First I will like to say that probably some of the code will be a little complicated and probably had to be reviewed, so I filling shamed in advanced :-<

Anyway enough with my apologies here is my code, I also added jsfiddle so you can view live example.

jsfiddle

In case you wish to download the code:

https://github.com/printmypic/js-form-generator

The problem I have is with edit once I edit and afterwards I click on new form, it takes the form values of the previews edit form.

I am not understand why the values of userForm are being set instead of the local var of formGenerator.form?

Thank you in advance.

HTML:

    <button class="btn btn-success" id="newUser">New User</button>
    <table id="data" class="table table-striped table-hover table-bordered dt-responsive nowrap dataTable no-footer" cellspacing="0" width="100%" role="grid" aria-describedby="data_info" style="width: 100%;">
            <thead>
                        <tr role="row"><th class="sorting_asc" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-sort="ascending" aria-label="id: activate to sort column descending" style="width: 50px;">id</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="user: activate to sort column ascending" style="width: 122px;">user</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="password: activate to sort column ascending" style="width: 214px;">password</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="email: activate to sort column ascending" style="width: 201px;">email</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="phone: activate to sort column ascending" style="width: 42px;">phone</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="full name: activate to sort column ascending" style="width: 92px;">full name</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="country: activate to sort column ascending" style="width: 51px;">country</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="pids: activate to sort column ascending" style="width: 221px;">pids</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="type: activate to sort column ascending" style="width: 29px;">type</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="bid: activate to sort column ascending" style="width: 21px;">bid</th></tr></thead>
                    <tbody>
                    <tr role="row" class="odd"><td class="sorting_1"><div class="btn-group">
            <button class="btn dropdown-toggle" data-toggle="dropdown">Action <span class="caret"></span></button>
            <ul class="dropdown-menu">
            <li class=""><a class="action editUser" data-id="1">Edit</a></li><li class=""><a class="action deleteUser" data-id="">Delete</a></li></ul></div></td><td>tal</td><td>222a3962a50d89a</td><td>someuser@gmail.com</td><td>34214324</td><td>frw</td><td>dsad</td><td>dsad</td><td>Admin</td><td></td></tr></tbody>
        </table>
<div id="myModal" class="modal fade">
<div class="modal-dialog">
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            <h4 class="modal-title" id="modaltitle">Modal title</h4>
        </div>
        <div class="modal-body clearfix" id="modalbody">
        </div>
        <div class="modal-footer">
            <button id="modalcancel" type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            <button id="modalsave" type="button" class="btn btn-primary">Save changes</button>
        </div>
    </div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->

JS

function showModal(modalContent,callback) {
    for (i in modalContent) {
        if (i === 'modalcancel' || i === 'modalsave') {
            $('#' + i).attr('onclick', modalContent[i]);
            if (modalContent[i] === '') {
                $('#' + i).text('close').hide();
            } else {
                $('#' + i).text('save').show();
            }
        } else if ($.isFunction(modalContent[i])) {
            $('#' + i).html(modalContent[i]());
        } else {
            $('#' + i).html(modalContent[i]);
        }
    }
    $('#myModal').modal();
    if($.isFunction(callback)){
        callback();
    }
}

var formGenerator = {
    tableSelector: '#data',
    tableHeaders: '#data th',
    formId: 'newUserForm',
    form: {},
    skipVars: ['id'],
    init: function (config, callback) {
        if (config.formId) {
            this.formId = config.formId;
        }

        if (config.tableHeaders) {
            this.tableHeaders = config.tableHeaders;
        }

        if (config.editElement) {
            this.form = this.setValuesByTableRow(config.editElement, config.form);
        } else {
            this.form = config.form;
        }

        if($('#'+this.formId).size()){
            $('#'+this.formId).remove();
        }

        var $form = $('<form id="'+this.formId+'" autocomplete="off" class="form-horizontal"></form>');
        var that = this;

        $(this.tableHeaders).each(function () {
            var name = $(this).text().toLowerCase().replace(/ /g, '_');
            if ($.inArray(name, that.skipVars) !== -1 || typeof (that.form[name]) === 'undefined') {
                return;
            }
            $formElement = that.createFormElement(that.form[name].name, that.form[name].type, that.form[name].value);
            $formElement.appendTo($form);
        });

        if(callback && $.isFunction(callback)){
            setTimeout(function () {
                callback()
            }, '200');
        }
        return this.htmlForm = $form[0].outerHTML;

    },
    createFormElement: function (name, type, value) {
        var $inputContainer = $('<div class="form-group col-md-6"></div>');
        var $container = $('<div class="form-group col-md-12"></div>');
        switch (type) {
            case 'password':
            case 'text':
            case 'email':
            case 'hidden':
            case 'number':
            value = value ? value : '';
            $element = $('<input autocomplete="off" type="' + type + '" class="form-control" id="' + name + '" placeholder="' + name.replace(/_/g, ' ') + '" name="' + name + '" value="' + value + '" />');
            break;
            case 'select':
            var options = this.getOptions(this.form[name].selectData,value);
            $element = $('<select class="form-control" id="' + name + '" placeholder="' + name + '" name="' + name + '">' + options + '</select>');
            break;
        }
        $inputContainer.append($element);
        $labelContainer = $('<div class="form-group col-md-6"><label for="' + name + '">' + name.replace(/_/g, ' ') + '</label></div>');
        $container.append($labelContainer);
        return $container.append($inputContainer);
    },
    getColByThTr: function (thText, $element, tableSelector) {
        var landingIndex = $(tableSelector + ' th:contains(' + thText + ')').index() + 1;
        return $element.closest('tr').find('td:nth-child(' + landingIndex + ')');
    },
    setValuesByTableRow: function ($element, form) {
        var editForm = form;
        for (i in editForm) {
            var th = i.replace(/_/g, ' ');
            if (editForm[i].type === 'select') {
                editForm[i].selectData.selected = this.getColByThTr(th, $element, this.tableSelector).text();
            } else if (editForm[i].type === 'password') {
                editForm[i].value = '';
            } else {
                editForm[i].value = this.getColByThTr(th, $element, this.tableSelector).text().trim();
            }
        }
        return editForm;
    },
    formatSelectArr: function (arr, nasted, selectedItem) {
        var formattedSelectArr = [];
        if (!selectedItem) {
            formattedSelectArr.push({'title': 'Select', 'selected': true, 'value': ''});
        }
        var value, title = '';
        for (i in arr) {
            title = arr[i];
            if (nasted) {
                value = i;
            } else {
                value = arr[i];
            }
            if (selectedItem === arr[i]) {
                selected = true;
            } else {
                selected = false;
            }
            formattedSelectArr.push({'title': title, 'selected': selected, 'value': value});
        }
        return formattedSelectArr;
    },
    getOptions: function (arr) {
        var data = this.formatSelectArr(arr.data, arr.nasted, arr.selected);
        var html = '';
        for (i in data) {
            selected = (data[i].selected) ? 'selected' : '';
            html += '<option value="' + data[i].value + '" ' + selected + '>' + data[i].title + '</option>';
        }
        return html;
    }

};



var userTypes = {"1":"Admin","2":"API"};
var bids = ["bid1","bid2"];
var countriesArr = ["Afghanistan","Albania","Algeria","American Samoa","Andorra","Angola","Anguilla","Antarctica","Antigua and Barbuda","Argentina","Armenia","Aruba","Australia","Austria","Azerbaijan","Bahamas","Bahrain","Bangladesh","Barbados","Belarus","Belgium","Belize","Benin","Bermuda","Bhutan","Bolivia","Bosnia and Herzegovina","Botswana","Bouvet Island","Brazil","British Indian Ocean Territory","Brunei Darussalam","Bulgaria","Burkina Faso","Burundi","Cambodia","Cameroon","Canada","Cape Verde","Cayman Islands","Central African Republic","Chad","Chile","China","Christmas Island","Cocos (Keeling) Islands","Colombia","Comoros","Congo","Congo, the Democratic Republic of the","Cook Islands","Costa Rica","Cote DIvoire","Croatia","Cuba","Cyprus","Czech Republic","Denmark","Djibouti","Dominica","Dominican Republic","Ecuador","Egypt","El Salvador","Equatorial Guinea","Eritrea","Estonia","Ethiopia","Falkland Islands (Malvinas)","Faroe Islands","Fiji","Finland","France","French Guiana","French Polynesia","French Southern Territories","Gabon","Gambia","Georgia","Germany","Ghana","Gibraltar","Greece","Greenland","Grenada","Guadeloupe","Guam","Guatemala","Guinea","Guinea-Bissau","Guyana","Haiti","Heard Island and Mcdonald Islands","Holy See (Vatican City State)","Honduras","Hong Kong","Hungary","Iceland","India","Indonesia","Iran, Islamic Republic of","Iraq","Ireland","Israel","Italy","Jamaica","Japan","Jordan","Kazakhstan","Kenya","Kiribati","Korea, Democratic Peoples Republic of","Korea, Republic of","Kuwait","Kyrgyzstan","Lao Peoples Democratic Republic","Latvia","Lebanon","Lesotho","Liberia","Libyan Arab Jamahiriya","Liechtenstein","Lithuania","Luxembourg","Macao","Macedonia, the Former Yugoslav Republic ","Madagascar","Malawi","Malaysia","Maldives","Mali","Malta","Marshall Islands","Martinique","Mauritania","Mauritius","Mayotte","Mexico","Micronesia, Federated States of","Moldova, Republic of","Monaco","Mongolia","Montserrat","Morocco","Mozambique","Myanmar","Namibia","Nauru","Nepal","Netherlands","Netherlands Antilles","New Caledonia","New Zealand","Nicaragua","Niger","Nigeria","Niue","Norfolk Island","Northern Mariana Islands","Norway","Oman","Pakistan","Palau","Palestinian Territory","Panama","Papua New Guinea","Paraguay","Peru","Philippines","Pitcairn","Poland","Portugal","Puerto Rico","Qatar","Reunion","Romania","Russia","Rwanda","Saint Helena","Saint Kitts and Nevis","Saint Lucia","Saint Pierre and Miquelon","Saint Vincent and the Grenadines","Samoa","San Marino","Sao Tome and Principe","Saudi Arabia","Senegal","Serbia","Seychelles","Sierra Leone","Singapore","Slovakia","Slovenia","Solomon Islands","Somalia","South Africa","South Georgia and the South Sandwich Isl","Spain","Sri Lanka","Sudan","Suriname","Svalbard and Jan Mayen","Swaziland","Sweden","Switzerland","Syrian Arab Republic","Taiwan, Province of China","Tajikistan","Tanzania, United Republic of","Thailand","Timor-Leste","Togo","Tokelau","Tonga","Trinidad and Tobago","Tunisia","Turkey","Turkmenistan","Turks and Caicos Islands","Tuvalu","Uganda","Ukraine","United Arab Emirates","United Kingdom","United States","United States Minor Outlying Islands","Uruguay","Uzbekistan","Vanuatu","Venezuela","Viet Nam","Virgin Islands, British","Virgin Islands, U.s.","Wallis and Futuna","Western Sahara","Yemen","Zambia","Zimbabwe","Montenegro"];
var userForm = {
    'full_name': {type: 'text', name: 'full_name',value:''},
    'user': {type: 'text', name: 'user',value:''},
    'password': {type: 'password', name: 'password',value:''},
    'bid': {type: 'select', name: 'bid', selectData: {'data':bids, 'nasted':false, 'selected':''},value:''},
    'pids': {type: 'text', name: 'pids',value:''},
    'phone': {type: 'number', name: 'phone',value:''},
    'type': {type: 'select', name: 'type', selectData: {'data':userTypes, 'nasted':true, 'selected':'Affiliate'},value:''},
    'country': {type: 'select', name: 'country', selectData:  {'data':countriesArr, 'nasted':false, 'selected':'Israel'},value:''},
    'email': {type: 'email', name: 'email',value:''},
};


myForm = formGenerator;


function editUser(element, id) {
    $element = $(element).closest('tr');

    showModal({
        'modalsave': '',
        'modalcancel': '',
        'modaltitle': 'Info',
        'modalbody': '' + myForm.init(
        {
            'tableHeaders': '#data th',
            'form': userForm,
            'editElement':$element
        }
        ) + ''
    });
}

function newUserForm(){
    showModal({
        'modalsave': 'alert(\'save\')',
        'modalcancel': '',
        'modaltitle': 'Info',
        'modalbody': '' + myForm.init(
        {
            'tableHeaders': '#data th',
            'form': userForm,
            'editElement':false
        }
        ) + ''
    });
}

$(function(){
    $('#newUser').on('click',function(){newUserForm();});
    $('.editUser').on('click',function(){editUser(this,$(this).data('id'));});
});
talsibony
  • 8,448
  • 6
  • 47
  • 46
  • Debugging help questions require a [mcve] as per the [help]. Your code is not minimal. Please [edit] your question to make sure that your code is Minimal (only the code necessary to reproduce your issue in your question), Complete (users do not need anything else to reproduce your issue), and Verifiable (the provided code does reproduce the exact issue you are facing). As it is your question is off-topic for Stack Overflow. Note that this is also a common [downvote reason](http://idownvotedyoubecause.com/so/TooMuchCode). – Kyll Jun 07 '16 at 09:40

1 Answers1

1

From this formId: 'newUserForm'

to this this.formId = config.formId;

is passed by reference. So what you have as formId inside formGenerator is in fact a reference of newUserForm. Does that make sense?

Javascript by default passes objects by reference. If you do not want that, you might want to write a clone function or perform a shallow/deep copy. jQuery makes this easy where you can simply do this.

var newUserForm2 = jQuery.extend({}, newUserForm)

This will make changes to newUserForm2 not affect newUserForm.

Please read this thread for more info

Community
  • 1
  • 1
phreakv6
  • 2,135
  • 1
  • 9
  • 11
  • I think it is more related to userForm , look in fiddle line 188 in the js section, I think I have to do there something line new userForm instead of userForm – talsibony Jun 07 '16 at 09:41
  • Thank you for your answer I am still trying to figure this out I will update you in case your suggestion was the solution. – talsibony Jun 07 '16 at 09:58
  • If I defined the userForm within the functions the problem is solved, so your answer is not the solution – talsibony Jun 07 '16 at 12:19
  • the solution I fined and made me understand that I don't know anything about global object is: var formObj = JSON.parse(JSON.stringify(userForm)); – talsibony Jun 07 '16 at 12:30
  • When you do that, you are essentially doing a deep copy of the json. – phreakv6 Jun 07 '16 at 12:33
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/114031/discussion-between-talsibony-and-phreakv6). – talsibony Jun 07 '16 at 12:50
  • Please edit your answer so I will be able to accept it as the solution – talsibony Jun 07 '16 at 12:56
  • Thank you for your help your assumption was correct and you lead me to the answer so I decided to accept your answer – talsibony Jun 07 '16 at 13:04