Render Bootstrap dropdown menu with c# html dropdown list helper - c#

I have created a search input for my website that is attached to a dropdown menu. But I need to populate the items in the dropdown menu with items from a html helper select list which is essential for the search function. Is it possible to render the items of the search list in a bootstrap dropdown menu that is posted to a controller?
HTML Search Function
<div class="col-lg-6">
#{using (Html.BeginForm("Results", "Searchv2", FormMethod.Get)) {
<div class="input-group">
<div class="input-group-btn">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">Action <span class="caret"></span></button>
<ul class="dropdown-menu">
#Html.DropDownList("Searchby", new SelectList(new[] { "User", "Restaurant", "Cuisine" }))
</ul>
</div>
<input type="text" class="form-control" placeholder="Search" name="SearchString" id="SearchString">
</div>
}}
</div>

Use the conventional hyperlink tags in the bootstrap dropdown-menu:
<ul class="dropdown-menu">
#foreach (var searchType in new[] { "User", "Restaurant", "Cuisine" })
{
<li>#searchType</li>
}
</ul>
Then use JQuery to set a hidden input value when these hyperlinks are selected:
<input type="hidden" name="SearchBy" />
<script>
$(".dropdown-menu a").click(function() {
$("input[name='SearchBy']").val($(this).html());
});
</script>

Related

Problem with saving value with the input type number to the chosen field to the database by C# in ASP .NET MVC

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.

jQuery: Can I select an element by name and read it's id when I have multiple elements with the same name, but unique id?

I have a list of buttons, each belonging to a hidden form with corresponding item.Id. I want to show the form when the button is clicked. To achieve this, I have a jQuery script which selects the button by name ($('[name="RequestSpeakButton"]')) and reads its id to know which hidden form to set to visible ($("#RequestSpeak"+this.id).css("visibility", "visible")).
But of course, it's not working. I.e. nothing happens when I click the buttons.
I don't know if it's of importance, but the document consists of a main view with several partial views. The script is located in the scripts section of the main view. The buttons are in a partial view and the forms in another partial view.
The forms are rendered like this (in a partial view):
#foreach (AgendaItemViewModel item in Model.Agenda)
{
<div id="RequestSpeak#(item.Id)" style="visibility:hidden;">
<form asp-action="Action">
<input type="hidden" name="Id" value="#item.Id" />
<button type="submit">
Yes
</button>
<span class="btn btn-danger" onclick="javascript: document.getElementById('RequestSpeak'+#item.Id).style.visibility='hidden'">
No
</span>
</form>
</div>
}
The output of the forms looks like this:
<div id="RequestSpeak57e33e17-c988-4a28-66a0-08d978345a1d" style="visibility:hidden;">
<form action="/Controller/Action" method="post">
<input type="hidden" name="Id" value="57e33e17-c988-4a28-66a0-08d978345a1d" />
<button type="submit">
Yes
</button>
<span class="btn btn-danger" onclick="javascript: document.getElementById('RequestSpeak'+57e33e17-c988-4a28-66a0-08d978345a1d).style.visibility='hidden'">
No
</span>
</form>
</div>
The buttons that are supposed to show a form is rendered like this (in another partial view):
#foreach (AgendaItemViewModel item in Model.Agenda)
{
<a name="RequestSpeakButton" id="#item.Id"
class="btn btn-primary">
Speak
</a>
}
And the output looks like this:
<a name="RequestSpeakButton" id="57e33e17-c988-4a28-66a0-08d978345a1d"
class="btn btn-primary">
Speak
</a>
This is the script for the buttons:
$(document).ready(function () {
$('[name="RequestSpeakButton"]').click(function () {
alert("test"); /* Checking if the script runs. It doesn't. */
$("#RequestSpeak"+this.id).css("visibility", "visible")
});
})
I would imagine that since I have many buttons with the same name, they all get selected by $('[name="RequestSpeakButton"]'). Can I know which one was clicked? Is this.Id enough?
Perhaps it would work if I dropped the name, and just selected the buttons by id. But I am going to add other buttons later, which is going to perform different operations on the items, so I need the name to know which operation to perform.
Try this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
</head>
<body>
<a name="RequestSpeakButton" id="57e33e17-c988-4a28-66a0-08d978345a1d"
class="btn btn-primary">
Speak1
</a>
<a name="RequestSpeakButton" id="57exxx7-cxx8-4x8-6xx0-08xxxxxxa1d"
class="btn btn-primary">
Speak2
</a>
<div id="RequestSpeak57e33e17-c988-4a28-66a0-08d978345a1d" style="visibility:hidden;">
<form action="/Controller/Action" method="post">
<input type="hidden" name="Id" value="57e33e17-c988-4a28-66a0-08d978345a1d" />
<button type="submit">
Yes
</button>
<span class="btn btn-danger" onclick="document.getElementById('RequestSpeak57e33e17-c988-4a28-66a0-08d978345a1d').style.visibility='hidden'">
No
</span>
</form>
</div>
<div id="RequestSpeak57exxx7-cxx8-4x8-6xx0-08xxxxxxa1d" style="visibility:hidden;">
<form action="/Controller/Action" method="post">
<input type="hidden" name="Id" value="57exxx7-cxx8-4x8-6xx0-08xxxxxxa1d" />
<button type="submit">
Yes
</button>
<span class="btn btn-danger" onclick="document.getElementById('RequestSpeak57exxx7-cxx8-4x8-6xx0-08xxxxxxa1d').style.visibility='hidden'">
No
</span>
</form>
</div>
<script>
$("[name='RequestSpeakButton']").click(function(){
var thisid = $(this).attr("id");
$("#RequestSpeak"+thisid).css("visibility", "visible")
})
</script>
</body>
</html>
Or maybe you prefer this?
#model WebApplication1.Models.TestModel
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
#foreach (AgendaItemViewModel item in Model.Agenda)
{
<div id="RequestSpeak#(item.Id)" style="visibility:hidden;">
<form asp-action="Action">
<input type="hidden" name="Id" value="#item.Id" />
<button type="submit">
Yes
</button>
<span class="btn btn-danger" name="noBtn">
No
</span>
</form>
</div>
}
#foreach (AgendaItemViewModel item in Model.Agenda)
{
<a name="RequestSpeakButton" id="#item.Id"
class="btn btn-primary">
Speak
</a>
}
<script>
$("[name='RequestSpeakButton']").click(function () {
var thisid = $(this).attr("id");
$("#RequestSpeak" + thisid).css("visibility", "visible")
})
$("[name='noBtn']").click(function () {
var thisid = $(this).parent().parent().css("visibility", "hidden");
})
</script>
document.getElementById('RequestSpeak'+57e33e17-c988-4a28-66a0-08d978345a1d)
is probably not what you want. That should probably even throw an error since it isn't a proper string. If you change it to all be within quotes like this, it should at least get you a step in the right direction:
document.getElementById('RequestSpeak57e33e17-c988-4a28-66a0-08d978345a1d')
To get that change your view template to be the item.id but in quotes.
document.getElementById('RequestSpeak'+'#item.Id')
and see if that does the trick.

