This is a migrated thread and some comments may be shown as answers.
Gridview Images Do Not Move Up or Down when prompted
0 Answers 61 Views
This is a migrated thread and some comments may be shown as answers.
Jamie
Top achievements
Rank 1
Jamie asked on 11 Jul 2012, 05:04 PM
I have a gridview that allows users to upload a picture, but want to allow them the ability move the records up or down in within the gridview.  I have written some code, and everything in the row moves, expect for the image.  Can anyone tell me where I am going wrong?

View: 
@using ACS.CSG.ReviewContentManager.Models
@model ACS.CSG.ReviewContentManager.Models.AttributeViewModel 

@{
var lockTitle = Model.IsLocked ? "Locked" : "Unlocked";
var lockImage = Url.Content(String.Format("~/Content/Common/Images/Icons/{0}.png", Model.IsLocked ? "locked" : "unlocked"));

}
@using (Html.BeginForm())
{
<fieldset>
<legend>Attribute</legend>

@Html.HiddenFor(model => model.ID)
<table class="t-separator" width="100%">
<tr>
<td align="right">
@Html.LabelFor(m => m.LongName, new { @class = "editor-label required" }):
</td>
<td>
@Html.TextBoxFor(m => m.LongName, new { @class = "display-field" })
@Html.ValidationMessageFor(m => m.LongName)
</td>
<td align="right">
@Html.LabelFor(m => m.ShortName, new { @class = "editor-field" }):
</td>
<td>
@Html.TextBoxFor(m => m.ShortName, new { @class = "display-field" })
@Html.ValidationMessageFor(m => m.ShortName)
</td>
<td style="vertical-align:middle;" align="right">
@Html.LabelFor(model => model.Class, new { @class = "editor-label" }):&nbsp;
</td>
<td style="vertical-align:middle;">
@Html.EditorFor(model => model.ClassValue, "Class", new { @class = "editor-field" })
@Html.ValidationMessageFor(model => model.Class)
</td>
</tr>
<br />
<tr>
<td style="vertical-align:middle;" align="right">
@Html.LabelFor(m => m.AnswerType, new { @class = "editor-label required" }):
</td>
<td colspan="6" style="vertical-align:middle;">&nbsp;
@Html.EditorFor(m => m.AnswerTypeValue, "AnswerType", new { @class = "editor-field", style = "width: 210px;" })
@Html.ValidationMessageFor(m => m.AnswerType)
</td>
<td rowspan="3">
<button id="lock" title="@lockTitle" class="entity-action"><img alt="@lockTitle" height="24" src="@lockImage" width="24" /></button>
<button id="save" title="Save" class="entity-action"><img alt="Save" height="24" src="@Url.Content("~/Content/Common/Images/Icons/save.png")" width="24" /></button>
<button id="cancel" title="Exit" class="entity-action"><img alt="Exit" height="24" src="@Url.Content("~/Content/Common/Images/Icons/cancel.png")" width="24" /></button>
</td>
</tr>
<br />
<tr>
<td align="right">
@Html.LabelFor(m => m.Information):
</td>
<td colspan="6">
@Html.TextAreaFor(m => m.Information, new { @class = "wide-text", style = "width: 86%;" })
@Html.ValidationMessageFor(m => m.Information)
</td>
</tr>
</table>

<hr />


@(Html.Telerik().Splitter().Name("AnswerOptionSplitter")
.Orientation(SplitterOrientation.Horizontal)
.Panes(panes =>
{
panes.Add()
.Size("28px")
.Resizable(false)
.Content(@<text>
<div class="entity-tools-vertical">
<button id="editAnswerOption" title="Edit" class="entity-action"><img alt="Edit" height="24" src="@Url.Content("~/Content/Common/Images/Icons/edit-disabled.png")" width="24" /></button>
<button id="moveUpAnswerOption" title="Move Up" class="entity-action"><img alt="Move Up" height="24" src="@Url.Content("~/Content/Common/Images/Icons/up-disabled.png")" width="24" /></button>
<button id="moveDownAnswerOption" title="Move Down" class="entity-action"><img alt="Move Down" height="24" src="@Url.Content("~/Content/Common/Images/Icons/down-disabled.png")" width="24" /></button>
<button id="toggleEnableAnswerOption" title="Enabled" class="entity-action"><img alt="Enabled" height="24" src="@Url.Content("~/Content/Common/Images/Icons/accept-disabled.png")" width="24" /></button>
<button id="deleteAnswerOption" title="Delete" class="entity-action"><img alt="Delete" height="24" src="@Url.Content("~/Content/Common/Images/Icons/recycle-disabled.png")" width="24" /></button>
</div>
</text>);
panes.Add()
.Resizable(false)
.Content(
@Html.Telerik().Grid<AnswerOptionViewModel>()
.Name("AnswerOptions")
.ToolBar(command => command.Insert().ButtonType(GridButtonType.ImageAndText))
.DataKeys(k => k.Add(o => o.ID))
.DataBinding(dataBinding => dataBinding.Ajax()
.OperationMode(GridOperationMode.Client)
.Select("_AnswerOptionsAjax", "Attribute", new { id = Model.ID })
.Update("_AnswerOptionsUpdateAjax", "Attribute", new { attributeId = Model.ID })
.Delete("_AnswerOptionsDeleteAjax", "Attribute", new { id = Model.ID })
.Insert("_AnswerOptionsCreateAjax", "Attribute", new { id = Model.ID})
)
.Columns(columns =>
{
columns.Bound(m => m.AnswerAbbr).Title("");
columns.Bound(m => m.AnswerText).Title("");
columns.Bound(m => m.AnswerValue).Title("").Width(32);
columns.Bound(m => m.RelatedImageId).Title("");
columns.Bound(m => m.RelatedImage).Title("")
.ClientTemplate("<img alt='<#= AnswerText #>' class='answer-option-icon' src='"
+ Url.Action("AttributeAnswerOption", "ImageGenerator", new { id = Model.ID, index = 0, })
+ "' />").Width(32);
columns.Bound(m => m.Ordinal).Hidden().HtmlAttributes(new { style = "display: none;" });
})
.ClientEvents(c => c
.OnRowSelect("AnswerOptions_onRowSelect")
.OnDataBound("AnswerOptions_onDataBound")
.OnSave("AnswerOptions_onGridSave")
)
.HtmlAttributes(new { @class = "t-widget t-grid grid-no-header grid-no-footer" })
.Selectable()
.Editable(e => e.Mode(GridEditMode.PopUp))
.ToHtmlString()
);
})
)

</fieldset>
<style type="text/css">
.t-edit-form-container
{
width: 500px;
margin: 1px;
}
</style>

}
<script type="text/javascript">
//<![CDATA[
// Shared Functions

