Image as a submit button - asp.net-mvc

I'm changing the buttons to images which are used for OAuth (see oauth2 tutorial).
I'm also grayscaling those images, and for this I use this code.
This is my _ExternalLoginsPartial.cshtml:
#{
var loginProviders = Context.GetOwinContext().Authentication.GetExternalAuthenticationTypes();
string action = Model.Action;
string returnUrl = Model.ReturnUrl;
using (Html.BeginForm(action, "Account", new { ReturnUrl = returnUrl }))
{
#Html.AntiForgeryToken()
foreach (AuthenticationDescription p in loginProviders)
{
<ul class="imglist" id="socialLogin">
#if (p.AuthenticationType == "Google")
{
<li><img src="/Content/google.png" /></li>
<li><img src="/Content/google.png" /></li>
<li><img src="/Content/google.png" /></li>
}
#if (p.AuthenticationType == "Microsoft")
{
<li><img src="/Content/outlook.jpg" /></li>
}
#if (p.AuthenticationType == "Facebook")
{
<li><img src="/Content/facebook.png" /></li>
}
</ul>
}
}
}
I can't remove the <a href="#"> because that will break the grayscaling.
And I can't place a button tag inside it, because that is bad HTML (compiler complains about it if done so).
So how can I turn these images to act like a submit button?
EDIT:
http://i61.tinypic.com/2ns7t00.png

