JoakimB
JoakimB

Reputation: 1206

data-table problems editing each row

I am building a domain-management tool and I select a domain and then I ng-repeat all domain records in a table. For each row I also add an "Edit" and "Delete" button.

All rows are connected to an ng-switch. When I press edit on a row it changes into <input> fields allowing me to edit single rows.

The form tag exists around the table, and the input fields inside the td's.

Now to the problems ( making a list ).

Issue 1: Since I loop out this datatable I set the ng-model to the same on all rows, field-wise, so the content field for example will have ng-model="record.conent" on each row. When I edit 2 or more rows at the same time, my field patterns affect all opened rows and is set to the one I opened first. Ng-pattern is set by a function that returns a regex depending on what record type I choose. See the image bellow:

enter image description here

Issue 2: If I press edit and start editing a field and I leave the field in a failed state where my ng-pattern isn't getting a match and then press cancel to ng-switch back to text only, the whole ng-model gets wiped clean. How can I preserve the initial value in the loop? The model seems to be updating everywhere on the site. Look at pictures down bellow:

enter image description here Then I cancel... enter image description here And record content is wiped out

End question is.. am I doing this right at all? I have the feeling that I have built myself into a corner.

Template code down bellow:

<form novalidate name="recordForm" class="css-form">

    <table class="table table-striped table-bordered table-white table-responsive swipe-horizontal" style="border: 1px #dbdbdb solid;" edit-record>

        <!-- Table heading -->
        <thead >
            <tr class="domains-tr-heading">
                <th>Sub</th>
                <th>Domain</th>
                <th>Type</th>
                <th>Address</th>
                <th>TTL</th>
                <th>Priority</th>
                <th></th>
            </tr>
        </thead>
        <!-- // Table heading END -->

        <!-- Table body -->
        <tbody>

            <tr ng-repeat="record in domain.data" class="gradeA" ng-controller="ChildEditRecordCtrl">

                <td ng-init="startingNameData = record.name" ng-switch on="record.edit" class="domains-td" style="width: 10%;">
                    <span ng-switch-default>{{record.name}}</span>
                    <span ng-switch-when="true">
                        <input type="hidden" ng-model="record.id" name="id" class="span12" style="margin: 0px;" required/>
                        <input type="text" ng-model="record.name" required style="margin: 0px;" class="span12 edit-record-input">
                    </span>
                </td>
    
                <td class="domains-td" style="width: 20%;">
                    {{ updateDomainForm.name }}
                </td>

                <td ng-init="startingTypeData = record.type" class="domains-td" ng-switch on="record.edit" style="width: 10%;">
                    <span ng-switch-default>{{record.type}}</span>
                    <span ng-switch-when="true">
                        <select style="margin: 0px;" ng-model="record.type" ng-options="c for c in domainRecordTypes" class="span12">

                        </select>
                    </span>
                </td>

                <td ng-init="startingContentData = record.content" class="domains-td validation-dropdown-error-parent" ng-switch on="record.edit" style="width: 25%;">
                    <span ng-switch-default>{{record.content}}</span>
                    <span ng-switch-when="true">
                        <span class="validation-dropdown-error" ng-show="recordForm.content.$error.pattern">
                            Invalid {{ addRecordForm.type }} record
                        </span>
                        <input type="text" ng-model="record.content" name="content" required style="margin: 0px;" class="span12 edit-record-input" ng-pattern="/^([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])$/" required />
                    </span>
                </td>

                <td ng-init="startingTTLData = record.ttl" class="domains-td" ng-switch on="record.edit" style="width: 10%;">
                    <span ng-switch-default>{{record.ttl}}</span>
                    <span ng-switch-when="true">
                        <input type="number" ng-model="record.ttl" required style="margin: 0px;" class="span12 edit-record-input" />
                    </span>
                </td>

                <td ng-init="startingPrioData = record.prio" class="domains-td" ng-switch on="record.edit" style="width: 10%;">
                    <span ng-switch-default>{{record.prio}}</span>
                    <span ng-switch-when="true">
                        <select style="margin: 0px;" ng-model="record.prio" ng-options="c for c in domainRecordPriorities" class="span12 edit-record-input">
                        </select>
                    </span>
                </td>

                <td class="domains-td" ng-switch on="record.edit" style="width: 14%">

                    <button ng-switch-when="true" ng-if="hideRecordType(record.type)" ng-click="editRecord(record, domainId); record.edit=false" type="submit" class="btn btn-block btn-primary btn-icon" style="width: 55px; float: left; margin-right: 5px; margin-top: 5px;"><i></i>Save</button>
                    <button ng-switch-when="true" ng-if="hideRecordType(record.type)" ng-click="record.edit=false; record.name = startingNameData; record.type = startingTypeData; record.content=startingContentData; record.ttl = startingTTLData; startingPrioData = record.prio" class="btn btn-block btn-primary btn-icon" style="width: 55px; float: left; margin-top: 5px;"><i></i>Cancel</button>

                    <button ng-switch-when="1" ng-if="hideRecordType(record.type)" ng-click="deleteRecord(record.id, domainId); record.edit=false;" class="btn btn-block btn-danger btn-icon" style="width: 55px; float: left; margin-right: 5px; margin-top: 5px;"><i></i>Delete</button>
                    <button ng-switch-when="1" ng-if="hideRecordType(record.type)" ng-click="record.edit=false" class="btn btn-block btn-primary btn-icon" style="width: 55px; float: left; margin-top: 5px;"><i></i>Cancel</button>

                    <button ng-switch-default ng-if="hideRecordType(record.type)" ng-click="record.edit=true;" class="btn btn-block btn-primary btn-icon" style="width: 55px; float: left; margin-right: 5px; margin-top: 5px;"><i></i>Edit</button>
                    <button ng-switch-default ng-if="hideRecordType(record.type)" ng-click="record.edit=1;" class="btn btn-block btn-danger btn-icon" style="width: 55px; float: left; margin: 0 auto; margin-top: 5px;"><i></i>Delete</button>

                    <span style="clear:both;"></span>
                </td>
            </tr>

        </tbody>
        <!-- // Table body END -->

    </table>

