commerce – Ajax callback doesn’t work

I’m working on a payment gateway, so I’ve created a BasePaymentOffsiteForm form where I’m trying to make an ajax callback, but it is not working.
Can you help me to know what is wrong with my code?

    $form = parent::buildConfigurationForm($form, $form_state);

    $form('content') = (
      '#type' => 'container',
      '#prefix' => '<div id="validate-phone-number">',
      '#suffix' => '</div>',
    );

    $form('content')('mobile_phone') = (
      '#type'   => 'textfield',
      '#title'  => $this->t('Mobile phone'),
    );

    $form('content')('validate_client') = (
      '#type' => 'button',
      '#value' => $this->t('Validate Client'),
      '#ajax' => (
        '#callback' => (get_class($this), 'clientValidateForm'),
        'event' => 'click',
        'wrapper' => 'validate-phone-number',
      ),
    );

    $form('content')('cancel') = (
      '#type' => 'link',
      '#title' => $this->t('Cancel'),
      '#url' => Url::fromUri($form('#cancel_url')),
    );


    return $form;
  }

  public static function clientValidateForm(array $form, FormStateInterface $form_state) {
    $form('submit') = (
      '#type' => 'submit',
      '#value' => 'Pay',
    );
    return $form('submit');
  }

It never gets in cientValidateForm method.

Ajax callback values not found with upload managed_file field

I have a custom module in drupal 8 that has a few sections that utilize Ajax updates. I also have a “managed_file” field (Form API).
The ajax works fine and updates two dependent fields, but the managed_file loses the form_state after I hit the Upload button.
If I only select the drop-down ajax field, then the $form_state(‘values’) is updated and retains the values for the fields that exist in the form. However, if I select a file to upload and click on the “Upload” button that is generated by the managed_file element, the $form_state(‘values’) seems to get reset and the only thing that is present there is the ID of the file that got uploaded. Anything else that was in the $form_state(‘values’) prior to the upload is lost and the drop-down dependency is broken.

I noticed this is very common issue in drupal 8. So please help in this regard.

public function buildForm(array $form, FormStateInterface $form_state) {



    $instrument_family_options = static::getFirstDropdownOptions();

    if (empty($form_state->getValue('instrument_family_dropdown'))) {
      // Use a default value.
      $selected_family = key($instrument_family_options);
    }
    else {
      // Get the value if it already exists.
      $selected_family = $form_state->getValue('instrument_family_dropdown');
    }

    $form('instrument_family_fieldset') = (
      '#type' => 'fieldset',
      '#title' => $this->t('Choose an instrument family'),
    );
    $form('instrument_family_fieldset')('instrument_family_dropdown') = (
      '#type' => 'select',
      '#title' => $this->t('Instrument Type'),
      '#options' => $instrument_family_options,
      '#default_value' => $selected_family,
      '#ajax' => (
        'callback' => '::instrumentDropdownCallback',
        'wrapper' => 'instrument-fieldset-container',
      ),
    );
    $form('instrument_family_fieldset')('choose_family') = (
      '#type' => 'submit',
      '#value' => $this->t('Choose'),
      '#attributes' => ('class' => ('ajax-hide', 'ajax-example-inline')),
    );

    $form('instrument_fieldset_container') = (
      '#type' => 'container',
      '#attributes' => ('id' => 'instrument-fieldset-container'),
    );
    // Build the instrument field set.
    $form('instrument_fieldset_container')('instrument_fieldset') = (
      '#type' => 'fieldset',
      '#title' => $this->t('Choose an instrument'),
    );
    $form('instrument_fieldset_container')('instrument_fieldset')('instrument_dropdown') = (
      '#type' => 'select',
      '#title' => $instrument_family_options($selected_family) . ' ' . $this->t('Instruments'),
      '#options' => static::getSecondDropdownOptions($selected_family),
      '#default_value' => !empty($form_state->getValue('instrument_dropdown')) ? $form_state->getValue('instrument_dropdown') : '',
    );



     $form('mainslider_slide_one')('image_dir') = (
        '#type'                 => 'managed_file',
        '#upload_location'      => 'public://module-images/home-slider-images/',
        '#multiple'             => FALSE,
        '#description'          => t('Allowed extensions: mp4 avi'),
        '#upload_validators'    => (
          'file_validate_extensions'    => array('mp4 avi'),
          'file_validate_size'          => array(25600000)
        ),
        '#title'                => t('Upload an image file for this slide')
    );

    $form('actions')('submit') = (
          '#type' => 'submit',
          '#value' => $this->t('Submit'),
        );

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $trigger = (string) $form_state->getTriggeringElement()('#value');
    switch ($trigger) {
      case 'Submit':
        // Submit: We're done.
        $this->messenger()->addMessage($this->t('Your values have been submitted. Instrument family: @family, Instrument: @instrument', (
          '@family' => $form_state->getValue('instrument_family_dropdown'),
          '@instrument' => $form_state->getValue('instrument_dropdown'),
        )));
        return;
    }

    $form_state->setRebuild();
  }


  public function instrumentDropdownCallback(array $form, FormStateInterface $form_state) {
    return $form('instrument_fieldset_container');
  }

