Ajax form – jak vykonat JS po úspěšném submit?
- dreken
- Člen | 36
Ahoj,
mám ajax formulář, který se zobrazuje v modálním dialogu. Po úspěšném
potvrzení formuláře bych chtěl tento dialog zavřít javascriptem. Jaké
mám možnosti? Javascriptový onsubmit mi nestačí, protože to ještě
nevím, jestli jsou data ve formu validní.
Předem díky za rady.
Editoval dreken (11. 10. 2014 11:07)
- SvvimX
- Člen | 65
Používám to tak, že mám presenter, který má formulář a metodu pro zpracování, v šabloně je jen ten formulář (bez layoutu).
Ajaxově načítám tendle presenter do modal okna – a odesílám ho ajaxem. Při chybě ve formuláři ti server vrátí 200 OK a normálně HTML ze šablony – kde je formulář s daty a errory – tím nahradíš obsah modal okna.
Při správném odeslání mi server vrátí redirect (protože po úspěšném odeslání presenter přesmeruje), což v JS odchytíš a zavřeš modal okno. Pokud by to nebylo JS, tak se přesměruje, na tu správnou stránku, což je takový bonus.
Další chyby a jejich kódy si v tom presenteru můžeš doimplementovat a reagovat si na ně dle libosti.
- SvvimX
- Člen | 65
Celý příklad asi není ani potřeba, mít presetner a formulář je snad jasné. Javascript, který toto dělá:
$.ajax({
type: "POST",
url: $(this).attr("action"),
data: $(this).serialize(), // serializes the form's elements.
success: function(data)
{
if (data.redirect) {
window.location.href=data.redirect; // presmeruje, zde si muzes zavrit modal okno a nekam napsat, ze je to OK
}
else {
$("#Modal-addItemToIndex").find(".modal-content").html(data); // zmena obsahu modal okna, protoze nedoslo k redirectu, tedy ve formu byly chyby
}
}
});
- SvvimX
- Člen | 65
https://doc.nette.org/cs/forms#… $form->onSuccess[] – jiná metoda pro každý formulář
- steelbull
- Člen | 241
Priklad:
Formular:
class LrProjectFormFactory {
private $context;
private $translator;
/**
* Load database context
*/
function __construct($context, $translator) {
$this->context = $context;
$this->translator = $translator;
}
/**
* Create form
*/
function create($data = NULL) {
// Create new instance
$form = new Form();
$form->method = 'post';
$form->getElementPrototype()->addAttributes(array('id' => 'lrProjectForm'));
$form->addText('pdts_number', $this->translator->translate('lr_projects.form.pdts_number').':')
->setAttribute('class', 'form-control')
->setDefaultValue(($data == NULL) ? NULL : $data->pdts_number)
->setRequired($this->translator->translate('lr_projects.form.please_insert_the_pdts_number'));
$form->addText('title', $this->translator->translate('lr_projects.form.title').':')
->setAttribute('class', 'form-control')
->setDefaultValue(($data == NULL) ? NULL : $data->title)
->setRequired($this->translator->translate('lr_projects.form.please_insert_the_title'));
$form->addText('description', $this->translator->translate('lr_projects.form.description').':')
->setAttribute('class', 'form-control')
->setDefaultValue(($data == NULL) ? NULL : $data->description);
$form->addHidden('id')
->setDefaultValue(($data == NULL) ? NULL : $data->id);
$form->addProtection();
// Validate form
$form->onValidate[] = function($form) {
$projectsModel = new Model\ProjectsModel($this->context);
$data = $form->getValues();
// Check, if project exists
if ($projectsModel->checkUnique($data)) {
$form['pdts_number']->addError($this->translator->translate('lr_projects.form.pdts_number_error_unique'));
}
};
return $form;
}
}
Presenter:
class LrPresenter extends BaseSecuredPresenter {
/**
* Render add view for create and save new labRequest
*/
public function renderAdd() {
//Call function to RenderForm
$form = (new LrFormFactory($this->context, $this->translator))->create();
$typeForm = (new LrTypeFormFactory($this->context, $this->translator))->create();
//Takto riesim defaultny formular, ale neviem com mam robit s
if ($form->isSuccess()) {
$model = new Model\LabRequestsModel($this->context);
$data = $form->getValues();
// Try to save data
try {
$model->saveLabRequest($data);
$this->flashMessage($this->translator->translate('flash.record_was_saved'), 'success');
$this->redirect('Lr:default');
} catch (\PDOException $e) {
$this->flashMessage($this->translator->translate('flash.error_while_saving_record'), 'danger');
$this->redirect('Lr:default');
}
}
// Load WuModel Form
$formWuModel = (new WuModelFormFactory($this->context, $this->translator))->create();
//Send data to form
$this->template->form = $form;
$this->template->typeForm = $typeForm;
}
AJAX:
$(document).ready(function () {
$('button.form-submit').each(function () {
$(this).click(function () {
var target = $(this).attr('form-target');
$('form#' + target).submit(function (event) {
event.preventDefault();
var $this = $(this);
var url = $this.attr('action');
var dataToSend = $this.serialize();
var posting = $.post(url, dataToSend);
posting.done(function (data) {
$('div.data').append(data);
});
});
});
});
});
Skoncil som na tom, ze neviem, kam mam data odoslat a taktiez neviem, ako ich v Nette prijat. Ale mozno ze povies, ze je to cele zle :(
- steelbull
- Člen | 241
SvvimX: takže prerobil som všetko podľa Teba, je to skutočne podstatne lepšie, ale: stále to neviem zajaxovať:
Form:
/**
* Create form
*/
public function create($data = NULL) {
// Create new instance
$form = new UI\Form;
// Form data
$form->method = 'post';
$form->getElementPrototype()->addAttributes(array('id' => 'lrTypeForm'));
$form->getElementPrototype()->addAttributes(array('class' => 'ajax'));
$form->addText('title', $this->translator->translate('lr_types.form.title') . ':')
->setAttribute('class', 'form-control')
->setDefaultValue(($data == NULL) ? NULL : $data->title)
->setRequired($this->translator->translate('lr_types.form.title'));
$form->addText('description', $this->translator->translate('lr_types.form.description') . ':')
->setAttribute('class', 'form-control')
->setDefaultValue(($data == NULL) ? NULL : $data->description);
$form->addHidden('id')
->setDefaultValue(($data == NULL) ? NULL : $data->id);
$form->addSubmit('pokus');
$form->addProtection();
$form->onSuccess[] = array($this->instance, $this->callback);
return $form;
}
Presenter:
/**
* LrTypeForm create
*
* @return type
*/
public function createComponentLrtypeform() {
$form = (new LrTypeFormFactory($this, 'LrTypeFormSuccess', $this->context, $this->translator))->create();
return $form;
}
/**
* LrTypeForm Success
*
* @param Form $form
*/
public function lrTypeFormSuccess(Form $form) {
$model = new Model\LrTypesModel($this->context);
$data = $form->getValues();
try {
$model->saveLrType($data);
$this->flashMessage($this->translator->translate('flash.record_was_saved'), 'success');
} catch (\PDOException $e) {
$this->flashMessage($this->translator->translate('flash.error_while_saving_record'), 'danger');
}
$this->redirect('this');
}
Latte:
<div class="modal fade" id="addTypeModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">{_cp.close}</span></button>
<h4 class="modal-title" id="myModalLabel">{_lr.modals.create_lr_type}</h4>
</div>
<div class="modal-body">
{control lrtypeform}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{_cp.cancel}</button>
<button type="button" class="btn btn-primary form-submit" form-target="lrTypeForm">{_cp.save}</button>
</div>
</div>
</div>
</div>
a do layout.latte som vlozil:
$.ajax({
type: "POST",
url: $(this).attr("action"),
data: $(this).serialize(), // serializes the form's elements.
success: function(data)
{
if (data.redirect) {
window.location.href=data.redirect; // presmeruje, zde si muzes zavrit modal okno a nekam napsat, ze je to OK
}
else {
$("#Modal-addItemToIndex").find(".modal-content").html(data); // zmena obsahu modal okna, protoze nedoslo k redirectu, tedy ve formu byly chyby
}
}
});
Editoval steelbull (5. 11. 2014 20:08)