@@ -1,23 +1,33 @@
@{
ViewBag .Title = " Home Page" ;
@using ImageUploader .Web .Extensions
@model ImageUploader .Web .Models .ValuationRequest
@{
ViewBag .Title = " Valuation" ;
}
<style >
#holder {
border : 10px dashed #ccc ;
width : 300px ;
min-height : 300px ;
margin : 20px auto ;
.validationMessage {
color : red ;
}
#holder {
border : 1px solid #ddd ;
border-radius : 4px 4px 0 0 ;
/* width: 100%;*/
/* min-height: 140px;*/
margin : 20px auto ;
padding : 20px ;
text-align : center ;
vertical-align : middle ;
}
#holder .hover {
border : 10px dashed #0c0 ;
}
#holder img {
display : block ;
margin : 10px auto ;
}
/* #holder img {
display: block;
margin: 10px auto;
} */
#holder p {
margin : 10px ;
@@ -41,19 +51,327 @@
.hidden {
display : none !important ;
}
/* http://stackoverflow.com/questions/11235206/twitter-bootstrap-form-file-element-upload-button*/
.btn-file {
position : relative ;
overflow : hidden ;
}
.btn-file input [type = file ] {
position : absolute ;
top : 0 ;
right : 0 ;
min-width : 100% ;
min-height : 100% ;
font-size : 100px ;
text-align : right ;
filter : alpha (opacity=0 );
opacity : 0 ;
outline : none ;
background : white ;
cursor : inherit ;
display : block ;
}
</style >
<article >
<div id =" holder" >
<h2 >Online Valuation</h2 >
@using (Html .BeginForm ("", "ValuationRequest ", FormMethod .Post , new { id = "requestValuationForm ", @class = "form -horizontal ", role = "form ", enctype = "multipart /form -data " }))
{
@Html.AntiForgeryToken()
<div class =" form-horizontal" >
<hr />
@Html.ValidationSummary(true , " " , new { @class = " text-danger" } )
<fieldset class =" form-horizontal" >
<legend >Item Details </legend >
<div class =" form-group" >
@Html.MyLabelFor(model = > model .DescriptionOfItemToSell )
<div class =" col-md-10" >
@Html.MyTextInputFor(model = > model .DescriptionOfItemToSell )
</div >
</div >
<div class =" form-group" >
@Html.MyLabelFor(model = > model .MakeOrManufacturer )
<div class =" col-md-10" >
@Html.MyTextInputFor(model = > model .MakeOrManufacturer )
</div >
</div >
<div class =" form-group" >
@Html.MyLabelFor(model = > model .Model )
<div class =" col-md-10" >
@Html.MyTextInputFor(model = > model .Model )
</div >
</div >
<div class =" form-group" >
@Html.MyLabelFor(model = > model .SerialNumber )
<div class =" col-md-10" >
@Html.MyTextInputFor(model = > model .SerialNumber )
</div >
</div >
<div class =" form-group" >
@Html.MyLabelFor(model = > model .OtherDetails )
<div class =" col-md-10" >
@Html.MyTextInputFor(model = > model .OtherDetails )
</div >
</div >
<div class =" form-group" >
@Html.MyLabelFor(model = > model .Condition )
<div class =" col-md-10" >
@Html.MyDropDownListFor(model = > model .Condition )
</div >
</div >
<div class =" form-group" >
@Html.MyLabelFor(model = > model .AmountRequestedForProperty )
<div class =" col-md-10" >
@Html.MyTextInputFor(model = > model .AmountRequestedForProperty )
</div >
</div >
<div class =" form-group" >
@Html.MyLabelFor(model = > model .Images )
<div class =" col-md-10" >
<span class =" btn btn-primary btn-file" >
Upload images <input type =" file" name =" images" multiple accept =" image/*"
data-bind =" event: { change: function() { $root.setFiles($element.files) } }"
class =" btn btn-default" />
</span >
<p class =" validationMessage" data-bind =" validationMessage: images" ></p >
<div id =" holder" >
Pending image upload &hellip ;
</div >
</div >
</div >
</fieldset >
<fieldset class =" form-horizontal" >
<legend >Customer Details </legend >
<div class =" form-group" >
@Html.MyLabelFor(model = > model .Name )
<div class =" col-md-10" >
@Html.MyTextInputFor(model = > model .Name )
</div >
</div >
<div class =" form-group" >
@Html.MyLabelFor(model = > model .IsCustomerOver18YearsOld )
<div class =" col-md-10" >
<div class =" checkbox" >
@Html.MyCheckboxInputFor(model = > model .IsCustomerOver18YearsOld )
</div >
</div >
</div >
</fieldset >
<div class =" form-group" >
@Html.MyLabelFor(model = > model .Email )
<div class =" col-md-10" >
@Html.MyEmailInputFor(model = > model .Email )
</div >
</div >
<div class =" form-group" >
@Html.MyLabelFor(model = > model .Phone )
<div class =" col-md-10" >
@Html.MyTelInputFor(model = > model .Phone )
</div >
</div >
<div class =" form-group" >
@Html.MyLabelFor(model = > model .IsCustomerRighfulOwner )
<div class =" col-md-10" >
<div class =" checkbox" >
@Html.MyCheckboxInputFor(model = > model .IsCustomerRighfulOwner )
</div >
</div >
</div >
<div class =" form-group" >
<div class =" col-md-offset-2 col-md-10" >
<input type =" submit" value =" Create" class =" btn btn-default" />
</div >
</div >
</div >
<p id =" upload" class =" hidden" ><label >Drag & drop not supported, but you can still upload via this input field:<br ><input type =" file" ></label ></p >
<p id =" filereader" >File API & FileReader API not supported</p >
<p id =" formdata" >XHR2's FormData is not supported</p >
<p id =" progress" >XHR2's upload progress isn't supported</p >
<p >Upload progress: <progress id =" uploadprogress" min =" 0" max =" 100" value =" 0" >0</progress ></p >
<p >Drag an image from your desktop on to the drop zone above to see the browser both render the preview, but also upload automatically to this server.</p >
</article >
}
<div >
@Html.ActionLink( "Back to List", "Index")
</div >
@section scripts {
<script src =" ~/Scripts/Inhouse/ImageUpload.js" ></script >
}
<script >
// HTML features we may want to use
var tests = {
filereader: typeof FileReader != ' undefined' ,
dnd: ' draggable' in document .createElement (' span' ),
formdata: !! window .FormData ,
progress: " upload" in new XMLHttpRequest
};
// TODO redirect if these test fail
ko .validation .rules [' phoneAUS' ] = {
validator : function (phoneNumber , validate ) {
if (typeof (phoneNumber) !== ' string' ) {
return false ;
}
if (ko .validation .utils .isEmptyVal (phoneNumber)) {
return true ;
} // makes it optional, use 'required' rule if it should be required
phoneNumber = phoneNumber .replace (/ \s + / g , " " );
return validate && phoneNumber .length === 10 &&
phoneNumber .match (/ ^ (0(2| 3| 4| 7| 8))? \d {8} $ / );
},
message: ' Please specify a valid australian phone number'
};
ko .validation .rules [" mustBeTrue" ] = {
validator : function (val , validate ) {
if (! validate) {
return true ;
}
return val === true ;
}
};
ko .validation .registerExtenders ();
var ValuationRequest = function () {
var self = this ;
self .name = ko .observable ().extend ({ required: true });
self .isCustomerOver18YearsOld = ko .observable ().extend ({ required: true , mustBeTrue: { message: ' Customer must be over 18' } });
self .descriptionOfItemToSell = ko .observable ().extend ({ required: true });
self .makeOrManufacturer = ko .observable ();
self .model = ko .observable ();
self .serialNumber = ko .observable ();
self .condition = ko .observable ().extend ({ required: true , minLength: 1 }); // enum just dont select the empty option
self .otherDetails = ko .observable ();
self .images = ko .observableArray ().extend ({ required: true });
self .isCustomerRighfulOwner = ko .observable ().extend ({ required: true , mustBeTrue: { message: ' Customer must be the rightful owner' } });
self .amountRequestedForProperty = ko .observable ().extend ({ required: true , number: true });
self .email = ko .observable ().extend ({ required: true , email: true , });
self .phone = ko .observable ().extend ({ required: true , phoneAUS: true });
var errors = ko .validation .group (self , { deep: true , observable: true });
self .canSubmit = ko .computed (function () {
return errors ().length === 0 ;
});
self .showAllMessages = function () {
errors .showAllMessages ();
};
self .setFiles = function (files ) {
$ (" #holder" ).empty ();
self .images .removeAll ();
console .log (files);
for (var i = 0 ; i < files .length ; i++ ) {
self .images .push (files[i]);
previewfile (files[i], $ (" #holder" ));
}
};
}
function previewfile (file , $element ) {
console .log (" previewfile" );
console .log (file);
var img = document .createElement (" img" );
img .src = window .URL .createObjectURL (file);
img .className = " img-responsive img-thumbnail" ;
img .onload = function () {
window .URL .revokeObjectURL (this .src );
}
$element .append (img);
}
vm = new ValuationRequest ();
ko .applyBindings (vm);
function postAjax () {
if (! vm .canSubmit ()) {
vm .showAllMessages ();
return ;
}
var formData = new FormData ();
formData .append (' Name' , vm .name ());
formData .append (' IsCustomerOver18YearsOld' , vm .isCustomerOver18YearsOld ());
formData .append (' DescriptionOfItemToSell' , vm .descriptionOfItemToSell ());
formData .append (' MakeOrManufacturer' , vm .makeOrManufacturer ());
formData .append (' Model' , vm .model ());
formData .append (' SerialNumber' , vm .serialNumber ());
formData .append (' Condition' , vm .condition ());
formData .append (' OtherDetails' , vm .otherDetails ());
formData .append (' IsCustomerRighfulOwner' , vm .isCustomerRighfulOwner ());
formData .append (' AmountRequestedForProperty' , vm .amountRequestedForProperty ());
formData .append (' Email' , vm .email ());
formData .append (' Phone' , vm .phone ());
for (var i = 0 ; i < vm .images ().length ; i++ ) {
var image = vm .images ()[i];
console .log (image);
formData .append (' Images[' + i + ' ]' , image);// Conforms to the MultipartDataMediaFormatter expecations
}
var xhr = new XMLHttpRequest ();
xhr .open (' POST' , ' /api/ValuationRequest' );
// xhr.onload = function () {
// progress.value = progress.innerHTML = 100;
// };
if (tests .progress ) {// TODO REMOVE - we should just bail if their browser sucks
console .log (" Can show progress" );
xhr .upload .onprogress = function (event ) {
console .log (" making progress" );
if (event .lengthComputable ) {
console .log (" event length is Computable" );
var complete = (event .loaded / event .total * 100 | 0 );
console .log (" event.loaded / event.total = " + event .loaded + " / " + event .total );
// progress.value = progress.innerHTML = complete;
}
}
}
console .log (formData);
xhr .send (formData);
}
$ (' #requestValuationForm' ).submit (function (e ) {
e .preventDefault ();
console .log (ko .toJS (vm));
try {
postAjax ();
} catch (e) {
console .log (e);
debugger ;
throw e;
}
});
// Prefill the form - delete me if you want
vm .name (" Rhys" );
vm .isCustomerOver18YearsOld (true );
vm .descriptionOfItemToSell (" Fender guitar" );
vm .makeOrManufacturer (" fender" );
vm .model (" Stratocaster" );
vm .serialNumber (" 12311222" );
// self.condition = ko.observable().extend({ required: true, minLength: 1 }); //enum just dont select the empty option
vm .otherDetails (" Played by hendrix" );
// self.images = ko.observableArray().extend({ required: true });
vm .isCustomerRighfulOwner (true );
vm .amountRequestedForProperty (750 );
vm .email (" asdasd@asdasd.asd" );
vm .phone (" 0788877766" );
// END Prefill the form
</script >
}