How To show only one id in laravel - laravel-9

I found a problem when I wanna show my data's detail, it always take two data.
this is my controller
public function show(Transaction $transactions)
{
$tran=Transaction::find($transactions);
return $tran;
return view('admin.transaction.show', compact('tran','transactions'));
}
This is my show Button
<td>
<i class="far fa-eye" style="color:blue"></i>
</td>
and this is the return
How to solve it?

Related

Pass model subset on button click Mvc Core

i am looking to pass through a class from a model subset on button click, this is because i have a model that contains multiple lists of classes that correspond to different datatable. I want to be able to pass one of the classes to a controller on button click or form submit. Below is what i have am aiming for.
#foreach (var item in Model.PersonForm.Where(x => x.PersonType == Utils.PersonTypeEnum.PurchaseType.Owner))
{
<tr>
<th scope="row">#item.Id</th>
<td>#(item.PersonModel.Id)</td>
<td>#(item.PersonModel.Name)</td>
<td>Normal</td>
<td>#($"{item.PersonModel.DOB}")</td>
<td>
<button class="btn-success btn " onclick="location.href='#Url.Action("AcceptPersonJob", "PersonArea",item.PersonModel)'">Accept</button>
</td>
</tr>
}
The 405 error mainly casused by the Http method. The button send a get request, you can put a [HttpGet] attribute on your action. If this is not the case, please show us your controller action and your model.

Selecting specific element in vue 2 inside v-for loop

Please see the code
<div v-for="msg in leftMsg">
div v-if="msg.last_sender" #click.prevent="loadMsg(msg)">
<tr :class="['active',{ 'seens' : !msg.seen, 'selected':msg.isActive}]">
// some html
</tr>
</div>
</div>
loadMsg(obj){
obj.isActive = !obj.isActive;
}
The problem is, it is adding selected class properly but when I click another item it adds selected but doesn't remove the old one. How can I keep only the most recent clicked item selected?
Thank you.
Add a data property outside of the msg objects and use that to track the active message.
data(){
return {
activeMessage: null,
...
}
}
Then in your template, set the activeMessage.
<div v-for="msg in leftMsg">
<div v-if="msg.last_sender" #click.prevent="activeMessage = msg">
<tr :class="['active',{ 'seens' : !msg.seen, 'selected': msg === activeMessage}]">
// some html
</tr>
</div>
</div>
The key parts I changed here are #click.prevent="activeMessage = msg" and 'selected': msg === activeMessage. This will set activeMessage to the clicked message, and then the selected class will be applied to the activeMessage and will only apply to the activeMessage.
I would also note that it's strange that you have a tr element nested inside div. I assume it was just because of your example, but that's not technically valid HTML.
I have solved this issue using a for loop. I thought it may help some other.
In order to remove the all other previous active classes all you need to run a for loop and make them false and then assign active=true to the newest one.
Here is the code that may help
// make all other selected class false first
for(let i=0; i<this.leftMsg.length; i++){
this.leftMsg[i].isActive=false;
}
/*now making the newest one active*/
obj.isActive = true;

Display specific data with parameter using Stored Procedure

Hi I have error in regards with my displaying specific data. I passed a parameter through a model and I get error on regarding creating a new instance. here is my code:
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult ViewEmployeeSalary(spGetSalaryPerEmployee getsal)
{
var salary = _Context.Set<spGetSalaryPerEmployee>().FromSql("spGetSalaryPerEmployee #empID = {0}", getsal.EmployeeID).AsNoTracking();
return View(salary);
}
View
This the button where you click to redirect to the details page
#foreach(var item in Model)
{
a class="btn btn-primary btn-sm" asp-controller="Salary" asp-action="ViewEmployeeSalary" asp-route-id="#item.EmployeeId"><span class="glyphicon glyphicon-dashboard" style="vertical-align:middle;margin-top: -5px"></span> Salary Details</a>
}
Here is the page where it views the details
#model PEMCOLoan.DAL.Entities.spModels.spGetSalaryPerEmployee
#{
ViewBag.Title = "Salary Details";
}
<h2>#Html.DisplayFor(model => model.FullName)'s Salary Details</h2>
<table class="table">
<tr>
<td class="form-horizontal">ID:</td>
<td>#Html.DisplayTextFor(model => model.EmployeeID)</td>
</tr>
<tr>
<td class="form-horizontal">Salary Amount:</td>
<td>#Html.DisplayFor(model => model.Salary)</td>
</tr>
<tr>
<td class="form-horizontal">Remarks:</td>
<td>#Html.DisplayTextFor(model => model.Remarks)</td>
</tr>
</table>
I get this error:
I don't really what really happens but stated the I need to create an instance.
I have still a little knowledge about asp.net core and ef core and still studying for this language for now. I really need your help in regards with this since I'm a bit new with this language.
Any suggestion would be a greatly appreciated!
Your controller method needs to return single record as error states. Now it returns a list, so you need to change to something like this:
var salary = _Context.Set<spGetSalaryPerEmployee>().FromSql("spGetSalaryPerEmployee #empID = {0}", getsal.EmployeeID).AsNoTracking().SingleOrDefault();
//salary now is single record
return View(salary);
And maybe you need to check salary variable is not null before passing it to view, because then you'll have errors there.

