Is there a way to hook into drupals ajax system? I am using the managed_file module, and creating a managed_file in a module I am making. When doing so, after you upload a file, the id of the file field changes, but the <label> for the field does not. This creates an accessibility issue, as there is no a label with no field associated with it. 

My solution was to hook into the ajax thats ran after the file is uploaded, and change the labels for="" attribute to match the now appended ID. (If the original id was edit-file-upload, after you upload it becomes edit-file-upload--2). I would want to make the label at this point for="edit-file-upload--2" to fix the accessibility issue. 

Comments

VM’s picture

jfurnas’s picture

I saw that, but I think that is more related to handling a file after the system has added it to the database. I need to hook into the ajax callback exclusively so I can change the #id on the page after the upload is complete. 

Jaypan’s picture

You can use hook_form_alter() and replace the ajax callback to use your own. In your own ajax callback, call the original, then make changes to the value of the original callback before returning it.

jfurnas’s picture

Jaypan do you have a quick example of how that's done? Or a guide somewhere that demonstrates that? It seems a little complicated.

Jaypan’s picture

Ok, imagine that you're working with the following submit button on the form:

$form['actions']['submit'] = [
  '#type' => 'submit',
  '#value' => t('Submit'),
  '#ajax' => [
    'callback' => 'some_ajax_callback',
    'wrapper' => 'some_wrapper',
  ],
];

In this case, the default ajax callback is some_ajax_callback(), and that is to be overridden.

function my_module_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'some_form_id') {
    $form['actions']['submit']['#ajax']['callback'] = 'my_module_some_ajax_callback';
  }
}

With the code in hook_form_alter(), the original callback is overwritten, saying to instead use my_module_some_ajax_callback(). The next thing to do is to define that function:

function my_module_some_ajax_callback(&$form, &$form_state) {
  // Call original callback:
  some_ajax_callback($form, $form_state);
  // Do your own stuff here
}

Depending on your needs, you could reverse this and instead call some_ajax_callback() at the end.

One important thing to note is that if you are wanting to make changes to the form here, then you are doing it the wrong way, and as like as not will end up with some error. If changes need to be made to the form, then you should do it in hook_form_alter().

jfurnas’s picture

@Jaypan thanks for the example. You mentioned if you want to make changes to the form, you should do it in hook_form_alter, not in the ajax callback, correct? 

The problem is, I think, that the ajax for managed_file changes the fields name (by appending a --x to it), during the callback. What happens is when you click the 'Upload' button, and it uploads the file, the field refreshes via ajax and its no longer an upload field, and the name of the field has changed. When it doesn't this, it doesn't update the field labels 'for' attribute, which results in an accessibility issue. I was attempting to override the id of the label (or the field) manually in the ajax so that it would remain accessible. 

As far as I know, there isn't a way to change the field labels 'for' attribute in hook_form_alter, is there? using #id appears to change the <label> id, but not the actual 'for' value. (I was expecting it to change the actual <input name=""> value, but it doesn't)

Jaypan’s picture

Sorry, I don't really have the answer to those questions.