function enableImage($img) {
var src = $img.attr('src');
var re = /(.+)\-disabled(\.png)/i;
if (re.test(src))
src = src.replace(re, '$1$2');

$img.attr('src', src);
}

function disableImage($img) {
var src = $img.attr('src');
if (src.contains('-disabled') === false)
src = src.replace(/(.+)(\.png)/i, '$1-disabled$2');

$img.attr('src', src);
}

function enableButton($btn) {
if ($btn.is(':disabled'))
$btn.removeAttr('disabled');

enableImage($btn.find('img:first'));
}

function disableButton($btn) {
if ($btn.not(':disabled'))
$btn.attr('disabled', 'disabled');

disableImage($btn.find('img:first'));
}

// Set Common Variables

var gridAnswerOptions = null,
$selectedRow = null,
selectedRowIndex = -1,
isDirty = false,
changedFields = [],
isNew = @((Model.ID == Guid.Empty).ToString().ToLower()),
isNewAnswerOption = false,
lockTitle = '@(lockTitle)',
lockImage = '@(lockImage)'
;

var attribute = @Html.Raw(Json.Encode(Model));

// Page Load Events

jQuery(function () {
gridAnswerOptions = jQuery('#AnswerOptions').data('tGrid');

disableButton(jQuery('#save'));
// set onchange for form inputs to handle dirty state
// rudimentary implementation only sets the flag if any change--even undo--occurs
jQuery('.editor-field').each(function () {
var $ele = jQuery(this);
$ele.change(function (e) {
isDirty = true;
if (jQuery.inArray($ele.text(), changedFields) == -1)
changedFields.push($ele.text());

enableButton(jQuery('#save'));
});
});

jQuery('#Class').bind('valueChange', function () {
isDirty = true;
if (jQuery.inArray('Class', changedFields) == -1)
changedFields.push('Class');

enableButton(jQuery('#save'));
});

// bind and trigger AnswerType_onChange which sets current display of AnswerOptions
jQuery('#AnswerType').bind('valueChange', AnswerType_onChange).trigger('valueChange');

if (isNew)
disableButton(jQuery('#lock'));
else
enableButton(jQuery('#lock'));


// AJAXify attribute buttons
jQuery('#lock').click(function (e) {
if (e.preventDefault) e.preventDefault();
isDirty = true;
if (jQuery.inArray('State', changedFields) == -1)
changedFields.push('State');

var url = '@Url.Action("_LockAjax", new { id = Model.ID })';
jQuery.post(url, jQuery('form').first().serialize(), function (data) {
gridAnswerOptions.refresh();
});

return false;
});

jQuery('#save').click(function (e) {
if (e.preventDefault) e.preventDefault();

// cause client-side validation
var $form = jQuery('form');
if ($form.valid()) {
var url = '@Url.Action("_SaveAjax", new { id = Model.ID })';
jQuery.post(url, jQuery('form').first().serialize(), function (data) {
isDirty = false;
gridAnswerOptions.refresh();
});
}

return false;
});


var exitDialog;
jQuery('#cancel').click(function (e) {
if (e.preventDefault) e.preventDefault();

var $form = jQuery('form');
var redirectUrl = '@Url.Action("Index", "Attribute")';
// prompt to save changes if there are any
if (isDirty && $form.valid()) {
if (!exitDialog) {
// create and display the dialog
exitDialog = jQuery.telerik.window.create({
title: 'Exit Edit Attribute',
modal: true,
resizable: false,
draggable: false,
visible: false,
html: 'The following fields have changed: '
+ changedFields.join(', ')
+ '<br /><br />Do you want to save your changes?'
+ '<button class="exit-dialog-button-yes" title="Yes">Yes</button>'
+ '<button class="exit-dialog-button-no" title="No">No</button>'
})
.data('tWindow');
}

exitDialog.center().open();
jQuery(exitDialog.element).find('.exit-dialog-button-yes').first().click(function (e) {
if (e.preventDefault) e.preventDefault();

var url = '@Url.Action("_SaveAjax", new { id = Model.ID })';
jQuery.post(url, jQuery('form').first().serialize(), function (data) {
exitDialog.close();
window.location = redirectUrl;
});

return false;
});
jQuery(exitDialog.element).find('.exit-dialog-button-no').first().click(function (e) {
if (e.preventDefault) e.preventDefault();

exitDialog.close();
window.location = redirectUrl;

return false;
});
}

return false;
});

// set AnswerOption button state to disabled, where relevant
disableButton(jQuery('#editAnswerOption'));
disableButton(jQuery('#moveUpAnswerOption'));
disableButton(jQuery('#moveDownAnswerOption'));
disableButton(jQuery('#toggleEnableAnswerOption'));
disableButton(jQuery('#deleteAnswerOption'));

// wire up answer option button events

jQuery('#editAnswerOption').click(function (e) {
if (e.preventDefault) e.preventDefault();
isDirty = true;

if (jQuery(this).is(':disabled') || $selectedRow == null)
return false;

gridAnswerOptions.editRow($selectedRow);


// show and set click handlers for update/cancel
$selectedRow.find('.entity-action-update').each(function () {
var $that = jQuery(this);
$that.show();
$that.click(function (e) {
if (e.preventDefault) e.preventDefault();
isDirty = true;

gridAnswerOptions.updateRow($selectedRow);
selectedRowIndex = $selectedRow[0].sectionRowIndex;
gridAnswerOptions.refresh();

return false;
});
});
$selectedRow.find('.entity-action-cancel').each(function () {
var $that = jQuery(this);
$that.show();
$that.click(function (e) {
if (e.preventDefault) e.preventDefault();
if (gridAnswerOptions.cancel) gridAnswerOptions.cancel();
// hide edit-related update/cancel
jQuery('.entity-action-update, .entity-action-cancel').each(function () {
jQuery(this).hide();
});
return false;
});
});

return false;
});

jQuery('#moveUpAnswerOption').click(function (e) {
if (e.preventDefault) e.preventDefault();
isDirty = true;
debugger;
var rowIndex = $selectedRow[0].sectionRowIndex;
if (rowIndex > 0) {
var url = '@Html.Raw(Url.Action("_AnswerOptionsMoveRow", new { id = Model.ID, index = 0, num = -1 }))'.replaceIndexParam(rowIndex);
jQuery.post(url, function (data) {
selectedRowIndex = data.index;
gridAnswerOptions.refresh();
});
}

return false;
});

jQuery('#moveDownAnswerOption').click(function (e) {
if (e.preventDefault) e.preventDefault();
isDirty = true;
debugger;
var rowIndex = $selectedRow[0].sectionRowIndex;
if (rowIndex < $selectedRow.parent().children().length - 1) {
var url = '@Html.Raw(Url.Action("_AnswerOptionsMoveRow", new { id = Model.ID, index = 0, num = 1 }))'.replaceIndexParam(rowIndex);
jQuery.post(url, function (data) {
selectedRowIndex = data.index;
gridAnswerOptions.refresh();
});
}

return false;
});

jQuery('#toggleEnableAnswerOption').click(function (e) {
if (e.preventDefault) e.preventDefault();
isDirty = true;

var rowIndex = $selectedRow[0].sectionRowIndex;
var url = '@Html.Raw(Url.Action("_AnswerOptionsToggleEnableAjax", new { id = Model.ID, index = 0 }))'.replaceIndexParam(rowIndex);
jQuery.post(url, function (data) {
selectedRowIndex = data.index;
gridAnswerOptions.refresh();
});

return false;
});

jQuery('#deleteAnswerOption').click(function (e) {
if (e.preventDefault) e.preventDefault();
isDirty = true;

var rowIndex = $selectedRow[0].sectionRowIndex;
if (gridAnswerOptions.editing.confirmDelete === false || confirm(gridAnswerOptions.localization.deleteConfirmation)) {
var url = '@Html.Raw(Url.Action("_AnswerOptionsDeleteAjax", new { id = Model.ID, index = 0 }))'.replaceIndexParam(rowIndex);
jQuery.post(url, function (data) {
selectedRowIndex = data.index;
gridAnswerOptions.refresh();
});
}

return false;
});
});