Ajax callback values not found on submit in drupal 8

I have a custom form. “instrument_dropdown” fields populate via ajax after selection of “instrument_family_dropdown” select field. It works fine if i does not add upload field. When i add upload file field into form, then “instrument_dropdown” fields does not submit data on form submission. “instrument_dropdown” remain always empty. Kindly help.

<?php

namespace Drupaldrupalup_simple_formForm;

use DrupalCoreFormFormBase;
use DrupalCoreFormFormStateInterface;
use DrupalCoreLink;

/**
 * Re-populate a dropdown based on form state.
 */
class DependentDropdown extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'drupalup_simple_form_dependent_dropdown';
  }

  /**
   * {@inheritdoc}
   *
   * The $nojs parameter is specified as a path parameter on the route.
   *
   * @see drupalup_simple_form.routing.yml
   */
  public function buildForm(array $form, FormStateInterface $form_state) {



    $instrument_family_options = static::getFirstDropdownOptions();

    if (empty($form_state->getValue('instrument_family_dropdown'))) {
      // Use a default value.
      $selected_family = key($instrument_family_options);
    }
    else {
      // Get the value if it already exists.
      $selected_family = $form_state->getValue('instrument_family_dropdown');
    }

    $form('instrument_family_fieldset') = (
      '#type' => 'fieldset',
      '#title' => $this->t('Choose an instrument family'),
    );
    $form('instrument_family_fieldset')('instrument_family_dropdown') = (
      '#type' => 'select',
      '#title' => $this->t('Instrument Type'),
      '#options' => $instrument_family_options,
      '#default_value' => $selected_family,

      '#ajax' => (

        'callback' => '::instrumentDropdownCallback',
        'wrapper' => 'instrument-fieldset-container',
      ),
    );
    // Since we don't know if the user has js or not, we always need to output
    // this element, then hide it with with css if javascript is enabled.
    $form('instrument_family_fieldset')('choose_family') = (
      '#type' => 'submit',
      '#value' => $this->t('Choose'),
      '#attributes' => ('class' => ('ajax-hide', 'ajax-example-inline')),
    );

    $form('instrument_fieldset_container') = (
      '#type' => 'container',
      '#attributes' => ('id' => 'instrument-fieldset-container'),
    );
    // Build the instrument field set.
    $form('instrument_fieldset_container')('instrument_fieldset') = (
      '#type' => 'fieldset',
      '#title' => $this->t('Choose an instrument'),
    );
    $form('instrument_fieldset_container')('instrument_fieldset')('instrument_dropdown') = (
      '#type' => 'select',
      '#title' => $instrument_family_options($selected_family) . ' ' . $this->t('Instruments'),

      '#options' => static::getSecondDropdownOptions($selected_family),
      '#default_value' => !empty($form_state->getValue('instrument_dropdown')) ? $form_state->getValue('instrument_dropdown') : '',
    );

    $format = 'd-m-Y';

        $form('startDate') = array(
           '#type' => 'date', // types 'date_text' and 'date_timezone' are also supported. See .inc file.
           '#title' => t('Start Date'),
           '#default_value' => NULL,
           '#date_format' => $format,
           '#date_year_range' => '-3:+3', // Optional, used to set the year range (back 3 years and forward 3 years is the default).
        );

         $form('mainslider_slide_one')('image_dir') = (
            '#type'                 => 'managed_file',
            '#upload_location'      => 'public://module-images/home-slider-images/',
            '#multiple'             => FALSE,
            '#description'          => t('Allowed extensions: mp4 avi'),
            '#upload_validators'    => (
              'file_validate_extensions'    => array('mp4 avi'),
              'file_validate_size'          => array(25600000)
            ),
            '#title'                => t('Upload an image file for this slide')
        );

    $form('actions')('submit') = (
          '#type' => 'submit',
          '#value' => $this->t('Submit'),
        );

    if ($selected_family == 'none') {
      $form('instrument_fieldset_container')('instrument_fieldset')('instrument_dropdown')('#title') =
        $this->t('You must choose an instrument family.');
      $form('instrument_fieldset_container')('instrument_fieldset')('instrument_dropdown')('#disabled') = TRUE;
      $form('instrument_fieldset_container')('instrument_fieldset')('submit')('#disabled') = TRUE;
    }
    else {
      $form('instrument_fieldset_container')('instrument_fieldset')('instrument_dropdown')('#disabled') = FALSE;
      $form('instrument_fieldset_container')('instrument_fieldset')('submit')('#disabled') = FALSE;
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $trigger = (string) $form_state->getTriggeringElement()('#value');
    switch ($trigger) {
      case 'Submit':
        // Submit: We're done.
        $this->messenger()->addMessage($this->t('Your values have been submitted. Instrument family: @family, Instrument: @instrument', (
          '@family' => $form_state->getValue('instrument_family_dropdown'),
          '@instrument' => $form_state->getValue('instrument_dropdown'),
        )));
        return;
    }
    // 'Choose' or anything else will cause rebuild of the form and present
    // it again.
    $form_state->setRebuild();
  }


  public function instrumentDropdownCallback(array $form, FormStateInterface $form_state) {
    return $form('instrument_fieldset_container');
  }


  public static function getFirstDropdownOptions() {
    return (
      'none' => 'none',
      'String' => 'String',
      'Woodwind' => 'Woodwind',
      'Brass' => 'Brass',
      'Percussion' => 'Percussion',
    );
  }


  public static function getSecondDropdownOptions($key = '') {
    switch ($key) {
      case 'String':
        $options = (
          'Violin' => 'Violin',
          'Viola' => 'Viola',
          'Cello' => 'Cello',
          'Double Bass' => 'Double Bass',
        );
        break;

      case 'Woodwind':
        $options = (
          'Flute' => 'Flute',
          'Clarinet' => 'Clarinet',
          'Oboe' => 'Oboe',
          'Bassoon' => 'Bassoon',
        );
        break;

      case 'Brass':
        $options = (
          'Trumpet' => 'Trumpet',
          'Trombone' => 'Trombone',
          'French Horn' => 'French Horn',
          'Euphonium' => 'Euphonium',
        );
        break;

      case 'Percussion':
        $options = (
          'Bass Drum' => 'Bass Drum',
          'Timpani' => 'Timpani',
          'Snare Drum' => 'Snare Drum',
          'Tambourine' => 'Tambourine',
        );
        break;

      default:
        $options = ('none' => 'none');
        break;
    }
    return $options;
  }

}