Html.BeginForm in a partial view?

I have a block of code that uses the Html.BeginForm to submit a value from textbox to controller. When I put this in a View, it works fine. That is, the controller's action method is called. However, when I place this block of code inside a partial view that will get rendered in the View, the controller's action never gets called.
Not sure if this is the usual behavior or if I am missing something...
#using (Html.BeginForm("TestAction", "Home", FormMethod.Post, new { id = "formId" }))
{<table>
<tr>
<td>Data Date</td>
<td>#Html.TextBox("date")</td>
</tr>
<tr>
<td></td>
<td><input id="btnRun" type="submit" value="submit" /></td>
</tr>
}
Controller:
[HttpPost]
public ActionResult TestAction(string date)
{
[doing something......]
return View();
}
Thanks in advance!
Typically #Html.BeginForm() renders the <form> tag's action to point back to the route details that got it here. Thus in partial views, you're actually rendering back to the outer page. (Yeah, mind-bending.) If you want to specifically direct the form post to a particular route, add additional parameters to the #Html.BeginForm(). See http://msdn.microsoft.com/en-us/library/system.web.mvc.html.formextensions.beginform(v=vs.108).aspx

How can I select checkboxes using the Selenium Java WebDriver?

How can I check the checkboxes using an id or XPath expression? Is there a method similar to select by visibletext for a dropdown?
Going through the examples given for all other related questions, I could not find a proper solution that works in a concise way that by few line or method I can check a chekbox or radio button.
A sample HTML section is below:
<tbody>
<tr>
<td>
<span class="120927">
<input id="ctl00_CM_ctl01_chkOptions_0" type="checkbox" name="ctl00$CM$ctl01$chkOptions$0"/>
<label for="ctl00_CM_ctl01_chkOptions_0">housingmoves</label>
</span>
</td>
</tr>
<tr>
<td>
<span class="120928">
<input id="ctl00_CM_ctl01_chkOptions_1" type="checkbox" name="ctl00$CM$ctl01$chkOptions$1"/>
<label for="ctl00_CM_ctl01_chkOptions_1">Seaside & Country Homes</label>
</span>
</td>
</tr>
</tbody>
Selecting a checkbox is similar to clicking a button.
driver.findElement(By.id("idOfTheElement")).click();
will do.
However, you can also see whether the checkbox is already checked. The following snippet checks whether the checkbox is selected or not. If it is not selected, then it selects.
if ( !driver.findElement(By.id("idOfTheElement")).isSelected() )
{
driver.findElement(By.id("idOfTheElement")).click();
}
It appears that the Internet Explorer driver does not interact with everything in the same way the other drivers do and checkboxes is one of those cases.
The trick with checkboxes is to send the Space key instead of using a click (only needed on Internet Explorer), like so in C#:
if (driver.Capabilities.BrowserName.Equals(“internet explorer"))
driver.findElement(By.id("idOfTheElement").SendKeys(Keys.Space);
else
driver.findElement(By.id("idOfTheElement").Click();
If you want to click on all checkboxes at once, a method like this will do:
private void ClickAllCheckboxes()
{
foreach (IWebElement e in driver.FindElements(By.xpath("//input[#type='checkbox']")))
{
if(!e.Selected)
e.Click();
}
}
Solution for C#
try
{
IWebElement TargetElement = driver.FindElement(By.XPath(xPathVal));
if (!TargetElement.Selected)
{
TargetElement.SendKeys(Keys.Space);
}
}
catch (Exception e)
{
}
You can use the following code:
List<WebElement> checkbox = driver.findElements(By.name("vehicle"));
((WebElement) checkbox.get(0)).click();
My HTML code was as follows:
<.input type="checkbox" name="vehicle" value="Bike">I have a bike<br/>
<.input type="checkbox" name="vehicle" value="Car">I have a car<br/>
To get the checkbox for 'Seaside & Country Homes', use this XPath:
//label[text()='Seaside & Country Homes']/preceding-sibling::input[#type='checkbox']
To get the checkbox for 'housingmoves', use this XPath:
//label[text()='housingmoves']/preceding-sibling::input[#type='checkbox']
The principle here is to get the label with the text you want, then get the checkbox that is before the label, since that seems to be how your HTML is laid out.
To get all checkboxes, you would start a little higher up and then work down, so that is to say get the table, and then get any checkbox within a span:
//table/descendant::span/input[#type='checkbox']
I found that sometimes JavaScript doesn't allow me to click the checkbox because was working with the element by onchange event.
And that sentence helps me to allow the problem:
driver.findElement(By.xpath(".//*[#id='theID']")).sendKeys(Keys.SPACE);
This should help -
IWebElement elementToClick = driver.findElement(By.xpath(""//input[contains(#id, 'lstCategory_0')]"));
elementToClick.Click();
You can also pass an id.
If you want something like visible text you can "find element" by name if they have names.
The below code will first get all the checkboxes present on the page, and then deselect all the checked boxes.
List<WebElement> allCheckbox = driver.findElements(By
.xpath("//input[#type='checkbox']"));
for (WebElement ele : allCheckbox) {
if (ele.isSelected()) {
ele.click();
}
}
A solution using WebDriver and C# is below. The key idea is to get the ID of the checkbox from the labels' 'for' attribute, and use that to identify the checkbox.
The code will also set the checkbox state only if it needs to be changed.
public void SetCheckboxStatus(string value, bool toCheck)
{
// Get the label containing the checkbox state
IWebElement labelElement = this.Driver.FindElement(By.XPath(string.Format("//label[.='{0}']",value)));
string checkboxId = labelElement.GetAttribute("for");
IWebElement checkbox = this.Driver.FindElement(By.Id(checkboxId));
if (toCheck != checkbox.Selected)
{
checkbox.Click();
}
}
Maybe a good starting point:
isChecked = driver.findElement((By.id("idOftheElement"))).getAttribute("name");
if(!isChecked.contains("chkOptions$1"))
{
driver.FindElement(By.Id("idOfTheElement")).Click();
}
Running this approach will in fact toggle the checkbox; .isSelected() in Java/Selenium 2 apparently always returns false (at least with the Java, Selenium, and Firefox versions I tested it with).
The selection of the proper checkbox isn't where the problem lies -- rather, it is in distinguishing correctly the initial state to needlessly avoid reclicking an already-checked box.
To select a checkbox, use the "WebElement" class.
To operate on a drop-down list, use the "Select" class.
Step 1:
The object locator supposed to be used here is XPath. So derive the XPath for those two checkboxes.
String housingmoves="//label[contains(text(),'housingmoves')]/preceding-sibling::input";
String season_country_homes="//label[contains(text(),'Seaside & Country Homes')]/preceding-sibling::input";
Step 2:
Perform a click on the checkboxes
driver.findElement(By.xpath(housingmoves)).click();
driver.findElement(By.xpath(season_country_homes)).click();
For a partial match, do the following:
getDriver().findElement(By.cssSelector("<tag name>[id*='id pattern to look for']")).click();
Here is the C# version of Scott Crowe's answer. I found that both IEDriver and ChromeDriver responded to sending a Key.Space instead of clicking on the checkbox.
if (((RemoteWebDriver)driver).Capabilities.BrowserName == "firefox")
{
// Firefox
driver.FindElement(By.Id("idOfTheElement")).Click();
}
else
{
// Chrome and Internet Explorer
driver.FindElement(By.Id("idOfTheElement")).SendKeys(Keys.Space);
}
I tried with various approaches, but nothing worked. I kept getting "Cannot click element" or ElementNotVisibleException.
I was able to find the input, but I couldn't check it. Now, I'm clicking on the div that contains the checkbox and it works with following HTML (CSS based on Bootstrap).
#foreach (var item in Model)
{
<tr>
<td>
<div id="#item.Id" class="checkbox">
<label><input type="checkbox" class="selectone" value="#item.Id"></label>
</div>
</td>
<td val="#item.Id">
#item.Detail
</td>
<td>
<div>#item.Desc
</div>
</td>
<td>
#Html.ActionLink("Edit", "Create", new { EditId = item.Id })
</td>
</tr>
}
This is the code for WebDriver:
var table = driver.FindElement(By.TagName("table"));
var tds = table.FindElements(By.TagName("td"));
var itemTds = tds.Where(t => t.Text == itemtocheck);
foreach (var td in itemTds)
{
var CheckBoxTd = tds[tds.IndexOf(td) - 1];
var val = td.GetAttribute("val");
CheckBoxTd.FindElement(By.Id(val)).Click();
}
In this approach, I give the item id as id for the div and also add an attribute for td with that id. Once I find the td of the item that needs to be checked, I can find the div before that td and click it. We can also use the XPath query that supports before (here is the example http://learn-automation.com/how-to-write-dynamic-xpath-in-selenium/).