Getting ID attribute when event is fired (subscriptions) - dom

I have a subscription to calculate (Calculate String msg) something when user is writing on some divs (contenteditable).
subscriptions : CvModel -> Sub Msg
subscriptions _ =
onKeyUp (Decode.succeed Calculate) -- I need add the id element in message.
But, how I can get id attribute of the div where user is writing?

The decoder that you pass to onKeyUp is decoding the event object, so you can extract the id property of the target element (much like targetValue).
onKeyUp (Decode.at ["target", "id"] Decode.string |> Decode.map Calculate)
There's an example app at https://ellie-app.com/9MVn2Zsxptva1

Related

RxSwift - change specific object in PublishSubject on event

struct Contact : Codable, Hashable {
var id : String
...
}
I use PublishSubject to feed the data to the UITableView
let contacts : PublishSubject<[Contact]> = PublishSubject()
And when the value is changed on the other view controller, I want to change the specific value in the array.
I want to change the Contact object with the specific id.
contacts.filter {$0.id == contactId}[0].someKey = someValue
How can I do this with RxSwift?
Understand that a PublishSubject doesn't contain any state so there is nothing in it that you can change. Instead, you emit a new array from the publish subject with a new contact that has the new value.
Somewhere in your code, you are calling onNext(_:) on the subject (or connecting it to an Observable that is doing that. We would need to see that code to help you solve your problem.

Scala Play Framework Editing a value and storing the new value

I have a need in my web application where I need to allow a user to update an existing item. However I want to know how I can store the original value so that it can be deleted and the new one used once the user has filled in the form.
Let me expand a bit:
Basically, I initially provide the user with a form to fill. After the form is filled in, I create an object from the properties of the form - things like age, name, height, etc are stored in an object, let's call it Person:
case class Person(age: Int, name: String, height: Int)
Now this information can be edited when the user clicks an edit button beside the item. So on the website, there is an option to edit the person.
My question is, how do I store the previous person, and once the user presses Update on the site, I am able to delete the original person object and replace it with the new one?
My current solution is to store the original object in the Session (as JSON), then when the form is updated, I read the JSON from the session to do more work.
I feel like this is not safe because (correct me if I'm wrong) it is possible to change the session data json from outside the app, thus allowing someone to change the person's name or something and I will not know this and then delete the wrong person from the list rather than the one I was going to update.
def editPerson(name: String) = Action { implicit request =>
Person.findByName(name).map { person =>
val form = personForm.fill(person)
Ok(views.html.persons.editPerson(form))
.addingToSession(("Edit", Json.prettyPrint(Json.toJson(person))))
} getOrElse NotFound
}
The above method is mapped to a route which allows one to specify a person to edit. When the Update button is pressed, the following controller method is called:
def save = Action { implicit request =>
val newPersonForm = personForm.bindFromRequest()
newPersonForm.fold(
hasErrors = { form =>
request.session.get("Edit").map { person =>
Redirect(routes.Persons.editPerson(person.name))
.flashing(Flash(form.data) + ("error" -> Messages("validation.errors")))
} getOrElse(BadRequest.removingFromSession("Edit"))
},
success = { newPerson =>
request.session.get("Edit").foreach { prevP =>
Person.remove(prevP) // delete the person that was edited
}
Person.add(newPerson) // add the new person
val message = Messages("persons.new.success", newPerson.name)
Redirect(routes.Persons.show(newPerson.name)).flashing("success" -> message).removingFromSession("Edit")
}
)
}
What the above save method does is that if the form was completed with errors, the person information is read once again from the session and we are redirected to the edit page once more.
If the form has no errors, we once again read the person information from the session and this time, it is deleted and the new person added.
What other methods can I use to ensure that the object is not exposed to the outside and remains within the controller until the user enters valid values in the form, at which point the object to edit is then deleted and the new one added?

Populate Tabular form field value with change of another field

There is a Tabular form with description, previous_value, unit_price fields in my Oracle Apex app.
I need to populate value of previous_value field with data on description field. I have a query to get value for previous_value field from database. i need to add onChange event to description field. with the changes in description field, value for previous_value field should be populate using my query.
how could i do this ?
You can bind the change event to the field in several ways. Target through the td headers,
or edit the column, and in the "Element attributes" field you could add a class (eg "fireAjax").
You can then bind to the event with either javascript code, or do this via a dynamic action.
You can do an ajax call in either of these 2 forms: through htmldb_Get or with jquery.post:
$('td[headers="ENAME"] input').change(function(){
var ajaxRequest = new htmldb_Get( null , $v('pFlowId') , 'APPLICATION_PROCESS=get_job' , $v('pFlowStepId'));
ajaxRequest.addParam('x01', $(this).val());
ajaxResult = ajaxRequest.get();
$(this).closest("tr").find("td[headers='JOB'] input").val(ajaxResult);
});
OR
$('td[headers="ENAME"] input').change(function(){
var that = this;
$.post('wwv_flow.show',
{"p_request" : "APPLICATION_PROCESS=get_job",
"p_flow_id" : $v('pFlowId'),
"p_flow_step_id" : $v('pFlowStepId'),
"p_instance" : $v('pInstance'),
"x01" : $(this).val()
},
function(data){
var eJob = $(that).closest("tr").find("td[headers='JOB'] input");
eJob.val(data);
},
"text"
);
});
With this application process, defined on the page with execution point "AJAX Callback":
Name: get_job
DECLARE
l_job emp.job%TYPE;
BEGIN
SELECT job
INTO l_job
FROM emp
WHERE ename = apex_application.g_x01;
htp.p(l_job);
EXCEPTION WHEN no_data_found THEN
htp.p('');
END;
Remember, handling errors and return in this process is up to you! Make sure you catch common errors such as no_data_found and/or too_many_rows. If they occur and are not trapped, chances are big you will encounter javascript errors because your javascript callback code can not handle the error (which in apex will be a full page html with the error message in it).
Also, as you can see i'm using the x01 variable, which is one of the 10 global temporary variables in apex. This way it is not required to use a page item and submit the value to session state for it.
If you want to put this code in a dynamic action you can. Pick "Change" as event and jQuery selector if you go for a dynamic action, and as true action pick execute javascript code. You can then put the function code in there. With the exception that $(this)will need to be $(this.triggeringElement)

Validation on DataTable when new row is added

When a new row was added programmatically using an auto generated method on my strongly typed DataTable, How can I fire my custom validation which validate the maxleng of my field?
My client (C#)
DAL.ImportMarcDataSet.PublicationsRow newRow = importMarcDataSet.Publications.NewPublicationsRow();
newRow.CallNumber ="QA76.76.A65";
newRow.Title = "Programming WCF services";
newRow.ISBN = "0596526997";
importMarcDataSet.Publications.AddPublicationsRow(newRow);
My Data Access Layer (VB)
Partial Class ImportMarcDataSet
Partial Class PublicationsDataTable
Private Sub CallNumberMaxLength(ByVal pRow As PublicationsRow)
If pRow.CallNumber.Length > 25 Then
pRow.SetColumnError("CallNumber", "The value entered is over the maximum length")
Else
pRow.SetColumnError("CallNumber", "")
End If
End Sub
'this event is ok when user made changes to the CallNumber column of the current row
Private Sub PublicationsDataTable_ColumnChanged(ByVal sender As Object, ByVal e As System.Data.DataColumnChangeEventArgs) Handles Me.ColumnChanged
If e.Column Is Me.CallNumberColumn Then
CallNumberMaxLength(e.Row)
End If
End Sub
End Class
End Class
You can handle the table's RowChanging event. When the DataRowChangeEventArgs.Action is equal to Add or one of the change... actions do your validation.
It has been a long time since I did this, but I believe you can even cancel the edit if needed by calling CancelEdit on the DataRowChangeEventArgs.Row. Check the documentation. See Handling DataTable Events (ADO.NET) at http://msdn.microsoft.com/en-us/library/w9y9a401.aspx.
The TableNewRow will not help because it is only raised when NewRow is called.

MVC2 Add Collection of Object to Another Object

Not sure if this has been asked before, but I have an object (Restaurant) and I have a details view of that restaurant. On that details view, I want to have a list of cuisines that the restaurant offers. I want to also have a dropdownlist of the available cuisines and have the ability to click an "Add" button and it adds that cuisine to the Restaurant. I have a RestaurantCuisine table (using Entity Framework) that has a foreign key of the ID of the cuisine from a Cuisine table that has a primary key of ID.
So, now, my question, how do I do this? I sortof understand the concept behind the Create view and then the Create view post, but in this case, I'm not posting back the Restaurant object. So, how do I get the restaurant ID and the Cuisine ID so that I can add that to the restaurant cuisine collection?
Ok, so, now after investigating more, I believe I have asked the wrong question. My actual issue, is that I have a View that displays a Restaurant's details and I have a Details function in my controller for it. This works fine. The next step I want to do is have a dropdownlist with available Cuisines that this restaurant offers and have an 'Add' button next to it. And if you click on the 'Add' button, it adds the value of the item in the dropdownlist to the collection of cuisines setup in the Restaurant object.
Is this "easily" possible? I'm beginning to lose my faith in MVC2 :(
Ok, last try here. Let me ask this, does anyone know how to have a dropdownlist (I have now got this created) and have an "Add" button next to it, and get the selected value from that dropdownlist?
For those of you attempting to use VB.Net with MVC, I'm saying a prayer for you. It's rough. There are rarely any examples, and some syntax is not available that IS available in C#. So, as far as the answer to my original question. It seems as though it was my inexperience that caused the instant flare of the question.
After analying my problem, I figured out a way around it. First of all, let me clarify what I was attempting to do then explain what I did. The goal was to have an object (Restaurant in my case). And I wanted to have a list of properties (cuisines in my case) displayed on the Details view that I could assign to that object (Restaurant). The properties were cuisines that I had setup in a Cuisines table (CuisineId, Name, Description) and when you add a cuisine to a restaurant, it writes a record in another table RestaurantCuisine (RestaurantCuisineId, RestaurantId, CuisineId). So, getting the list of cuisines was the first task and have them display in a dropdownlist. That was done by creating a SelectList of cuisines in the Details view function by creating a CuisineRepository and calling a function that gets a list of all cuisines:
Dim cuiss As New CuisineRepository()
ViewData("Cuisines") = New SelectList(cuiss.FindAllCuisines().ToList(), "CuisineId", "Name")
Once you have this setup as a SelectList, it's easy to display that on the view by doing the following:
<h3>Cuisines:</h3>
<br />
<%= Html.DropDownList("Cuisines")%>
So, the problem after this was the real problem. I wanted to have an ActionLink that would be bound to the value of the DropDownList. I was unsuccessful in this attempt. But luckily, my jQuery is not dusty so I performed a little magic by doing the following:
<script type="text/Javascript">
$(document).ready(function () {
$('#Cuisines').change(function (e) {
$('#SelectedCuisine').val($('#Cuisines').val());
setHref($(this).val());
});
setHref($('#Cuisines').val());
});
function setHref(val) {
if (val) {
$("#addCuisine").attr('href', '/Restaurant/AddCuisine/' + $('#RestaurantId').val() + '?cuisineId=' + val);
}
}
</script>
<h3>Cuisines:</h3>
<br />
<%= Html.DropDownList("Cuisines")%>
<a id="addCuisine" href="">Add</a>
So, as you can see, I simply modify the href of the anchor as the user changes the selected Cuisine. Then, in my controller, I have a function setup to add a cuisine and to remove a cuisine from a restaurant:
Function AddCuisine(ByVal id As Guid, ByVal cuisineId As String) As ActionResult
Try
If ModelState.IsValid Then
'Dim selcuisInp As HtmlInputHidden = ViewData("SelectedCuisine")
Dim selectedCuisineId As Guid = New Guid(cuisineId)
Dim rc As New RestaurantCuisine
rc.RestaurantCuisineId = Guid.NewGuid
rc.RestaurantId = id
rc.CuisineId = selectedCuisineId
'rc.CuisineId = New Guid(selList.SelectedValue.ToString)
rc.CreatedDate = DateTime.Now()
'rc.CreatedBy =
db.AddToRestaurantCuisines(rc)
db.SaveChanges()
End If
Return RedirectToAction("Details", New With {.id = id})
Catch e As Exception
Dim innerE As String = e.InnerException.ToString
Return RedirectToAction("Details", New With {.id = id})
End Try
End Function
Function DeleteRestaurantCuisine(ByVal id As Guid) As ActionResult
Dim rc = (From rcs In db.RestaurantCuisines
Where rcs.RestaurantCuisineId = id
Select rcs).Single()
Dim rid As Guid = rc.RestaurantId
Try
db.RestaurantCuisines.DeleteObject(rc)
db.SaveChanges()
Return RedirectToAction("Details", New With {.id = rid})
Catch ex As Exception
Return RedirectToAction("Details", New With {.id = rid})
End Try
End Function
Notice the RedirectToAction. I had to pass the id of the object (Restaurant) that the Details view required and couldn't find the syntax anywhere. Finally, after a while of searching, found this site that the guy has a few examples of controllers and luckily he gives examples of both C# and VB. To add routeValues to the RedirectToAction, you declare a new list, and use an inline with and add your values with a period (.) preceding them:
Return RedirectToAction("Details", New With {.id = rid})
I hope this helps someone. It sure made the difference in my decision to use MVC. I am 100% sold even though I know I'm going to run into many roadblocks along the way.