Reputation: 167
I trying to create ImageBrowser in Asp.net MVC 5. Problem is when I try to switch to another picture. Here's my code: In View:
@model Katalog.Models.Model
@{
Model.enumerator = 0;
int count = Model.ImageList.Count;
int index = 1;
}
....
<table>
<tbody>
<tr>
<td> @index/@count </td>
....
</tr>
<tr>
@using (Html.BeginForm("previous", "Home",FormMethod.Post))
{
<td>
<input type="hidden" name="number" value="1" />
<input value="<" type="submit" onclick="ImageLeft()" class="buttonLeftRight"/>
</td>
}
<td>@{Html.RenderPartial("~/Views/Shared/ImageViews.cshtml", Model);}</td>
<td>
@using (Html.BeginForm("next", "Home", FormMethod.Post))
{
@Html.HiddenFor(a => a.ImageList)
@Html.HiddenFor(a => a.enumerator)
<input type="submit" class="buttonLeftRight" onclick="ImageRight()"/>
}
</td>
</tr>
</tbody>
</table>
....
<script>
function ImageRight()
{
@{ Model.enumerator++; }
}
</script>
My Controller
....
public ActionResult next(Katalog.Models.Model model)
{
model = MyModel;
return View("Searcher",model);
}
....
and my PartialView:
@model Katalog.Models.Model
<img id="foto" class="imgFinded" src="@Model.ImageList[@Model.enumerator]"/>
When I click Next button my model.ImageList
is empty. Why?
Upvotes: 1
Views: 1038
Reputation:
The reason your models ImageList
property is null
is because your generating a hidden input @Html.HiddenFor(a => a.ImageList)
which generates
<input name="ImageList" value="System.Collections.Generic.List[]String" .. />
which will not bind to your collection in the POST method (when something is not binding, always insect the name
and value
attribute of the form controls your generating.
In order to bind to that list you would need to generate an input for each item in the list using a loop.
The other issue is that your scripts does nothing at all. Your model is server side code, and you cannot increment the value of a model property using javascript - you need to send a request to the controller to do that.
Since you sending the collection of images to the view, there is no need to make a request back to the server - you can just update the src
attribute of the <img>
tag.
Change the model to
public class Model
{
public int InitialIndex { get; set; }
public int ImageCount { get { return ImageList.Count; } }
public List<string> ImageList { get; set; }
}
and then the view can be just (the partial is unnecessary)
<img id="foto" class="imgFinded" src="@Model.ImageList[@Model.InitialIndex ]"/>
<button type="button" id="previous">Previous</button>
<button type="button" id="next">Next</button>
and the scripts
var imagelist = @Html.Raw(Json.Encode(Model.ImageList));
var index = @Html.Raw(Json.Encode(Model.InitialIndex));
var max = @Html.Raw(Json.Encode(Model.ImageCount));
var image = $('#foto');
// Set the initial state of the buttons
if (index === 0) {
$('#previous').prop('disabled', true);
} else if (index === max) {
$('#previous').prop('disabled', true);
}
$('#next').click(function() {
$('#previous').prop('disabled', false);
index++;
image.attr('src', imagelist[index]);
if (index === max) {
$(this).prop('disabled', true);
}
})
$('#previous').click(function() {
$('#next').prop('disabled', false);
index--;
image.attr('src', imagelist[index]);
if (index === 0) {
$(this).prop('disabled', true);
}
})
Upvotes: 1
Reputation: 148
The code @{Model.enumerator++;} and @{Model.enumerator--;} within the two Javascript functions is server side code so it will only be executed once when the view is rendering on the server and before it is passed to the client browser. So triggering the onclick="ImageRight()" by pressing the submit button will not change the server side value.
You could instead try to post the current index to the action in your controller and increment or decrement it depending on which action has been invoked.
@using (Html.BeginForm("Next", "Home", FormMethod.Post))
{
@Html.HiddenFor(a=>a.CurrentIndex)
<input type="submit" class="buttonRightLeft"/>
}
@using (Html.BeginForm("Previous", "Home", FormMethod.Post))
{
@Html.HiddenFor(a=>a.CurrentIndex)
<input type="submit" class="buttonLeftRight"/>
}
public ActionResult Next(int CurrentIndex)
{
// Get the NEXT image and return as model
model = MyModel;
return View("Searcher",model);
}
public ActionResult Previous(int CurrentIndex)
{
// Get the PREVIOUS image and return as model
model = MyModel;
return View("Searcher",model);
}
Upvotes: 1