[c#] validace formu ajaxem

Webdesign, HTML, CSS, Flash, PHP, ASP, .NET, JavaScript. Kritika www stránek na Smetišti.

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod dyžon 18. 2. 2020 13:50

Zdravím,
potřeboval bych prosím poradit.
mám na stránce formulář:
Kód: Vybrat vše
@using (Html.BeginForm("MojeAkce", "MujController", FormMethod.Post, new
        {
            enctype = "multipart/form-data",
            onSubmit = "return updateTextarea(this);",
            data_restUrl = Url.Action("Index", "MujController"),
            id = "formik"
        }))
        {

pred samotným posláním ještě upravuju textareu Popis:
Kód: Vybrat vše
function updateTextarea(form) {
    for (instance in CKEDITOR.instances) {
        CKEDITOR.instances["Popis"].updateElement();
    }
    AjaxPost(form);
}

pomocí Ajaxu posílám data formuláře k validaci:
Kód: Vybrat vše
function AjaxPost(form) {
    $.validator.unobtrusive.parse(form);
    if ($(form).valid()) {
        var ajaxConfig = {
            type: 'POST',
            url: form.action,
            data: new FormData(form),
            success: function (hotovo) {
                if (hotovo.success) {
                    if (hotovo.presmeruj) {
                        window.location.href = hotovo.redirectUrl;
                        $("#modalObsah").modal("hide");
                    }
                }
                else {
                    $("#error").text(hotovo.zprava);
                }
            }
        }
        if ($(form).attr('enctype') == "multipart/form-data") {
            ajaxConfig["contentType"] = false;
            ajaxConfig["processData"] = false;
        }
        $.ajax(ajaxConfig);

    }
    return false;
}

no a v Controleru mám test validace:
Kód: Vybrat vše
if(ModelState.IsValid)
            {
               return Json(new { success = true, redirectUrl = Url.Action("Index", "MujController"),
                                 presmeruj = true },
                             JsonRequestBehavior.AllowGet);
            }
            else
            {
                return Json(new { ssucces = false, zprava = "spatne" },
                             JsonRequestBehavior.AllowGet);
            }

je to samozřejmě ořezany jen na důležity věci.
bohužel, když form neprojde validací, tak místo toho, aby se to vrátilo na form a vypsaly se hlášky například:
Kód: Vybrat vše
<p class="margin-bottom-0 modal-zprava text-danger">@Html.ValidationMessageFor(x => x.Nazev)</p>

tak se objeví bílá obrazovka s:
{"ssucces":false,"message":"spatne"}

nepostřehli jste, kde je co špatně ??
prosím poraďte
AMD FX-6300; Gigabyte 970A-DS3P; DDR3 8192MBytes; AMD Radeon HD 6700 Series
dyžon
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 18. 2. 2020 18:26

Nechybí ti někde definice kdy má být formulář validní? Např. pole email musí mít formát ..., heslo minimálně x znaků apod?

Jinak pokud se vrátí "success" jako "false", tak to "ASI" nechá #modalObsah viditelný a někam do #error vypíše chybovou hlášku. Takže bílá obrazovka tam už musí být předtím.

Taky poslední doplněk - kde máš ošetřeno neodeslání formuláře standardním způsobem ( tj. submit button )?
Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod dyžon 19. 2. 2020 16:09

zapoměl jsem uvést, že jde o MVC
ošetření validity je v jiném souboru, to tady není potřeba.
v akci MojeAkce v controlleru MujController je uveden rozdíl, co se vrací z Ajax dotazu a to buď když je model.IsValid= true , formulář je vyplněn správně, a nebo model.IsValid = false, a to je právě třeba když je email ve špatnym formátu, není vyplněné povinné pole a podobně.
když je model validní, proběhne všechno v pořádku, protože funkce AjaxPost provede reload na Index, MujController.
když ale není validní, místo toho, aby se to vrátilo do otevřenýho modálního okna (jak jsi správně poznal) a vypsaly se hlášky, co je všechno špatně, tak proběhne jakejsi reload na prázdnou stránku s tím textem co jsem uvedl výše.
v url je http://doména.cz/MujController/MojeAkce, bílá stránka a vypsany proměnny s hodnotama, ktery jsem vracel z Controlleru.

myslím, že problém by mohl být v tom, že z formuláře nevolám přímo funkci AjaxPost, ale UpdateTextarea a až z ní AjaxPost.
v případě, že form není validní to vrací místo do formu do té funkce UpdateTextarea, ze které volám AjaxPost.

existuje nějaká metoda, jak funkci UpdateTextarea volat těsně před odesláním formuláře.
jinak ano, ten je odesílán Button type="submit".

napadá mě ještě tu funkci UpdateTextarea volat v události KeyUp té textarey, ale to by se podle mě volala zbytečně často ...
mě stačí ji volat jen jednou před odesláním formuláře.
zkoušel jsem v tom formu třeba
Kód: Vybrat vše
@using (Html.BeginForm("MojeAkce", "MujController", FormMethod.Post, new
        {
            enctype = "multipart/form-data",
            onBegin =  return UpdateTextarea,
            onSubmit = "return AjaxPost(this);",
            data_restUrl = Url.Action("Index", "MujController"),
            id = "formik"
        }))
        {

ale to nefunguje. ta funkce Update neprobehne.
nějaky nápady ??

CKEDITOR je knihovna, co převede obyčejnou textareu na editor (barva, velikost, styl písma a tak), vytvoří místo ní iframe
a funkce UpdataTextarea zase naplní původní teareu textem včetně všech potřebných tagů.
AMD FX-6300; Gigabyte 970A-DS3P; DDR3 8192MBytes; AMD Radeon HD 6700 Series
dyžon
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 19. 2. 2020 19:23

Tak prvně bych dodal alespoň toto ( a to hlavně kvůli tomuto: onSubmit = "return updateTextarea(this);" )
Kód: Vybrat vše
function updateTextarea(form) {
    for (instance in CKEDITOR.instances) {
        CKEDITOR.instances["Popis"].updateElement();
    }
    AjaxPost(form);
    return false; // <-- doplnit, zablokuje klasické odeslání formu
}


Nebo se vyprdnout na onSubmit a napsat klasické jQuery, které ošetří odeslání formu
Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod dyžon 20. 2. 2020 08:35

to je ono,
tím, že se do funkcí v jQuery nemusí psát návratová hodnota, tak mi to nedošlo.
děkuju moc.

používám stejnou funkci AjaxPost na různých místech, jako je přihlášení a podobně, a v onSubmit mám rovnou AjaxPost(this).
stačilo to v pohodě, tady poprvé jsem k tomu potřeboval před odesláním něco upravit.

sláva tobě .. :-) :-)) :-D
AMD FX-6300; Gigabyte 970A-DS3P; DDR3 8192MBytes; AMD Radeon HD 6700 Series
dyžon
Junior
Uživatelský avatar

