Is there are more elegant way of getting arbitrary javascript objects by id, when checkboxes are marked? - knockout-2.0

Wannt to give the user the possibility to select people via checkboxes in a list.
This sample works, but I would like to know, if you would do it the same way.
The main problem is, that javascript arbitrary objects cannot be compared against easily. So there must be a mapping.
Is this ok so? I don't want to create a custom-binding for this, where I could defined an Id field in the binding.
function Person(id, name, age) {
this.id = id;
this.name = name;
this.age = age;
}
function Party(id, name, persons) {
var self = this;
this.id = id;
this.name = name;
this.persons = ko.observableArray(persons);
this.persons_checked = ko.observableArray(); //<--- for the checkboxes
this.persons_checked.subscribe(function(newValue) {
var mapped = [];
mapped = $.map(newValue, function(id) {
return $.grep(listOfPeople, function(n) { return n.id == id; }); });
self.persons(mapped);
});
}
Complete Sample here: http://jsbin.com/ukipek/6/edit
Thank you

The simplest solution is to use knockoutjs 3.x and not 2.x, and it is magically done !
I've taken your example and modified it:
The HTML part:
<h1 data-bind="text: party.name"></h1>
<ul data-bind="foreach: people">
<li>
<input type="checkbox" data-bind="checkedValue: $data, checked: $root.party.persons_checked, attr: {value: id}">
<span data-bind="text:name"></span>
</li>
</ul>
And the JS part:
function Person(id, name, age) {
var self = this;
self.id = id;
self.name = name;
self.age = age;
}
function Party(id, name, persons) {
var self = this;
self.id = id;
self.name = name;
self.persons = ko.observableArray(persons);
self.persons_checked = ko.observableArray();
}
var listOfPeople = [
new Person(1, 'Fred', 25),
new Person(2, 'Joe', 60),
new Person(3, 'Sally', 43)];
var viewModel = function() {
var self = this;
this.party = new Party(1, "Weihnachtsfeier1", []);
this.people = ko.observableArray(listOfPeople);
};
ko.applyBindings(new viewModel());
No more mappings, knockoutjs handles everything alone :-)
You can have a look at this jsbin if you want : http://jsbin.com/sasuvuwabu/1/edit
Hope that helps !

Related

Update image from www/Upload/DP/image.png asp.net core 2

