it-swarm-eu.dev

Formulář Ajax, který mění hodnotu tlačítka

Když uživatel stiskne prvek tlačítka označený ajaxem, chtěl bych, aby zpětné volání změnilo hodnotu tlačítka (text zobrazený na tlačítku) a nechal jej aktualizovat jak v prohlížeči, tak ve stavu formuláře. Aktualizace v prohlížeči je snadná vrácením hovoru ajax_command_replace. Ale nemám štěstí s aktualizací formuláře, abych si pamatoval aktualizovanou hodnotu tlačítka při příštím stisknutí tlačítka.

Zdá se, že způsob, jakým je formulář Ajax vytvořen, je počáteční hodnota tlačítka pevně zakódována, kde je definována funkce zpětného volání na stránce javascript, což pravděpodobně vysvětluje, proč se prvek tlačítka vrácený zpětnému volání ajaxu neshoduje s hodnotou, kterou zobrazuje v prohlížeči (poté, co jsem to změnil pomocí Ajax_command_replace).

Ale mohu s tím žít, pokud dokážu získat formulář (nebo form_state), aby si skutečně pamatoval novou hodnotu prvku tlačítka z předchozího vyvolání zpětného volání.

Také jsem se pokusil upravit hodnoty form/form_state ve formuláři ověření háku, ale bez úspěchu.

Takže i přesto, že už to víme, nefunguje, následující kód se pokouší ilustrovat, co se snažím udělat:

function testajax_callback($form, &$form_state) {
  $form['mybtn']['#value'] = 'New value';
  return array(
    '#type' => 'ajax',
    '#commands' => array(
      ajax_command_replace('#mybtnwrapper' => drupal_render($form['mybtn']))
  );
}

Jakákoli pomoc ohledně toho, jak to provést způsobem Drupal 7) by byla oceněna.

aktualizace 1:

Mám náznak na fórech Drupal) Následující kód je pravděpodobně více podle Drupal 7 designu a stylu:


function betapp_testajax_callback($form, &$form_state) {
  $form['mybtn']['#value'] = 'New value';
  return $form['mybtn'];
}

function betapp_testajax_form($form, &$form_state) {
  $form['mybtn'] = array(
    '#type' => 'button',
    '#id' => 'mybtn',
    '#prefix' => '',
    '#suffix' => '',
    '#default_value' => 'Default value',
    '#ajax' => array(
      'callback' => 'betapp_testajax_callback',
      'wrapper' => 'testajaxwrapper',
      'method' => 'replace',
      'effect' => 'fade'
    )
  );
  return $form;
}

Kód se podaří změnit na vzhled tlačítka (hodnota tlačítka), ale když stisknete tlačítko s aktualizovanou hodnotou, stará je stále ta, která byla odeslána, takže ve skutečnosti se žádné hodnoty ve formuláři nezměnily, pouze vzhled tlačítka.

Může mít něco společného s pevně zakódovanými hodnotami v definicích zpětného volání na stránce html (která se načte pouze jednou). Najdu záznamy jako jsou tyto:


{"callback":"betapp_testajax_callback","wrapper":"testajaxwrapper","method":"replaceWith","effect":"fade","event":"mousedown","keypress":true,"url":"\/d7\/system\/ajax","submit":{"_triggering_element_name":"op","_triggering_element_value":"Default value"}}

Pokud se použije _triggering_element_value bez ohledu na skutečnou hodnotu prvku, vysvětluje to, proč nová hodnota není vyzvednuta. Možná by měla být _triggering_element_value vyhledána za běhu, když se aktivuje zpětné volání?

Nějaké nápady na řešení/opravy?

4
Marius Kjeldahl

Krátké řešení mé původní otázky lze kódovat takto:


function betapp_testajax_callback($form, &$form_state) {
  return $form['mybtn'];
}

function betapp_testajax_form($form, &$form_state) {
  dd('');
  dd('betapp_testajax_form');
  $form['mybtn'] = array(
    '#type' => 'button',
    '#id' => 'mybtn',
    '#default_value' => 'Ignored default value',
    '#prefix' => '',
    '#suffix' => '',
    '#ajax' => array(
      'callback' => 'betapp_testajax_callback',
      'wrapper' => 'testajaxwrapper',
      'method' => 'replace',
      'effect' => 'fade'
    )
  );
  $prevval = '(blank)';
  if (isset($form_state['values']['mybtn'])) {
    $prevval = $form_state['values']['mybtn'];
    dd('prevval : ' . $prevval);
  }

  $form['mybtn']['#value'] = 'Newval ' . Rand(0, 100);

  dd('newval  : ' . $form['mybtn']['#value']);
  return $form;
}

které vedou k výstupu jako:


betapp_testajax_form
newval  : Newval 48

betapp_testajax_form
prevval : Newval 48
newval  : Newval 62

betapp_testajax_form
prevval : Newval 62
newval  : Newval 0

betapp_testajax_form
prevval : Newval 0
newval  : Newval 59

Moje použití vyžaduje trochu víc; při každé změně tlačítka existují i ​​další prvky, které by měly být rovněž aktualizovány. Ale myslím, že se mi to podařilo pohromadě (vypadá teď prozatím správně) a v duchu sdílení se mi tu podařilo přilepit:


