<%: Html.ActionLink("Cancel", "Edit", "Users", new {id = " + userID + " }, null) %>
In the code above userId is a variable. This syntax is not right, what should it be?
You cannot use an HTML helper which is run on the server to use a Javascript variable which is known on the client. So you need to generate your URL with the information you dispose on the server. So all you can do on the server is this:
<%: Html.ActionLink("Cancel", "Edit", "Users", null, new { id = "mylink" }) %>
Then I suppose that on the client you are doing some javascript (ideally with jquery) and a moment comes when you want to query the server using this url and the userID you've calculated on the client. So for example you could modify the link action dynamically by appending some id:
$(function() {
$('#mylink').click(function() {
var userId = ...
this.href = this.href + '?' + userId;
});
});
or if you wanted to AJAXify this link:
$(function() {
$('#mylink').click(function() {
var userId = ...
$.ajax({
url: this.href,
data: { id: userId },
success: function(result) {
...
}
});
return false;
});
});
Related
I've found a video from SharePointTech that explains how to change a textfield to a dropdown list on a List Form using data from open API. I'm trying to recreate it, but I'm hitting a roadblock with the new SharePoint Online. Instead of using "Country/Region", I created a new custom list with Company_Name. I took the person's code and made little changes that made a reference to "WorkCountry". When I save the changes (stop editing), the changes do not reflect and I get the same textfield. I had to use SharePoint Designer 2013 to create a new TestNewForm for new entry. Has anyone been able to reproduce this in SharePoint 2013 Designer? If so, would you be able an example?
I use jQuery's ajax method.
Updated code for your reference(you need to change the list name to your list name,InternalName is also):
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
</script>
<script>
var demo = window.demo || {};
demo.nodeTypes = {
commentNode: 8
};
demo.fetchCountries = function ($j) {
$.ajax({
url: _spPageContextInfo.siteAbsoluteUrl + "/_api/web/lists/getbytitle('Company_Name')/items",
type: "get",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
$j('table.ms-formtable td.ms-formbody').contents().filter(function () {
return (this.nodeType == demo.nodeTypes.commentNode);
}).each(function (idx, node) {
if (node.nodeValue.match(/FieldInternalName="Country_x002f_Region"/)) {
// Find existing text field (<input> tag)
var inputTag = $(this).parent().find('input');
// Create <select> tag out of retrieved countries
var optionMarkup = '<option value="">Choose one...</option>';
$j.each(data.d.results, function (idx, company) {
optionMarkup += '<option>' + company.Title + '</option>';
});
var selectTag = $j('<select>' + optionMarkup + '</select>');
// Initialize value of <select> tag from value of <input>
selectTag.val(inputTag.val());
// Wire up event handlers to keep <select> and <input> tags in sync
inputTag.on('change', function () {
selectTag.val(inputTag.val());
});
selectTag.on('change', function () {
inputTag.val(selectTag.val());
});
// Add <select> tag to form and hide <input> tag
inputTag.hide();
inputTag.after(selectTag);
}
});
},
error: function (data) {
console.log(data)
}
});
}
if (window.jQuery) {
jQuery(document).ready(function () {
(function ($j) {
demo.fetchCountries($j);
})(jQuery);
});
}
</script>
My source list:
Test result:
Updated:
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
</script>
<script>
var demo = window.demo || {};
demo.nodeTypes = {
commentNode: 8
};
demo.fetchCountries = function ($j) {
$.ajax({
url: 'https://restcountries.eu/rest/v1/all',
type: "get",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
$j('table.ms-formtable td.ms-formbody').contents().filter(function () {
return (this.nodeType == demo.nodeTypes.commentNode);
}).each(function (idx, node) {
if (node.nodeValue.match(/FieldInternalName="Country_x002f_Region"/)) {
// Find existing text field (<input> tag)
var inputTag = $(this).parent().find('input');
// Create <select> tag out of retrieved countries
var optionMarkup = '<option value="">Choose one...</option>';
$j.each(data, function (idx, company) {
optionMarkup += '<option>' + company.name + '</option>';
});
var selectTag = $j('<select>' + optionMarkup + '</select>');
// Initialize value of <select> tag from value of <input>
selectTag.val(inputTag.val());
// Wire up event handlers to keep <select> and <input> tags in sync
inputTag.on('change', function () {
selectTag.val(inputTag.val());
});
selectTag.on('change', function () {
inputTag.val(selectTag.val());
});
// Add <select> tag to form and hide <input> tag
inputTag.hide();
inputTag.after(selectTag);
}
});
},
error: function (data) {
console.log(data)
}
});
}
if (window.jQuery) {
jQuery(document).ready(function () {
(function ($j) {
demo.fetchCountries($j);
})(jQuery);
});
}
</script>
The difference in API will not have a great effect, the key is here '$ j.each (data, function (idx, company) {'. The structure of the return value of different APIs are different, you need to find useful data in return value.
Controller
#RequestMapping(value = Array("getPatternId.html"), method = Array(RequestMethod.GET))
#ResponseBody def getPattern(model:ModelMap,#RequestParam patternId: Long):List[Question] = {
var list: List[Question] = questionService.findQuestionByQuestionPattern(patternId)
var questions: java.util.List[Question] = ListBuffer(list: _*)
questions
}
script
function getPattern(id) {
$.ajax({
type : 'GET',
url : " /learnware/getPatternId.html ",
data : ({
patternId : id
}),
success : function(response) {
// we have the response
$('#info').html(response);
},
error : function(e) {
alert('Error: ' + e);
}
});
}
When i send response as string it display it on html page
but when i return a list it does no show the data
<div id="info" style="color:green;"></div>
current response will be add to div witn id info
How can i make an image as an Ajax Action Link?
You could do this:
<a href="<%: Url.Action("someaction", "somecontroller") %>" id="mylink">
<img src="<%: Url.Content("~/images/foo.png") %>" alt="foo" />
</a>
and then in a separate javascript file AJAXify this link:
$(function() {
$('#mylink').click(function() {
$.ajax({
url: this.href,
type: 'GET',
success: function(result) {
alert('success');
}
});
return false;
});
});
And if you want to avoid the tag soup in your views you could write a custom helper:
public static class HtmlExtensions
{
public static MvcHtmlString ImageLink(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues, object htmlAttributes, string imageSource)
{
var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);
var image = new TagBuilder("img");
image.Attributes["src"] = urlHelper.Content(imageSource);
var anchor = new TagBuilder("a");
anchor.Attributes["href"] = urlHelper.Action(actionName, controllerName, routeValues);
anchor.MergeAttributes(new RouteValueDictionary(htmlAttributes));
anchor.InnerHtml = image.ToString(TagRenderMode.SelfClosing);
return MvcHtmlString.Create(anchor.ToString());
}
}
and then in your view simply:
<%: Html.ImageLink(
"someaction",
"somecontroller",
null,
new { id = "mylink" },
"~/images/foo.png"
) %>
and of course the process of AJAXifying it stays the same.
What about something like:
<a href='<%= Url.Action(...) %>'><img src='...' /></a>
Not certain if there is a helper that does this.
Bob
To push the id to the edit control whilst displaying an edit image instead of the word Spag you can try this:
#MvcHtmlString.Create(
Ajax.ActionLink("Spag", "Edit",
new { id = item.x0101EmployeeID },
new AjaxOptions() {
UpdateTargetId = "selectDiv",
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET"
}
).ToHtmlString().Replace(
"Spag",
"<img src=\"" + Url.Content("../../Images/edit.png") + "\" />"
)
)
how can i load second dropdown on selection of first and third on second. in asp.net mvc 2
I have the dropdown trigger an ajax post that sends the selected ID selected to a controller and then return a partial view which overwrites the html for a placeholder div.
View; this sets the ActionUrl, you will also need a placeholder div (in my case called departments) for the drop down to be injected:
<script type="text/javascript">
var ActionUrl = '<%= Url.Action("RenderDepartments", "ControllerName") %>';
</script>
<script src="<%: ResolveUrl("~/Scripts/Custom/DepartmentFilter.js")%>" type="text/javascript"></script>
<%: Html.DropDownListFor(model => model.OfficeId, Model.ListItems, "-- Please Select --", new { onchange = "GetDepartments()" })%>
// ^^ ON CHANGE IS IMPORTANT ^^
<div id="departments"></div>
JQuery;
function GetDepartments() {
$.ajax(
{
type: "POST",
url: ActionUrl,
data: { officeId: $("#OfficeId").val() },
success: function (data) {
$("#departments").html(data);
}, error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('XMLHttpRequest:' + XMLHttpRequest.responseText);
alert('textStatus:' + textStatus);
//alert('errorThrown:' + errorThrown);
}
});
}
Controller Action;
public ActionResult RenderDepartments(int? officeId)
{
if (officeId.HasValue)
{
var departments = new SelectList(ents.GetDepartments(officeId), "departmentID", "Name");
var model = new DropdownListViewModel(departments);
return PartialView("DepartmentDropdown", model);
}
return null;
}
This is nullable because the user could submit "-- please select --" which will in this case return null and remove the departments dropdown.
I've looked around on SO to see if this has been asked before and couldn't find anything (so if it has indeed been asked before then I apologize.
Here's what I'm trying to do, a user can select from a list of skills for their profile, if a skill they want isn't in the list then they can add it to the database, I have that accomplished with WCF & jQuery AJAX. Here's the code for that:
$("#AddNewSkill").click(function () {
$("#AddNewSkill").attr("disabled", true);
$("#newSkill").attr("disabled", true);
var newSkill = $("#newSkill").val();
var data = { name: $("#newSkill").val(), description: "", type: "Skill" };
data = JSON.stringify(data)
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "../WeddingPhotographerService.svc/AddNew",
data: data,
dataType: "json",
success: function () {
successCall('#newSkill', '#AddNewSkill');
//$('#SkillListViewContainer').load('../Account/GetSkillControl');
},
error: function (msg) {
$("#AddSkillError").text(msg.d);
$("#AddSkill").attr("disabled", false);
$("#NewSkill").attr("disabled", false);
}
});
});
Here's the method in the AJAX-Enabled WCF service:
[OperationContract]
public bool AddNew(string name, string description, string type)
{
switch (type)
{
case "":
goto default;
case "skill":
IRepository<Skill> skillRepo = ObjectFactory.GetInstance<IRepository<Skill>>();
var skill = new Skill { Name = name, Description = (string.IsNullOrEmpty(description)) ? string.Empty : description };
skillRepo.Save(skill);
return true;
case "equipment":
IRepository<Equipment> eqRep = ObjectFactory.GetInstance<IRepository<Equipment>>();
var eq = new Equipment { Name = name, Description = (string.IsNullOrEmpty(description)) ? string.Empty : description };
eqRep.Save(eq);
return true;
case "occasion":
IRepository<Occassion> occRepo = ObjectFactory.GetInstance<IRepository<Occassion>>();
var oc = new Occassion { Name = name, Description = (string.IsNullOrEmpty(description)) ? string.Empty : description };
occRepo.Save(oc);
return true;
default:
IRepository<Skill> repo = ObjectFactory.GetInstance<IRepository<Skill>>();
var s = new Skill { Name = name, Description = (string.IsNullOrEmpty(description)) ? string.Empty : description };
repo.Save(s);
return true;
}
}
It's kind of ugly but I'll optimize it once I have this 2nd part working. Here's how the ListBox is being loaded in the view:
<%: Html.ListBox("Skills", Model.SkillList, new { #style = "width:157px; height:90px;background:#e2f0f1;", #size = "3", #class = "inputbox" })%>
Which comes from RegistrationModelView.cs, here's SkillList in my model view:
private MultiSelectList GetSkills(string[] selectedValues)
{
List<Skill> list = new List<Skill>();
IRepository<Skill> skills = ObjectFactory.GetInstance<IRepository<Skill>>();
foreach (Skill skill in skills.GetAll())
{
list.Add(new Skill()
{
Key = skill.Key,
Name = skill.Name,
Description = ""
});
}
return new MultiSelectList(list, "Key", "Name", selectedValues);
}
And the action in AccountController.cs that loads the view
[MoveFormsScript]
public ActionResult Index()
{
return View(new RegistrationModelView());
}
I'm pretty sure all the code I posted (other than how the new item is added with the WCF service and the jQuery for consuming said service is irrelevant but I thought I'd offer as much information as possible).
Like I said the new value is added to the database no problem, my issue is updating the ListBox to reflect the new values. Anyone got any ideas and can help with this?
Well I mucked around until I found something that does what I need it to do. It may not be the most efficient or elegant way to accomplish the task but it at least works (Maybe someone will come along with a different solution some day).
What I ended up doing was make another $,ajax() call in the success of the first call like this
$("#AddNewSkill").click(function () {
$("#AddNewSkill").attr("disabled", true);
$("#newSkill").attr("disabled", true);
var data = { name: $("#newSkill").val(), description: "", type: "skill" };
data = JSON.stringify(data)
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "../WeddingPhotographerService.svc/AddNew",
data: data,
dataType: "json",
success: function () {
$.ajax({
type:"POST",
datatype:"json",
url: "../Account/GetSkills",
success:updateSkillsListBox
});
},
error: function (msg) {
alert(msg.d);
}
});
});
function updateSkillsListBox(data, status) {
$("#Skills").html("");
for(var d in data) {
$("<option value=\"" + data[d].Value + "\">" + data[d].Name + "</option>").appendTo("#Skills");
}