I have a code for image upload and that working as expected, in my way image is DP display picture of user.
Create.cshtml
<div class="form-group">
<label asp-for="DP" class="control-label">Profile Image</label>
<input type="file" name="DP" asp-for="DP" class="form-control" />
<span asp-validation-for="DP" class="text-danger"></span>
</div>
Controller Action
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Profile profile, IFormFile DP)
{
if (ModelState.IsValid)
{
var id = _userManager.GetUserName(HttpContext.User);
var fileName = Path.Combine(_environment.WebRootPath +"/Upload/DP/", Path.GetFileName(id+".png"));
DP.CopyTo(new FileStream(fileName,FileMode.Create));
//profile.DP = fileName;
ViewBag.fileName = fileName;
var create = new Profile {
userName = profile.userName,
uId = profile.uId,
rId = profile.rId,
Mobile = profile.Mobile,
Job = profile.Job,
City = profile.City,
Address = profile.Address,
dof = profile.dof,
DP = profile.DP = Path.GetFileName(id+".png"),
CreatedOn = profile.CreatedOn,
Status = profile.Status
};
_context.Add(profile);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["rId"] = new SelectList(_context.Set<CharityRole>(), "rId", "Name", profile.rId);
return View(profile);
}
Question: How I can delete existing image and add a new one with same name bcz its display on user profile like:
<img src="#Url.Content("~/Upload/DP/"+ _userManager.GetUserName(User)+".png")">
There are two issues in your post.
You need to use Using for FileStream, otherwise, the filestream will be not disposed.
using (var fileStream = new FileStream(fileName, FileMode.Create))
{
await DP.CopyToAsync(fileStream);
}
You need to pass create instead of profile to _context.Add.
Here is the complete demo code:
public async Task<IActionResult> Create(Profile profile, IFormFile DP)
{
if (ModelState.IsValid)
{
var id = _userManager.GetUserName(HttpContext.User);
var fileName = Path.Combine(_environment.WebRootPath + "/Upload/DP/", Path.GetFileName(id + ".png"));
using (var fileStream = new FileStream(fileName, FileMode.Create))
{
await DP.CopyToAsync(fileStream);
}
var create = new Profile
{
UserName = profile.UserName,
DP = Path.GetFileName(id + ".png")
};
_context.Add(create);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(profile);
}

Custom validation are not executing on focus change of applied control but works well in case of form submit

I am using normal mvc textboxfor on strong view, I have created custom validation attribute (the detailed code explained below).
On form submit everything works fine. In case if validation fails by natural it shows error message as configured.
Now when I enter the correct value inside text box I expect the error message to be vanished automatically but this does not happen until I post the form
JS File
$.validator.addMethod('validaterequiredif', function (value, element, parameters) {
var id = parameters['dependentproperty'];
var clickValue = $("input[name=" + id + "]:checked").val();
// get the target value (as a string,
// as that's what actual value will be)
var targetvalue = parameters['targetvalue'];
if (clickValue == targetvalue) {
if (value == null) {
return false;
}
else {
return $.validator.methods.required.call(
this, value, element, parameters);
}
}
else {
return true;
}
});
$.validator.unobtrusive.adapters.add(
'validaterequiredif',
['dependentproperty', 'targetvalue'],
function (options) {
options.rules['validaterequiredif'] = {
dependentproperty: options.params['dependentproperty'],
targetvalue: options.params['targetvalue']
};
options.messages['validaterequiredif'] = options.message;
});
Server side custom validator class as below
public class ValidateRequiredIf : ValidationAttribute, IClientValidatable
{
protected RequiredAttribute _innerAttribute;
public string DependentProperty { get; set; }
public object TargetValue { get; set; }
public bool AllowEmptyStrings
{
get
{
return _innerAttribute.AllowEmptyStrings;
}
set
{
_innerAttribute.AllowEmptyStrings = value;
}
}
public ValidateRequiredIf(string dependentProperty, object targetValue)
{
_innerAttribute = new RequiredAttribute();
DependentProperty = dependentProperty;
TargetValue = targetValue;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// get a reference to the property this validation depends upon
var containerType = validationContext.ObjectInstance.GetType();
var field = containerType.GetProperty(DependentProperty);
if (field != null)
{
// get the value of the dependent property
var dependentValue = field.GetValue(validationContext.ObjectInstance, null);
// trim spaces of dependent value
if (dependentValue != null && dependentValue is string)
{
dependentValue = (dependentValue as string).Trim();
if (!AllowEmptyStrings && (dependentValue as string).Length == 0)
{
dependentValue = null;
}
}
// compare the value against the target value
if ((dependentValue == null && TargetValue == null) ||
(dependentValue != null && (TargetValue.Equals("*") || dependentValue.Equals(TargetValue))))
{
// match => means we should try validating this field
//if (!_innerAttribute.IsValid(value))
if (value == null)
// validation failed - return an error
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName), new[] { validationContext.MemberName });
}
}
return ValidationResult.Success;
}
private string BuildDependentPropertyId(ModelMetadata metadata, ViewContext viewContext)
{
// build the ID of the property
string depProp = viewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(DependentProperty);
// unfortunately this will have the name of the current field appended to the beginning,
// because the TemplateInfo's context has had this fieldname appended to it. Instead, we
// want to get the context as though it was one level higher (i.e. outside the current property,
// which is the containing object, and hence the same level as the dependent property.
var thisField = metadata.PropertyName + "_";
if (depProp.StartsWith(thisField))
// strip it off again
depProp = depProp.Substring(thisField.Length);
return depProp;
}
public virtual IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "validaterequiredif",
};
string depProp = BuildDependentPropertyId(metadata, context as ViewContext);
// find the value on the control we depend on;
// if it's a bool, format it javascript style
// (the default is True or False!)
string targetValue = (TargetValue ?? "").ToString();
if (TargetValue is bool)
targetValue = targetValue.ToLower();
rule.ValidationParameters.Add("dependentproperty", depProp);
rule.ValidationParameters.Add("targetvalue", targetValue);
yield return rule;
}
}
Model property
[ValidateRequiredIf("IsFeederSelected", "True", ErrorMessage = "Please select atleast one feeder")]
public List<string> selectedMeterName { get; set; }
Strongly typed view
<div class="meterTextboxRadio col-md-4">
<p>
#Html.RadioButtonFor(m => m.IsFeederSelected, true, new { #class = "radio", #Name = "IsFeederSelected", value = "meter", id = "rdbMeterConsumption", #checked = "checked" })
<span> Feeder</span>
#Html.RadioButtonFor(m => m.IsFeederSelected, false, new { #class = "radio", #Name = "IsFeederSelected", value = "group", id = "rdbGroupConsumption",style= "margin-left: 30px;" })
<span> Group</span>
</p>
<div class="group dropdownhidden" id="MeterNameConsumption" style="margin-top:4px;">
#Html.DropDownListFor(m => m.selectedMeterName, Model.MeterName
, new { #class = "chosen-select" ,#id= "ddlConsumptionMeterName", multiple = "multiple", Style = "width:100%", data_placeholder = "Choose Feeders.." })
<span class="highlight"></span> <span class="bar"></span>
</div>
<div class="group dropdownhidden" id="GroupNameConsumption" style="margin-top:4px;">
#Html.DropDownListFor(m => m.selectedGroupName, Model.GroupName
, new { #class = "chosen-select", #id = "ddlConsumptionGroupName", multiple = "multiple", Style = "width:100%", data_placeholder = "Choose Group.." })
<span class="highlight"></span> <span class="bar"></span>
</div>
#Html.ValidationMessageFor(m => m.selectedMeterName, "", new { #class = "error" })
#Html.ValidationMessageFor(m => m.selectedGroupName, "", new { #class = "error" })
</div>
Please provide some inputs for the same
Thanks.

Umbraco 7 searchCriteria with all fields

Hi i have search on Umbraco 7 and it works OK, but i have to add a lot of search fields to index and it´s not practic. How can i search through all fields?
#{
string searchQuery = Request["query"];
if (String.IsNullOrWhiteSpace(searchQuery))
{
searchQuery = "";
}
var searcher = ExamineManager.Instance;
var searchCriteria = searcher.CreateSearchCriteria();
var query = searchCriteria.GroupedOr(new[] {
"nodeName",
//"packSizes",
"name",
"title",
"bodyText",
"body",
"field1",
"field2",
"field3",
"field4",
"field5",
"field6"
}, searchQuery).Compile();
var SearchResults = searcher.Search(query).Where(x => x["__IndexType"] == "content").ToList(); } #if (SearchResults.Any()) {
<ul class="search-results-box">
#foreach (var result in SearchResults)
{
var node = Umbraco.TypedContent(result.Id);
var pathIds = result["__Path"].Split(',');
var path = Umbraco.TypedContent(pathIds).Where(p => p != null).Select(p => new { p.Name }).ToList();
if (node != null)
{
<li>#node.Name</li>
}
}
</ul> }
You can add an event to the indexing command to concatenate all of the fields into one large field at indexing time, and just search that one field.
To hook into the event, in your OnApplicationStarting event handler, do the following:
ExamineManager.Instance.IndexProviderCollection["YOUR INDER NAME HERE"].GatheringNodeData += SetSiteSearchFields;
And then for the function, you can do something like this, combining all of the fields int a single field:
void SetSiteSearchFields(object sender, IndexingNodeDataEventArgs e)
{
//grab some fields
var combined = e.Fields["field1"] + " " + e.Fields["field2"];
//add as new field
e.Fields.Add("searchField", combined);
}
This would then give you a field called "searchField" that you could search, making your search much simpler.

