.hide() not working after dialog postaback - javascript

I'm having a problem with a jQuery dialog that is probably right in front of me but I can't figure out...
The dialog works fine. It shows the fields and sends the information and, if it's the case, brings back the validation message. My problem is that when I initialize it, I tell it to hide a div inside of if, and it does. On open the div is not there, but if I try to send the information and it brings back the validation message, it shows the div.
Here is the js that calls the dialog:
$(function () {
$('.openDialog').click(function () {
$.ajax({
url: this.href,
type: 'GET',
cache: false,
data: { idUsuario: $('#idUsuario').val() },
success: function (result) {
$('#result').html(result).dialog('open');
$('#formButtom').hide();
}
});
return false;
});
$('#result').dialog({
autoOpen: false,
modal: true,
show: { effect: "drop", direction: "up" },
dialogClass: "dialog",
width: 400,
resizable: false,
position: "center",
buttons: {
"Confirmar": function () {
$("form").submit();
},
"Cancelar":function () { $('#result').dialog('close'); }
}
});
});
function dialogSucces(result) {
if (result.cadastro) {
$('#result').dialog('close');
window.location.href = '/usuario/index';
} else {
$('#result').html(result);
}
}
and here is the html:
<form id="createUsuarioForm">
Nome
<div class="editor-field">
#Html.EditorFor(model => model.Nome)<br />
#Html.ValidationMessageFor(model => model.Nome, String.Empty, new { #class = "text-error"})
</div>
<br />
E-mail / Login
<div class="editor-field">
#Html.EditorFor(model => model.Login)<br />
#Html.ValidationMessageFor(model => model.Login, String.Empty, new { #class = "text-error"})
</div>
<br />
<div id="formButtom" class="row demo-row">
<div class="span2">
<input type="submit" value="Confirmar" class="btn btn-primary" />
</div>
<div class="span2">
#Html.ActionLink("Cancelar", "Index", "Usuario", new { #class = "btn btn-primary" })
</div>
</div>
</form>
I've seen this post: jQuery Show/Hide not working after postback and tried doing this in the function, but it didn't work:
$(function () {
$('.openDialog').click(function () {
$.ajax({
url: this.href,
type: 'GET',
cache: false,
data: { idUsuario: $('#idUsuario').val() },
success: function (result) {
$('#result').html(result).dialog('open');
$('#formButtom').hide();
}
});
return false;
if (this.isPostback) { $('#formButtom').hide(); };
});
Does anyone know what I'm doing wrong?

You didn't show how your dialogSuccess function runs, but I suppose it executes in case of form fault also. If that is, you should to add a line into your if else statement there. Like this:
function dialogSucces(result) {
if (result.cadastro) {
$('#result').dialog('close');
window.location.href = '/usuario/index';
} else {
$('#result').html(result);
$('#formButtom').hide(); // once defected form rendered again,
// div hide directive should be launched again too
}
}

Related

How to send files using modal window and MVC

I have a working modal window that saves an entity to the database, my question is how to send files from the modal?
Here as my current JavaScript function:
$('#btn-save').on('click', function () {
$.ajax({
url: '#Url.Action("CreateModal", "Suggestions")',
type: 'POST',
data: $('#modal-form').serialize(),
success: function (data) {
if (data.success == true) {
$('#suggestion-modal').modal('hide');
location.reload(true);
} else {
$('.modal-content').html(data);
$('#suggestion-modal').modal('show');
}
}
});
});
This part does not send data, but works fine when not using modal and using standard MVC Create template:
<form id="modal-form" method="post" enctype="multipart/form-data">
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.UserId)
<div>
#Html.LabelFor(model => model.Title)
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title, "")
</div>
<div>
#Html.LabelFor(model => model.Images, "Images")
<input type="file" name="upload" multiple />
</div>
<div>
<input id="btn-save" type="button" value="" />
</div>
</form>
I've left the rest of the partial view out as that all works correctly.
EDIT: Just added where my button was in the form. It was there, I just removed much of the code not relevant to the question - should have left the button in. Also added extra model properties - These must be sent with the file, including validation token.
EDIT: Many thanks to Jasen. I've included the JavaScript below for anyone else struggling with this.
$('#btn-save').on('click', function () {
var formData = new FormData($('form').get(0));
$.ajax({
url: '#Url.Action("CreateModal", "Suggestions")',
type: 'POST',
processData: false,
contentType: false,
data: formData,
success: function (data) {
if (data.success == true) {
$('#suggestion-modal').modal('hide');
location.reload(true);
} else {
$('.modal-content').html(data);
$('#suggestion-modal').modal('show');
}
}
});
});

Main view stacks on the same page after calling partial view