javascript – Como tornar uma função callback

Estou com dificuldade de entender o uso de uma callback, mas nesse caso sei que é necessário para complementar a ação do click.

Essa função está passando parâmetros do click de uma modal:

await props.saveOrUpdateConverter(converter, props.type);

Para essa função aqui, que deveria ser uma callback e retornar seus dois parâmetros:

const handleSaveUpdateConverter = async(converter, type) =>{
      return await props.saveOrUpdateConverter(converter, type)
    }

Como eu faria essa mudança ?

Object Oriented Design of Callback Methods

Assume that there is a library and it provides an interface to its users in order to callback them. Users implement this interface and receive notifications from the library.

Let’s say, ICallback is the interface, and Notify1(arg1), …, Notify5(arg5) are the interface methods.

interface ICallback;
+ Notify1(arg1)
+ ...
+ Notify5(arg5)

This library also provides a concrete class of the ICallback and distributes this class with the library package.

class CallbackAdapter : implements ICallback
+ Notify1(arg1)
+ ...
+ Notify5(arg5)

The owner of the library calls this concrete class as “adapter”. Users are encouraged to use this class instead of interface because it is claimed that;

a. You may not want to implement all notify methods 1 to 5 because you want to keep your code clean. If you extend this adapter class instead of implementing interface directly, then you can select methods to override. (This is the main motivation written in the class document)