Asynchronous Task controllers in C#4

I want to write an asynchronous Controller that is displaying in output an IEnumerable<IEnumerable<Video>>
I don't know I can manage to write correctly my function Task<IEnumerable<IEnumerable<Video>>> GetVideosAsync(xxxxx) especially the Task.ContinueWhenAll function (in order not to have blocking code ).
Is it better to use a lambda for this piece of code ...?
Can someone help me ?
Nb: *I can only use C#4 and visual Studio 2010
public class HomeController : AsyncController
{
string[] sources = {
"http://xxxx/membervideos/1",
"http://xxxx/membervideos/2"
};
public Task<ActionResult> Async()
{
var sw = Stopwatch.StartNew();
var data = GetVideosAsync();
sw.Stop();
ViewBag.Elapsed = sw.ElapsedMilliseconds;
return View("~/views/home/index.cshtml", data);
}
Task<IEnumerable<IEnumerable<Video>>> GetVideosAsync()
{
var allVideosTasks = new List<Task<IEnumerable<Video>>>();
foreach (var url in sources)
{
allVideosTasks.Add(DownloadDataAsync(url));
}
var context = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.ContinueWhenAll<IEnumerable<Video>,IEnumerable<IEnumerable<Video>>(
/// CODE TO ComplETE HERE
);
Task<IEnumerable<Video>> DownloadDataAsync(string url)
{
var httpClient = new HttpClient();
var httpResponseMessage = httpClient.GetAsync(url);
var result = httpResponseMessage.ContinueWith
(t =>
{
t.Result.EnsureSuccessStatusCode();
return t.Result.Content.ReadAsAsync<IEnumerable<Video>>();
}
).Unwrap();
return result;
}
/**** VIEW ******/
#{
ViewBag.Title = "Home Page";
}
#model IEnumerable<IEnumerable<MvcApplication1.Models.Video>>
<table>
#foreach (var memberVideos in Model)
{
<tr>
#foreach(var video in memberVideos){
<td>
<div>#video.Title</div>
<div><img src="http://xxxxxx/membervideos/#video.ImageUrl" style="width: 185px;"/> </div>
</td>
}
</tr>
}
</table>
<h1>#ViewBag.Elapsed</h1>