Form does not submit when I click submit button of it C# & jQuery

I append my select option from database table. Select option has two type
scalar
event
If the option type is scalar, I need to show 2 input fields (alarm, reset) so that user can inset values in it and when the option type is event I need to hide 2 input fields (alarm, reset) so that user cannot inset values in it.
When the option type is scalar, my form saves successfully but when option type is event form submit button not going to perform any action.
Can you please help?
Here is my code
HTML
<div class="row">
<form method="post" action="/Home/SaveTriggers" class="form-inline">
<div class="col-md-12">
<div class="col-md-2">
<select name="sourceId" class="select2" required>
#foreach (var i in ViewBag.opt)
{
<option value="#i.Id,#i.name,#i.type" id="opt">#i.name</option>
}
</select>
</div>
<div class="col-md-2">
<input id="alarm" name="alarm" type="text" placeholder="alarm" style="display:none" required />
</div>
<div class="col-md-2">
<input id="reset" name="reset" type="text" placeholder="reset" style="display:none" required />
</div>
<div class="col-md-1">
<input type="text" name="delay" id="delay" placeholder="delay" required />
</div>
<div class="col-md-3">
<select class="address2" name="action" id="select" required>
<option selected disabled>Select alarm action</option>
<option>John Doe, Switch on warning light</option>
<option>John Doe</option>
<option>Do anything</option>
</select>
</div>
<div class="col-md-2">
<button id="delete2" type="button" class="btn btn-default">Delete</button>
</div>
<button class=" add btn btn-primary" type="submit">Add</button>
</div>
</form>
</div>
Jquery(as i have to hide or show alarm or reset fields respectively)
<script>
$(document).ready(function () {
$(".select2").change(function () {
var text = $(".select2 option:selected").text();
var val = $(".select2 option:selected").val();
var res = val.split(",");
var type = res[2];
if (type == "scalar") {
document.getElementById("reset").style.display = "block";
document.getElementById("alarm").style.display="block"
}
else if(type=="event") {
document.getElementById("reset").style.display = "none";
document.getElementById("alarm").style.display = "none"
var alarm = document.getElementById("alarm");
}
});
});
</script>
The problem is most likely your inputs for alarm and reset.
If type is event, they are hidden and will most likely hold no value. But since they are required, the form will not submit until that error is resolved.
So you can either remove the required attribute from those 2 input fields, populate them with default values or use novalidate in your form tag. This disables form validation. You'd have to validate your inputs by hand in javascript.
<div class="col-md-2">
<input id="alarm" name="alarm" type="text" placeholder="alarm" style="display:none" />
</div>
<div class="col-md-2">
<input id="reset" name="reset" type="text" placeholder="reset" style="display:none" />
</div>
<div class="col-md-2">
<input id="alarm" name="alarm" type="text" placeholder="alarm" style="display:none" required />
</div>
<div class="col-md-2">
<input id="reset" name="reset" type="text" placeholder="reset" style="display:none" required />
as you're having required attribute in your input element, the validation is getting triggered and not letting you submit the form.
i would suggest you to do a validation on jquery on submit instead of using default html5 validation