// AnswerType Events

function AnswerType_onChange() {
isDirty = true;
enableButton(jQuery('#save'));
if (jQuery.inArray('AnswerType', changedFields) == -1)
changedFields.push('AnswerType');

// only show AnswerOptions if (Multiple) Specified Options is selected
var answerTypeData = jQuery(this).data('tComboBox');
var answerType = answerTypeData.text();

if (answerType.toLowerCase().contains('specified options'))
jQuery('#AnswerOptionSplitter').show();
else {
jQuery('#AnswerOptionSplitter').hide();

// remove the AnswerOptions collection
var url = '@Html.Raw(Url.Action("_AnswerOptionsClearAjax", new { id = Model.ID }))';
jQuery.post(url, function(data) {
$selectedRow = null;
selectedRowIndex = -1;
gridAnswerOptions.refresh();
});
}
}

// AnswerOptions Events

function AnswerOptions_onDataBound(e) {
var grid = jQuery(e.target).data('tGrid');
grid.updateFilter('Code', 'AnswerAbbr');
grid.updateFilter('Value', 'AnswerText');

gridAnswerOptions = grid;

grid.updateEntityText('Value');
grid.updateEntityText('ImageType');

// update upload links
jQuery('.upload-icon-button').each(function () {
var $that = jQuery(this);
$that.click(function (e) {
if (e.preventDefault) e.preventDefault();

// select the row the anchor is in
var $tr = $that.parents('tr').first();
$tr.click();

// show the window
jQuery('#UploadWindow').data('tWindow').center().open();
});
});

// update icon src
jQuery('.answer-option-icon').each(function () {
var $that = jQuery(this);
var src = $that.attr('src');
var $tr = $that.parents('tr').first();
var rowIndex = $tr[0].sectionRowIndex;
$that.attr('src', src.replaceIndexParam(rowIndex));
});

// hide edit-related update/cancel
jQuery('.entity-action-update, .entity-action-cancel').each(function () {
jQuery(this).hide();
});

// check if selectedRowIndex is set and select that row
if (selectedRowIndex >= 0) {
grid.selectRow(selectedRowIndex);
selectedRowIndex = -1;
}
// check if it's a newly created AnswerOption and set into edit mode
if (isNewAnswerOption) {
jQuery('#editAnswerOption').click();
isNewAnswerOption = false;
}
}

