/** * JS that handles our fields in the admin. * Uses backbone data models to send only modified field data to the db. */ // Model to hold our field settings. var nfField = Backbone.Model.extend( { toggleMetabox: function() { /** * Open and close a field metabox. * When a metabox is closed: * - update the field collection with any values that might have changed. * - remove the HTML * When a metabox is opened: * - send an ajax request to grab the HTML * - populate the field settings HTML */ var field_id = this.id; // Get our current metabox state. var current_metabox_state = this.get( 'metabox_state' ); if ( current_metabox_state == 1 ) { // If our current state is 1, then we are closing the metabox. var new_metabox_state = 0; } else { // If our current state is 0, then we are opening the metabox. var new_metabox_state = 1; } // Perform specific tasks based upon the state of the metabox. if ( new_metabox_state == 1 ) { // If we have opened the metabox. // Fetch our HTML. this.updateHTML(); } else { // If we have closed the metabox. // Update our model data. this.updateData(); // Remove any tinyMCE editors jQuery( '#ninja_forms_field_' + field_id + '_inside' ).find( 'div.rte' ).each( function() { if ( 'undefined' != typeof tinymce ) { try { var editor_id = jQuery( this ).find( 'textarea.wp-editor-area' ).prop( 'id' ); tinymce.remove( '#' + editor_id ); } catch (e ) { } } } ); jQuery( '#ninja_forms_field_' + field_id + '_inside' ).slideUp('fast', function( e ) { // Remove the HTML contents of this metabox. jQuery( '#ninja_forms_field_' + field_id + '_inside' ).empty(); // Add our no-padding class jQuery( '#ninja_forms_field_' + field_id + '_inside' ).addClass( 'no-padding' ); }); } // Save the state of the metabox in our data model. this.set( 'metabox_state', new_metabox_state ); }, updateHTML: function() { var field_id = this.id; jQuery( '#ninja_forms_metabox_field_' + field_id ).find( '.spinner' ).show(); jQuery( '#ninja_forms_metabox_field_' + field_id ).find( '.spinner' ).css( 'visibility', 'visible' ); this.updateData(); var data = JSON.stringify( this.toJSON() ); var that = this; jQuery.post( ajaxurl, { field_id: field_id, data: data, action:'nf_output_field_settings_html', nf_ajax_nonce:ninja_forms_settings.nf_ajax_nonce }, function( response ) { jQuery( '#ninja_forms_metabox_field_' + field_id ).find( '.spinner' ).hide(); // Remove our no-padding class. jQuery( '#ninja_forms_field_' + field_id + '_inside' ).removeClass( 'no-padding' ); jQuery( '#ninja_forms_field_' + field_id + '_inside' ).append( response ); if ( typeof nf_ajax_rte_editors !== 'undefined' && 'undefined' !== typeof tinyMCE ) { for (var x = nf_ajax_rte_editors.length - 1; x >= 0; x--) { try { var editor_id = nf_ajax_rte_editors[x]; tinyMCE.init( tinyMCEPreInit.mceInit[ editor_id ] ); try { quicktags( tinyMCEPreInit.qtInit[ editor_id ] ); } catch(e){ console.log( 'error' ); } } catch (e) { } }; } that.removeEmptySettings(); jQuery( '#ninja_forms_field_' + field_id + '_inside' ).slideDown( 'fast' ); // Re-run makeSortable for new HTML nfFields.listOptionsSortable(); jQuery( '.nf-field-settings .title' ).disableSelection(); } ); }, updateData: function() { var field_id = this.id; if ( 'undefined' != typeof tinyMCE ) { try { tinyMCE.triggerSave(); } catch (e) { } } var data = jQuery('[name^=ninja_forms_field_' + field_id + ']'); var field_data = jQuery(data).serializeFullArray(); if ( typeof field_data['ninja_forms_field_' + field_id] != 'undefined' ) { var field = field_data['ninja_forms_field_' + field_id]; for( var prop in field ) { if ( field.hasOwnProperty( prop ) ) { nfFields.get( field_id ).set( prop, field[ prop ] ); } } } nfForm.set( 'saved', false ); }, remove: function() { var field_id = this.id; var answer = confirm( nf_admin.remove_field ); if ( answer ) { var form_id = ninja_forms_settings.form_id jQuery.post(ajaxurl, { form_id: form_id, field_id: field_id, action: 'ninja_forms_remove_field', nf_ajax_nonce:ninja_forms_settings.nf_ajax_nonce }, function( response ) { jQuery( '#ninja_forms_field_' + field_id).remove(); jQuery( document ).trigger( 'removeField', [ field_id ] ); }); } }, removeEmptySettings: function() { var field_id = this.id; jQuery( '#ninja_forms_field_' + field_id + '_inside' ).find( '.nf-field-settings .inside' ).each( function() { var html = jQuery.trim( jQuery( this ).html() ); if ( html == '' ) { jQuery( this ).parent().remove(); } } ); } } ); // Collection to hold our fields. var nfFields = Backbone.Collection.extend({ model: nfField, setup: function() { // Loop through our field JSON that is already on the page and populate our collection with it. if( 'undefined' !== typeof nf_admin.fields ) { _.each( nf_admin.fields, function( field ) { nfFields.add( { id: field.id, metabox_state: field.metabox_state } ); } ); } }, updateData: function() { // Loop through our fields collection and update any field lis that are open _.each( this.models, function( field ) { if ( field.get( 'metabox_state' ) == 1 ) { field.updateData(); } } ); }, newField: function( button ) { var limit = jQuery( button ).data( 'limit' ); var type = jQuery( button ).data( 'type' ); var form_id = ninja_forms_settings.form_id if ( limit != '' ){ var current_count = jQuery( '.' + type + '-li' ).length; }else{ var current_count = ''; } if ( typeof jQuery( button ).data( 'field' ) == 'undefined' ) { var field_id = ''; var action = 'ninja_forms_new_field'; } else if ( jQuery( button ).data( 'type' ) == 'fav' ) { var field_id = jQuery( button ).data( 'field' ); var action = 'ninja_forms_insert_fav'; } else { var field_id = jQuery( button ).data( 'field' ); var action = 'ninja_forms_insert_def'; } if ( ( limit != '' && current_count < limit ) || limit == '' || current_count == '' || current_count == 0 ) { jQuery.post( ajaxurl, { type: type, field_id: field_id, form_id: form_id, action: action, nf_ajax_nonce:ninja_forms_settings.nf_ajax_nonce }, this.newFieldResponse ); } else { jQuery( button ).addClass( 'disabled' ); } nfForm.set( 'saved', false ); }, newFieldResponse: function( response ) { // Fire our custom jQuery addField event. jQuery( document ).trigger('addField', [ response ]); }, addFieldDefault: function( response ) { jQuery( '#ninja_forms_field_list' ).append( response.new_html ).show( 'slow' ); if ( response.new_type == 'List' ) { this.listOptionsSortable(); } if ( typeof nf_ajax_rte_editors !== 'undefined' && 'undefined' !== typeof tinyMCE ) { for (var x = nf_ajax_rte_editors.length - 1; x >= 0; x--) { try { var editor_id = nf_ajax_rte_editors[x]; tinyMCE.init( tinyMCEPreInit.mceInit[ editor_id ] ); try { quicktags( tinyMCEPreInit.qtInit[ editor_id ] ); } catch(e){} } catch (e) { } }; } // Add our field to our backbone data model. this.add( { id: response.new_id, metabox_state: 1 } ); nfFields.get( response.new_id ).removeEmptySettings(); }, listOptionsSortable: function ( response ) { //Make List Options sortable jQuery(".ninja-forms-field-list-options").sortable({ helper: 'clone', handle: '.ninja-forms-drag', items: 'div', placeholder: 'ui-state-highlight', update: function( event, ui ) { var order = jQuery( this ).sortable( 'toArray' ); var x = 0; _.each( order, function( id ) { var field_id = jQuery( '#' + id ).data( 'field' ); var label_name = 'ninja_forms_field_' + field_id + '[list][options][' + x + '][label]'; var value_name = 'ninja_forms_field_' + field_id + '[list][options][' + x + '][value]'; var calc_name = 'ninja_forms_field_' + field_id + '[list][options][' + x + '][calc]'; var selected_name = 'ninja_forms_field_' + field_id + '[list][options][' + x + '][selected]'; jQuery( '#' + id ).find( '.ninja-forms-field-list-option-label' ).attr( 'name', label_name ); jQuery( '#' + id ).find( '.ninja-forms-field-list-option-value' ).attr( 'name', value_name ); jQuery( '#' + id ).find( '.ninja-forms-field-list-option-calc' ).attr( 'name', calc_name ); jQuery( '#' + id ).find( '.ninja-forms-field-list-option-selected' ).attr( 'name', selected_name ); x++; } ); } }); } }); var nfForm = Backbone.Model.extend( { defaults: { 'id' : ninja_forms_settings.form_id, 'status' : nf_admin.form_status, 'title' : nf_admin.form_title, 'saved' : true }, setup: function() { this.changeMenu(); }, changeMenu: function() { if ( 'new' == this.get( 'status' ) ) { // If we're working with a new form, highlight the "Add New" menu item. jQuery( '.wp-submenu li' ).removeClass( 'current' ); jQuery( 'a[href="admin.php?page=ninja-forms&tab=builder&form_id=new"]' ).parent().addClass( 'current' ); } else { var html = '