Setting the selected value of bootstrap dropdown button on postback in MVC view

I have built a bootstrap search with a dropdown button that allows selection of the search type, for example first name or last name. I have this mostly working and am able to pass the search type and string into my model without problem. The problem I have is that after the search button is clicked and the postback occurs the dropdown selector returns to its default setting, and I would like to display the search type that is placed back into the hiddenfield during postback.
The hidden field and the search string are populated on postback, but I'm unsure of the best method of setting the value of the dropdown.
<div class="row">
#using (Html.BeginForm())
{
<div class="input-group col-md-6 col-md-offset-3">
<div class="input-group-btn search-All-panel">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
<span id="search_All_concept">#SiteStrings.FilterBy</span> <span id="txt" class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>#SiteStrings.All</li>
<li>#SiteStrings.Level</li>
<li>UCI</li>
<li>#SiteStrings.FirstName</li>
<li>#SiteStrings.LastName</li>
</ul>
</div>
#Html.HiddenFor(s => s.search_All_param)
#*<input type="text" class="form-control" name="search_All_String" placeholder="Search term..." />*#
#Html.EditorFor(s => s.search_All_String, new { htmlAttributes = new { #class = "form-control", #placeholder = "Search for..." } })
<span class="input-group-btn">
<button class="btn btn-primary" type="submit"><span class="glyphicon glyphicon-search"></span></button>
</span>
</div>
}
</div>
Just use a ternary to apply the active class:
<li class="#(Model.search_All_param == SiteStrings.All ? "active" : null)">
#SiteStrings.All
</li>
Rinse and repeat for each of the items in the dropdown.
Guess there are better ways, but this gives me exactly what I need...
<div class="row">
#using (Html.BeginForm())
{
<div class="input-group col-md-6 col-md-offset-3">
<div class="input-group-btn search-All-panel">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
<span id="search_All_concept">
#{
switch(#Model.search_All_param)
{
case "level":
#SiteStrings.Level
break;
case "firstname":
#SiteStrings.FirstName
break;
case "lastname":
#SiteStrings.LastName
break;
default:
#SiteStrings.FilterBy
break;
}
}
</span> <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>#SiteStrings.All</li>
<li>#SiteStrings.Level</li>
<li>#SiteStrings.FirstName</li>
<li>#SiteStrings.LastName</li>
</ul>
</div>
#Html.HiddenFor(s => s.search_All_param)
#Html.EditorFor(s => s.search_All_String, new { htmlAttributes = new { #class = "form-control", #placeholder = "Search for..." } })
<span class="input-group-btn">
<button class="btn btn-primary" type="submit"><span class="glyphicon glyphicon-search"></span></button>
</span>
</div>
}
</div>

Templates C#/MVC 4/Razor

The goal
Create Shared UI Templates with C# + MVC 4 + Razor Engine.
The problem
I do not know how to do.
Details
I have the follow template:
<li>
<div class="introduction">
<h3>{productName}</h3>
</div>
<div class="presentation">
<img src="{productImage}" alt="" />
</div>
<div class="description">
<p>Starting by</p>
<h3>{minProductPrice}</h3>
<p class="product-unity">/a <span class="product-measure"
data-measure-shortcut="{productMeasureShortname">{productMeasureName}
</span></p>
</div>
<div class="controls">
<button class="button green add" title="Add to comparsion list">+</button>
<div class="tooltip-quantity">
<p class="float-left">Quantity:</p>
<form method="post" action="#">
<input class="quantity float-left" name="product_quantity"
maxlength="2" type="text" />
<span class="float-left">/{productMeasureName}(s)</span>
<button disabled class="button orange filled float-right">
Add
</button>
</form>
</div>
<button class="button light-blue filled compare float-right" title="This product is available in 6 stores">Compare</button>
</div>
</li>
and when I want to call it, I would to do something like this:
#Html.RenderMyTemplate("Product Name", "Product Image", "Min Product Price"...)
Logically, the parameters will replace the placeholders on the template.
Any idea?
Thanks in advance!
You can use partial view:
#Html.Partial("MyView", Model)
Basicaly it renders given file (MyView) using model (Model) as regular razor powered template.
In your case (I used string[] as Model, but you can use whatever you want e.g. IDictionary<string, string>):
#Html.Partial("MyView", new[] { "Product Name", "Product Image", "Min Product Price" })
In view:
#inherits System.Web.Mvc.WebViewPage<string[]>
<li>#Model[0]</li>
UPDATE (with dictionary)
#Html.Partial("MyView", new Dictionary<string, object> { { "name", "Product1"}, { "price", 100 } })
then
#inherits System.Web.Mvc.WebViewPage<Dictionary<string, object>>
<li>#Model["name"]</li>

Categories

Resources