You can replace the anchor element with a button element but you will have to change the code a little:
<button type="submit"><img src="..."></button>
Then change the selectors in the code:
$(window).load(function() {
$('button img').each(function() {
...
});
$(document).ready(function() {
$("button").hover(
...
);
});
If you want to get rid of the button styles, just use css:
button {
padding: 0;
border: none;
}

You could submit the form with Javascript by clicking on a link:
using (Html.BeginForm(action, "Account", new { ReturnUrl = returnUrl, id = "myId" }))
{
<a href="#" onclick="document.getElementById('myId').submit();">
<img src="/Content/facebook.png" />
</a>
}
This is just sample code for how you could add an id to the form and add a click event on the link.

You can do something like <input type="image" src="submit.gif"> which will submit your page within the form tag. An alternative would be to use jQuery and create a click event for the image.

As you specified in a response to another question, you wanted to return a value as well you could do this instead: (based off of Kevin's Answer)
using (Html.BeginForm(action, "Account", new { ReturnUrl = returnUrl, id = "myId" }))
{
<a href="#" onclick="document.getElementById('#p.AuthenticationType').click();">
<img src="/Content/facebook.png" />
</a>
<input name ="provider" type="submit" style="display:none;" id="#p.AuthenticationType" value="#p.AuthenticationType" />
}

Related

I want to use Url.Action with Knockout

I am new to knockout and I am having trouble getting the syntax right when using it with MVC markup.
For example this code here;
<a href="text.Answer" target="_blank">
<span style="display:inline-block">
<img src="#Url.Action("GetPhotoThumbnail", new { path = text.Answer, width = 120, height = 80 })" alt="Property Image" style="margin-top: 5px;" />
</span>
</a>
EDIT
So "Answer" is in the ViewModel and in knockout you would type data-bind="text:Answer" but here I have put in 2 places text.Answer. How do I replace text.Answer in the above code with the correct Knockout markup?
I know the above code will not work but this is a simplified way of showing the problem. I want to data-bind to text.Answer. What is the correct syntax for doing that?
If I understood you correctly that your text.Answer is something bind in client side.
You can't mix #Url.Action with client side variables
Try creating your URL like this
"#Url.Action("GetPhotoThumbnail")?path="+variable1+"&width="+variable2+"&height=" +variable3
You could pass the values you need into the ViewModel.
<div id="test">
<a href="#" data-bind="attr: { href: href }" target="_blank">
<span style="display:inline-block">
<img src="" data-bind="attr: { src: imageUrl }" alt="Property Image" style="margin-top: 5px;" />
</span>
</a>
</div>
<script type="text/javascript">
function MyViewModel(defaultValues) {
this.href = defaultValues.href;
this.imageUrl = defaltValues.imageUrl
}
var viewModel = new MyViewModel({
imageUrl: '#Url.Action("GetPhotoThumbnail", new { path = text.Answer, width = 120, height = 80 })',
href: '#Url.Action("Test")'
});
ko.applyBindings(viewModel, document.getElementById('test'));
</script>
I'm guessing you've got a view model binded to this part of the DOM, so you should be able to use the data-bind attribute and the attr binding to achieve the following:
<a href="" data-bind="attr : { href: text.Answer } " target="_blank">
<span style="display:inline-block">
<img src="#Url.Action("GetPhotoThumbnail", new { path = text.Answer, width = 120, height = 80 })" alt="Property Image" style="margin-top: 5px;" />
</span>
</a>
See http://knockoutjs.com/documentation/attr-binding.html for more details on this binding.
Also you'll need to make the view model generate you the img[src] attribute value so try something like:
<img data-bind="attr:{ src: text.answerImgSrc() } " alt="Property Image" style="margin-top: 5px;" />

MVC foreach set item.ID to model.ID

I have a form that shows all the available hotel rooms, each room has a button that does a HttpPost if clicked, I have made a property in the BookingViewModel called 'RoomID'. I would like to assign the item.RoomID to Model.RoomID so I can use it in my controller to get the id from the selected room but i'm not sure how to achieve this.
ChooseRoom View
#foreach (var item in Model.AvailableRooms)
{
<li class="room-item clearfix">
<h5>#item.Name</h5>
<div class="room-list-left">
<img src="#item.Image" alt="" />
</div>
<div class="room-list-right">
<div class="room-meta">
<ul>
<li><span>Occupancy:</span> #item.Adults Adults #item.Childs Children</li>
#if (item.SmokingRoom)
{
<li><span>Smoking Allowed:</span> Yes</li>
}
else
{
<li><span>Smoking Allowed:</span> No</li>
}
</ul>
</div>
<div class="room-price">
<p class="price">From: <span>$#item.Price</span> / Night</p>
</div>
<div class="clearboth"></div>
#using (Html.BeginForm("chooseroom", "booking", FormMethod.Post))
{
<input class="button2" type="submit" value="Select Room" />
}
BookingController
[HttpPost]
public ActionResult ChooseRoom(BookingViewModel vm)
{
BookingViewModel bookingObj = GetBooking();
bookingObj.SelectedRoom = Repository.GetRoomByID(vm.RoomID);
return View("reservation", bookingObj);
}
Thank you for your time!
update your begin form as below
#using (Html.BeginForm("chooseroom", "booking", FormMethod.Post))
{
<input type="hidden" name="RoomId" value="#item.RoomID" />
<input class="button2" type="submit" value="Select Room" />
}
Just need to provide input tags having the same name as your ViewModel property.
You could add inputs in foreach loop , it should be inside form. Something like this <input name="Model.AvailableRooms[index].RoomID" value="Id Here"/>
Or if you want to select one Room you should use ajax and post id.
If I'm not wrong you form is in loop,so you could add hidden input with id
#Html.HiddenFor(c => c.AvailableRooms[index].RoomID)

Ajax.BeginForm works first time, but calls method twice from second call

Ajax.BeginForm works first time, but calls method twice from second call.. I have referenced all the required scripts.
Firstly, In my main view, I have a common div for two partail views and I am loading respective views based on a radio button selection.
My Select Partial View
<div>
#using (Ajax.BeginForm("GetRandomThirdPartyList", "RandomList", new AjaxOptions { UpdateTargetId = "Contractors" }, new { id = "FORM" }))
{
<div id="Contractors">
<div id="ThirdParty">
<br />
<h3>Third Party Contractors</h3><hr />
<div>Enter High Risk Percentage: #(Html.Kendo().TextBoxFor<int?>(model => model.HighThirdPercent)
.HtmlAttributes(new { style = "width: 50px; height:25px" })
)
</div>
<input type="submit" value="Generate Report" class="k-button btn-primary" id="btn_thirdpaty" />
#* <b>#Html.DisplayFor(model => model.TotHighRisk) HighRisk Employees / #(Html.DisplayFor(model => model.TotLowRisk)) LowRisk Employees</b>*#
</div>
<br />
<div id="ThirdPartytab">
<div id="ReportForm" class="k-content">
<ul id="tabstrip2" class="nav nav-tabs" role="tablist">
<li class="active">HighRisk Third Party Contractors</li>
#* <li style="float:right"><img src="~/Images/icon_ssrs.png" title="Export to SSRS" /></li>*#
</ul>
#*Tab Content Containers*#
<div class="tab-content">
#if (Model.ThirdParty != null)
{
<div class="tab-pane fade in active" id="ThirdPartytab"> #Html.Partial("ThirdParty", Model) </div>
}
</div>
</div>
</div>
</div>
}
My Controller :
int tphigh = 0;
// GET: /RandomList/
[HttpPost]
public ActionResult GetRandomThirdPartyList(VM.RandomList random)
{
// tphigh=Convert.ToInt32(random.HighThirdPercent);
if (random.HighThirdPercent != null)
{
tphigh = Convert.ToInt32(random.HighThirdPercent);
// RedirectToAction("HighRiskCOPL", high);
}
List<VM.RiskList> risklist = (List<VM.RiskList>)AutoMapDomainModel<List<VM.RiskList>>(randomDBentity.GetRandomList(0, 0, tphigh,null));
mainlist.HighThirdPercent = tphigh;
mainlist.ThirdParty = //some list as third party is a Ienumerable
return PartialView("ThirdPartyContractors",mainlist);
}
The form posts properly first time, but from second time, it calls all the code lines in the action method tiwce, sometimes in a haphazard order and finally either populates the grid, or doesnt send any result.
Solved it.. My updatetargetid div was not the parent div..
replaced that..

Foreach not updating HTML list elements

Using knockout 2.2.0
I'm trying to use the same dialog for add and edit. I have the code mostly working, but when I replace the observable with the new edited one, it doesn't cause an update in the foreach (or at least it continues to display the old values) It does update the actual model, as I can see in dev tools. I even tried to force an update with .valueHasMutated(), but with no luck.
self.editReference = function () {
self.isEdit(true);
self.open();
self.dialogReferences(this);
};
self.saveEditReference = function () {
self.references.replace(this, self.dialogReferences);
self.references.valueHasMutated();
self.dialogReferences(newReferences());
self.close();
};
And here is the some of the partial view with the references section of HTML code:
<ul class="sortable references-summary" data-bind="foreach: references">
<li class="ui-state-default"><b>Name: </b><!-- ko text:name --><!-- /ko--><br /><b>Company: </b><!-- ko text:company --><!-- /ko--><span class="ui-icon ui-icon-closethick"></span><span class="ui-icon ui-icon-wrench"></span></li>
</ul>
Thanks to CrimsonChris for pointing out my bug. The updated code below works as expected.
The approach is to have a reference you are editing, in addition to the references in your array. When you start to edit, you copy the values from the array to your edit reference. When you save the edit, you copy them back. There is no need for valueHasMutated for this to work.
function reference(name, company) {
return {
name: ko.observable(name),
company: ko.observable(company)
};
}
// Copy r1 into r2
reference.copy = function(r1, r2) {
r2.name(r1.name());
r2.company(r1.company());
}
var self = {
editingReference: undefined,
dialogReferences: reference('', ''),
references: ko.observableArray([
reference('One', 'First Company'),
reference('Two', '2nd Company')
]),
dialogIsOpen: ko.observable(false),
open: function() {
self.dialogIsOpen(true);
},
close: function() {
self.dialogIsOpen(false);
}
};
self.editReference = function(item) {
self.editingReference = item;
self.open();
reference.copy(item, self.dialogReferences);
};
self.removeReference = function(item) {
self.references.remove(item);
self.close();
};
self.saveEditReference = function(item) {
reference.copy(item, self.editingReference);
self.close();
};
ko.applyBindings(self);
<link href="//code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.2.0/knockout-min.js"></script>
<ul class="sortable references-summary" data-bind="foreach: references">
<li class="ui-state-default"> <b>Name: </b>
<!-- ko text:name() -->
<!-- /ko-->
<br /> <b>Company: </b>
<!-- ko text:company() -->
<!-- /ko--> <span class="ui-icon ui-icon-closethick"></span>
<span class="ui-icon ui-icon-wrench"></span>
</li>
</ul>
<div data-bind="if: dialogIsOpen">
<div data-bind="with:dialogReferences">
<label>Name</label>
<input data-bind="value:name" />
<br/>
<label>Company</label>
<input data-bind="value:company" />
<input type="button" value="Save" data-bind="click: $parent.saveEditReference" />
</div>
</div>

Form action not hitting MVC controller method

I want to do a simple file upload using Html forms. I have the following in my view:
<form action='#Url.Action("Save", "Order")' method="post" enctype="multipart/form-data" id="attachmentForm">
<div >
<label style="text-align: left;">Delivery note:</label>
</div>
<div style="float:left; ">
<input type="file" name="DeliveryNoteFile" id="DeliveryNote" style="width: 400px;" />
</div>
<div style="float:right; margin-top:10px; margin-left:5px; margin-bottom:0px;">
#(Html.Kendo().Button()
.Name("btnAddAttachment")
.HtmlAttributes( new {type = "submit"} )
.Content("Submit"))
</div>
</form>
Now here is my controller method. Controller name: Order , Method name: Save.
Why is it not hitting my controller method?
[HttpPost]
public ActionResult Save(HttpPostedFileBase file)
{
if (file != null)
{
var fileName = Path.GetFileName(file.FileName);
var physicalPath = Path.Combine(Server.MapPath("C:\\Attachments"), fileName);
file.SaveAs(physicalPath);
}
return Content("");
}
Note that this is only a first draft. Any suggestions to improve this are also welcome.
I think in your case your button is not of type submit that is why it is not hitting controller action just try making submit button this way:
#(Html.Kendo().Button()
.Name("btnAddAttachment")
.HtmlAttributes( new {type = "submit"} )
.Content("Submit"))
as # AbbasGaliyakot comment worked for the user in comment section so i m also including it here.
Change controller action parameter name from file to DeliveryNoteFile.
Please try this out. This would help.
#using (Html.BeginForm("Save", "Order", FormMethod.Post, new { enctype = "multipart/form-data", id = "attachmentForm" }))
{
<div >
<label style="text-align: left;">Delivery note:</label>
</div>
<div style="float:left; ">
<input type="file" name="DeliveryNoteFile" id="DeliveryNote" style="width: 400px;" />
</div>
<div style="float:right; margin-top:10px; margin-left:5px; margin-bottom:0px;">
#(Html.Kendo().Button()
.Name("btnAddAttachment")
.HtmlAttributes( new {type = "submit"} )
.Content("Submit"))
</div>
}
And in JS you need to bind the click function of your submit button like shown below:
$('#btnAddAttachment').bind('click', function () {
$('#attachmentForm').submit();
});
Thanks!

Resources