I have this action that returns different partial view based on the selected value from the drop down list.
Controller:
[HttpPost]
public ActionResult Foo(SomeViewModel VM)
{
var model = VM
if (Request.IsAjaxRequest())
{
if (model.SelectedValue == 1 || model.SelectedValue == 2 || model.SelectedValue == 3)
{
// ...
return PartialView("PartialView1", model);
}
else if (model.SelectedValue == 4)
{
// ...
return PartialView("PartialView2", model);
}
else (model.SelectedValue == 5)
{
// ...
return PartialView("PartialView3", model);
}
}
return View(model);
}
Main View:
<script src="~/Scripts/jquery-3.2.1.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
<div>
<h2>Paint Computation</h2>
#using (Ajax.BeginForm("Foo", "Controller",
new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "Result"
}))
{
<div class="col-md-10">
<h5>Type of Paint</h5>
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.DropDownListFor(m => m.SelectedValue, new SelectList(Model.PaintType, "Value", "Text"),
"Please Select", htmlAttributes: new { #class = "form-control" })
</div>
<br />
// Some HTML helpers
<input type="submit" value="Compute" class="btn btn-default" id="Submit" />
</div>
}
</div>
//This is how I render my partial view using jQuery in my main View:
<div id="Result">
<hr />
</div>
<script type="text/javascript">
$(document).ready(function () {
$('#Submit').click(function () {
$('#Result').load('/Controller/Foo');
});
});
</script>
Whenever I clicked the button, the partial view appears, but when I clicked it again for the 3rd or 4th time, the main view content stacks on the same main view. I tried to use the inspect element and that's how I determined that it stacks the same main view elements.
Is my way of calling the partial view is right? As much as possible I want to use ajax for calling the partial view every time the button is clicked. Please guide me to correct it. Thanks.
Here's the of the problem.
<script type="text/javascript">
$(document).ready(function () {
$('#Submit').click(function () {
$.ajax({
type: 'POST',
url: '/Controller/Foo',
cache: false,
contentType: "application/html; charset=utf-8",
dataType: 'html',
success: function (result) {
$('#Result').html(result);
}
});
});
});
</script>
Now it works. I changed my code and use the code above. I use .html() rather than .append() or .replaceWith(). Now every time i click the button, it changes the <div id = "Result> content.

JQuery ui autocomplete in a MVC partial view only works once

I've been trying to get autocomplete to work for my partial view using JQuery ui. The partial view is updated using AJAX.
The problem is that the autocomplete only works up until the point where the partial view is updated.
This is my partial view
<div id="tagList">
#using (Ajax.BeginForm("AddToTagList", new { urlLocation = Model.UrlLocation }, new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "tagList" }))
{
if (Model.TagList != null)
{
<div class="form-group">
#Html.LabelFor(model => model.Tag.Text, "Tags", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-xs-10">
<div class="input-group" style="max-width: 300px;">
#Html.EditorFor(model => model.Tag.Text, new { htmlAttributes = new { #class = "form-control", #id = "search_term" } })
#Html.ValidationMessageFor(model => model.Tag.Text, "", new { #class = "text-danger" })
<div class="input-group-btn">
<button type="submit" value="Add Tag" class="btn btn-default">+</button>
</div>
</div>
</div>
</div>
}
}
</div>
This is my JavaScript
$(document).ready(function () {
$("#search_term").autocomplete({
source: function (request, response) {
$.ajax({
url: "/Tag/SearchAutoComplete",
type: "POST",
dataType: "json",
data: { term: request.term },
success: function (data) {
response($.map(data, function (item) {
return { label: item.Text, value: item.Text };
}));
}
});
},
});
});
and this is my autocomplete search action
public JsonResult SearchAutoComplete(string term)
{
using (IDocumentSession session = RavenDbConfig.RavenDBDocumentStore.OpenSession())
{
var results = session.Query<Tag>().Where(x => x.Text.StartsWith(term)).ToList();
return Json(results,JsonRequestBehavior.AllowGet);
}
}
So, my question is, how can i make this work even after the partial view has been updated once?
Your problem is when you reload your PartialView you basicaly delete some part of DOM in your html document and create new one. And all your bindings that you add in $(document).ready() event will be lost.
One of the posible solutions for this problem is to place your autocomplete init code in addition to .ready() event in jquery .ajaxSuccess() global event becouse you reload your PartialViews via Ajax. Like this:
$(document).ajaxSuccess(function() {
$("#search_term").autocomplete({
source: function (request, response) {
$.ajax({
url: "/Tag/SearchAutoComplete",
type: "POST",
dataType: "json",
data: { term: request.term },
success: function (data) {
response($.map(data, function (item) {
return { label: item.Text, value: item.Text };
}));
}
});
},
});
});
That way you will init your autocomplete every time you reload PartialView.

Showing message from "return json(message)" of action in previous jquery dialog after posting its form

I shown a partial view in a jquery dialog to create news group . my code are:
"_AddNewsGroup" partialView:
#model SmsMenu.Models.NewsGroupViewModel
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
#using (Html.BeginForm("AddNewsGroup", "News", FormMethod.Post, new { id = "newsGroupForm" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div id="MessBox"></div>
<div class="editor-label">
#Html.LabelFor(model => model.NewsGroupTitle)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.NewsGroupTitle)
#Html.ValidationMessageFor(model => model.NewsGroupTitle)
</div>
<p>
<input type="submit" id="SubmitButton" value="Save" />
</p>
}
Jquery Codes in "Index" view to show dialog:
<script type="text/javascript">
$(document).ready(function () {
$("#addnewsgroup").css('display', 'none');
});
$(function () {
$('#addnewsgroup').dialog({
autoOpen: false,
width: 400,
resizable: false,
// title: 'hi there',
modal: true,
open: function (event, ui) {
//Load the CreateAlbumPartial action which will return
// the partial view _CreateAlbumPartial
$(this).load("#Url.Action("AddNewsGroup","News")");
},
buttons: {
"Close": function () {
$(this).dialog("close");
}
}
});
});
$("#SubmitButton").click(function () {
if (!$("#newsGroupForm").valid()) {
return false;
}
var groupTitle = $("#NewsGroupTitle").val();
$.ajax({
url: '/Admins/NewsGroup/AddNewsGroup',
type: 'post',
dataType: 'json',
data: JSON.stringify({ newsgroup: { 'NewsGroupTitle': groupTitle } }),
contentType: 'application/json; charset=utf-8',
success: function (result) {
$("#MessBox").html(result.message).dialog({
buttons: [{
text: "Ok",
click:
function () {
$("#addnewsgroup").dialog('close');
location.href = '/Admins/NewsGroup/Index';
}
}]
});
}
});
});
</script>
function for add button in index view for showing dialog:
function AddNewsGroup() {
$('#addnewsgroup').dialog('open');
}
and these are my actions:
public ActionResult AddNewsGroup()
{
return View("_AddNewsGroup");
}
[HttpPost]
public ActionResult AddNewsGroup(NewsGroupViewModel newsgroup)
{
if (newsSrv.AddNewsGroup(newsgroup))
{
return Json("successful!",JsonRequestBehavior.AllowGet);
}
else
{
return Json("Error!",JsonRequestBehavior.AllowGet);
}
}
I want to show "Successfull!" and "Errors!" after posting in previous dialog box that has been shown ;
but these are shown in a blank page!!
what should i do?
thanks for helping...
You need to use preventDefault first inside the click handler, otherwise the default action (submitting the form) will proceed.
$("#SubmitButton").click(function (e) {
e.preventDefault();

Get content from TinyMCE editor

I'm trying to get the Content from TinyMCE, but it only returns null. The problem it's loaded in a Dialog box.
The dialog view:
<form>
<textarea name="content" cols="40" rows="25" id="tinymce">
Dette er noget tekst
</textarea>
</form>
<input class="close" onclick="get_editor_content()" name="submit" type="submit" value="Kontakt Oline" style="float: right" id="contenttiny" />
<script type="text/javascript">
tinyMCE.init({
// General options
mode: "textareas",
theme: "advanced",
plugins: "autolink,lists,spellchecker,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template",
</script>
The view where the dialog is opened from:
<a class="openDialog" data-dialog-id="emailDialog" data-dialog-title="Kontakt/prospekt" href="/Home/tinymce">Contact US</a>
<div id="result"></div>
<script type="text/javascript">
$.ajaxSetup({ cache: false });
$(document).ready(function () {
$(".openDialog").live("click", function (e) {
e.preventDefault();
$("<div ></div>")
.addClass("dialog")
.attr("id", $(this).attr("data-dialog-id"))
.appendTo("body")
.dialog({
title: $(this).attr("data-dialog-title"),
close: function () { $(this).remove() },
modal: true,
position: ['center', 40],
minWidth: 670,
resizable: false
})
.load(this.href);
});
});
$(".close").live("click", function (e) {
e.preventDefault();
var content = tinyMCE.get('tinymce').getContent(); //$("#contenttiny").val();
$.ajax({
type: "POST",
url: "/Home/tinymce",
data: { "content": content },
success: function (data) {
$("#result").html(data.nameret);
$(".dialog").dialog("close");
},
error: function (data) {
alert("There was error processing this");
$(this).closest(".dialog").dialog("close");
}
});
});
</script>
The Controller:
[HttpPost]
public ActionResult tinymce(string content)
{ /*Your other processing logic will go here*/
return Json(new
{
nameret = content
}, JsonRequestBehavior.
AllowGet);
}
P.S. I have used this example to create the modal dialog. Which is an PartialView. It's possible to get the content from tinymce in the main index view. But not in the ajax call.
The solution to the problem was rather simple. The reason was that the tinymce is returning html text, which per default is not allowed. The solution was to put [ValidateInput(false)] over the Controller method.

Categories

Resources