Running into issues trying to update list options in a select. When Function One button is clicked, it fires functionTwo which returns a new list, that should now be the updated list shown in the <select>/<option>
Can someone educate me on what I am not getting correct?
<button ... #onclick="functionOne">Function One</button>
<select #bind="#SelectedValue">
#foreach (var val in updatedList)
{
<option value="#val">#val</option>
}
</select>
public void functionOne()
{
...
List<string> updatedList ...
updatedList = functionTwo();
...
}
public List<string> functionTwo()
{
...
return strList ;
}
Copy this into index.razor of blazor see if it works
#page "/"
<p>#SelectedValue</p>
<button #onclick="functionOne">Function One</button>
<select #bind="#SelectedValue">
#foreach (var val in updatedList)
{
<option value="#val">#val</option>
}
</select>
#code
{
string SelectedValue { get; set; }
List<string> updatedList = new List<string>();
private void functionOne()
{
updatedList = functionTwo();
}
public List<string> functionTwo()
{
return new List<string> { "AAA", "BBB", "CCC" };
}
}
Related
I am a newbie to spring boot and thymeleaf,
I have a list of books ina table with checkboxes, I am not sure how to pass selected booksId s from the view to the controller and use them by the borrow or Return bttons? could you please help?
Here is my Html file https://wtools.io/paste-code/b5g4
and this is the relevant part from my bookService implementation :
public void borrowBook(String userEmail, String bookIds, Model model) {
if (!CollectionUtils.isEmpty(books)) {
User user = userRepository.findByEmail(userEmail);
List<String> requestedBooks = getRequestedBookIds(bookIds);
List<Book> borrowedBooks = new ArrayList<>();
List<Book> invalidBooks = new ArrayList<>();
for (Book book : books) {
if (requestedBooks.contains(book.getId()) && !book.isBorrowed() && user != null) {
book.setBorrowed(true);
book.setBorrowedBy(user.getFirstName());
borrowedBooks.add(book);
model.addAttribute("bookStatus", "Book BOrrowed By " + user.getFirstName());
} else {
invalidBooks.add(book);
model.addAttribute("bookStatus", "No Books are available");
}
}
model.addAttribute("inValidBooks", invalidBooks);
model.addAttribute("bookList", borrowedBooks);
}
}
#SuppressWarnings("unchecked")
private List<String> getRequestedBookIds(String bookIds) {
List<String> requestedBookIds = null;
try {
requestedBookIds = new ObjectMapper().readValue(bookIds, ArrayList.class);
} catch (Exception e) {
e.printStackTrace();
}
return !CollectionUtils.isEmpty(requestedBookIds) ? requestedBookIds : new ArrayList<>();
}
and this is from the controller:
#GetMapping(value = "/available", produces = MediaType.APPLICATION_JSON_VALUE)
public String getAvailableFreeBooks(Model model) {
List<Book> availableBooks= bookService.getAllAvailaBooks();
model.addAttribute("listBooks", availableBooks);
return "available_books";
}
In your html you would probably:
<input type="checkbox" th:field="*{requestedBooks}" value="${book.getId}">
omit the id (if you don't need it).
use th:field (instead of name).
set value to the id of the current book.
In your controller: requestedBooks (#ModelAttribute("requestedBooks") List<String> requestedBooks) will (should) contain all checked book ids.
Ref: https://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#checkbox-fields
A sample repository:
https://github.com/xerx593/soq67602860
Uppdate:
To process the checkboxes client-sided (jquery),
you can obtain an array of ids like:
<script language="javascript" type="text/javascript">
$(document).ready(function () {
$("#btnBorrow").click(function() {
var reqBookIds = new Array();
$('input[name="requestedBooks"]:checked').each(function() {
reqBookIds .push(this.value);
});
alert("Number of selected Books: "+reqBookIds .length+"\n"+"And, they are: "+reqBookIds);
// do stuff with reqBookIds ...
)};
});
</script>
With the mentioned <input type="checkbox" .../> (consider that <input/> should be inside a <form/>!!) and a button like:
<button id="btnBorrow">Borrow</button>
..the userEmail must come from client side???
Hi im making a reservation page in razor pages asp.net. On my page I have two drop downlist. One for the location other for the rooms of that specific location. I want to pass the value of that selected location to the function which shows the rooms (function is named showRoom()), so that the rooms will be shown depending on which location you selected. How do i do that with html? I tried something but didnt really work. Here is the html code
<td>Select location</td>
<div class="form-group">
<select id="locations" name="Location">
#foreach(var reservations in #Model.PopulateReservations())
{
<option>#Html.DisplayFor(m => reservations.LocationName)</option>
}
</select>
</div>
<td>Select Room</td>
<div class="form-group">
<select id="rooms" name="Room">
#foreach(var reservations in #Model.ShowRoom(string LocationName))
{
<option>#Html.DisplayFor(m => reservations.RoomName)</option>
}
</select>
</div>
Here is the function showRoom
public List<WorkspaceModel> ShowRoom(string loc)
{
var cs = Database.Database.Connector();
List<WorkspaceModel> res = new List<WorkspaceModel>();
using var con = new NpgsqlConnection(cs);
{
string query = "Select room FROM workspaces WHERE location = '"+ loc +"'";
using NpgsqlCommand cmd = new NpgsqlCommand(query, con);
{
cmd.Connection = con;
con.Open();
using (NpgsqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
res.Add(new WorkspaceModel { RoomName = dr["room"].ToString() });
}
}
con.Close();
}
}
Here is a demo(I use fake data to test):
class:
public class PopulateReservation
{
public string LocationName { get; set; }
}
public class WorkspaceModel
{
public string RoomName { get; set; }
}
TestDropDown.cshtml:
<td>Select location</td>
<div class="form-group">
<select id="locations" name="Location">
#foreach (var reservations in #Model.PopulateReservations)
{
<option>#Html.DisplayFor(m => reservations.LocationName)</option>
}
</select>
</div>
<td>Select Room</td>
<div class="form-group">
<select id="rooms" name="Room">
#foreach (var reservations in #Model.Rooms)
{
<option>#Html.DisplayFor(m => reservations.RoomName)</option>
}
</select>
</div>
<form>
#Html.AntiForgeryToken()
</form>
#section scripts{
<script>
$('#locations').on('change', function () {
var arr = [];
$.ajax({
type: "POST",
url: '?handler=ShowRoom',
headers: {
RequestVerificationToken: $('input:hidden[name="__RequestVerificationToken"]').val()
},
data: { "loc": $("#locations").val() },
dataType:"json"
}).done(function (data) {
$("#rooms").empty();
$.each(data, function (i, item) {
$("#rooms").append('<option> ' + item["roomName"] + ' </option>');
});
});
});
</script>
}
TestDropDown.cshtml.cs:
public class TestDropDownModel : PageModel
{
[BindProperty]
public List<PopulateReservation> PopulateReservations { get; set; }
[BindProperty]
public List<WorkspaceModel> Rooms { get; set; }
public IActionResult OnGet()
{
PopulateReservations = new List<PopulateReservation> {
new PopulateReservation { LocationName = "location1" },
new PopulateReservation { LocationName = "location2" },
new PopulateReservation { LocationName = "location3" }
};
Rooms = new List<WorkspaceModel> {
new WorkspaceModel { RoomName = "Room1" },
new WorkspaceModel { RoomName = "Room2" },
new WorkspaceModel { RoomName = "Room3" },
};
return Page();
}
public IActionResult OnPost()
{
return Page();
}
public IActionResult OnPostShowRoom(string loc)
{
List<WorkspaceModel> l= new List<WorkspaceModel> {
new WorkspaceModel { RoomName = loc + "Room1" },
new WorkspaceModel { RoomName = loc + "Room2" },
new WorkspaceModel { RoomName = loc + "Room3" },
};
return new JsonResult(l);
}
}
result:
I'm new using Apache Wicket. I'm creating a panel to add articles on a web site. My panel to edit an article is formed with a TabbedPanel: the first tab is to edit and the second tab is to preview the article.
If after I entered some text in the editor (textarea), I switch to the preview and go back to the editor, le textarea is empty.
Here a part of the code for the panel with the TabbedPanel:
public AddArticlePanel(String id, ArticleEdit articleEdit) {
super(id);
final List<AbstractTab> tabList = new ArrayList<>();
tabList.add(new AbstractTab(new Model<String>("Editor")) {
#Override
public WebMarkupContainer getPanel(String panelId) {
return new ArticleEditorPanel(panelId, articleEdit);
}
});
tabList.add(new AbstractTab(new Model<String>("Preview")) {
#Override
public WebMarkupContainer getPanel(String panelId) {
return new ArticlePreviewPanel(panelId, articleEdit);
}
});
tabs = new TabbedPanel<AbstractTab>("tabs", tabList);
final SubmitLink submitButton = new SubmitLink("submit") {
#Override
public void onSubmit() {
// TODO
}
};
addArticleForm = new Form<ArticleEdit>("add-article-form", new Model<ArticleEdit>(articleEdit));
addArticleForm.add(tabs);
addArticleForm.add(submitButton);
add(addArticleForm);
}
Here the HTML for the editor panel:
<wicket:panel>
<div wicket:id="feedback"></div>
<div class="fields">
<label for="title">Title</label>
<input type="text" name="title" wicket:id="title">
</div>
<div class="fields">
<label for="text">Text</label>
<textarea class="notab" name="text" wicket:id="text"></textarea>
</div>
<div class="fields">
<label for="keywords">Keywords</label>
<input type="text" name="keywords" wicket:id="keywords">
</div>
</wicket:panel>
The code for this editor panel:
public ArticleEditorPanel(String id, ArticleEdit articleEdit) {
super(id);
final FeedbackPanel feedbackPanel = new FeedbackPanel("feedback");
title = new TextField<String>("title", new PropertyModel<String>(articleEdit, "title"));
title.setRequired(true);
text = new TextArea<String>("text", new PropertyModel<String>(articleEdit, "text"));
text.setRequired(true);
keywords = new TextField<String>("keywords", new PropertyModel<String>(articleEdit, "keywords"));
keywords.setRequired(true);
add(title);
add(text);
add(keywords);
add(feedbackPanel);
}
Finally, the source code of the ArticleEdit class:
public class ArticleEdit implements Serializable {
private String title;
private String text;
private String keywords;
private String preview;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getKeywords() {
return keywords;
}
public void setKeywords(String keywords) {
this.keywords = keywords;
}
public String getPreview() {
return preview;
}
public void setPreview(String preview) {
this.preview = preview;
}
}
Why it doesn't work out of the box ? Where is my mistake ?
Thank you for your help.
You do not save the state from your EDIT tab before navigating to the PREVIEW tab.
By clicking the "Preview" link the browser will make a new request to the server and Wicket will re-render the whole page, so any data entered in the form fields will be lost.
You can easily save the data by adding AjaxFormComponentUpdatingBehavior to the form fields. For example for the title field:
title = new TextField<String>("title", new PropertyModel<String>(articleEdit, "title"));
title.setRequired(true);
title.add(new AjaxFormComponentUpdatingBehavior("change") {
#Override public void onUpdate(AjaxRequestTarget target) {}
#Override public void onError(AjaxRequestTarget target) {
target.add(feedbackPanel);
}
});
I am having trouble getting the value selected in my dropdownlist in my Homecontroller. I have the DropDownList in a form but I think my format may be wrong. I'm new to MVC and new to HTML so I'm struggling pretty hard. Would appreciate some help.
Here is my controller (I put this in my homecontroller, is that a bad idea?):
public IActionResult Index()
{
_ = new List<MyjsonSettings>();
var obj = new StatusPortController(configuration);
List<MyjsonSettings> PortList = obj.GetPortNum();
List<SelectListItem> AppNameList = PopulateDropDown(PortList);
ViewData["Applications"] = AppNameList;
return View("~/Views/Home/dataview.cshtml");
}
public List<SelectListItem> PopulateDropDown(List<MyjsonSettings> PortList)
{
List<SelectListItem> AppNameList = new List<SelectListItem>();
for (int i = 0; i < PortList.Count(); i++)
{
AppNameList.Add(new SelectListItem {
Text = PortList[i].NAME, Value = (i+1).ToString()
});
}
return AppNameList;
}
Here is the view (dataview.cshtml):
#{
ViewData["Title"] = "Home Page";
}
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
#Html.DropDownList("Applications", ViewData["AppNameList"] as List<SelectListItem>)
<input type="submit" value="submit" />
}
Any ideas? No errors when I run, I just don't know how to get the response back.
you can rebuild the structure to a more usable way, and in order to submit form with drop down list or any type of fields you need to first return a view with Model and then submit the form to an action that receive same Model type as parameter
example:
model:
public class ApplicationsAddModel {
public ApplicationsAddModel (){
//constructer to initialize the list
ApplicationsList = new List<SelectListItem>();
}
public string test{ get; set; }
public int selectedApplicationId { get; set; }
public List<SelectListItem> ApplicationsList { get; set; }
}
controller
//this is the first action that return the model
[HttpGet]
public IActionResult Index()
{
ApplicationsAddModel model = new ApplicationsAddModel ();
//fill your drop down list
List<SelectListItem> AppNameList = PopulateDropDown(PortList);
model.ApplicationsList = AppNameList;
return View(model);
}
[HttpPost] //recive the form
public IActionResult Index(ApplicationsAddModel SubmittedModel)
{
var selectedApplication = SubmittedModel.selectedApplicationId; //get the selected value from ddl
//fill your drop down list
List<SelectListItem> AppNameList = PopulateDropDown(PortList);
model.ApplicationsList = AppNameList;
return View(SubmittedModel);
}
view (index.cshtml):
#model projectName.ApplicationsAddModel
#{ ViewData["Title"] = "Home Page"; }
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
#Html.LabelFor(m => m.selectedApplicationId)
#Html.DropDownListFor(m => m.selectedApplicationId, Model.ApplicationsList, "---", new { #class = "custom-select form-control" })
<input type="submit" value="submit" />
}
summary:
in MVC when you have to submit data to controller, create your model, go to controller and create your first action (GET) which fill the form with initial data and fill your drop down lists if exist, then create the (POST) action which receive the model of same type of the view and MVC will bind it automatically for you
best regards
I'm trying to group together radiobuttons that are creating using a for loop and Razor syntax. Here is the code:
#for (var i = 0; i < Model.Sessions.Count(); i++)
{
#Html.HiddenFor(it => it.Sessions[i].Id)
#Html.RadioButtonFor(it => it.Sessions[i].Checkbox, "0", new {#class = "Sessions", #id = id, #name="Sessions"})
#Html.LabelFor(it => it.Sessions[i].Name, Model.Sessions[i].Name)
<span class="time-span"><em>#Model.Sessions[i].StartTime</em><em>#Model.Sessions[i].EndTime</em></span>
<br />
}
The third line inside the for loop is where the problem is. Basically the name doesn't change and it's always "Sessions[x].Checkbox". The checkbox is a property (bool) of a custom class. I can't seem to get the hang of debugging Razor stuff, so any help would be greatly appreciated, I'm guessing this will be extremely obvious to someone here.
EDIT
Dimitrov's post helped a lot. Below is the final code I used. I use the #class and #id attributes to be able to use Javascript to select the session originally picked (since this is an edit, not create form).
#for (var i = 0; i < Model.Sessions.Count(); i++)
{
#Html.HiddenFor(it => it.Sessions[i].Id)
var SId = #Model.Sessions[i].Id;
#Html.RadioButtonFor(it => it.selectedSession, Model.Sessions[i].Id, new { id = SId, #class = "Sessions" })
#Html.LabelFor(it => it.Sessions[i].Name, Model.Sessions[i].Name)
<span class="time-span"><em>#Model.Sessions[i].StartTime</em><em>#Model.Sessions[i].EndTime</em></span>
<br />
}
If you want to be able to select only a single radio button you need to have a single property on your view model to hold the selected session id, like this:
public class SessionViewModel
{
public int SelectedSessionId { get; set; }
public IList<Session> Sessions { get; set; }
}
public class Session
{
public int Id { get; set; }
public string Name { get; set; }
}
and then have a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new SessionViewModel
{
SelectedSessionId = 2,
Sessions = Enumerable.Range(1, 5).Select(x => new Session
{
Id = x,
Name = "session" + x,
}).ToList()
};
return View(model);
}
[HttpPost]
public ActionResult Index(SessionViewModel model)
{
return Content("Thank you for selecting session id: " + model.SelectedSessionId);
}
}
and finally a view:
#model SessionViewModel
#using (Html.BeginForm())
{
for (var i = 0; i < Model.Sessions.Count(); i++)
{
#Html.HiddenFor(x => x.Sessions[i].Id)
#Html.RadioButtonFor(x => x.SelectedSessionId, Model.Sessions[i].Id, new { id = "session_" + i })
#Html.Label("session_" + i, Model.Sessions[i].Name)
<br/>
}
<button type="submit">OK</button>
}