I'm using uploadify fileupload plugin for my MVC3 project.
I'm trying to use the uploading file to the controller.
How do i use multi file upload and single file upload together ?
I know to use IEnumerable<HttpPostedFileBase> files for multiple files and HttpPostedFileBase files for single file upload. How to combine these.
In my project, the user may select multiple files or only a single file to upload it to the controller.
so, if i use IEnumerable<HttpPostedFileBase> files in my controller action, i'm unable to get single files(files is null) and if i use HttpPostedFileBase files it doesnot show anything, files is always null here.
How to get work with single file upload, i can get the multiple file uploads but not the single files.
How to get this work ?
Here is my code:
HTML
<body>
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div id="fileupload" style="display:none">
<div style="clear: none;">
File to Upload:
<input type="file" name="file_upload" id="file_upload" style="padding-left: 50px;"/><hr />
</div>
<p style="text-align: right;">
<input type="submit" id="selectimage" value="Ok" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"/>
<input type="submit" id="cancelimage" value="Cancel" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" onclick="cancelupload();" />
</p>
</div>
<input type="button" id="btnImg" />
<div id="filecontent">
Added Images:
</div>
}
</body>
<script>
$(function(){
$('#file_upload').uploadify({
'checkExisting': 'Content/uploadify/check-exists.php',
'swf': '/Content/uploadify/uploadify.swf',
'uploader': '/Home/Index',
'auto': false,
'buttonText': 'Browse',
'fileTypeExts': '*.jpg;*.jpeg;*.png;*.gif;*.zip',
'removeCompleted': false,
'onSelect': function (file) {
$("#selectimage").click(function () {
$("#file_upload-queue").appendTo("#filecontent");
});
}
});
});
</script>
Controller Action
public ActionResult Index(IEnumerable<HttpPostedFileBase> fileData)
{
foreach (var file in fileData)
{
if (file.ContentLength > 0)
{
string currpath = Server.MapPath("~/Images/");
currpath = Path.Combine(Server.MapPath("~/Images/Admin"), file.FileName);
file.SaveAs(currpath);
}
}
return View();
}
What should i change in controller action to get single file upload and multi file upload to work?
Update
Neither IEnumerable<HttpPostedFileBase> fileData nor HttpPostedFileBase fileData working
The controller action will be called multiple times for each file to be uploaded. But you seem to have hidden the upload form (you placed it in a div with display:none). Also you never use Uploadify to actually upload the files. You have set auto: false and you never trigger the file upload using the upload method. So I guess that you are somehow submitting the form and expecting to get something on the server side, but that's not gonna happen like this.
So, let's clean and simplify things up:
<div>
<input type="file" name="file_upload" id="file_upload" />
</div>
<hr />
<div id="filecontent">
Added Images:
</div>
<input type="button" id="upload" value="Upload selected files to the server" />
<script type="text/javascript" src="#Url.Content("~/Content/Uploadify/jquery.uploadify-3.1.min.js")"></script>
<script type="text/javascript">
$('#file_upload').uploadify({
'swf': '#Url.Content("~/Content/uploadify/uploadify.swf")',
'uploader': '#Url.Action("index", "home")',
'auto': false,
'multu': true,
'buttonText': 'Browse',
'fileTypeExts': '*.jpg;*.jpeg;*.png;*.gif;*.zip',
'removeCompleted': false,
'onSelect': function (file) {
$("#selectimage").click(function () {
$("#file_upload-queue").appendTo("#filecontent");
});
}
});
$('#upload').click(function () {
$('#file_upload').uploadify('upload', '*');
return false;
});
</script>
and your controller action could now become:
[HttpPost]
public ActionResult Index(HttpPostedFileBase fileData)
{
if (fileData != null && file.ContentLength > 0)
{
var currpath = Path.Combine(
Server.MapPath("~/Images/Admin"),
fileData.FileName
);
fileData.SaveAs(currpath);
}
return Json(new { success = true });
}
try it plugin: works with html5 + flash + silverligth according: client browser.
http://des.delestesoft.com:8080/?go=2
Related
With the fine-uploader plugin I am trying to add multiple (dynamic could be 1, or 10) instances with an optional caption field and a manual upload button per section.
The form I am uploading from is dynamically generated in layout as well as content, the uploaded files have to be stored by the handler based upon the section of the form as well as the instance of fine-uploader. I also need the ability to effectively upload each instance of fine-uploader independently
The issue that I am hitting is following the guidelines & demo for the manual upload option, ie adding a click function it will always find only the first instance as it searches for the button using .getElementById.
I can get around this by defining a new template for each instance however I would prefer to use a single template.
The template code (for each instance - abbreviated for simplicity) is
<script type="text/template" id="qq-template-manual-trigger#XX#">
<div class="qq-uploader-selector qq-uploader" qq-drop-area-text="Drop files here">
...
<div class="buttons">
<div class="qq-upload-button-selector qq-upload-button">
<div>Select files</div>
</div>
<button type="button" id="trigger-upload#XX#" class="btn btn-primary">
<i class="icon-upload icon-white"></i> Upload
</button>
</div>
...
<ul class="qq-upload-list-selector qq-upload-list" aria-live="polite" aria-relevant="additions removals">
<li>
...
<input class="caption" tabindex="1" type="text">
...
</li>
</ul>
...
</div>
</script>
<div id="fine-uploader-manual-trigger#XX#"></div>
and the uploader script
<script>
var manualUploader#XX# = new qq.FineUploader({
element: document.getElementById('fine-uploader-manual-trigger#XX#'),
template: 'qq-template-manual-trigger#XX#',
request: {
inputName: "imagegroup[]",
endpoint: '/SaveFile.aspx'
},
autoUpload: false,
debug: true,
callbacks: {
onError: function(id, name, errorReason, xhrOrXdr) {
alert(qq.format("Error on file number {} - {}. Reason: {}", id, name, errorReason));
},
onUpload: function (id) {
var fileContainer = this.getItemByFileId(id)
var captionInput = fileContainer.querySelector('.caption')
var captionText = captionInput.value
this.setParams({
"descr[]": captionText,
<-- Other parameters here -->
}, id)
}
},
});
qq(document.getElementById("trigger-upload#XX#")).attach("click", function () {
manualUploader#XX#.uploadStoredFiles();
});
</script>
in the ideal world I would prefer simply have a single
<script type="text/template" id="qq-template-manual-trigger">
....
</script>
then where required multiple times through the form
<div id="fine-uploader-manual-trigger"></div>
<script>
var manualUploader#XX# = new qq.FineUploader({
element: document.getElementById('fine-uploader-manual-trigger'),
template: 'qq-template-manual-trigger',
...
}
qq(document.getElementById("trigger-upload")).attach("click", function () {
manualUploader#XX#.uploadStoredFiles();
});
</script>
The use of the attach function by calling .getElementById just feels wrong, or at the very least cludgy, is there a better way of activating the upload on a per-instance basis?
Thanks in advance
K
Sorted, but if anyone has a better answer...
Instead of using the demo of document.getElementById("trigger-upload")
Simply use document.querySelector("#fine-uploader-manual-trigger #trigger-upload")
eg
<div id="fine-uploader-manual-triggerXX"></div>
<script>
var manualUploaderXX = new qq.FineUploader({
element: document.getElementById('fine-uploader-manual-triggerXX'),
template: 'qq-template-manual-trigger',
... // omitted for brevity
}
qq(document.querySelector("#fine-uploader-manual-triggerXX #trigger-upload")).attach("click", function () {
manualUploaderXX.uploadStoredFiles();
});
</script>
I have a controller(SearchController) which fetches data on clicking a search button (inside myview.gsp) i want to populate 2 text fields present in the same myview.gsp with the data i have in my controller (SearchController) .I know i need to do ajax calling because i want to populate only 2 fields and dont want to reload the page which contains other valuable information . How can i achieve it please guide me
here is my Controller
def searchItem() {
def itemFound = MyService.searchP20Code(params["item"])
def resultMap = [:]
if (itemFound!=null)
{
resultMap.put("CODE",itemFound[1])
resultMap.put("DESC",itemFound[2])
}
println "Result:"+resultMap
session.setAttribute("searchResult", resultMap)
render(view: myview" )
}
myview.gsp
myview.gsp
<div class="leftPanel filter-label">
<a href="#" class="tt"> <g:message
code="Normal.label.Code" />
</a>
</div>
<div class="rightPanel filter-field-wrapper">
<input type="text"
name="Code" maxlength="30"
value=""
id="i_code" />
</div>
</div>
<div class="formLables">
<div class="leftPanel filter-label">
<a href="#" class="tt"> <g:message
code="Normal.label.Description" />
</a>
</div>
<div class="rightPanel filter-field-wrapper">
<input type="text"
name="Desc" maxlength="30"
onkeyup="fieldMaxlength('material_code')" value=""
id="i_description" />
</div>
</div>
<g:actionSubmit
value="${message(code:'Normal.button.search', default: 'Search Code')}"
action="searchItem" />
please help my how can i update only these two text fields in myview.gsp onclicking search button using ajax .I am using grails 2.1.0
Here you can find a detailed example with Grails build-in Ajax support.
You can also use JQuery (example here)
EDIT:
Your controller needs to look like this:
import grails.converters.JSON
class ExampleController {
....
def searchItem() {
def itemFound = MyService.searchP20Code(params["item"])
def resultMap = [:]
if (itemFound!=null) {
resultMap.put("CODE",itemFound[1])
resultMap.put("DESC",itemFound[2])
}
println "Result:"+resultMap
//session.setAttribute("searchResult", resultMap)
render(resultMap as JSON )
}
}
and your gsp
<head>
...
<g:javascript plugin="jquery" library="jquery" src="jquery/jquery-{WRITE_YOUR_VERSION_HERE}.js"/>
<script>
function callAjax(e){
e.preventDefault();
$.ajax({
url: "example/search",
type:"post",
dataType: 'json',
success: function(data) {
console.log(data);
$("input[name='Code']").val(data.CODE);
$("input[name='Desc']").val(data.DESC);
}
});
}
</script>
...
</head>
<body>
....
<input type="submit" value="Call Ajax Function" onclick="callAjax()">
....
</body>
I am using Jquery Form wizard plugin in a MVC application. http://thecodemine.org/
I have a form with 4 steps. in one of step i have upload functionality.
I want submit functionality at each step and also back and next steps. later steps are optional.
I was able to add a submit button in navigation. On clicking it, form data related to active step is only submitted and other data is null.
For more clarity of my issue:
View :
<form id="myform" method="post" action="/Controller/Action">
<div id="fieldWrapper">
<fieldset class="step fieldset" id="first">
<legend class="legend">First step</legend>
Some input controls
</fieldset>
<fieldset class="step fieldset" id="second">
<legend class="legend">Second step</legend>
some more input controls (optional)
</fieldset>
<fieldset class="step fieldset" id="third">
<legend class="legend">Third step</legend>
some more input controls with filu upload
(optional)
</fieldset>
<fieldset class="step fieldset" id="fourth">
<legend class="legend">Fourth step</legend>
some more input controls (optional)
</fieldset>
</div>
<div id="demoNavigation">
<input class="navigation_button" id="back" value="Back" type="reset" />
<button type="submit" id="submitBtn">Submit and Finish</button>
<input class="navigation_button" id="next" value="Next" type="submit" />
</div>
</form>
Script:
<script type="text/javascript">
$(function () {
$("#myform").formwizard({
validationEnabled: true,
focusFirstInput: false,
disableUIStyles: true,
textSubmit: 'Submit and Finish',
textNext: 'Continue to next step',
next: "input:submit"
}
);
});
</script>
Updated the Jquery.form.wizard.js to so that the submit button hides at last step.
Now on each step i have submit button and navigation button.
When i submit form on second step, form data in second step is only posted and rest is not posted.
I went through the samples but could not find the appropriate one.
Can anyone suggest how to achieve this?
I went through the documentation and jquery.form.wizard.js file to get beeter understanding of what is done.
I just have to write some script as follows:
<script type="text/javascript">
$(function () {
$("#myform").formwizard({
validationEnabled: true,
focusFirstInput: false,
disableUIStyles: true,
textSubmit: 'Submit and Finish',
textNext: 'Continue to next step',
next: "input:submit"
}
);
});
$('#submitBtn').click(function () {
var stepInfo = $('#myform').formwizard('state');
for (var i = 0; i < stepInfo.activatedSteps.length; i++) {
stepInfo.steps.filter("#" + stepInfo.activatedSteps[i]).find(":input").not(".wizard-ignore").removeAttr("disabled");
}
});
</script>
First, sorry for my bad english.
I would like when one people click on the button "Page1", the controller return a renderpartial of the "Page1" and the same things for "page2" and "allPage".
My views is:
#{
ViewBag.Title = "Title";
}
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
<h2>Title</h2>
#using (Ajax.BeginForm("NameAction", //controller action name
"NameController", //controller name
new AjaxOptions //ajax options that tell mvc how to perform the replacement
{
UpdateTargetId = "ViewPage", //id of div to update
HttpMethod = "Post" //how to call the controller action
}, new { id = "FormName" }))
{
<input type="submit" id="btn" value="p1" id="p1"/>
<input type="submit" id="btn" value="p2" id="p2"/>
<input type="submit" id="btn" value="AllPage" id="AllPage"/>
<div id="ViewPage">
//render partial view
</div>
}
And my controller is:
public class NameController : Controller
{
[HttpPost]
public ActionResult NameAction(String btn)
{
if (Request.IsAjaxRequest())
if(btn="p1")
return PartialView("p1");
if(btn="2")
return PartialView("p2");
if(btn="3")
return PartialView("p3");
return View();
}
}
Request.isAjaxRequest equals always false and the partialview not update the div but erase all page
Thanks for your helps.
Give your submit buttons a name:
<input type="submit" name="btn" value="page1" id="Page1"/>
<input type="submit" name="btn" value="Page2" id="Page2"/>
<input type="submit" name="btn" value="AllPage" id="AllPage"/>
and then:
[HttpPost]
public ActionResult NameAction(string btn)
{
if (btn == "page1")
{
// the page1 button was clicked
}
else if (btn == "page2")
{
// the page2 button was clicked
}
else if (btn == "AllPage")
{
// the AllPage button was clicked
}
...
}
and if you didn't want to depend on the actual label of the button:
<button type="submit" name="btn" value="p1" id="Page1">Show page 1</button>
<button type="submit" name="btn" value="p2" id="Page2">Show page 2</button>
<button type="submit" name="btn" value="all" id="AllPage">Show all pages</button>
and in the controller you could check against the value.
UPDATE:
Make sure that you have included the jquery.unobtrusive-ajax script to your page so that the Ajax.BeginForm works and sends an AJAX request:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
I am combing the jQuery validation plug-in with the jQuery Form Plugin to submit the form via AJAX.
This works perfectly in Firefox & Chrome, but (as usual) Internet Explorer is being a pain. For reasons that are alluding me, IE is ignoring the ajaxSubmit, as a result it submits the form in the normal fashion.
I've followed the validation plug-in's documentation when constructing my code:
JS:
<script src="/js/jquery.validate.min.js" type="text/javascript"></script>
<script src="/js/jquery.form.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
var validator = $("#form_notify").validate({
messages: {
email: {
required: 'Please insert your email address. Without your email address we will not be able to contact you!',
email:'Please enter a <b>valid</b> email address. Without a valid email address we will not be able to contact you!'
}
},
errorLabelContainer: "#error",
success: "valid",
submitHandler: function(form) {$(form).ajaxSubmit();}
});
$('#email').blur(function() {
if (validator.numberOfInvalids() > 0) {
$("#label").addClass("label_error");
return false;
}
else {$("#label").removeClass("label_error");}
});
$('#form_notify').submit(function() {
if (validator.numberOfInvalids() == 0) {
$(this).fadeOut('fast', function() {$('#thank-you').fadeIn();});
return true;
}
return false;
});
});
</script>
Form HTML:
<form id="form_notify" class="cmxform" name="form_notify" action="optin.pl" method="get">
<fieldset>
<div class="input">
<label id="label" for="email">Email Address:</label>
<input type="text" id="email" name="email" value="" title="email address" class="{required:true, email:true}"/>
<div class="clearfix"></div>
</div>
<input type="hidden" name="key" value="sub-745-9.224;1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0;;subscribe-224.htm">
<input type="hidden" name="followup" value="19">
<input type="submit" name="submit" id="submit-button" value="Notify Me">
<div id="error"></div>
</fieldset>
</form>
I can't understand what is causing IE to act differently, any assistance would be greatly appreciated.
I can provide more information if needed.
Thanks in advance!
Try the following:
$('#form_notify').submit(function(e) {
e.preventDefault();
if (validator.numberOfInvalids() == 0) {
$(this).fadeOut('fast', function() {$('#thank-you').fadeIn();});
return true;
}
return false;
});