b. If the interface is changed, say Notify6() is added, then user don’t have to change anything in the client code. No compilation error occurs when version is bumped. (This is an extra motivation suggested by people who extends adapter class)

Note that, some overridden methods of CallbackAdapter class aren’t just empty methods, they contain code, and do some work with objects provided by library (args).

This design really disturbs me. Firstly, I will explain why I’m not comfortable with it and then I will suggest a solution to above motivations. Finally, the question will be asked at the end.

1. Favor object composition over class inheritance

When user code extends CallbackAdapter, there will be coupling between user code and an external class.
This can break the user code easily since encapsulation is terribly broken by inheriting an external class.
Anyone can have a look at Effective Java 1st Edition, Item 14 for more details.

2. Ambiguous adapter pattern

I think the adapter pattern is misused here unless this isn’t another pattern with an “adapter” postfix in the name.

As far as I know, the adapter pattern is used when there is an external alternative implementation that we want to use but our interface doesn’t match to use alternative solution directly. Hence, we write an adapter to gain capabilities of alternative implementation (adaptee).

For all the adapter examples that I’ve seen, there is an adaptation to a concrete class, a class which does a real job and have a capability. However, for the given example, the adaptation is against an interface but not a concrete class.

Is this a valid adapter as we know it? I don’t think so.

There is a statement at applicability section of adapter pattern in the book of GoF Design Patterns:

Use the Adapter pattern when you want to use an existing class, and its interface does not match the one you need.

I think developers misinterpreted the word “interface” in this statement. Author mentions of adaptee’s interface which eventually declares the methods of concrete adaptee class. It seems that developers thought like this: There will be a class that a user created, this class will implement the interface provided by us (as library developers), user will want to use this existing class now and then, one day we will change interface, and won’t match with user code, so that we must provide an adapter, and distribute this adapter with our library.

I have just tried to understand the motivation of this adapter design. Above reasoning may be wrong but this doesn’t make code safer, it’s still insecure because of 1.

3. Distribution of adapter class

If there will be an adapter class, it shouldn’t be in the library package, it should be in the user package, this makes more sense to me because user adapts his code to work with new implementations.

4. It’s not good to break contract silently

Interfaces define behavior and are used to make contracts among participants. If a contract ends and a new contract starts, I think both sides must be aware of this change. Breaking a contract silently as given in the above example, may produce undefined behavior that we can’t notice at compile time but encounter on run time.

Solutions to Motivations

a. Just override methods and keep them empty if you don’t want to do anything with them.