running stored procedures into own model with servicestack ormlite

Is there any examples to be found for running a stored procedure on serviceStack MVC using ormlite? mythz ? seen this block of code:
var results = new List<EnergyCompare>
{dbFactory.Exec(dbCmd =>
{
dbCmd.CommandType = CommandType.StoredProcedure;
dbCmd.Parameters.Add(new SqlParameter("#id", 1));
dbCmd.CommandText = "GetAuthorById";
return dbCmd.ExecuteReader().ConvertTo<EnergyCompare>();
}
)};
but came with the text of never worked on the google groups!
i can also write this:
using(var db = new SwitchWizardDb())
{
var results2 = db.dbCmd.ExecuteProcedure()
}
but not sure how to complete this with parameters, and in the source code I looked at, it said obsolete?
thanks
Looks like ServiceStack.ORMLite has been updated to make this easier:
List<Poco> results = db.SqlList<Poco>("EXEC GetAnalyticsForWeek 1");
List<Poco> results = db.SqlList<Poco>("EXEC GetAnalyticsForWeek #weekNo", new { weekNo = 1 });
List<int> results = db.SqlList<int>("EXEC GetTotalsForWeek 1");
List<int> results = db.SqlList<int>("EXEC GetTotalsForWeek #weekNo", new { weekNo = 1 });
This example is on the front page of the github repo.
Well I figured it was best to roll my own handler so have created this, any thoughts would be most welcome, especially with how I could pass over params in some kind of func or something:
I have a main class to deal with easy access to my connection object:
public class DatabaseNameSp : IDisposable
{
private readonly SqlConnection _spConn = new SqlConnection(DatabaseNameSp .dbConString);
public readonly SqlCommand SpCmd;
public DatabaseNameSp (string procedureName)
{
_spConn.Open();
SpCmd = new SqlCommand
{
Connection = _spConn,
CommandType = CommandType.StoredProcedure,
CommandText = procedureName
};
}
public void Dispose()
{
_spConn.Close();
SpCmd.Dispose();
}
}
usage:
using (var db = new DatabaseNameSp ("procedurenname"))
{
db.SpCmd.Parameters.Add(new SqlParameter("#Id", 1));
var rdr = db.SpCmd.ExecuteReader(CommandBehavior.CloseConnection);
var results = new List<CustomDTO>();
while (rdr.Read())
{
results.Add(new CustomDTO { Name = rdr["name"].ToString(), Id = rdr["id"].ToString() });
}
return new CustomDTOResponse { Results = results };
}
Any thoughts !
thanks
Here is an example of running a stored procedure with ormLite that may help you:
IList<MyDTO> myList = DbFactory.Run(dbCnx =>
{
using (var dbCmd = dbCnx.CreateCommand())
{
dbCmd.CommandType = CommandType.StoredProcedure;
dbCmd.CommandText = "mySchema.myStoredProc";
dbCmd.Parameters.Add(new SqlParameter("#param1", val1));
dbCmd.Parameters.Add(new SqlParameter("#param2", val2));
var r = dbCmd.ExecuteReader();
return r.ConvertToList<MyDTO>();
}
});
To just simply run a stored procedure with no data returned:
public class ComsManager : Dbase
{
private IDbConnection dbConn;
public ComsManager()
{
dbConn = Dbase.GetConnection();
}
public void Housekeeping()
{
using(var dbCmd = dbConn.CreateCommand())
dbConn.Exec(res => { dbCmd.CommandType = CommandType.StoredProcedure; dbCmd.CommandText = "SP_housekeeping"; dbCmd.ExecuteNonQuery(); });
}

Resources