function AnswerOptions_onRowSelect(e) {
/* persist any row changes locally
jQuery('.t-grid-edit-row').each(function () {
gridAnswerOptions.overrideUpdateRow(jQuery(this));
selectedRowIndex = e.row.sectionRowIndex;
gridAnswerOptions.refresh();
});*/

$selectedRow = jQuery(e.row);
var rowIndex = e.row.sectionRowIndex;
var tr = ($selectedRow.data('tr') || $selectedRow)[0];
var dataItem = gridAnswerOptions.dataItem(tr);

// update buttons and state
enableButton(jQuery('#editAnswerOption'));

enableButton(jQuery('#moveUpAnswerOption'));
enableButton(jQuery('#moveDownAnswerOption'));
if (rowIndex == 0)
disableButton(jQuery('#moveUpAnswerOption'));
else if (rowIndex == e.row.parentElement.children.length - 1)
disableButton(jQuery('#moveDownAnswerOption'));

if (dataItem.Enabled === true)
jQuery('#toggleEnableAnswerOption').find('img:first').attr('src', '@Url.Content("~/Content/Common/Images/Icons/accept.png")');
else
jQuery('#toggleEnableAnswerOption').find('img:first').attr('src', '@Url.Content("~/Content/Common/Images/Icons/disabled.png")');

enableButton(jQuery('#toggleEnableAnswerOption'));
enableButton(jQuery('#deleteAnswerOption'));
}