If user can work without new method, Notify6(), this smells like a large interface problem. A segregation may be considered.

If you insist to have such a feature, you can design a callback register mechanism. Users can register any method they want. May register any of them, all of them or none of them. Keep function objects in the library, and callback registered functions. This seems a better OOP design compared to using inheritance.

b. Just avoid silent contract breaks. If an interface changes, it’s more secure to see compilation errors and solve them one by one at compile time.

Discussed design is currently in use in a widely used open source project. I’ve explained thoughts in my mind about it. All of them seems sensible to me.

I don’t think discussed motivations are huge gain. I can’t understand why does someone take the risks given at 1 and 4. Help me to understand advantages of such design. What am I missing here?

Form Alter Ajax callback add paragraph item

Possible to add a paragraph row/item based on another field Ajax callback in form Alter.

I attempted copying an existing item from the widget array and appending it back into the array.

It does render and show up on the front end but does not save

SharePoint break callback result as a drag block

I have a rest API call in sharepoint and everything works as expected, however the output returns per call in an array array if there are more than 100 records (attachments)
Idle API call output

I'm not sure how to handle it, it means the result may be less than 100 or more than 100. I need some advice here.

authentication – Securing callback API

While working on securing API of my microservice, I have come across a problem.
OAuth2.0 is used for securing all the API ( calls originated from other servers or web portals).

We are using some 3rd party services where the flow is asynchronous. We make a request and provide a callback API. The service makes a call to callback API with relevant data.

Since this is a callback, there is no way to enforce OAuth flow. How can we secure these types of API? We have enforced strict rate-limiting for now. Is there any other way possible?

Edit:
I may not have been clear above. What I want is a way to secure my Callback API which I have provided to the 3rd party service to respond once processing is complete.

Once the API is leaked, anyone other than the 3rd party can hit the API and corrupt the system. I want to prevent that

javascript – array.push () inside mysql.query callback (nodejs)

Hello
I'm having a problem adding a custom error to an error array, validating a form with nodejs.
I have tried to change the focus, but I have not found a solution,

    //PARTE 1
    let errors = ()
    db.query('SELECT * FROM Users WHERE email = ?', (emailregister), (err, result) => {
         if (result.length > 0) {
           errors.push ({ err_email_msg: 'Email já cadastrado' })
         }
    })

    //PARTE 2
    if (errors.length == 0) {
       db.query('INSERT INTO Users (`name`, `email`, `password`, `celnumber`, `genre`, `birthdate`) VALUES (?, ?, ?, ?, ?, ?)',
      (name, emailregister, registerpwd, celnumber, genreOption, datanascimento), (err, rows, fields) => {
        if (err)
          res.send(err)
        else
          res.send('Register OK!')
      })
  } else {
    res.render('register', {
      errors,
      primeironome,
      sobrenome,
      emailregister,
      registerpwd,
      confirmpwd,
      celnumber,
      genreOption,
      datanascimento,
      title: 'Registre-se'
    })
  }

Turns out you're entering the if from part 2, with errors.length == 0 being TRUE, even going through errors.push from part 1.

With a console.log () right after errors.push inside the if part of 1, the error array prints correctly, but if you put console.log after db.query in part 1, an empty array
Why does this error.push () in part 1 not work correctly?

8 – Save the response of an item's Ajax callback in a custom FieldWidget plugin

I have created a field widget for text fields in a content type. If a URL is entered into the text field, an ajax event callback is triggered on change and the URL is parsed to get the Open Graph tags if they exist in the field.

The ajax callback also converts the image link from the OG tag to an image tag and adds it to the field container. However, I cannot save the value of the scanned image. I would like to save it as the parsed image value.

I'm thinking of adding a hidden text field that would save the value of the parsed field by allowing the ajax callback to add the new image tag to that field. Or better perhaps save this image value in another field in content type like text area.

What other solutions are recommended for this problem?