From 29957aa9cb4254d0154d3c91b368615e832c5152 Mon Sep 17 00:00:00 2001 From: Tyler Frankenstein Date: Thu, 12 Sep 2013 00:45:36 -0500 Subject: [PATCH] #178. Added theme_submit(). Added _drupalgap_form_state_values_assemble_get_element_value() using code extracted from drupalgap_form_state_values_assemble(). Changed drupalgap_form_state_values_assemble() to properly iterate over field delta values. Changed _drupalgap_form_render_element() to again run the element item(s) through the theme system after preprocessing the item based on its type. Changed drupalgap_entity_build_from_form_state() to properly iterate over field delta items. Temporarily commented out image_form_alter(). Changed drupalgap_node_assemble_data() to properly iterate over field item delta(s). --- includes/form.inc.js | 368 +++++++++++++++++++-------------------- includes/theme.inc.js | 10 ++ modules/entity/entity.js | 13 +- modules/field/field.js | 5 - modules/image/image.js | 4 +- modules/services/node.js | 35 ++-- 6 files changed, 225 insertions(+), 210 deletions(-) diff --git a/includes/form.inc.js b/includes/form.inc.js index 56e42008..3971d932 100644 --- a/includes/form.inc.js +++ b/includes/form.inc.js @@ -110,53 +110,29 @@ function drupalgap_form_set_error(name, message) { */ function drupalgap_form_state_values_assemble(form) { try { - if (drupalgap.settings.debug) { - console.log('drupalgap_form_state_values_assemble()'); - console.log(JSON.stringify(arguments)); - } var form_state = {'values':{}}; $.each(form.elements, function(name, element) { if (name == 'submit') { return; } // Always skip the form 'submit'. - // Set delta if it is a field, also determine the css selector for the - // form element. - var delta = null; var id = null; if (element.is_field) { - delta = 0; - id = drupalgap_form_get_element_id(name, form.id, drupalgap.settings.language, delta); - } - else { - id = drupalgap_form_get_element_id(name, form.id); - } - var selector = ''; - if (element.type == 'radios') { - selector = 'input:radio[name="' + id + '"]:checked'; - } - else { selector = '#' + id; } - // Determine the value of the form element. - var value = null; - if (element.type == 'checkbox') { - if ($(selector).is(':checked')) { value = 1; } - else { value = 0; } - } - if (value == null) { value = $(selector).val(); } - // Set the form state value. - if (element.is_field) { - // TODO - is this the structure that Drupal follows? form_state.values[name] = {}; form_state.values[name][drupalgap.settings.language] = {}; - form_state.values[name][drupalgap.settings.language][delta] = value; + var allowed_values = element.field_info_field.cardinality; + if (allowed_values == -1) { + allowed_values = 1; // Convert unlimited value field to one for now... + } + for (var delta = 0; delta < allowed_values; delta++) { + id = drupalgap_form_get_element_id(name, form.id, drupalgap.settings.language, delta); + form_state.values[name][drupalgap.settings.language][delta] = _drupalgap_form_state_values_assemble_get_element_value(id, element); + } } else { - form_state.values[name] = value; + id = drupalgap_form_get_element_id(name, form.id); + form_state.values[name] = _drupalgap_form_state_values_assemble_get_element_value(id, element); } }); // Attach the form state to drupalgap.form_states keyed by the form id. drupalgap.form_states[form.id] = form_state; - if (drupalgap.settings.debug) { - console.log(JSON.stringify(form_state)); - } - dpm(form); dpm(form_state); return form_state; } @@ -165,6 +141,28 @@ function drupalgap_form_state_values_assemble(form) { } } +/** + * + */ +function _drupalgap_form_state_values_assemble_get_element_value(id, element) { + try { + var value = null; + var selector = ''; + if (element.type == 'radios') { + selector = 'input:radio[name="' + id + '"]:checked'; + } + else { selector = '#' + id; } + if (element.type == 'checkbox') { + if ($(selector).is(':checked')) { value = 1; } + else { value = 0; } + } + if (value == null) { value = $(selector).val(); } + if (typeof value === 'undefined') { value = null; } + return value; + } + catch (error) { drupalgap_error(error); } +} + /** * Given a form id, this will render the form and return the html for the form. * Any additional arguments will be sent along to the form. @@ -409,8 +407,8 @@ function _drupalgap_form_render_element(form, element) { } // What module handles this element? var module = element.field_info_instance.widget.module; - dpm(module); - dpm(cardinality); + //dpm(module); + //dpm(cardinality); // Determine the hook_field_widget_form() function for this field. var field_widget_form_function = module + '_field_widget_form'; if (drupalgap_function_exists(field_widget_form_function)) { @@ -450,12 +448,11 @@ function _drupalgap_form_render_element(form, element) { // Open the element. if (element.type != 'hidden') { html += '
'; } - dpm(name); - $.each(items, function(index, item){ - dpm(item); + //dpm(item); variables.attributes.id = item.id; + variables.element = item; // Add a label to the element, except submit and hidden elements. if (index == 0 && element.type != 'submit' && element.type != 'hidden') { @@ -481,9 +478,148 @@ function _drupalgap_form_render_element(form, element) { // function. var theme_function = item.type; - // If the element isn't an outlier, run it through the theme system. - if (item.type != 'submit' && item.type != 'image') { - // Theme the element. + // Make any preprocess modifications to the elements so they will map + // cleanly to their theme function. + // The following element types apply cleanly to their corresponding theme + // functions: + // email + // hidden + // password + // radios + // select + // textfield + // textarea + // The following element types need their theme function adjusted: + // textarea + // text_long + // text_with_summary + // text_textarea + // The following element types need their variables adjusted: + // checkbox + // radios + // select + // textarea + // text_long + // text_with_summary + // text_textarea + // The following element types are not yet supported: + // taxonomy_term_reference + // ... + // The following fields are outliers and need to be converted to use a theme + // function. + // image + // submit + switch (item.type) { + case 'checkbox': + // If the checkbox has a default value of 1, check the box. + if (item.default_value == 1) { variables.checked = true; } + break; + case 'image': + // Set the default button text, and if a value was provided, + // overwrite the button text. + var button_text = 'Add Image'; + if (item.value) { + button_text = item.value; + } + // Place a hidden input to hold the file id. + html += ''; + // Place variables into document for PhoneGap image processing. + var item_id_base = item.id.replace(/-/g, '_'); + var image_field_source = item_id_base + '_imagefield_source'; + var imagefield_destination_type = item_id_base + '_imagefield_destination_type'; + var imagefield_data = item_id_base + '_imagefield_data'; + eval('var ' + image_field_source + ' = null;'); + eval('var ' + imagefield_destination_type + ' = null;'); + eval('var ' + imagefield_data + ' = null;'); + // Build an imagefield widget with PhoneGap. Contains a message + // div, an image item, and button to add an image. + //'' + html += '
' + + '
' + + '' + + '' + button_text + '' + + '
'; + // Open extra javascript declaration. + html += ''; + break; + case "radios": + // Add options and value to variables and remove the value attribute. + variables.options = item.options; + variables.value = item.default_value; + delete variables.attributes.value; + break; + case "select": + // Add options and value to variables and remove the value attribute. + variables.options = item.options; + variables.value = item.default_value; + delete variables.attributes.value; + // Required? + if (item.required) { + variables.options[-1] = 'Select'; + variables.value = -1; + } + break; + case "submit": + variables.attributes.onclick = '_drupalgap_form_submit(\'' + form.id + '\');'; + if (!variables.attributes['data-theme']) { + variables.attributes['data-theme'] = 'b'; + } + break; + case "text": + theme_function = 'textfield'; + break; + case 'textarea': + case 'text_long': + case "text_with_summary": + case 'text_textarea': + theme_function = 'textarea'; + // Add value to variables and remove the value attribute. + variables.value = item.default_value; + delete variables.attributes.value; + break; + } + + + // If the item isn't an outlier, run it through the theme system. + //if (item.type != 'submit' && item.type != 'image') { + // Theme the item. if (drupalgap_function_exists('theme_' + theme_function)) { html += theme(theme_function, variables); } @@ -497,12 +633,12 @@ function _drupalgap_form_render_element(form, element) { console.log('WARNING: _drupalgap_form_render_element() - ' + msg); } } - } + //} }); - // Added element description. + // Add element description. if (element.description && element.type != 'hidden') { html += '
' + element.description + '
'; } @@ -512,153 +648,9 @@ function _drupalgap_form_render_element(form, element) { html += '
 
'; } - console.log(html); // Return the element html. return html; - - - // The following element types apply cleanly to their corresponding theme - // functions: - // email - // hidden - // password - // radios - // select - // textfield - // textarea - // The following element types need their theme function adjusted: - // textarea - // text_long - // text_with_summary - // text_textarea - // The following element types need their variables adjusted: - // checkbox - // radios - // select - // textarea - // text_long - // text_with_summary - // text_textarea - // The following element types are not yet supported: - // taxonomy_term_reference - // ... - // The following fields are outliers and need to be converted to use a theme - // function. - // image - // submit - switch (element.type) { - case 'checkbox': - // If the checkbox has a default value of 1, check the box. - if (element.default_value == 1) { variables.checked = true; } - break; - case 'image': - // Set the default button text, and if a value was provided, - // overwrite the button text. - var button_text = 'Add Image'; - if (element.value) { - button_text = element.value; - } - // Place a hidden input to hold the file id. - html += ''; - // Place variables into document for PhoneGap image processing. - var element_id_base = element.id.replace(/-/g, '_'); - var image_field_source = element_id_base + '_imagefield_source'; - var imagefield_destination_type = element_id_base + '_imagefield_destination_type'; - var imagefield_data = element_id_base + '_imagefield_data'; - eval('var ' + image_field_source + ' = null;'); - eval('var ' + imagefield_destination_type + ' = null;'); - eval('var ' + imagefield_data + ' = null;'); - // Build an imagefield widget with PhoneGap. Contains a message - // div, an image element, and button to add an image. - //'' - html += '
' + - '
' + - '' + - '' + button_text + '' + - '
'; - // Open extra javascript declaration. - html += ''; - break; - case "radios": - // Add options and value to variables and remove the value attribute. - variables.options = element.options; - variables.value = element.default_value; - delete variables.attributes.value; - break; - case "select": - // Add options and value to variables and remove the value attribute. - variables.options = element.options; - variables.value = element.default_value; - delete variables.attributes.value; - // Required? - if (element.required) { - variables.options[-1] = 'Select'; - variables.value = -1; - } - break; - case "submit": - var submit_attributes = { - 'type':'button', - 'data-theme':'b', - 'id':element.id, - 'onclick':'_drupalgap_form_submit(\'' + form.id + '\');' - }; - html += ''; - break; - case "text": - theme_function = 'textfield'; - break; - case 'textarea': - case 'text_long': - case "text_with_summary": - case 'text_textarea': - theme_function = 'textarea'; - // Add value to variables and remove the value attribute. - variables.value = element.default_value; - delete variables.attributes.value; - break; - default: - break; - } - // Give modules a chance to alter the variables. //module_invoke_all('form_element_alter', form, element, variables); diff --git a/includes/theme.inc.js b/includes/theme.inc.js index f9a08d2e..3fd0b7ba 100644 --- a/includes/theme.inc.js +++ b/includes/theme.inc.js @@ -260,6 +260,16 @@ function theme_link(variables) { } } +/** + * Implementation of theme_submit(). + */ +function theme_submit(variables) { + try { + return ''; + } + catch (error) { drupalgap_error(error); } +} + /** * Implementation of template_preprocess_page(). */ diff --git a/modules/entity/entity.js b/modules/entity/entity.js index ed1fd1bd..bb1beefa 100644 --- a/modules/entity/entity.js +++ b/modules/entity/entity.js @@ -150,13 +150,22 @@ function drupalgap_entity_build_from_form_state(form, form_state) { // Attach the key and value to the entity. var key = drupalgap_field_key(name); // e.g. value, fid, tid, nid, etc. if (key) { - var delta = 0; - eval('entity.' + name + ' = {' + language + ':[{' + key + ':"' + value[language][delta] + '"}]}'); + var allowed_values = form.elements[name].field_info_field.cardinality; + if (allowed_values == -1) { + allowed_values = 1; // convert unlimited value fields to one, for now... + } + entity[name] = {}; + entity[name][language] = []; + for (var delta = 0; delta < allowed_values; delta++) { + eval('entity[name][language].push({' + key + ':"' + value[language][delta] + '"});'); + //eval('entity.' + name + ' = {' + language + ':[{' + key + ':"' + value[language][delta] + '"}]}'); + } } else { entity[name] = value; } }); + dpm(entity); return entity; } catch (error) { drupalgap_error(error); } diff --git a/modules/field/field.js b/modules/field/field.js index f66bd958..3a94a2ea 100644 --- a/modules/field/field.js +++ b/modules/field/field.js @@ -188,10 +188,6 @@ function text_field_formatter_view(entity_type, entity, field, instance, langcod */ function text_field_widget_form(form, form_state, field, instance, langcode, items, delta, element) { try { - dpm('text_field_widget_form'); - //dpm(form); - dpm(form.elements[element.name][langcode][delta]); - //dpm(arguments); // Determine the widget type, then set the delta item's type property. var type = null; switch (element.type) { @@ -208,7 +204,6 @@ function text_field_widget_form(form, form_state, field, instance, langcode, ite //delete variables.attributes.value; } form.elements[element.name][langcode][delta].type = type; - dpm(form.elements[element.name][langcode][delta]); } catch (error) { drupalgap_error(error); } } diff --git a/modules/image/image.js b/modules/image/image.js index 0dbf3ef9..da283b4b 100644 --- a/modules/image/image.js +++ b/modules/image/image.js @@ -49,7 +49,7 @@ function image_fields_present_on_entity_type(entity_type, bundle) { /** * Implements hook_form_alter(). */ -function image_form_alter(form, form_state, form_id) { +/*function image_form_alter(form, form_state, form_id) { // Make potential alterations to any entity edit form that has an image field // element(s). if (form.entity_type) { @@ -70,7 +70,7 @@ function image_form_alter(form, form_state, form_id) { } } } -} +}*/ /** * The success callback function used when handling PhoneGap's camera diff --git a/modules/services/node.js b/modules/services/node.js index 879e3f30..65134bf8 100644 --- a/modules/services/node.js +++ b/modules/services/node.js @@ -132,21 +132,30 @@ function drupalgap_node_assemble_data(options) { $.each(fields, function(field_name, field){ var key = drupalgap_field_key(field_name); if (key) { - // Skip fields without values. - if (typeof options.node[field_name][lng][0][key] === 'undefined' || - !options.node[field_name][lng][0][key] || - options.node[field_name][lng][0][key] == '') { return; } - // Encode the value. - var value = encodeURIComponent(options.node[field_name][lng][0][key]); - // Add the key and value to the data string. Note, select does not work - // with [und][0][value] but works with [und][value] - if (field.widget.type == 'options_select') { - data += '&node[' + field_name + '][' + lng + '][' + key + ']='; + // Iterate over each delta value in the field cardinality. + var field_info_field = drupalgap_field_info_field(field_name); + var allowed_values = field_info_field.cardinality; + if (allowed_values == -1) { + allowed_values = 1; // convert unlimited value fields to one, for now... } - else { - data += '&node[' + field_name + '][' + lng + '][0][' + key + ']='; + for (var delta = 0; delta < allowed_values; delta++) { + // Skip fields without values. + if (typeof options.node[field_name][lng][delta][key] === 'undefined' || + !options.node[field_name][lng][delta][key] || + options.node[field_name][lng][delta][key] == '') { continue; } + // Encode the value. + var value = encodeURIComponent(options.node[field_name][lng][delta][key]); + if (!value) { continue; } + // Add the key and value to the data string. Note, select does not work + // with [und][0][value] but works with [und][value] + if (field.widget.type == 'options_select') { + data += '&node[' + field_name + '][' + lng + '][' + key + ']='; + } + else { + data += '&node[' + field_name + '][' + lng + '][' + delta + '][' + key + ']='; + } + data += value; } - data += value; } });