function betapp_testajax_callback2($form, &$form_state) {
  return array(
    '#type' => 'ajax',
    '#commands' => array(
      ajax_command_replace('#mybtn', drupal_render($form['mybtn'])),
      ajax_command_replace('#inp', drupal_render($form['inp']))
    )
  );
}

function betapp_testajax_form2($form, &$form_state) {
  dd('');
  dd('betapp_testajax_form');
  $form['mybtn'] = array(
    '#type' => 'button',
    '#id' => 'mybtn',
    '#default_value' => 'Ignored default value',
    '#prefix' => '',
    '#suffix' => '',
    '#ajax' => array(
      'callback' => 'betapp_testajax_callback',
      'wrapper' => 'testajaxwrapper',
      'method' => 'replace',
      'effect' => 'fade'
    )
  );
  $prevval = '(blank)';
  if (isset($form_state['values']['mybtn'])) {
    $prevval = $form_state['values']['mybtn'];
    dd('prevval : ' . $prevval);
  }

  $form['mybtn']['#value'] = 'Newval ' . Rand(0, 100);

  $form['inp'] = array(
    '#type' => 'textfield',
    '#value' => $prevval,
    '#id' => 'inp'
  );
  dd('newval  : ' . $form['mybtn']['#value']);
  return $form;
}

Tento kód aktualizuje původní tlačítko a nastaví vstupní pole na předchozí hodnotu tlačítka. Můj případ vyžaduje úpravu dalších tlačítek, ale doufejme, že to bude fungovat. Pokud tomu tak není, budu vás na toto vlákno znovu bugovat.

Děkuju.

0
Marius Kjeldahl

A pro další doplnění informací je zde ještě něco víc:

Speciální péče s tlačítky Zaslal kjeldahl dne 18. května 2011 v 18:02

Pokud máte formuláře s mnoha tlačítky a používáte iax, jak jsem viděl výše, ujistěte se, že jste také nastavili názvy tlačítek na jedinečné hodnoty (nastavím důl na stejnou hodnotu jako vlastnost id), nebo Drupal bude mít potíže s rozpoznáním, na které tlačítko ve skutečnosti kliklo, když změníte hodnoty tlačítek. Ve výchozím nastavení Drupal pojmenovává všechna tlačítka „op“ ..

Další gotcha souvisí s $ form_state ['triggering_element'] Zveřejnil kjeldahl dne 18. května 2011 v 20:47 hodin

V mé aplikaci (jednoduchá hra) mám řadu tlačítek, která spouští zpětné volání Ajaxu do mého Drupal modulu. ID a jméno tlačítka se liší od hodnoty, protože hodnota Tlačítko se používá k zobrazení některých lidských čitelných informací uživateli. Podobně jako u kódu, který jsem zde zobrazil, vytvořím-li řadu tlačítek, kde jeho stisknutí přepíná hodnotu (např. přepínáním předpony hodnoty tlačítka hvězdičkou nebo podobné), funguje to dobře, pokud stále stisknu jedno tlačítko. Jakmile však stisknu jiné tlačítko, Drupal ztratí přehled o tom, co bylo stisknuto, a spustí nějakou další výchozí akci, která nastaví triggering_element na první tlačítko definované ve výchozím nastavení. Jen jsem se krátce podíval na form.inc a související kód a zdá se, že chování prvního tlačítka je „záměrně“.

Co však možná není záměrné, je skutečnost, že Drupal není schopen sledovat triggering_element v případu použití, který jsem popsal níže. Dumping stavu $ form_value mě však vedl k pokusu o použití něco, čemu věřím, je místo toho „soukromá“ hodnota stavu, jmenovitě $ form_state ['input'] ['_ triggering_element_name'], které, na rozdíl od $ form_state ['triggering_element'], se vždy zdá být naplněno správnou hodnotou v mé aplikaci ajax .

Věřím, že se jedná o chybu, ale právě teď nemám čas sledovat přesné podrobnosti. Uvnitř form.inc je kód, který se podle všeho chová odlišně v závislosti na tom, zda se ID tlačítka rovná jeho názvu nebo hodnotě, ale netuším, jaký je návrhový cíl tohoto chování. Ale bez použití _triggering_element_name to vypadá Drupal nefunguje dobře pro moje prvky Ajax'y tlačítka.

0
Marius Kjeldahl

Ještě jedna věc. Pokud máte formuláře s mnoha tlačítky a používáte iax, jak jsem viděl výše, ujistěte se, že jste také nastavili názvy tlačítek na jedinečné hodnoty (nastavím důl na stejnou hodnotu jako vlastnost id), nebo Drupal bude mít potíže s rozpoznáním, na které tlačítko bylo ve skutečnosti kliknuto, když změníte hodnoty tlačítek. Ve výchozím nastavení Drupal pojmenuje všechna tlačítka "op", která, jak se zdá, způsobuje nějaké potíže, pokud se pokusíte upravit hodnoty více tlačítek při stisknutí jednoho z nich.

0
Marius Kjeldahl