So I have a list in which I loop through and I create the table rows.
#if (Model.TbAuctions != null && Model.TbAuctions.Count > 0)
{
foreach (var item in Model.TbAuctions)
{
<tr>
<td>
<img src="~/images/ebayonly.gif" />
</td>
<td>
#{
<form asp-page="GetSellerListModel" method="post" data-ajax="true" data-ajax-method="post" data-ajax-begin="begin" data-ajax-complete="complete" data-ajax-failure="failed">
<input type="hidden" value="#item.AuctionId" name="auctionId" />
<input id="submitBtn" style="display:none;" type="submit">
#Html.DisplayFor(modelItem => item.AuctionId)
</form>
}
</td>
</tr>
}
}
Code Behind:
public async Task<IActionResult> OnPostAsync(string auctionId)
{
try
{
if (ModelState.IsValid)
{
var itemId = auctionId;
}
}
catch (Exception ex)
{
throw ex;
}
return Page();
}
I have one input hidden field in which I save the value of the AuctionId, so when i click in the a href it clicks the other input via javascript and I send the AuctionId value as a parameter in the Post method. Till now everything is okay, however because the name of the input is always the same, it always takes the first input value regardless of where you click. What can I do here, so I can get the exact value of the input I clicked ?
P.s. I click the input via <a href because I want 'a' tag styling.
You have serveral inputs which ids are submitBtn,you need to make id unique,so that you can click the button which you want.You can do like this:
#{ var i = 0;}
#foreach (var item in Model.TbAuctions)
{
<tr>
<td>
<img src="~/images/ebayonly.gif" />
</td>
<td>
#{
<form asp-page="GetSellerListModel" method="post" data-ajax="true" data-ajax-method="post" data-ajax-begin="begin" data-ajax-complete="complete" data-ajax-failure="failed">
<input type="hidden" value="#item.AuctionId" name="auctionId" />
<input id="submitBtn#(i)" style="display:none;" type="submit">
#Html.DisplayFor(modelItem => item.AuctionId)
</form>
i++;
}
</td>
</tr>
}
Related
Validation not working for radio button in Angular.
When radio button is not selected, form is getting submitted.
Also not showing error.
HTML Code
<form [formGroup]="feedbackFormWithArray" (ngSubmit)="submitData()">
<table class="res-tbl">
<tbody formArrayName="skills" class="tbl">
<tr class="skill-tr table-data" *ngFor="let skill of skills; let i = index">
<td class="table-data res-td tbl-border skill-td">
<b value="skill.skillId"><span class="text-danger">*</span>{{skill.skillName}}<span>:</span></b><p class="skill-description-p"> {{skill.skillDescription}}</p>
</td>
<td class="table-data center rating-td">
<input type="radio" formControlName="{{ i }}" [value]="3" />
</td>
<td class="table-data center rating-td">
<input type="radio" formControlName="{{ i }}" [value]="2" />
</td>
<td class="table-data center rating-td">
<input type="radio" formControlName="{{ i }}" [value]="1" />
</td>
</tr>
</tbody>
<div *ngIf="(submitted && skills.invalid)">
<small *ngIf="skills.errors?.required" class="text-danger">Please select Skills</small>
</div>
</table>
<Button type="submit" [disabled]="feedbackFormWithArray.invalid" class="btn button-btn" >{{feedbackId ? 'Update' : 'Create'}}</Button>
</form>
TS Code
import { Validators } from '#angular/forms';
submitted : boolean = false;
this.feedbackFormWithArray= this.fb.group({
skills: this.fb.array(
this.skills.map((t) => {
this.fb.control(t);
}), {validators: Validators.required}
)
});
submitData() {
this.submitted = true;
}
How to solve this?
Thank you!
I am gonna guess you have a button inside your form, something like:
component.html
<button (click)="submitData()">Submit</button>
You could add a check to change submitted state like
submitData() {
if (this.feedbackFormWithArray.valid) {
this.submitted = true;
}
if (this.feedbackFormWithArray.invalid) {
// Do something like this.tryToSubmitWithError = true
// Popup to say you cannot submit
// ...
}
}
I think also you wanted to use feedbackFormWithArray instead of skills in the *ngIf below:
<div *ngIf="(submitted && skills.invalid)">
<small *ngIf="skills.errors?.required" class="text-danger">Please select Skills</small>
</div>
That could be like:
<div *ngIf="tryToSubmitWithError && feedbackFormWithArray.invalid">
<small *ngIf="feedbackFormWithArray.errors?.required" class="text-danger">
Please select Skills
</small>
</div>
I have a table, which gets filled at Runtime. In the last Row I want to add one button to each Column and when one button is pressed it shall Link to the same Post method, but with a different value.
<form method="post" asp-action="ChangeAll">
<input asp-for="DataId" type="hidden" />
<table>
<thead>
.....
</thead>
<tbody>
....data dynamically loaded
(
<td>
<input type="checkbox" name="boxes" value="#Model.RowId" />
</td> )
//last Row:
<tr>
<td>
<input type="submit" value="Update" />
<input type="hidden" name="selectedAction" value="#MyEnum.Value1" hidden />
</td>
......
<td>
<input type="submit" value="Update" />
<input type="hidden" name="selectedAction" value="#MyEnum.Value20" hidden />
</td>
</tr>
</tbody>
</table>
</form>
[HttpPost]
public async Task<IActionResult> ChangeAll(int[] boxes, int DataId, string
selectedAction){
The problem with the above is that no matter what button I click, it always posts back the value of the first button (MyEnum.Value1).
I have tried to add an asp-action="ChangeAll" to each button, but the behaviour stays the same.
So, how can I get the value of the Button I actually clicked?
In your code, All the hidden input have the same name, So when you submit the form. It will bind the first one. You can change your code like this:
<form method="post" asp-action="ChangeAll" id="Form">
.....
<input type="hidden" name="selectedAction" id="select" hidden />
<tr>
<td>
<input type="submit" value="Update" data-action="#MyEnum.Value1" onclick="choice(this,event)"/>
</td>
........
<td>
<input type="submit" value="Update" data-action="#MyEnum.Value20" onclick="choice(this,event)"/>
</td>
</tr>
</form>
<script>
function choice(a,event){
event.preventDefault();
var result = $(a).data("action");
document.getElementById("select").value = result;
document.getElementById("Form").submit();
}
</script>
In the above code, I only wrote one hidden input and customized an attribute--data-action to accept #MyEnum.Valuexx's value, and then assigned this value to the hidden input.
i have weird situation in which data is displayed in json format instead of html !!
At route http://127.0.0.1:8000/addpost form to add post is displayed and the recently added post.
Its show the form to add post and when submit is clicked it returns data in json format insteaad of displaying the form and the post added.
1)why it is returning json data ?
2)how do i display data in html format ?
thats me route
web.php
Route::get('addpost','PostController#index');
Route::post('addpost','PostController#store');
Controller ->
PostController.php
class PostController extends Controller
{
public function index()
{
$posts = Post::latest()->first();
return view('addpost',compact('posts'));
}
public function store(Request $request)
{
$post =new Post();
$post->title= $request->input('title');
$post->body= $request->input('body');
if($request->hasfile('postimage'))
{
$file=$request->file('postimage');
$extention=$file->getClientOriginalExtension();
$filename=time().'.'.$extention;
$file->move('uploads/post',$filename);
$post->postimage=$filename;
}
else{
return $request;
$post->postimage='';
}
$post->save();
return back()->with('success', 'Your images has been successfully Upload');
}
}
and the view
<div class="container">
<div class="jumbotron">
#if(Auth::user())
<h3> Add new post with images</h3>
<form action="{{url('addpost')}}" method="POST" enctype="multipart/form-data">
{{csrf_field()}}
<div class="form-group">
<label>Title</label>
<input type="text" name="title" class="form-control" >
</div>
<div class="form-group">
<label>Body</label>
<input type="text" name="body" class="form-control" >
</div>
<div class="input-group">
<div class="custom-file">
<input type="file" name="image" class="custom-file-input">
<label class="custom-file-label">Choose file</label>
</div>
</div>
<button type="submit" name="submit" class="btn-brn-primary"> Save Post</button>
#if($posts)
#foreach($posts as $post)
<tr>
<td>{{$post->id}}</td>
<td>{{$post->title}}</td>
<td>{{$post->body}}</td>
<!-- <td><img src="{{asset('uploads/post/'.$post->image)}}" style="height: 150px;"></td>
<td>EDIT</td> -->
</tr>
#endforeach
#endif
#else
<h1>no</h1>
#endif
</form>
</div>
</div>
if($request->hasfile('postimage')) // -> you are checking for postimage, in your html
// markup the file filed is called "image",
// therefore you will never enter this if block
{
$file=$request->file('postimage');
$extention=$file->getClientOriginalExtension();
$filename=time().'.'.$extention;
$file->move('uploads/post',$filename);
$post->postimage=$filename;
}
else{
return $request; // here you are returning the $request object that
// causes your unformatted response
$post->postimage='';
}
I'm rendering mulitple forms like this:
trait = (name, dice, mod) => {
return `
<tr><form action="#" onsubmit="renderRoll()">
<td><label>${name}</label></td>
<td><input type="text" name="dice" value="${dice}"></td>
<td><input type="text" name="mod" value="${mod}"></td>
<td><input type="submit" value="Slå" name="roll" ></td>
</form></tr>`;
};
document.getElementById('content').innerHTML += trait;
The forms don't have unique id:s and there are always more than one in the DOM. How can I run renderRoll() and access the values of the form that was triggered?
You have to pass an argument inside function "renderRoll()" to work.
<form action="#" onsubmit="renderRoll(event)">
function renderRoll(event) {
//here is your target...
var target = event.target;
alert(target.innerHTML);
}
I suggest you use a unique id as a name for the form element like as below:
const trait = (id, name, dice, mod) => {
return `
<tr><form name="${id}" action="#" onsubmit="renderRoll">
<td><label>${name}</label></td>
<td><input type="text" name="dice" value="${dice}"></td>
<td><input type="text" name="mod" value="${mod}"></td>
<td><input type="submit" value="Slå" name="roll" ></td>
</form></tr>`;
};
document.getElementById('content').innerHTML += trait("form", "test", "test", "test");
And use form data whenever form has triggered:
function renderRoll() {
let data = document.forms.namedItem("form").elements;
data = [...data].map(({name, value}) => ({name, value}));
console.log(data)
}
I hope it will be useful.
is there a way to have a nested form?
like this
<form action="" method="post">
<input type="text".... />
<input type="text".... />
<form action="some action">
<input type="submit" .... />
</form>
</form>
if not, how would I go around getting the same function without nested forms
No you can't have nested forms but there is a simple solution to your problem.
<form action="" method="post">
<input type="submit" name="action" value="action1" />
<input type="submit" name="action" value="action2" />
</form>
If you use PHP this code will handle your form submissions:
//if user clicks on the first submit button, action1 is triggered
if (isset($_POST['action']) && $_POST['action'] == 'action1') {
// do something
}
//if user clicks on the second submit button, action2 is triggered
if (isset($_POST['action']) && $_POST['action'] == 'action2') {
// do something else
}
ps: As I see you work with C# and .NET, this would be translated into:
public class ExampleController : Controller
{
....
[HttpPost]
public ActionResult Index(string action)
{
if (!string.IsNullOrEmpty(action) == "action1") {
// Do something
}
if (!string.IsNullOrEmpty(action) == "action2") {
// Do something
}
}
...
}