Odeslat příspěvekod dyžon 20. 2. 2020 11:47

ještě jedna věc, se kterou si nevím rady.
mám vytvořenej model.
pro jednoduchost jsem to ořezal ...
Kód: Vybrat vše
public class Neco : IEntity
{
    public virtual int Id { get; set; }

    [Display(Name = "Cislo")]
    [Required(ErrorMessage = "Číslo musí být")]
    public virtual int Cislo { get; set; }

    [Display(Name = "Nazev")]
    [Required(ErrorMessage = "Název musí být")]
    [StringLength(50, ErrorMessage = "Název přesáhl 50 znaků")]
    public virtual string Nazev { get; set; }

    [Display(Name = "Datum")]
    [Required(ErrorMessage = "Datum musí být")]
    [DisplayFormat(DataFormatString = "{0: yyyy-MM-dd}")]
    [DataType(DataType.Date, ErrorMessage = "Formát datumu je špatný")]
    [ZkontrolujDatum(ErrorMessage = "Datum musí být starší než dnes")]
    public virtual DateTime? Datum { get; set; }
}

no a pro validaci datumu (ZkontrolujDatum) jsem hned pod to napsal
Kód: Vybrat vše
public class ZkontrolujDatumAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        DateTime vlozenyDatum = Convert.ToDateTime(value);
        if (vlozenyDatum > DateTime.Now.Date)
        {
            return ValidationResult.Success;
        }
        else
        {
            return new ValidationResult(ErrorMessage);
        }
    }
}

když odesílám formulář, tak všechny ty validační podmínky se vyhodnotí před odesláním ajaxu (funkce AjaxPost) příkazem
Kód: Vybrat vše
$.validator.unobtrusive.parse(form);
    if ($(form).valid()) {

ale ta mnou napsana validace ZkontrolujDatum se hodnotí až na úrovni Controlleru > if (ModelState.IsValid)
jak docílím toho, aby se ta podmínka ZkontrolujDatum provedla už před odesláním formu ajaxem ??
AMD FX-6300; Gigabyte 970A-DS3P; DDR3 8192MBytes; AMD Radeon HD 6700 Series
dyžon
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 22. 2. 2020 19:45

Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod dyžon 24. 2. 2020 13:10

jak jsi tohle našel ... :D
jen jsem to zhruba prolít a vypadá to, že je to opět přesně co potřebuji.
děkuji a opět sláva tobě .. ;-] :D
AMD FX-6300; Gigabyte 970A-DS3P; DDR3 8192MBytes; AMD Radeon HD 6700 Series
dyžon
Junior
Uživatelský avatar


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků