I have two div html elements (with contenteditable attribute) and I would like to get de id attribute of the element when keypress is triggered (onblur event as well).
This is my current code (it does not work, I have added any comments):
module Mytest exposing (main)
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Json.Decode as Json
import Debug
type alias Model =
{ div1 : String
, div2 : String
}
initialModel : Model
initialModel =
{ div1 = "test1"
, div2 = "test2"
}
init : () -> ( Model, Cmd Msg )
init () =
( initialModel, Cmd.none )
view : Model -> Html Msg
view model =
div []
[ div [ id "div1", contenteditable True, onKeyPress KeyPressed ] [ text model.div1 ]
, div [ id "div2", contenteditable True, onKeyPress KeyPressed ] [ text model.div2 ]
]
type Msg
= KeyPressed Int
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
KeyPressed code ->
let
-- is there any way to use Debug.log without let block?
a = Debug.log "div1 event" code
in
-- keypressed on div1 should be update div1 field model
-- the same to div2
({model | div1 = String.fromInt code}, Cmd.none)
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
main : Program () Model Msg
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
onKeyPress : (Int -> msg) -> Attribute msg
onKeyPress tagger =
on "keypress" (Json.map tagger keyCode)
EDIT:
The following examples do not trigger the events in div contenteditable:
onInput : (String -> msg) -> Attribute msg
onInput tagger =
on "input" (Json.map tagger keyCode)
onBlur : (String -> msg) -> Attribute msg
onBlur tagger =
on "blur" (Json.map tagger targetValue)
onInput : (String -> msg) -> Attribute msg
onInput tagger =
stopPropagationOn "DOMCharacterDataModified" <|
Json.map alwaysStop (Json.map tagger (Debug.log "bbb" targetValue))
alwaysStop : a -> (a, Bool)
alwaysStop x =
(x, True)
However, in javascript it works: http://jsfiddle.net/MBags/
Unless there are additional constraints not evident from your example you could just add an extra argument to KeyPressed and pass the id through that:
type Msg
= KeyPressed String Int
view : Model -> Html Msg
view model =
div []
[ div [ id "div1", contenteditable True, onKeyPress (KeyPressed "div1") ] [ text model.div1 ]
, div [ id "div2", contenteditable True, onKeyPress (KeyPressed "div2") ] [ text model.div2 ]
]
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
KeyPressed id code ->
-- Now you have the id
However, you probably shouldn't rely on string ids in the first place, since stringly typed data is very error-prone. Ideally you'd have separate Msg variants for each component:
type Msg
= Div1KeyPressed Int
| Div2KeyPressed Int
Or if you need a bit more dynamism you could use a custom Id type:
type Id
= Div1
| Div2
type Msg
= KeyPressed Id Int
view : Model -> Html Msg
view model =
div []
[ div [ contenteditable True, onKeyPress (KeyPressed Div1) ] [ text model.div1 ]
, div [ contenteditable True, onKeyPress (KeyPressed Div2) ] [ text model.div2 ]
]
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
KeyPressed Div1 code ->
-- update model.div1
KeyPressed Div2 code ->
-- update model.div2
Related
Does anyone know how to recreate sampling behavior in Combine?
Here's a diagram of the sample's behavior in RXMarbles
The gist of sample() is that there are two streams, when one is triggered, the latest value of the other stream is sent if it already hasn't been sent.
The CombineExt library has the withLatestFrom operator which does what you want, along with many other useful operators.
Here is a Playground that might do what you want. I didn't do a whole lot of testing on it so please proceed with caution:
import UIKit
import Combine
import PlaygroundSupport
struct SamplePublisher<DataSeq, Trigger, E> : Publisher
where DataSeq : Publisher,
Trigger : Publisher,
DataSeq.Failure == Trigger.Failure,
E == DataSeq.Failure,
DataSeq.Output : Equatable {
typealias Output = DataSeq.Output
typealias Failure = E
// The two sequences we are observing, the data sequence and the
// trigger sequence. When the trigger fires it will send the
// latest value from the dataSequence UNLESS it hasn't changed
let dataPublisher : DataSeq
let triggerPublisher : Trigger
struct SamplePublisherSubscription : Subscription {
var combineIdentifier = CombineIdentifier()
let dataSubscription : AnyCancellable
let triggerSubscription : Subscription
func request(_ demand: Subscribers.Demand) {
triggerSubscription.request(demand)
}
func cancel() {
dataSubscription.cancel()
triggerSubscription.cancel()
}
}
func receive<S>(subscriber: S) where S : Subscriber, E == S.Failure, DataSeq.Output == S.Input {
var latestData : DataSeq.Output?
var lastSent : DataSeq.Output?
var triggerSubscription : Subscription?
// Compares the latest value sent to the last one that was sent.
// If they don't match then it sends the latest value along.
// IF they do match, or if no value has been sent on the data stream yet
// Don't emit a new value.
func emitIfNeeded() -> Subscribers.Demand {
guard let latest = latestData else { return .unlimited }
if nil == lastSent ||
lastSent! != latest {
lastSent = latest
return subscriber.receive(latest)
} else {
return .unlimited
}
}
// Here we watch the data stream for new values and simply
// record them. If the data stream ends, or erors we
// pass that on to our subscriber.
let dataSubscription = dataPublisher.sink(
receiveCompletion: {
switch $0 {
case .finished:
subscriber.receive(completion: .finished)
case .failure(let error):
subscriber.receive(completion: .failure(error))
}
},
receiveValue: {
latestData = $0
})
// The thing that subscribes to the trigger sequence.
// When it receives a value, we emit the latest value from the data stream (if any).
// If the trigger stream ends or errors, that will also end or error this publisher.
let triggerSubscriber = AnySubscriber<Trigger.Output,Trigger.Failure>(
receiveSubscription: { subscription in triggerSubscription = subscription },
receiveValue: { _ in emitIfNeeded() },
receiveCompletion: {
switch $0 {
case .finished :
emitIfNeeded()
subscriber.receive(completion: .finished)
case .failure(let error) :
subscriber.receive(completion: .failure(error))
}
})
// subscribe to the trigger sequence
triggerPublisher.subscribe(triggerSubscriber)
// Record relevant information and return the subscription to the subscriber.
subscriber.receive(subscription: SamplePublisherSubscription(
dataSubscription: dataSubscription,
triggerSubscription: triggerSubscription!))
}
}
extension Publisher {
// A utility function that lets you create a stream that is triggered by
// a value being emitted from another stream
func sample<Trigger, E>(trigger: Trigger) -> SamplePublisher<Self, Trigger, E>
where Trigger : Publisher,
Self.Failure == Trigger.Failure,
E == Self.Failure,
Self.Output : Equatable {
return SamplePublisher( dataPublisher : self, triggerPublisher : trigger)
}
}
var count = 0
let timer = Timer.publish(every: 5.0, on: RunLoop.current, in: .common).autoconnect().eraseToAnyPublisher()
let data = Timer.publish(every: 1.0, on: RunLoop.current, in: .common)
.autoconnect()
.scan(0) { total, _ in total + 1}
var subscriptions = Set<AnyCancellable>()
data.sample(trigger: timer).print()
.sink(receiveCompletion: {
debugPrint($0)
}, receiveValue: {
debugPrint($0)
}).store(in: &subscriptions)
PlaygroundSupport.PlaygroundPage.current.needsIndefiniteExecution = true
I have a view that depends both on a #ObservedObject and a #State.
In a Button action, I modify them both, and this leads to a crash. If I modify only the #ObservedObject, then everything is OK (except, I don't get the intended behavior, of course).
public struct PointListEditorView: View {
#ObservedObject var viewModel: PointListEditorViewModel
#State var selectedCellIndex: Int = NO_CELL_SELECTED_INDEX
public var body: some View {
(...)
Button(action: {
let savedSelectedCellIndex = self.selectedCellIndex
self.selectedCellIndex = NO_CELL_SELECTED_INDEX // No crash if I remove this line
self.viewModel.removePointEditorViewModel(at: savedSelectedCellIndex)
},
label: (...)
What happens is that I have a crash in the body of a subview after the call to removePointEditorViewModel. This body goes through an array of objects that is modified by removePointEditorViewModel. removePointEditorViewModel triggers the #Published variables of the #ObservedObject.
The same thing happens if I invert both lines like this :
self.viewModel.removePointEditorViewModel(at: savedSelectedCellIndex)
self.selectedCellIndex = NO_CELL_SELECTED_INDEX//##
I first thought there would be some kind of strange interference between #State and #ObservedObject, but the first answers (thanks guys) pointed me in another direction.
Edit to provide more information
Edit 2 to make the title and the rest consistent with the current investigations
Here is the hierarchy of my views :
PointListEditorView
+ PointListEditorContentView
+ PointListEditorCellView (n times)
The PointListEditorView has this selectedCellIndex #State. This state is binded by PointListEditorContentView and PointListEditorCellView. It is modified by PointListEditorCellView through a tapGesture.
I have logged the entry and exit of the body computation. I have also logged the creation of PointListEditorCellView, and when I deleted things in my model. I have spotted some strange things.
**APP START**
Enter PointListEditorView body
Exit PointListEditorView body
Enter PointListEditorContentView body
count of pointEditorViewModels : 0
count of pointEditorViewModelsAndIndex : 0
End preparation PointListEditorContentView body
Exit PointListEditorContentView body
**ADD ONE CELL**
Enter PointListEditorContentView body
count of pointEditorViewModels : 1
map call with index : 0
count of pointEditorViewModelsAndIndex : 1
End preparation PointListEditorContentView body
Exit PointListEditorContentView body
created PointListEditorCellView : 35779A71-811F-42DD-A803-3C0E82C3CAD8
Enter PointListEditorCellView body : 35779A71-811F-42DD-A803-3C0E82C3CAD8
Exit PointListEditorCellView body
Enter PointListEditorView body
Exit PointListEditorView body
All this looks pretty normal to me. But now :
**SELECT THE CELL**
Enter PointListEditorView body
Exit PointListEditorView body
Enter PointListEditorContentView body
count of pointEditorViewModels : 1
map call with index : 0
count of pointEditorViewModelsAndIndex : 1
End preparation PointListEditorContentView body
Exit PointListEditorContentView body
Enter PointListEditorCellView body : 35779A71-811F-42DD-A803-3C0E82C3CAD8
<== Why the hell do we have that ???
This is the cell view created at previous step. It
should be forgotten and replaced by another one
as seen below
Exit PointListEditorCellView body
created PointListEditorCellView : 2EA80249-67B6-46A0-88C9-C5F5E8FEAE80
Enter PointListEditorCellView body : 2EA80249-67B6-46A0-88C9-C5F5E8FEAE80
Exit PointListEditorCellView body
**DELETE THE CELL**
Enter delete callback
Delete model element
#Published var modified, the view is notified
Exit delete callback
Enter PointListEditorView body
Exit PointListEditorView body
Enter PointListEditorContentView body
count of pointEditorViewModels : 0
count of pointEditorViewModelsAndIndex : 0
<== This shows there is nothing in the model, there should be
no cell view created - just like during app init
End preparation PointListEditorContentView body
Exit PointListEditorContentView body
Enter PointListEditorCellView body : 2EA80249-67B6-46A0-88C9-C5F5E8FEAE80
Fatal error: Index out of range: file /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.8.25.8/swift/stdlib/public/core/ContiguousArrayBuffer.swift, line 444
<== This "ghost" cell is refering to a model elemnt that
has been deleted, os of course there is a crash, but why
does this cell still exist ???
After some more investigations, I managed to spot that the "retain" only happens when I have a tapGesture attached to the cell view. This is done in the PointListEditorContentView view this way :
struct PointListEditorCellView: View
var pointEditorViewModel: PointEditorBaseViewModel
var index: Int
#Binding var selectedCellIndex: Int
var body: some View {
VStack(spacing: 3.0) {
PointEditorView(pointEditorViewModel)
.onTapGesture {
if (self.selectedCellIndex == self.index) {
self.selectedCellIndex = NO_CELL_SELECTED_INDEX
} else {
self.selectedCellIndex = self.index
}
}
}
}
If I remove the .gesture, I don't see the ghost appear.
There is no interference between #State and #ObservedObject.
With the little code you provided, I would look hard into the
self.viewModel.removePointEditorViewModel(at: savedSelectedCellIndex)
is the index (savedSelectedCellIndex) valid for that model?
I finally found a solution.
From my point of view, this "ghost" views are the consequence of a bug inside SwiftUI. I came to this conclusion after flattening the view hierarchy, and suddenly, everything went fine.
I had the following code :
struct PointListEditorContentView: View {
#ObservedObject var viewModel: PointListEditorBaseViewModel
init(_ vm: PointListEditorBaseViewModel) {
self.viewModel = vm
}
var body: some View {
let pointEditorViewModels = viewModel.pointEditorViewModelsList()
let pointEditorViewModelsAndIndex = pointEditorViewModels.enumerated().map { (index, vm) in
return (vm: vm,
index: index)
}
return VStack(spacing: 3.0) {
ForEach(pointEditorViewModelsAndIndex, id: \.vm.id) { pointEditorViewModel in
PointListEditorCellView(pointListEditorViewModel: self.viewModel,
pointEditorViewModel: pointEditorViewModel.vm,
index: pointEditorViewModel.index)
}
PointListEditorDropableView(viewModel: viewModel,
positionOfDroppedItem: pointEditorViewModels.count)
}
.padding()
}
}
struct PointListEditorCellView: View {
#ObservedObject var pointListEditorViewModel: PointListEditorBaseViewModel
#ObservedObject var pointEditorViewModel: PointEditorBaseViewModel
var index: Int
var body: some View {
VStack(spacing: 3.0) {
PointListEditorDropableView(viewModel: pointListEditorViewModel,
positionOfDroppedItem: index)
.fixedSize(horizontal: false, vertical: true)
PointEditorView(pointEditorViewModel)
.shadow(color: (self.pointListEditorViewModel.selectedCellIndex == index ? Color.accentColor : Color.clear),
radius: (self.pointListEditorViewModel.selectedCellIndex == index ? 5.0 : 0.0))
.onTapGesture {
if (self.pointListEditorViewModel.selectedCellIndex == self.index) {
self.pointListEditorViewModel.selectedCellIndex = NO_CELL_SELECTED_INDEX
} else {
self.pointListEditorViewModel.selectedCellIndex = self.index
}
}
.onDrag {
let itemProvider = NSItemProvider()
itemProvider.registerObject(PointListEditorItemProvider(initialIndex: self.index),
visibility: .ownProcess)
return itemProvider
}
}
}
}
I just moved the content of the PointListEditorCellView body inside the ForEach like the following code, and everything went suddenly fine.
struct PointListEditorContentView: View {
#ObservedObject var viewModel: PointListEditorBaseViewModel
init(_ vm: PointListEditorBaseViewModel) {
self.viewModel = vm
}
var body: some View {
let pointEditorViewModels = viewModel.pointEditorViewModelsList()
let pointEditorViewModelsAndIndex = pointEditorViewModels.enumerated().map { (index, vm) in
return (vm: vm,
index: index)
}
return VStack(spacing: 3.0) {
ForEach(pointEditorViewModelsAndIndex, id: \.vm.id) { pointEditorViewModel in
VStack(spacing: 3.0) {
PointListEditorDropableView(viewModel: self.viewModel,
positionOfDroppedItem: pointEditorViewModel.index)
.fixedSize(horizontal: false, vertical: true)
PointEditorView(pointEditorViewModel.vm)
.shadow(color: (self.viewModel.selectedCellIndex == pointEditorViewModel.index ?
Color.accentColor : Color.clear),
radius: (self.viewModel.selectedCellIndex == pointEditorViewModel.index ? 5.0 : 0.0))
.onTapGesture {
if (self.viewModel.selectedCellIndex == pointEditorViewModel.index) {
self.viewModel.selectedCellIndex = NO_CELL_SELECTED_INDEX
} else {
self.viewModel.selectedCellIndex = pointEditorViewModel.index
}
}
.onDrag {
let itemProvider = NSItemProvider()
itemProvider.registerObject(PointListEditorItemProvider(initialIndex:
pointEditorViewModel.index),
visibility: .ownProcess)
return itemProvider
}
}
}
PointListEditorDropableView(viewModel: viewModel,
positionOfDroppedItem: pointEditorViewModels.count)
}
.padding()
}
}
I am documenting this in SO, so that if anybody has a different (and better explanation than just "it's a SwiftUI bug"), we can record the discussion.
I modify the example of Fabulous for Xamarin.Forms (Using Maps, full Elmish) : "https://fsprojects.github.io/Fabulous/Fabulous.XamarinForms/views-maps.html". However, the outcome is not same as I expected. The map wasn't shown, please advise how to fix the problem. Thank you.
// Copyright 2018-2019 Fabulous contributors. See LICENSE.md for license.
namespace SqueakyApp
open System.Diagnostics
open Fabulous
open Fabulous.XamarinForms
open Fabulous.XamarinForms.LiveUpdate
open Fabulous.XamarinForms.MapsExtension
open Xamarin.Forms
open Xamarin.Forms.Maps
module App =
// Declaration
type Model =
{ Count : int
Step : int
Pressed : bool }
type Msg =
| Increment
| Decrement
| UserLocation
// Functions
// Lifecycle
let initModel =
{ Count = 0
Step = 0
Pressed = false }
let init() = initModel, Cmd.none
let update msg model =
match msg with
| Increment -> { model with Count = model.Count + model.Step }, Cmd.none
| Decrement -> { model with Count = model.Count - model.Step }, Cmd.none
| Reset -> init()
let view (model : Model) dispatch =
let paris = Position(48.8566, 2.3522)
let london = Position(51.5074, -0.1278)
let calais = Position(50.9513, 1.8587)
let timbuktu = Position(16.7666, -3.0026)
let map =
View.Map
(hasZoomEnabled = true, hasScrollEnabled = true,
pins = [ View.Pin(paris, label = "Paris", pinType = PinType.Place)
View.Pin(london, label = "London", pinType = PinType.Place) ],
requestedRegion = MapSpan.FromCenterAndRadius(calais, Distance.FromKilometers(300.0)))
// View
View.ContentPage(content = map)
// Note, this declaration is needed if you enable LiveUpdate
let program = Program.mkProgram init update view
type App() as app =
inherit Application()
let runner =
App.program
|> Program.withConsoleTrace
|> XamarinFormsProgram.run app
Screen Shot
Learning an example from Timothé Larivière (https://github.com/TimLariviere/FabulousContacts).
It is necessary to initialize the FormsMaps in the file "AppDelegate.fs" under the sub-directory .iOS. There is a source file for reference.
// Copyright 2018 Fabulous contributors. See LICENSE.md for license.
namespace SqueakyApp.iOS
open System
open UIKit
open Foundation
open Xamarin
open Xamarin.Forms
open Xamarin.Forms.Platform.iOS
[<Register ("AppDelegate")>]
type AppDelegate () =
inherit FormsApplicationDelegate ()
override this.FinishedLaunching (app, options) =
Forms.Init()
FormsMaps.Init() //*** initialization the FormsMaps is required
let appcore = new SqueakyApp.App()
this.LoadApplication (appcore)
base.FinishedLaunching(app, options)
module Main =
[<EntryPoint>]
let main args =
UIApplication.Main(args, null, "AppDelegate")
0
In Golang ozzo-validation, how can I validate a field which is dependent on another field ?
For example, if I have the following:
return validation.ValidateStruct(&c,
validation.Field(&c.Name, validation.Required, validation.Length(5, 20)),
validation.Field(&c.Gender, validation.In("Female", "Male")),
validation.Field(&c.Email, is.Email),
validation.Field(&c.Address),
How can I add a validation that the Address is required only if email is not empty?
You can achieve it in two ways-
Adding your own custom rules
Conditionally add FieldRules based on precondition-value i.e check Email while creating field rules then supply it to validation.ValidateStruct
For e.g.:
type Sample struct {
Name string
Gender string
Email string
Address Address
}
type Address struct {
// ... fields
}
func (s Sample) Validate() error {
var fieldRules []*validation.FieldRules
fieldRules = append(fieldRules, validation.Field(&s.Name, validation.Required, validation.Length(5, 20)))
fieldRules = append(fieldRules, validation.Field(&s.Gender, validation.In("Female", "Male")))
fieldRules = append(fieldRules, validation.Field(&s.Email, is.Email))
if len(strings.TrimSpace(s.Email)) > 0 {
fieldRules = append(fieldRules, validation.Field(&s.Address, validation.Required))
fieldRules = append(fieldRules, validation.Field(&s.Address))
}
return validation.ValidateStruct(&s, fieldRules...)
}
The library now supports conditional validation by the validation.When function.
Here is a code snipped which fits the validation you described.
package main
import (
"fmt"
validation "github.com/go-ozzo/ozzo-validation" // or "github.com/go-ozzo/ozzo-validation/v4" if "When" not found
)
type Entry struct {
Name string
Gender string
Email string
Address string
}
func main() {
v := func(e Entry) {
fmt.Println(validation.ValidateStruct(&e,
validation.Field(&e.Name, validation.Required, validation.Length(5, 20)),
// Note that if gender is "" and not required, validation returns no error.
validation.Field(&e.Gender, validation.Required, validation.In("Female", "Male")),
validation.Field(&e.Address, validation.When(e.Email != "", validation.Required.Error("Address is required if Email is set"))),
))
}
// All is fine for no Email.
e := Entry{
Name: "My name is!",
Gender: "Male",
}
v(e)
// Validation fails for Email and no Address.
e = Entry{
Name: "My name is!",
Gender: "Male",
Email: "a#org.com",
}
v(e)
}
It outputs.
<nil>
Address: Address is required if Email is set.
The library documentation describes it as well: https://github.com/go-ozzo/ozzo-validation#conditional-validation
Helo !
I have a problem with display some data from an array to a NSTableView .
I have my info saved in core data. I take this info and add to an array, but when i try to add this info in table, all what i receive is a table with correct numbers of rows, but all have the same implicit text : "TableView Cell" .
For every table column i've set an identifier , and my binds, i think, they are made correctly.
Here is my code for Table Controller :
#IBAction func reload(sender: NSButton) {
tableView.reloadData()
}
func getItemsFromDataBase() {
let fetchRequest = NSFetchRequest(entityName: "MyData")
// Create a sort descriptor object that sorts on the "title"
// property of the Core Data object
let sortDescriptor = NSSortDescriptor(key: "nume", ascending: true)
// Set the list of sort descriptors in the fetch request,
// so it includes the sort descriptor
fetchRequest.sortDescriptors = [sortDescriptor]
if let fetchResults = managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as? [MyData] {
for var i = 0 ; i < fetchResults.count ; i++ {
objects.append(fetchResults[i]) //Get data from database and put in array
}
}
}
func numberOfRowsInTableView(tableView: NSTableView) -> Int {
getItemsFromDataBase()
showNames()
return objects.count
}
func tableView(tableView: NSTableView, objectValueForTableColumn tableColumn: NSTableColumn?, row: Int) -> AnyObject? {
let identifier = tableColumn?.identifier
println(identifier!)
if let propertyEnum = ArrayDisplayProperty(rawValue: identifier!) {
let cellView = tableView.makeViewWithIdentifier(identifier!, owner: self) as NSTableCellView
let object = objects[row]
switch propertyEnum {
case .Nume:
cellView.textField!.stringValue = object.nume
case .Prenume:
cellView.textField!.stringValue = object.prenume
case .Varsta:
cellView.textField!.stringValue = "\(object.varsta)"
case .Localitate :
cellView.textField?.stringValue = object.localitate
case .Major:
cellView.textField?.stringValue = object.major == 1 ? "Yes" : "No"
}
println(object.nume)
return object.varsta
}
return 0
}
Have you bounded only that table column or also that columns Text Field and Text Field Cell?
Both of these Value need to be bounded to Table Cell View with model key path (let say you have entity Person with attribute 'name') objectValue.name. Xcode shows some warning 'cannot resolve the entered key path', but I think that can be ignored.
So example, if I have that entity Person with only one attribute name, my bindings looks like following with Array Controller:
Table View -> Table Content -> Content -> Bind to Array Controller with controller key arrangedObjects
Name column -> Value > Bind to Array Controller with controller key arrangedObjects and Model Key Path name
Text Field -> Value -> Bind to Table Cell View with model key path objectValue.name
Text Field Cell -> Value -> Bind to Table Cell View with model key path objectValue.name
SWIFT Code:--
Follow the steps for populating the data in NSTableView through bindings:-
1) Connect your ArrayController to your FileOwner/Appdelegate:-
2) Select your TableColumns and bind to ArrayController -> arrangedObjects -> Key
3) Now in your method follow below code:-
#IBOutlet weak var arrController : NSArrayController!
var yourArray: NSMutableArray = []
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
var dataArray = [["FirstName": "Debasis", "LastName": "Das"],
["FirstName": "Nishant", "LastName": "Singh"],
["FirstName": "John", "LastName": "Doe"],
["FirstName": "Jane", "LastName": "Doe"],
["FirstName": "Mary", "LastName": "Jane"]];
for var i = 0; i < dataArray.count; i++
{
yourArray.addObject(dataArray[i])
}
arrController.rearrangeObjects()
}