I'm working on a MVC-project for fun that takes data from a public API, shows it, and calculates it depending on user input; I'm nearing the end of my goal, but one issue I've been having trouble with for the past day is blocking my progress.
The issue is as follows:
I want to be able to take data from my Controller, and show on button-press in my view, inside a writable text-box (so the user can both auto-generate data by inputting username and fetching their data from the public API, or specify their own custom data).
View
#{
ViewBag.Title = "Herblore";
Enter you name #Html.TextBox("Name")
<input type="submit" id="SubmitName" value="Submit" />
<script type = "text/javascript">
$('#SubmitName').click(function() {
var url = "/Calculator/PlayerLevelMsg";
var name = $('#Name').val();
$.get(url, {
Brugername: name
}, function(data) {
$("#lData").html(data);
});
})
</script>
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-3">
<h3 style="font-size: 24px">Current Level</h3>
</div>
<div class="col-md-3 col-md-pull-1">
<h3><output id="lData"/></h3>
</div>
<div class="col-md-3 col-md-pull-1">
<h3 style="font-size: 24px">Current EXP</h3>
</div>
<div class="col-md-3 col-md-pull-2">
<h3><input type="text" id="lData" /></h3>
</div>
</div>
</div>
</div>
My Javascript allows me to run this controller in my calculator controller class:
public string PlayerLevelMsg(string BrugerName) {
int Firemaking = 12;
var playerdata = new OS_Efficiency_Calculator.Controllers.PlayerSearchController();
string PlayerLevel = playerdata.GetLevel(BrugerName, Firemaking);
string moreLevel = "PlayerLevel = 85";
if (!String.IsNullOrEmpty(BrugerName))
return "Player Level" + " " + moreLevel;
else
return "Please enter your name.";
}
Which returns a string that holds a single value from the API - this shouldn't be important, in the name of reproducing my issue, commenting out the strings gathered from other classes in my project and using a basic text string will give you the same result as I'm getting, so if you wish to reproduce:
public string PlayerLevelMsg(string BrugerName) {
if (!String.IsNullOrEmpty(BrugerName))
return "Player Level = 99";
else
return "Please enter your name.";
}
My issue is as follows;
Using the above code, I can view the output of my controller just fine in the line "<output id="lData"/>" - however, this isn't a text-box, so the user can't edit it.
on the other hand, will not. This is likely because it's an input type, but I can't find a textbox-output type, nor am I experienced enough in MVC to fully understand why I can't just bind the textbox to the value through the ID, when that would work just fine in a general WPF application (where I've spent the most time practicing).
It seems to me that there should be some super-simple answer to this, and I hope you guys can help me, and that the semi-code provided is adequate; As said, the ideal solution is that in this picture:
Both of the values would be "85", but the text-box is adamant that it isn't supposed to change - Thanks so much for taking the time to look through!
#{
ViewBag.Title = "Herblore";
Enter you name #Html.TextBox("Name")
<input type="submit" id="SubmitName" value="Submit" />
< script type = "text/jscript" >
$('#SubmitName').click(function() {
var url = "/Calculator/PlayerLevelMsg";
var name = $('#Name').val();
$.get(url, {
Brugername: name
}, function(data) {
$("#lData").val(data);
});
})
< /script>
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-3">
<h3 style="font-size: 24px">Current Level</h3>
</div>
<div class="col-md-3 col-md-pull-1">
<h3><input type="text" id="lData"/></h3>
</div>
<div class="col-md-3 col-md-pull-1">
<h3 style="font-size: 24px">Current EXP</h3>
</div>
<div class="col-md-3 col-md-pull-2">
<h3><input type="text" id="lData" /></h3>
</div>
</div>
</div>
</div>
You need to make lData an input field with the type text and in the JavaScript function set the value of the field to the data returned from the controller.
Please visit this site to learn more about the input field: http://www.w3schools.com/tags/tag_input.asp
Related
I have a problem with implement saving value with input type number to the database. I have created website with ASP .NET MVC with UnitOfWork and Repositories. I have a Commodity model, where I have field Amount, and I have HomeViewModel in which I have a field Amount also. I would like to overwrite the amount field from the commodity model. Should I use onchange or onclick in input or a tags in html code, or all with my basic ideas are nonsens ?
Below is the code snippet with view created in RazorPages with extension .cshtml.
<div class="col-12">
<div class="row my-3">
#foreach(var Commodity in Model.CommodityList.Where(c=>c.CategoryId==category.Id))
{
<div class="col-lg-4 col-xl-3 col-md-6 pb-4">
<div class="card" style="border:2px solid #43ac6a;border-radius:5px;
backgroundcolor: #fffeee">
<div class="pl-3 pt-1 text-center">
<h3 class="card-title text-primary"><b>#Commodity.Name</b></h3>
</div>
<div class="d-flex justify-content-between">
<div class="pl-1 text-muted">#localizer.Get("Price")</div>
<div class="pr-1 text-danger h5">$#Commodity.Price</div>
</div>
<img src="#Commodity.ImageUrl" class="card-img-top p-2 rounded" />
<div class="col-9">
<input onchange="save()" asp-for="#Commodity.Amount" type="number"
id="quantity" name="quantity" min="0" max="100" />
</div>
<a onclick="save()" asp-action="Details" class="btn btn-success"
style="border-
radius:2px;" asp-route-id="#Commodity.Id"
onclick="save()">#localizer.Get("Details")</a>
</div>
</div>
}
</div>
</div>
My problem is that I can't write the value from after pressing the button below as the tag.
Below is the method written by me in controller regarding to the view
public IActionResult Index()
{
HomeVM = new HomeViewModel()
{
CategoryList = _unitOfWork.Category.GetAll(),
CommodityList = _unitOfWork.Commodity.GetAll(includeProperties: "Category"),
ServiceList = _unitOfWork.Service.GetAll(includeProperties: "Category,Payment"),
EmployeeList = _unitOfWork.Employee.GetAll(includeProperties: "Service"),
Amount = _unitOfWork.Commodity.GetFirstOrDefault(includeProperties:
"Category").Amount
};
foreach (var commodity in (_unitOfWork.Commodity.GetAll(includeProperties:
"Category")))
{
var CommodityFromDb = commodity;
CommodityFromDb.Amount = HomeVM.Amount;
_unitOfWork.Save();
}
_unitOfWork.Save();
return View(HomeVM);
}
I have a guess that you probably need to do it somehow with jquery, in a file with the extension js, but I have no idea how. I would be grateful for any help.
Dear friends I am currently creating an admin panel for user where they can easily can publish their articles. I also want to add to my form a little fileuploader but sadly I got some problems with DROPZONEJS.JS file in POST method. The main problem is I cannot give URL to project's local file in order to download to file there where website will access those file in order to publish them with current article's id. Please let me know if there is something not understandable.
#{
ViewBag.Title = "Uppy";
}
#{
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
<div class="content d-flex flex-column flex-column-fluid" id="kt_content">
<!--begin::Entry-->
<div class="d-flex flex-column-fluid">
<!--begin::Container-->
<div class="container">
<!--begin::Card-->
<div class="card card-custom gutter-b">
<div class="card-header">
<div class="card-title">
<h3 class="card-label">File Upload</h3>
</div>
</div>
<!--begin::Form-->
<form>
<div class="card-body">
<div class="form-group row">
<label class="col-form-label col-lg-3 col-sm-12 text-lg-right">Multiple File Upload</label>
<div class="col-lg-4 col-md-9 col-sm-12">
<div class="dropzone dropzone-default dropzone-primary" id="kt_dropzone_2">
<div class="dropzone-msg dz-message needsclick">
<h3 class="dropzone-msg-title">Drop files here or click to upload.</h3>
<span class="dropzone-msg-desc">Upload up to 10 files</span>
</div>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-form-label col-lg-3 col-sm-12 text-lg-right">File Type Validation</label>
<div class="col-lg-4 col-md-9 col-sm-12">
<div class="dropzone dropzone-default dropzone-success" id="kt_dropzone_3">
<div class="dropzone-msg dz-message needsclick">
<h3 class="dropzone-msg-title">Drop files here or click to upload.</h3>
<span class="dropzone-msg-desc">Only image, pdf and psd files are allowed for upload</span>
</div>
</div>
</div>
</div>
</div>
#using (Html.BeginForm("Uppy",
"FileUpload",
FormMethod.Post,
new { enctype = "multipart/form-data" })) //multipart/form-data gives functionlity to inputes (search at web);
{
<div class="card-footer">
<div class="row">
<div class="col-lg-3"></div>
<div class="col-lg-4">
<input type="submit" value="Submit" class="btn btn-light-primary mr-2" />
<button type="reset" class="btn btn-primary">Cancel</button>
</div>
</div>
</div>
}
</form>
<!--end::Form-->
</div>
<!--end::Card-->
<!--end::Row-->
</div>
<!--end::Container-->
</div>
<!--end::Entry-->
</div>
<!--end::Content-->
By the way my own upload code is working correctly and also sends choosen file to url location where I wrote in controller.
<label for="file">Upload File:</label>
<input type="file" name="file" id="file" class="btn-hover-bg-success" />
<br>
<br>
<input type="submit" value="Upload Image" />
<br>
<br>
#ViewBag.Message
This is my FileUploadController:
[HttpPost]
public ActionResult Uppy(HttpPostedFileBase file)
{
ADAPTIVE_TESTEntities ent = new ADAPTIVE_TESTEntities();
Adaptive.News.Models.NEWS news = new Adaptive.News.Models.NEWS();
if (file != null && file.ContentLength > 0)
try
{
var path = Path.Combine(Server.MapPath("~/Content/images"),
Path.GetFileName(file.FileName));
file.SaveAs(path);
news.PICTUREPATH = path;
ent.NEWS.Add(news);
ent.SaveChanges();
ViewBag.Message = "File uploaded successfully";
}
catch (Exception ex)
{
ViewBag.Message = "ERROR: " + ex.Message.ToString();
}
else
{
ViewBag.Message = "You have not specified a file.";
}
return View();
}
it is not obvious to me, what and where really your problem is. What do you mean with having problem. Is your problem with Dropzone.JS or with C#? Anyway, I examined your code slightly and have some ideas what your problem could be.
FIRST OF ALL: You have 2 DIV containers, which you use as Dropzone elements assigning them the css class "dropzone". Furthermore you generate a FORM element with ASP.Net HTML-Helper.
By default you have 2 options using Dropzone.
Declarative instantiation via assigning css class "dropzone" to any HTML element.
Dropzone discovers all DOM elements with class="dropzone" automatically and instantiates them.
Programmatically instantiating: You instantiate Dropzone by passing the id of the container element and THE OPTIONS CONTAINING POST URL to the Dropzone constructor.
DECLARATIVE DROPZONE
You must pay attention to this detail: If you use FORM element as Dropzone container element, Dropzone uses "action" attribute of the FORM element as post URL. But if you use
DIV element as container, then you get most possibly a JavaScript error. Because DIV elements do usually NOT have "action" attribute. If you use DIV as Dropzone container (and in your code you use it 2 times), you will get following JavaScript error:
dropzone.js:1027 Uncaught Error: No URL provided.
at new Dropzone (dropzone.js:1027)
at dropzone.js:2907
at Function.Dropzone.discover (dropzone.js:2919)
at Dropzone._autoDiscoverFunction (dropzone.js:3491)
at HTMLDocument.init (dropzone.js:3456)
In this case you have two options solve the problem:
Use FORM element instead of DIV as Dropzone container.
Add action="/your/post/url" to your DIV element, which you use as Dropzone container.
Where I would prefer the first option. Because it is not common that DIV elements have action attribute.
I have a simple contact message form written in razor asp.net and c#. Whenever the form is submitted, I am able to render the server response with no issues but for some reason, all of the input fields are maintaining the same values.
Here is the partial view:
#using PublicWebsite.Models.Contact;
#model ContactFormViewModel
<form role="form" id="contactForm" data-toggle="validator" method="post" asp-controller="Contact" asp-action="SubmitMessage">
#if (!string.IsNullOrWhiteSpace(Model.ServerResponse))
{
<div class="form-group">
<div class="row">
<div class="col-md-12">
<div class="alert #(Model.ServerResponseSuccess ? "alert-success" : "alert-danger")" role="alert">
#Model.ServerResponse
</div>
</div>
</div>
</div>
}
<div class="form-group">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<div class="prepend-icon">
<input type="text" asp-for="#Model.Name" name="Name" class="form-control input-lg" placeholder="Your Full Name" maxlength="50" required>
<i class="nc-icon-outline users_single-03"></i>
</div>
<div class="help-block with-errors"></div>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<div class="prepend-icon">
<input type="email" asp-for="#Model.Email" name="Email" class="form-control input-lg" placeholder="Email" maxlength="200" required />
<i class="nc-icon-outline ui-1_email-85"></i>
</div>
<div class="help-block with-errors"></div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<div class="prepend-icon">
<input type="tel" asp-for="#Model.Phone" name="Phone" class="form-control input-lg" placeholder="Phone Number" maxlength="25" required>
<i class="nc-icon-outline ui-2_phone"></i>
</div>
<div class="help-block with-errors"></div>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
<select class="form-control" asp-for="#Model.ContactReason" name="ContactReason" data-container-class="input-lg" required style="height:46px !important">
<option value="">Choose a Reason</option>
<option value="Home Remediation">Home Remediation</option>
<option value="Commercial Remediation">Commercial Remediation</option>
<option value="Employment Opportunities">Inquire about employment oppotunities</option>
<option value="Other">Other</option>
</select>
</div>
<div class="col-md-6">
</div>
</div>
</div>
<div class="form-group">
<textarea asp-for="#Model.Message" class="form-control" rows="10" name="Message" placeholder="Message" required></textarea>
<div class="help-block with-errors"></div>
</div>
<div class="form-group">
<div class="g-recaptcha" data-sitekey="mysitekeyishere"></div>
<input type="hidden" name="RecaptchaResponse" value="" />
</div>
<button type="submit" id="form-submit" class="btn btn-primary btn-lg icon-left-effect"><i class="nc-icon-outline ui-1_email-85"></i><span>Send message</span></button>
<div id="msgSubmit" class="hidden"></div>
</form>
Here is a look at the viewmodel:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace PublicWebsite.Models.Contact
{
public class ContactFormViewModel
{
[StringLength(50)]
public string Name { get; set; } = "";
[StringLength(200)]
public string Email { get; set; } = "";
[StringLength(25)]
public string Phone { get; set; } = "";
[StringLength(50)]
public string ContactReason { get; set; } = "";
public string Message { get; set; } = "";
[StringLength(250)]
public string ServerResponse { get; set; } = "";
public bool ServerResponseSuccess { get; set; } = false;
}
}
Inside of the Contact Index CSHTML page for Contact, I render the partial view without any issues.
#section Scripts {
<script src="#validatorPath"></script>
<script type="text/javascript">
$(function () {
$(document).on('submit', '#contactForm', function (e) {
$form = $(this);
$url = $form.attr('action');
$.ajax({
type: "POST",
url: $url,
data: $form.serialize(), // serializes the form's elements.
success: function (data) {
loadFormData(data); //This works
resetCaptcha();
},
error: function (data) {
alert(data);
}
});
e.preventDefault(); // avoid to execute the actual submit of the form.
});
function loadFormData(data) {
$formContainer = $('.contact-form-container');
$formContainer.empty();
$formContainer.html(data);
console.log(data); //This reports back the same results
}
function resetCaptcha() {
//reset captcha
$('.g-recaptcha').empty();
$.getScript('#recaptchaUrl');
}
});
</script>
}
<div class="col-md-7 contact-form-container">
#{ await Html.RenderPartialAsync("_ContactForm", new ContactFormViewModel()); }
</div>
Everything renders properly. As seen in the screenshot below.
Once the items are filled out, the following sendmessage function is called as seen in the scripts section above.
[HttpPost]
public async Task<IActionResult> SubmitMessage(ContactFormViewModel contactForm)
{
var captchaResponse = Request.Form["g-recaptcha-response"].ToString();
if (string.IsNullOrWhiteSpace(captchaResponse))
{
contactForm.ServerResponse = _errorCaptchaMessageBlank;
}
else
{
if (await ValidCaptcha(captchaResponse))
{
try
{
await SendCustomerMessage(contactForm);
var customerName = contactForm.Name;
//This works
contactForm = new ContactFormViewModel
{
ServerResponse = String.Format(_successfulSendMessage, customerName.Split(' ')[0]),
ServerResponseSuccess = true
};
}
catch
{
contactForm.ServerResponse = _errorCaptchaMessageInvalid;
}
}
else
{
contactForm.ServerResponse = _errorCaptchaMessageInvalid;
}
}
//This works and I get the response back on the front end
return PartialView("_ContactForm", contactForm);
}
You can even see the message errors on a successful attempt to the server (i.e. the server response as shown in the HTML) and it keeps the user's info as it should so they don't have to re-enter the data as shown in the image below.
Now on success, notice in the code above I create a new Contact Form with cleared values and a success message. However, the same information stays filled in like below. I want the contact form to be cleared out.
I have attempted even just returning back a completely new view model but still have the same problem where all of the data is almost cached. In my console.log response from the server, I get a partial view result with the values pre-filled so I know it's not a browser issue. Even when I debug the CSHTML page, I only see the server response and the success = true, all other fields are blank.
Any help to figure out why the server is still returning a partial view result with the filled in data would be much appreciated.
You can add this to your success callback function:
$('#contactForm').find('input[type=text], textarea, select').val('');
It basically finds all input fields within the form and clears out their values.
Try to change your success callback function like below:
success: function () {
document.getElementById("contactForm").reset();
},
Clearing model state helped to resolve a similar problem when Partial method returned messed-up data:
public PartialViewResult OnPostData()
{
...
ViewData.ModelState.Clear();
return Partial("_ViewName", model);
}
I currently have a form that when submit is clicked the selected value should be shown in the textarea/box and initial page should remain open.
But the problem I'm currently having is when I click the submit button, I'm being taken from the initial page and the value is being displayed on a blank page.
So basically I have two issues. How do I prevent being taken to another page once submit is clicked? And how can I get the value to be displayed in the textarea? I'm new to MVC, so any help would be greatly appreciated.
View:
<script language="JavaScript">
function showInput() {
document.getElementById('display').innerHTML =
document.getElementById("Envs").value;
}
</script>
<form asp-controller="CyberArk" asp-action="CyberArk" method="post" role="form" onsubmit="return confirm('Do you really want to carry out this action?');" id="form1" style="display:none;">
<div id="accordion" role="tablist" aria-multiselectable="true">
#* Form 1 *#
<div class="card">
<div class="card-header" role="tab" id="headingTwo">
<h5 class="mb-0">
<a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo" style="font-size:15px;">
Vault Status
</a>
</h5>
</div>
<div id="collapseTwo" class="collapse" role="tabpanel" aria-labelledby="headingTwo">
<div class="card-block">
<div class="form-group">
<div class="form-group">
<p> This script returns status of vault servers for the chosen environment. It is used to determine if any servers overlap in order to detect a split brain.</p>
</div>
#model PAM_Dashboard_Project.Models.Vaults
#Html.DropDownList("Envs", new SelectList(Enum.GetValues(typeof(Envs))), "Select Enivronment", new { #class = "form-control" })
<br>
<div>
<button type="submit" onclick="showInput();">Submit</button>
</div>
<br />
<textarea class="form-control" cols="20" id="ouput1" name="output1" rows="2"></textarea>
</div>
</div>
</div>
</div>
</div>
</form>
Model:
public class Vaults
{
public string Envs { get; set; }
}
public enum Envs
{
RTPprod,
OMA,
BG1,
BG2,
Cloud,
Workstation,
QA
}
Controller:
public class CyberArkController : Controller
{
public IActionResult CyberArk()
{
return View();
}
[HttpPost]
public string CyberArk(Vaults newVault)
{
string SelectedValue = newVault.Envs;
return (SelectedValue);
}
}
Update your event attribute to:
onclick="showInput(event);"
Update your showInput method to:
function showInput(e) {
e.preventDefault();
document.getElementById('display').innerHTML = document.getElementById("Envs").value;
}
Note: You don't have an element with the id display, so you need to fix that.
I have the following code for a webpage;
<div class="toolbox">
<div class="toolboxNest" align="left">
<div class="clear"> </div>
<div class="gap"> </div>
<label for="j_username">
<input id="j_username" type="text" name="j_username">
<div class="clear"> </div>
<div class="gap"> </div>
<label for="j_password">
<input id="j_password" type="password" name="j_password">
</div>
<div class="clear"></div>
<div class="gap"></div>
<div align="center">
<input class="formButtonGreen" type="submit" value="Login">
</div>
<div class="clear"></div>
<div class="gap"></div>
<div class="infoText">
I am able to click and enter text for the username and password, but I cant work out how to press the submit button, if it were just an element then that would be fine, but it's in a class and I'm unsure how to do it.
This is my code...
var x = webBrowser1.Document.All.GetElementsByName("j_username");
x[0].InnerText = "xxxxx";
var y = webBrowser1.Document.All.GetElementsByName("j_password");
y[0].InnerText = "xxxxxxxx";
//This part is not working....
var s = webBrowser1.Document.GetElementById("formButtonGreen");
s[0].InvokeMember("click");
Any one got any ideas?
Please note: I don't own the website so can't make changes to code behind webpage...
Thanks,
David
You should try using .Document.Body.GetElementsByTagName("input") which should help you get the button element and later you can use InvokeMember("click") on that element.
This will return a collection of matching elements, so if there are more than one you will have to identify it from the attributes by looping over it and then trigger for the one you need.
Instead of clicking the button, just submit the form itself.
jQuery wise, this is:
$("#my_form").submit();
Or you coulkd use any other means to select that Form. By class, parent element, tag name, ...