To implement a dynamic form where users can manage multiple phone numbers, distinguish between existing backend data and new user inputs using a flag within the data structure. This approach alllows conditional rendering in the view layer while maintaining a single source of truth in the JavaScript logic.
Data Structure Design
Define an array where each object represents a phone entry. Include a property to identify whether the entry is existing data or a new adddition. This flag controls the UI presentation, such as showing input fields for new entries versus static text for saved numbers.
// Initial state definition
data: {
phoneEntries: [],
MAX_PHONE_COUNT: 5
}
Initializing Data from API
When fetching customer information, parse the returned string into the structured array. Map each raw phone number to an object with the editable flag set to false.
loadCustomerData: function(response) {
const rawData = response.data.customerInfo.phones;
if (!rawData) return;
const phoneList = rawData.split(',').map((number) => {
return {
numberValue: number.trim(),
isEditable: false
};
});
this.setData({
phoneEntries: phoneList
});
}
Adding New Entries
Triggered by a user action, this function checks the current array length against a limit. If space is available, push a new object with empty values and the editable flag set to true.
onAddPhone: function() {
const currentList = this.data.phoneEntries;
if (currentList.length >= this.data.MAX_PHONE_COUNT) {
wx.showToast({
title: 'Limit reached',
icon: 'none'
});
return;
}
currentList.push({
numberValue: '',
isEditable: true
});
this.setData({
phoneEntries: currentList
});
}
Removing Entries
Implement a deletion handler that confirms the action before modifying the array. Use the index passed from the view to remove the specific element.
onDeletePhone: function(event) {
const index = event.currentTarget.dataset.idx;
wx.showModal({
title: 'Confirm',
content: 'Remove this number?',
success: (res) => {
if (res.confirm) {
const updatedList = this.data.phoneEntries;
updatedList.splice(index, 1);
this.setData({
phoneEntries: updatedList
});
}
}
});
}
View Layer Implementation
Use wx:for to iterate over the array. Conditional blocks (wx:if) render different structures based on the isEditable flag. Existing numbers display as text, while new entries show input fields and toggle options.
<view class="contact-section">
<view wx:for="{{phoneEntries}}" wx:key="index" wx:for-index="index">
<!-- Existing Data Display -->
<view class="entry-row static" wx:if="{{!item.isEditable}}">
<text class="label">Mobile</text>
<text class="value">{{item.numberValue}}</text>
<text wx:if="{{index > 0}}" class="tag">Default</text>
</view>
<!-- New Entry Input -->
<view class="entry-row editable" wx:if="{{item.isEditable}}">
<input
type="number"
value="{{item.numberValue}}"
placeholder="Enter number"
data-index="{{index}}"
bindinput="onInputChanged"
/>
<view class="actions">
<text class="btn-toggle" bindtap="toggleType">Landline</text>
<text class="btn-delete" bindtap="onDeletePhone" data-idx="{{index}}">Delete</text>
</view>
</view>
</view>
<view class="add-btn" bindtap="onAddPhone">
<text>+ Add Phone</text>
</view>
</view>