function AnswerOptions_onGridSave(e) {
var values = e.values;
if (!values.Picture) {

values.Picture = lastUploadedFile;
gridAnswerOptions.refresh();
}
}


// UploadWindow Events

function UploadWindow_onOpen(e) {
// remove any uploaded files--just remove the ul containing the list, the reupload will still work
// jQuery('ul.t-upload-files').remove();

}

// UploadIcon Events
function UploadIcon_onLoad(e) {
// change the Select... text
jQuery(e.target).find('.t-upload-button span').html('Select icon...');
}

function UploadIcon_onSelect(e) {
// select the row the anchor is in
var $tr = jQuery(this).parents('tr').first();
$tr.click();
}

function UploadIcon_onRemove(e) {
var rowIndex = $selectedRow[0].sectionRowIndex;
e.data = { id: '@Model.ID', index: rowIndex };
}

function UploadIcon_onError(e) {
if (e.response) {
var data = e.response;
alert(data.error.message);
}
}
//]]>
</script> 

Controller:
[HttpPost]
public JsonResult _AnswerOptionsMoveRow(Guid id, int index, int? num)
{
if (index < 0)
index = 0;

if (num == null)
num = -1;

var newIndex = index + (int)num;
var ao = Attribute.AnswerOptions[index];
Attribute.AnswerOptions.RemoveAt(index);
Attribute.AnswerOptions.Insert(newIndex, ao);

return Json(new { index = newIndex, answerOption = ao });


Model:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.Serialization;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Web.Script.Serialization;

namespace ACS.CSG.ReviewContentManager.Models
{
public class AnswerOptionViewModel : BaseViewModel
{
[Key]
[ReadOnly(true)]
[ScaffoldColumn(false)]
[DisplayName("Id")]
public int ID { get; set; }

[DisplayName("Code")]
[StringLength(10)]
public string AnswerAbbr { get; set; }

[Required(AllowEmptyStrings = false)]
[DisplayName("Value")]
[StringLength(200)]
public string AnswerText { get; set; }

public int? AnswerValue { get; set; }

[DisplayName("ImageType")]
public LookupViewModel ImageType { get; set; }
public string ImageTypeValue
{
get { return (ImageType == null) ? "" : ImageType.ColumnValue; }
set
{
if (String.IsNullOrEmpty(value) == false)
{
var lookup = LookupViewModel.GetLookup("AnswerOption", "ImageType", value) ??
LookupViewModel.GetLookup("AnswerOption", "ImageType", "image/bmp");

ImageType = lookup;
}
else
ImageType = null;
}
}

//[ScriptIgnore]
public byte[] RelatedImage
{
get;
set;
}

[DisplayName("Image")]
public string RelatedImageId
{
get { return ID.ToString(); }
}

[Required]
public Int16 Ordinal { get; set; }

[Required]
public bool Enabled { get; set; }

public void ToggleEnabled()
{
Enabled = !Enabled;
}

//[Required]
//public AttributeViewModel Attribute { get; private set; }

public static AnswerOptionViewModel CreateAttributeValue()
{
var answerOption = new AnswerOptionViewModel();

answerOption.ID = 45;
answerOption.AnswerText = null;
answerOption.AnswerAbbr = null;
answerOption.AnswerValue = null;
answerOption.Ordinal = 1;
answerOption.RelatedImage = null;
answerOption.ImageType = null;
answerOption.Enabled = true;


return answerOption;
}
}
}

Any suggestions you could provide would be greatly appreciated. 

No answers yet. Maybe you can help?

Tags
Grid
Asked by
Jamie
Top achievements
Rank 1
Share this question
or