Widgets in core presently do not make this easy. Please read Live Widget Previews: Widget Management in the Customizer in WordPress 3.9, and in particular the section “No more Update button (usually)”:
Widget forms on the admin page have a familiar Save button. In previous versions of Widget Customizer, we adapted the Save button to be an Update button, since it wouldn’t actually save the widget but would just update the preview with the widget’s latest state. Having to click this Update button to see the preview update, however, was a poor user experience and was unnecessary. Therefore, we implemented a means of submitting the form to update the widget’s state in the preview whenever a field in the control is updated: the Update button was hidden and the spinner appears when a change is being synced to the preview.
The logic which does this live submission of the widget form as you interact with it, depends on the fields in the widget form to be the same fields which get returned when the widget form is sanitized. This is so that the fields can be aligned for being updated with their sanitized values. We couldn’t go the route of the widget forms on the widgets admin page, which actually get fully replaced with the newly-sanitized form, because this would interfere with the user quickly inputting into these fields.
So if a widget form dynamically adds or changes which input fields are included, the live-as-you-type-them updates will stop and the Update button will re-appear. When you click this button, the form will replace itself with the sanitized version just like on the widgets admin page. We also introduced new jQuery events to help handle these form changes…
So what you need to do is carefully make sure that PHP generates the same fields as are generated in JS dynamically to ensure that the inputs align when the update-widget
Ajax request returns with the contents of the WP_Widget::form()
output.
The way widgets are implemented in the customizer are not ideal, however this was done to maximize backwards-compatibility. For a fresh take on widgets to make them JavaScript-driven as opposed to PHP-driven, please see #33507 and also see the JS Widgets feature plugin which entirely avoids the problem you’re facing since JS is used to manage the widget’s form UI entirely.