</form>

Upvotes: 1

Views: 1041

Answers (4)

JoakimB
JoakimB

Reputation: 1206

Ok so the solution to the first problem is using ng-form to validate a field that were dynamicly created.

<ng-form name="innercContentForm">
    <span class="validation-dropdown-error" ng-show="innercContentForm.content.$error.pattern">
        Invalid {{ addRecordForm.type }} record
    </span>
    <input type="text" ng-model="record.content" name="content" required style="margin: 0px;" class="span12 edit-record-input" ng-pattern="/^([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])$/" required />
</ng-form>

Upvotes: 0

alanmoo
alanmoo

Reputation: 1125

For the second problem, you could set the starting value of the record as an ng-init attribute of the <td>. Then when the cancel function gets called, just set the value of the field back to the initialized value.

For example,

<td class="domains-td" ng-switch on="record.edit" style="width: 10%;" ng-init="initialValue=record.prio">

And then inside the cancel method set record.prio = initialValue.

You might want to do some testing to make sure that if you save it then edit it again and cancel it reverts to the proper value though, as I believe ng-init only saves a value at bootstrap.

Upvotes: 1

Noogen
Noogen

Reputation: 1652

record is in a different scope each time it's repeat so it's not really the same value. The different value on the UI proves this point. Your problem for #1 is not because you have the same record, it's related to HTML5 validation and because you have the same input name. Try rendering unique name like: name="content-{{record.id}}"

Upvotes: 1

m.e.conroy
m.e.conroy

Reputation: 3538

I think you identified your problem for Issue 1, in that the ng-model is the same for all rows so when you edit one the display is affected for all. I think you need to find a way to affect the information in domain.data rather than the record.

Upvotes: 0

Related Questions